diff --git a/Cakefile b/Cakefile index 7842973a..5828cc43 100644 --- a/Cakefile +++ b/Cakefile @@ -11,6 +11,7 @@ sourceFiles = [ 'view/MainView' 'view/ResourceView' 'view/OperationView' + 'view/StatusCodeView' 'view/ParameterView' ] diff --git a/lib/swagger.js b/lib/swagger.js index 37d33ce3..30deb25f 100644 --- a/lib/swagger.js +++ b/lib/swagger.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.3.3 (function() { - var SwaggerApi, SwaggerOperation, SwaggerRequest, SwaggerResource, + var SwaggerApi, SwaggerModel, SwaggerModelProperty, SwaggerOperation, SwaggerRequest, SwaggerResource, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; SwaggerApi = (function() { @@ -41,6 +41,7 @@ this.failure = options.failure != null ? options.failure : function() {}; this.progress = options.progress != null ? options.progress : function() {}; this.headers = options.headers != null ? options.headers : {}; + this.booleanValues = options.booleanValues != null ? options.booleanValues : new Array('true', 'false'); this.discoveryUrl = this.suffixApiKey(this.discoveryUrl); if (options.success != null) { this.build(); @@ -109,6 +110,7 @@ return false; } } + this.setConsolidatedModels(); this.ready = true; if (this.success != null) { return this.success(); @@ -120,6 +122,29 @@ throw message; }; + SwaggerApi.prototype.setConsolidatedModels = function() { + var model, modelName, resource, resource_name, _i, _len, _ref, _ref1, _results; + this.modelsArray = []; + this.models = {}; + _ref = this.resources; + for (resource_name in _ref) { + resource = _ref[resource_name]; + for (modelName in resource.models) { + if (!(this.models[modelName] != null)) { + this.models[modelName] = resource.models[modelName]; + this.modelsArray.push(resource.models[modelName]); + } + } + } + _ref1 = this.modelsArray; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + model = _ref1[_i]; + _results.push(model.setReferencedModels(this.models)); + } + return _results; + }; + SwaggerApi.prototype.suffixApiKey = function(url) { var sep; if ((this.api_key != null) && jQuery.trim(this.api_key).length > 0 && (url != null)) { @@ -167,8 +192,11 @@ this.basePath = this.api.basePath; this.operations = {}; this.operationsArray = []; + this.modelsArray = []; + this.models = {}; if ((resourceObj.operations != null) && (this.api.resourcePath != null)) { - this.api.progress('reading resource ' + this.name + ' operations'); + this.api.progress('reading resource ' + this.name + ' models and operations'); + this.addModels(resourceObj.models); this.addOperations(resourceObj.path, resourceObj.operations); this.api[this.name] = this; } else { @@ -183,6 +211,7 @@ _this.basePath = response.basePath; _this.basePath = _this.basePath.replace(/\/$/, ''); } + _this.addModels(response.models); if (response.apis) { _ref = response.apis; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -199,13 +228,31 @@ } } + SwaggerResource.prototype.addModels = function(models) { + var model, modelName, swaggerModel, _i, _len, _ref, _results; + if (models != null) { + for (modelName in models) { + swaggerModel = new SwaggerModel(modelName, models[modelName]); + this.modelsArray.push(swaggerModel); + this.models[modelName] = swaggerModel; + } + _ref = this.modelsArray; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + model = _ref[_i]; + _results.push(model.setReferencedModels(this.models)); + } + return _results; + } + }; + SwaggerResource.prototype.addOperations = function(resource_path, ops) { var o, op, _i, _len, _results; if (ops) { _results = []; for (_i = 0, _len = ops.length; _i < _len; _i++) { o = ops[_i]; - op = new SwaggerOperation(o.nickname, resource_path, o.httpMethod, o.parameters, o.summary, o.notes, this); + op = new SwaggerOperation(o.nickname, resource_path, o.httpMethod, o.parameters, o.summary, o.notes, o.responseClass, o.errorResponses, this); this.operations[op.nickname] = op; _results.push(this.operationsArray.push(op)); } @@ -232,10 +279,110 @@ })(); + SwaggerModel = (function() { + + function SwaggerModel(modelName, obj) { + var propertyName; + this.name = obj.id != null ? obj.id : modelName; + this.properties = []; + for (propertyName in obj.properties) { + this.properties.push(new SwaggerModelProperty(propertyName, obj.properties[propertyName])); + } + } + + SwaggerModel.prototype.setReferencedModels = function(allModels) { + var prop, _i, _len, _ref, _results; + _ref = this.properties; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + prop = _ref[_i]; + if (allModels[prop.dataType] != null) { + _results.push(prop.refModel = allModels[prop.dataType]); + } else if ((prop.refDataType != null) && (allModels[prop.refDataType] != null)) { + _results.push(prop.refModel = allModels[prop.refDataType]); + } else { + _results.push(void 0); + } + } + return _results; + }; + + SwaggerModel.prototype.getMockSignature = function(prefix, modelToIgnore) { + var classClose, classOpen, prop, propertiesStr, returnVal, strong, strongClose, stronger, _i, _j, _len, _len1, _ref, _ref1; + propertiesStr = []; + _ref = this.properties; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + prop = _ref[_i]; + propertiesStr.push(prop.toString()); + } + strong = ''; + stronger = ''; + strongClose = ''; + classOpen = strong + 'class ' + this.name + '(' + strongClose; + classClose = strong + ')' + strongClose; + returnVal = classOpen + '' + propertiesStr.join(', ') + '' + classClose; + if (prefix != null) { + returnVal = stronger + prefix + strongClose + '
' + returnVal; + } + _ref1 = this.properties; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + prop = _ref1[_j]; + if ((prop.refModel != null) && (!(prop.refModel === modelToIgnore))) { + returnVal = returnVal + ('
' + prop.refModel.getMockSignature(void 0, this)); + } + } + return returnVal; + }; + + return SwaggerModel; + + })(); + + SwaggerModelProperty = (function() { + + function SwaggerModelProperty(name, obj) { + this.name = name; + this.dataType = obj.type; + this.isArray = this.dataType.toLowerCase() === 'array'; + this.descr = obj.description; + if (obj.items != null) { + if (obj.items.type != null) { + this.refDataType = obj.items.type; + } + if (obj.items.$ref != null) { + this.refDataType = obj.items.$ref; + } + } + this.dataTypeWithRef = this.refDataType != null ? this.dataType + '[' + this.refDataType + ']' : this.dataType; + if (obj.allowableValues != null) { + this.valueType = obj.allowableValues.valueType; + this.values = obj.allowableValues.values; + if (this.values != null) { + this.valuesString = "'" + this.values.join("' or '") + "'"; + } + } + } + + SwaggerModelProperty.prototype.toString = function() { + var str; + str = this.name + ': ' + this.dataTypeWithRef; + if (this.values != null) { + str += " = ['" + this.values.join("' or '") + "']"; + } + if (this.descr != null) { + str += ' {' + this.descr + '}'; + } + return str; + }; + + return SwaggerModelProperty; + + })(); + SwaggerOperation = (function() { - function SwaggerOperation(nickname, path, httpMethod, parameters, summary, notes, resource) { - var parameter, v, _i, _j, _len, _len1, _ref, _ref1, + function SwaggerOperation(nickname, path, httpMethod, parameters, summary, notes, responseClass, errorResponses, resource) { + var parameter, v, _i, _j, _len, _len1, _ref, _ref1, _ref2, _this = this; this.nickname = nickname; this.path = path; @@ -243,6 +390,8 @@ this.parameters = parameters != null ? parameters : []; this.summary = summary; this.notes = notes; + this.responseClass = responseClass; + this.errorResponses = errorResponses; this.resource = resource; this["do"] = __bind(this["do"], this); @@ -259,10 +408,22 @@ this.httpMethod = this.httpMethod.toLowerCase(); this.isGetMethod = this.httpMethod === "get"; this.resourceName = this.resource.name; - _ref = this.parameters; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - parameter = _ref[_i]; + if (((_ref = this.responseClass) != null ? _ref.toLowerCase() : void 0) === 'void') { + this.responseClass = void 0; + } + if (this.responseClass != null) { + this.responseClassSignature = this.getSignature(this.responseClass, this.resource.models); + } + this.errorResponses = this.errorResponses || []; + _ref1 = this.parameters; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + parameter = _ref1[_i]; parameter.name = parameter.name || parameter.dataType; + if (parameter.dataType.toLowerCase() === 'boolean') { + parameter.allowableValues = {}; + parameter.allowableValues.values = this.resource.api.booleanValues; + } + parameter.signature = this.getSignature(parameter.dataType, this.resource.models); if (parameter.allowableValues != null) { if (parameter.allowableValues.valueType === "RANGE") { parameter.isRange = true; @@ -271,9 +432,9 @@ } if (parameter.allowableValues.values != null) { parameter.allowableValues.descriptiveValues = []; - _ref1 = parameter.allowableValues.values; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - v = _ref1[_j]; + _ref2 = parameter.allowableValues.values; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + v = _ref2[_j]; if ((parameter.defaultValue != null) && parameter.defaultValue === v) { parameter.allowableValues.descriptiveValues.push({ value: v, @@ -294,6 +455,29 @@ }; } + SwaggerOperation.prototype.isListType = function(dataType) { + if (dataType.indexOf('[') >= 0) { + return dataType.substring(dataType.indexOf('[') + 1, dataType.indexOf(']')); + } else { + return void 0; + } + }; + + SwaggerOperation.prototype.getSignature = function(dataType, models) { + var isPrimitive, listType; + listType = this.isListType(dataType); + isPrimitive = ((listType != null) && models[listType]) || (models[dataType] != null) ? false : true; + if (isPrimitive) { + return dataType; + } else { + if (listType != null) { + return models[listType].getMockSignature(dataType); + } else { + return models[dataType].getMockSignature(dataType); + } + } + }; + SwaggerOperation.prototype["do"] = function(args, callback, error) { var body, headers; if (args == null) { diff --git a/src/main/coffeescript/view/OperationView.coffee b/src/main/coffeescript/view/OperationView.coffee index 67935356..92659bf1 100644 --- a/src/main/coffeescript/view/OperationView.coffee +++ b/src/main/coffeescript/view/OperationView.coffee @@ -16,6 +16,10 @@ class OperationView extends Backbone.View # Render each parameter @addParameter param for param in @model.parameters + + # Render each response code + @addStatusCode statusCode for statusCode in @model.errorResponses + @ addParameter: (param) -> @@ -23,6 +27,10 @@ class OperationView extends Backbone.View paramView = new ParameterView({model: param, tagName: 'tr', readOnly: @model.isReadOnly}) $('.operation-params', $(@el)).append paramView.render().el + addStatusCode: (statusCode) -> + # Render status codes + statusCodeView = new StatusCodeView({model: statusCode, tagName: 'tr'}) + $('.operation-status', $(@el)).append statusCodeView.render().el submitOperation: (e) -> e?.preventDefault() diff --git a/src/main/coffeescript/view/StatusCodeView.coffee b/src/main/coffeescript/view/StatusCodeView.coffee new file mode 100644 index 00000000..c00ca71a --- /dev/null +++ b/src/main/coffeescript/view/StatusCodeView.coffee @@ -0,0 +1,11 @@ +class StatusCodeView extends Backbone.View + initialize: -> + + render: -> + template = @template() + $(@el).html(template(@model)) + @ + + template: -> + Handlebars.templates.status_code + diff --git a/src/main/template/operation.handlebars b/src/main/template/operation.handlebars index 08c17b86..df827732 100644 --- a/src/main/template/operation.handlebars +++ b/src/main/template/operation.handlebars @@ -36,6 +36,21 @@ + {{#if errorResponses}} +
+

Status Codes

+ + + + + + + + + + +
HTTP Status CodeReason
+ {{/if}} {{#if isReadOnly}} {{else}}
diff --git a/src/main/template/status_code.handlebars b/src/main/template/status_code.handlebars new file mode 100644 index 00000000..32802e30 --- /dev/null +++ b/src/main/template/status_code.handlebars @@ -0,0 +1,3 @@ +{{code}} +{{{reason}}} +