UNPKG

caminte-cli

Version:

Command line interface for CaminteJS ORM

585 lines (560 loc) 20.6 kB
/** * Created by Alex on 8/23/2016. */ var inflection = require('./inflection'); var fs = require('fs'); var path = require('path'); var schema = { define: function (model, fields, ind) { ind = ind || {}; var inst = { model: model, fields: fields, primaryKeys: ind.primaryKeys || [], indexes: ind.indexes || {}, validated: [], validate: function (field, callback, params) { "use strict"; // todo: }, validateAsync: function (field, callback, params) { "use strict"; // todo: }, validatesLengthOf: function (name, params) { "use strict"; // todo: }, validatesInclusionOf: function (name, params) { "use strict"; // todo: }, validatesExclusionOf: function (name, params) { "use strict"; // todo: }, validatesNumericalityOf: function (name, params) { "use strict"; // todo: }, validatesUniquenessOf: function (name, params) { "use strict"; // todo: } }; inst.validatesPresenceOf = function () { "use strict"; for (var a in arguments) { if (typeof arguments[a] === 'string') { inst.validated.push(arguments[a]); } } }; inst.prototype = Object.prototype; return inst; } }; schema.prototype = Object.prototype; schema.Text = function Text() { }; schema.JSON = schema.Json = function JSON() { }; schema.Float = function Float() { }; schema.Real = schema.Double = function Real() { }; schema.Int = schema.Integer = function Integer() { }; schema.UUID = schema.Uuid = function UUID() { }; schema.TimeUUID = schema.TimeUuid = function TimeUUID() { }; schema.CounterColumn = function CounterColumn() { }; schema.Blob = schema.Bytes = function Blob() { }; schema.Date = schema.Timestamp = Date; schema.Boolean = schema.Tinyint = Boolean; schema.Number = Number; schema.String = schema.Varchar = String; var models = {}; var defaultSwagger = { 'swagger': '2.0', 'info': { 'title': 'Service API', 'description': 'Service API', 'version': '1.0.0', 'termsOfService': 'http://example.com/terms/', 'contact': { 'email': 'api@example.com' }, 'license': { 'name': 'Apache 2.0', 'url': 'http://www.apache.org/licenses/LICENSE-2.0.html' } }, 'host': 'api.example.com', 'schemes': [ 'http' ], 'basePath': '/v1', 'consumes': [ 'application/json', 'application/x-www-form-urlencoded', 'multipart/form-data' ], 'produces': [ 'application/json' // , 'application/xml' ], 'paths': {}, 'parameters': { 'skip': { 'name': 'skip', 'type': 'integer', 'in': 'query', 'description': 'Skip number of rows from ordered list', 'format': 'int32', 'minimum': 0, 'default': 0 }, 'limit': { 'name': 'limit', 'type': 'integer', 'in': 'query', 'description': 'Select number of rows from ordered list', 'format': 'int32', 'minimum': 0, 'maximum': 100, 'default': 20 }, 'search': { 'name': 'search', 'type': 'string', 'in': 'query', 'description': 'Search condition' }, 'sort': { 'name': 'sort', 'type': 'string', 'in': 'query', 'description': 'Sort order condition' } }, 'definitions': { 'Error': { 'type': 'object', 'properties': { 'statusCode': { 'type': 'integer', 'format': 'int32' }, 'message': { 'type': 'string' }, 'error': { 'type': 'string' }, 'attributes': { 'type': 'object' } } }, 'Count': { 'type': 'object', 'properties': { 'count': { 'type': 'integer', 'format': 'int32' } } } }, 'responses': { '404': { 'description': 'Not found', 'schema': { '$ref': '#/definitions/Error' } }, '400': { 'description': 'Bad request', 'schema': { '$ref': '#/definitions/Error' } }, '422': { 'description': 'Validation exception', 'schema': { '$ref': '#/definitions/Error' } }, '500': { 'description': 'Internal server error', 'schema': { '$ref': '#/definitions/Error' } }, 'default': { 'description': 'Unexpected error', 'schema': { '$ref': '#/definitions/Error' } } } }; module.exports.createSwagger = function (dstpath) { var modelDir = path.resolve(dstpath + 'models'); var modelList = fs.readdirSync(modelDir); for (var m = 0; m < modelList.length; m++) { var modelFileName = modelList[m]; if (/Model\.js$/i.test(modelFileName)) { var modelPath = modelDir + '/' + modelFileName; var modelName = modelFileName.replace(/Model\.js$/i, ''); var modelLower = modelName.toString().toLowerCase(); var modelPlural = modelLower.pluralize(); var apiPath = '/' + modelPlural; models[modelName] = require(modelPath)(schema); defaultSwagger.definitions[modelName] = { 'type': 'object', 'properties': {}, 'additionalProperties': false }; defaultSwagger.paths[apiPath] = { 'post': { 'summary': 'Save ' + modelName, 'description': 'Description for collection ' + modelName, 'operationId': 'save' + modelName, 'parameters': [], 'tags': [ modelPlural ], 'responses': { '201': { 'description': 'Operation create successful', 'schema': { '$ref': '#/definitions/' + modelName } }, '422': { '$ref': '#/responses/422' }, '400': { '$ref': '#/responses/400' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } }, 'get': { 'summary': modelName.pluralize() + ' List', 'description': 'Description for collection ' + modelName, 'operationId': 'find' + modelPlural.camelize(), 'parameters': [ { '$ref': '#/parameters/skip' }, { '$ref': '#/parameters/limit' }, { '$ref': '#/parameters/search' }, { '$ref': '#/parameters/sort' } ], 'tags': [ modelPlural ], 'responses': { '200': { 'description': 'An array of ' + modelLower.pluralize(), 'schema': { 'type': 'array', 'items': { '$ref': '#/definitions/' + modelName } } }, '400': { '$ref': '#/responses/400' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } } }; defaultSwagger.paths[apiPath + '/truncate'] = { 'delete': { 'summary': 'Truncate all of ' + modelPlural, 'description': 'Description for collection ' + modelName, 'operationId': 'truncate' + modelPlural.camelize(), 'parameters': [], 'tags': [ modelPlural ], 'responses': { '204': { 'description': 'Successful operation' }, '400': { '$ref': '#/responses/400' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } } }; defaultSwagger.paths[apiPath + '/{' + modelLower + '_id}'] = { 'get': { 'summary': 'Get ' + modelLower + ' by ID', 'description': 'Returns a single ' + modelLower, 'operationId': 'get' + modelName + 'ById', 'parameters': [ { '$ref': '#/parameters/' + modelLower + '_id' } ], 'tags': [ modelPlural ], 'responses': { '200': { 'description': 'Successful operation', 'schema': { '$ref': '#/definitions/' + modelName } }, '404': { '$ref': '#/responses/404' }, '400': { '$ref': '#/responses/400' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } }, 'put': { 'summary': 'Update an existing ' + modelLower, 'description': 'Returns updated ' + modelLower, 'operationId': 'update' + modelName + 'ById', 'parameters': [ { '$ref': '#/parameters/' + modelLower + '_id' } ], 'tags': [ modelPlural ], 'responses': { '200': { 'description': 'Successful operation', 'schema': { '$ref': '#/definitions/' + modelName } }, '400': { '$ref': '#/responses/400' }, '404': { '$ref': '#/responses/404' }, '422': { '$ref': '#/responses/422' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } }, 'delete': { 'summary': 'Delete ' + modelLower + ' by ID', 'description': 'Returns a single ' + modelLower, 'operationId': 'delete' + modelName + 'ById', 'parameters': [ { '$ref': '#/parameters/' + modelLower + '_id' } ], 'tags': [ modelPlural ], 'responses': { '204': { 'description': 'Successful operation' }, '400': { '$ref': '#/responses/400' }, '404': { '$ref': '#/responses/404' }, 'default': { '$ref': '#/responses/default' } } } }; defaultSwagger.paths[apiPath + '/new'] = { 'get': { 'summary': 'Create empty ' + modelLower, 'description': 'Returns a single ' + modelLower, 'operationId': 'empty' + modelName + '', 'parameters': [], 'tags': [ modelPlural ], 'responses': { '200': { 'description': 'Successful operation', 'schema': { '$ref': '#/definitions/' + modelName } }, '400': { '$ref': '#/responses/400' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } } }; defaultSwagger.paths[apiPath + '/count'] = { 'get': { 'summary': 'Get amount of ' + modelLower, 'description': 'Returns a count of ' + modelLower, 'operationId': 'count' + modelPlural.camelize() + '', 'parameters': [], 'tags': [ modelPlural ], 'responses': { '200': { 'description': 'Successful operation', 'schema': { '$ref': '#/definitions/Count' } }, '400': { '$ref': '#/responses/400' }, '500': { '$ref': '#/responses/500' }, 'default': { '$ref': '#/responses/default' } } } }; defaultSwagger.parameters[modelLower + '_id'] = { 'name': modelLower + '_id', 'description': 'The unique identifier for a ' + modelName, 'in': 'path', 'type': 'integer', 'format': 'int64', 'required': true }; defaultSwagger.paths[apiPath].get.parameters.push({ 'name': modelLower + '_id', 'description': 'The unique identifier for a ' + modelName, 'in': 'query', 'type': 'integer', 'format': 'int64' }); // additionalProperties: false for (var field in models[modelName].fields) { var fullField = models[modelName].fields[field]; if (fullField.type) { var type = (fullField.type.name || 'string').toString().toLowerCase(); var fullParam = { 'name': field, 'type': type, 'in': 'formData', 'description': 'Description for field ' + field }; var defField = { 'description': 'Description for field ' + field }; defField.type = type; switch (type) { case 'number': fullParam.type = 'integer'; fullParam.format = (fullField.limit && fullField.limit > 11) ? 'int64' : 'int32'; defField.format = (fullField.limit && fullField.limit > 11) ? 'int64' : 'int32'; break; case 'float': case 'double': case 'real': fullParam.type = 'number'; defField.type = 'number'; fullParam.format = type === 'real' ? 'double' : type; defField.format = type === 'real' ? 'double' : type; break; case 'bool': case 'boolean': fullParam.type = 'boolean'; break; case 'date': fullParam.type = 'string'; fullParam.format = 'date'; defField.type = 'string'; defField.format = 'date'; break; case 'json': fullParam.type = 'string'; fullParam.format = 'object'; defField.type = 'string'; defField.format = 'object'; break; default: fullParam.type = 'string'; defField.type = 'string'; } var validated = models[modelName].validated; if (validated.indexOf(field) !== -1) { fullParam.required = true; } if (fullField.limit && '|string|'.indexOf(type) !== -1) { fullParam.maxLength = fullField.limit; } // if (fullField.limit && '|number|float|real|double|'.indexOf(type)) { // fullParam.maximum = fullField.limit; // } if (defField.default && '|string|number|float|real|double|boolean|'.indexOf(type) !== -1) { fullParam.default = defField.default; } defaultSwagger.paths[apiPath].post.parameters.push(fullParam); defaultSwagger.paths[apiPath + '/{'+modelLower+'_id}'].put.parameters.push(fullParam); defaultSwagger.definitions[modelName].properties[field] = defField; } } } } fs.writeFileSync(dstpath + 'swagger.json', JSON.stringify(defaultSwagger, null, 4), 'utf8'); console.log('generated ' + dstpath + 'swagger.json') };