grunt-apidoc2swagger
Advanced tools
Comparing version 0.1.10 to 0.2.0
@@ -43,3 +43,2 @@ /* | ||
moduleName: 'APITest', // This is the model and file name | ||
angularjs: true, | ||
className: 'APITest', | ||
@@ -46,0 +45,0 @@ fileName: 'APITest.js' |
{ | ||
"name": "grunt-apidoc2swagger", | ||
"description": "Convert apidocjs files to Swagger", | ||
"version": "0.1.10", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/Giwi/apiDoc2Swagger", | ||
@@ -49,3 +49,4 @@ "author": { | ||
"dependencies": { | ||
"html-to-text": "^1.2.1" | ||
} | ||
} |
@@ -58,6 +58,11 @@ # grunt-apiDoc2Swagger | ||
### options.basePath | ||
Type: 'String' | ||
Default value: 'http://localhost' | ||
Your server URL if you want to test your API with [Swagger-ui](https://github.com/swagger-api/swagger-ui) | ||
### Usage Examples | ||
#### Default Options | ||
In this example, the default options are used to do something with whatever. So if the `testing` file has the content `Testing` and the `123` file had the content `1 2 3`, the generated result would be `Testing, 1 2 3.` | ||
@@ -71,3 +76,5 @@ ```js | ||
apiData: 'test/api_data.json', | ||
swagger: 'output/' | ||
swagger: 'output/', | ||
swaggerVersion: '1.2', | ||
basePath : 'http://localhost' | ||
} | ||
@@ -83,3 +90,5 @@ } | ||
## Release History | ||
### 1.1.7 | ||
### 1.2.0 | ||
Swagger 2.0 support | ||
### 1.1.10 | ||
Some bug fixes | ||
@@ -86,0 +95,0 @@ |
@@ -1,168 +0,202 @@ | ||
/* | ||
* grunt-apiDoc2Swagger | ||
* https://github.com/Giwi/apiDoc2Swagger | ||
* | ||
* Copyright (c) 2015 Xavier MARIN | ||
* Licensed under the MIT license. | ||
*/ | ||
'use strict'; | ||
module.exports = function (grunt) { | ||
(function() { | ||
'use strict'; | ||
/* | ||
* grunt-apiDoc2Swagger https://github.com/Giwi/apiDoc2Swagger | ||
* | ||
* Copyright (c) 2015 Xavier MARIN Licensed under the MIT license. | ||
*/ | ||
var htmlToText = require('html-to-text'); | ||
module.exports = function(grunt) { | ||
grunt.registerMultiTask('apidoc2swagger', 'Convert apidocjs files to Swagger', function() { | ||
// Please see the Grunt documentation for more information regarding task | ||
// creation: http://gruntjs.com/creating-tasks | ||
grunt.registerMultiTask('apidoc2swagger', 'Convert apidocjs files to Swagger', function () { | ||
function normalize(obj, key, models) { | ||
grunt.log.verbose.ok(key +" -> " +grunt.util.kindOf(obj)); | ||
switch(grunt.util.kindOf(obj)) { | ||
case "number" : | ||
return {type : "integer",format: "int64"}; | ||
case "string" : | ||
return {type : "string"}; | ||
case "boolean" : | ||
return {type : "boolean"}; | ||
case "object" : | ||
if(!models[key]) { | ||
models[key]= { | ||
id : key, | ||
properties : {} | ||
function normalize(obj, key, models) { | ||
grunt.log.verbose.debug(key + " -> " + grunt.util.kindOf(obj)); | ||
switch (grunt.util.kindOf(obj)) { | ||
case "number": | ||
return { | ||
type : "integer", | ||
format : "int64" | ||
}; | ||
for(var k in obj) { | ||
grunt.log.verbose.warn(">>> " + key + "->" +k); | ||
models[key].properties[k] = normalize(obj[k], k, models); | ||
case "string": | ||
return { | ||
type : "string" | ||
}; | ||
case "boolean": | ||
return { | ||
type : "boolean" | ||
}; | ||
case "object": | ||
if (!models[key]) { | ||
models[key] = { | ||
properties : {} | ||
}; | ||
for ( var k in obj) { | ||
grunt.log.verbose.debug(">>> " + key + "->" + k); | ||
models[key].properties[k] = normalize(obj[k], k, models); | ||
} | ||
} | ||
} | ||
return {'$ref' : key}; | ||
return { | ||
'$ref' : '#/definitions/' + key | ||
}; | ||
} | ||
} | ||
} | ||
var done = this.async(); | ||
var done = this.async(); | ||
// Merge task-specific and/or target-specific options with these defaults. | ||
var options = this.options({ | ||
swagger: 'swagger', | ||
apiData: 'api_data.json', | ||
apiProject: 'api_project.json', | ||
swaggerVersion: '1.2', | ||
basePath: 'http://localhost' | ||
}); | ||
// Merge task-specific and/or target-specific options with these | ||
// defaults. | ||
var options = this.options({ | ||
swagger : 'swagger', | ||
apiData : 'api_data.json', | ||
apiProject : 'api_project.json', | ||
swaggerVersion : '2.0', | ||
basePath : 'http://localhost' | ||
}); | ||
var apiProject = options.apiProject; | ||
var apiData = options.apiData; | ||
var apiProject = options.apiProject; | ||
var apiData = options.apiData; | ||
// Warn on and remove invalid source files (if nonull was set). | ||
if (!grunt.file.exists(apiProject)) { | ||
grunt.log.error('Project file "' + apiProject + '" not found.'); | ||
return false; | ||
} else if (!grunt.file.exists(apiData)) { | ||
grunt.log.error('Data file "' + apiData + '" not found.'); | ||
return false; | ||
} else { | ||
grunt.log.ok('Project file : ' + apiProject); | ||
grunt.log.ok('Data file : ' + apiData); | ||
var projectSrc = grunt.file.readJSON(apiProject); | ||
var dataSrc = grunt.file.readJSON(apiData); | ||
var swaggerMain = {swaggerVersion: options.swaggerVersion, info: {}, apis: []}; | ||
swaggerMain.apiVersion = projectSrc.version; | ||
swaggerMain.info.title = projectSrc.name; | ||
swaggerMain.info.description = projectSrc.description.replace(/<\/?[^>]+(>|$)/g, ""); | ||
// Warn on and remove invalid source files (if nonull was set). | ||
if (!grunt.file.exists(apiProject)) { | ||
grunt.log.error('Project file "' + apiProject + '" not found.'); | ||
return false; | ||
} else if (!grunt.file.exists(apiData)) { | ||
grunt.log.error('Data file "' + apiData + '" not found.'); | ||
return false; | ||
} else { | ||
grunt.log.ok('Project file : ' + apiProject); | ||
grunt.log.ok('Data file : ' + apiData); | ||
var projectSrc = grunt.file.readJSON(apiProject); | ||
var dataSrc = grunt.file.readJSON(apiData); | ||
var tags = {}; | ||
var swaggerMain = { | ||
swagger : options.swaggerVersion, | ||
info : {}, | ||
paths : {}, | ||
definitions : {}, | ||
tags : [] | ||
}; | ||
var models = []; | ||
swaggerMain.apiVersion = projectSrc.version; | ||
swaggerMain.info.title = projectSrc.name; | ||
swaggerMain.info.description = projectSrc.header.content; | ||
dataSrc.forEach(function(api) { | ||
grunt.log.ok(api.url); | ||
if (!swaggerMain.paths[api.url]) { | ||
swaggerMain.paths[api.url] = {}; | ||
} | ||
if(!tags[api.group]) { | ||
grunt.log.verbose.debug('not found : ' + api.group) | ||
tags[api.group] = {name : api.group}; | ||
} | ||
var method = api.type.toLowerCase(); | ||
swaggerMain.paths[api.url][method] = { | ||
description : htmlToText.fromString(api.description), | ||
summary : htmlToText.fromString(api.title), | ||
operationId : htmlToText.fromString(api.name), | ||
consumes : [ 'application/json' ], | ||
produces : [ 'application/json' ], | ||
parameters : [], | ||
responses : {}, | ||
tags : [] | ||
var apiCollection = []; | ||
var apiNames = []; | ||
}; | ||
swaggerMain.paths[api.url][method].tags.push(api.group); | ||
if (api.error) { | ||
swaggerMain.paths[api.url][method].responses['xxx'] = { | ||
description: htmlToText.fromString(api.error.fields['Error 4xx'][0].description), | ||
schema : { | ||
'$ref' : '#/definitions/' +api.error.fields['Error 4xx'][0].field | ||
} | ||
}; | ||
dataSrc.forEach(function (api) { | ||
if (!apiCollection[api.group]) { | ||
grunt.log.verbose.ok("found : " + api.group); | ||
apiNames.push(api.group); | ||
apiCollection[api.group] = { | ||
swaggerVersion: options.swaggerVersion, | ||
apis: [{path : api.url, operations : []}], | ||
apiVersion: api.version, | ||
basePath: options.basePath, | ||
resourcePath: '/', | ||
path: '/', | ||
models : {}, | ||
produces: ["application/json"] | ||
}; | ||
} | ||
var ope = { | ||
method: api.type, | ||
summary: api.description.replace(/<\/?[^>]+(>|$)/g, ""), | ||
notes: api.group, nickname: api.name, | ||
parameters: [] | ||
}; | ||
if (api.error) { | ||
ope.responseMessages = {code: 400, message: api.error.fields['Error 4xx'].field}; | ||
} | ||
if (api.success) { | ||
ope.type = api.success.fields['Success 200'].type; | ||
ope.item = {'$ref': api.success.fields['Success 200'].field}; | ||
} | ||
if (api.parameter) { | ||
api.parameter.fields.Parameter.forEach(function (param) { | ||
var myParam ={ | ||
name: param.field, | ||
description: param.description.replace(/<\/?[^>]+(>|$)/g, ""), | ||
required: param.optional, | ||
type: param.type | ||
if (api.error.examples) { | ||
api.error.examples.forEach(function(example) { | ||
swaggerMain.definitions[example.title] ={ | ||
properties : {} | ||
}; | ||
var content = JSON.parse(example.content); | ||
for ( var k in content) { | ||
grunt.log.verbose.debug(k + " -> " + JSON.stringify(content[k])); | ||
swaggerMain.definitions[example.title].properties[k] = normalize(content[k], k, swaggerMain.definitions); | ||
} | ||
}); | ||
} | ||
} | ||
if (api.success) { | ||
swaggerMain.paths[api.url][method].responses['200']= { | ||
description : htmlToText.fromString(api.success.fields['Success 200'][0].description), | ||
schema : {} | ||
}; | ||
if(api.url.indexOf("?" + myParam.name + "=") >0, api.url.indexOf("&" + myParam.name + "=") >0) { | ||
myParam.paramType = "query"; | ||
} else if(api.url.indexOf(":" + myParam.name) >0) { | ||
myParam.paramType = "path"; | ||
if('Object' === api.success.fields['Success 200'][0].type) { | ||
swaggerMain.paths[api.url][method].responses['200'].schema['$ref'] = '#/definitions/' + api.success.fields['Success 200'][0].field; | ||
} else { | ||
myParam.paramType ="body"; | ||
swaggerMain.paths[api.url][method].responses['200'].schema.type = api.success.fields['Success 200'][0].type; | ||
} | ||
if(api.parameter.examples) { | ||
api.parameter.examples.forEach(function(example) { | ||
if(example.title === myParam.name) { | ||
myParam.type = myParam.name; | ||
grunt.log.warn(myParam.type); | ||
if(!apiCollection[api.group].models[myParam.type]) { | ||
apiCollection[api.group].models[myParam.type] = { | ||
id : myParam.type, | ||
properties : {} | ||
}; | ||
var content = JSON.parse(example.content); | ||
for(var k in content) { | ||
apiCollection[api.group].models[myParam.type].properties[k] = normalize(content[k], k, apiCollection[api.group].models); | ||
} | ||
} | ||
} | ||
if (api.success.examples) { | ||
api.success.examples.forEach(function(example) { | ||
swaggerMain.definitions[example.title] ={ | ||
properties : {} | ||
}; | ||
var content = JSON.parse(example.content); | ||
for ( var k in content) { | ||
grunt.log.verbose.debug(k + " -> " + JSON.stringify(content[k])); | ||
swaggerMain.definitions[example.title].properties[k] = normalize(content[k], k, swaggerMain.definitions); | ||
} | ||
}); | ||
} | ||
ope.parameters.push(myParam); | ||
}); | ||
} | ||
if(api.header) { | ||
api.header.fields.Header.forEach(function (param) { | ||
ope.parameters.push({ | ||
name: param.field, | ||
description: param.description.replace(/<\/?[^>]+(>|$)/g, ""), | ||
required: param.optional, | ||
type: param.type, | ||
paramType : 'header' | ||
} | ||
if (api.header) { | ||
api.header.fields.Header.forEach(function(param) { | ||
swaggerMain.paths[api.url][method].parameters.push({ | ||
name : param.field, | ||
description : htmlToText.fromString(param.description), | ||
required : param.optional, | ||
type : param.type, | ||
paramType : 'header' | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
if (api.parameter) { | ||
api.parameter.fields.Parameter.forEach(function(param) { | ||
var myParam = { | ||
name : param.field, | ||
description : htmlToText.fromString(param.description), | ||
required : param.optional, | ||
type : param.type | ||
}; | ||
if (api.url.indexOf("?" + myParam.name + "=") > 0, api.url.indexOf("&" + myParam.name + "=") > 0) { | ||
myParam.paramType = "query"; | ||
} else if (api.url.indexOf(":" + myParam.name) > 0) { | ||
myParam.in = "path"; | ||
} else { | ||
myParam.in= "body"; | ||
} | ||
if (api.parameter.examples) { | ||
grunt.log.verbose.debug(JSON.stringify(api.parameter.examples)); | ||
grunt.log.verbose.ok("Pushing " + ope.nickname +" to " + api.group); | ||
apiCollection[api.group].apis.push({path : api.url, operations : [ope]}); | ||
}); | ||
apiNames.forEach(function (key) { | ||
var api = apiCollection[key]; | ||
grunt.log.verbose.ok("Writing " + api.path); | ||
swaggerMain.apis.push({ | ||
path: '/../' +key + '.json', | ||
description: key | ||
api.parameter.examples.forEach(function(example) { | ||
myParam.type = example.title; | ||
swaggerMain.definitions[example.title] ={ | ||
properties : {} | ||
}; | ||
var content = JSON.parse(example.content); | ||
for ( var k in content) { | ||
grunt.log.verbose.debug(k + " -> " + JSON.stringify(content[k])); | ||
swaggerMain.definitions[example.title].properties[k] = normalize(content[k], k, swaggerMain.definitions); | ||
} | ||
}); | ||
myParam.schema = {'$ref' : '#/definitions/' + myParam.type}; | ||
} | ||
swaggerMain.paths[api.url][method].parameters.push(myParam); | ||
}); | ||
} | ||
}); | ||
grunt.file.write(options.swagger + '/' + key + '.json', JSON.stringify(api, null, 2)); | ||
}); | ||
grunt.file.write(options.swagger + '/index.json', JSON.stringify(swaggerMain, null, 2)); | ||
done(); | ||
} | ||
}); | ||
}; | ||
grunt.log.verbose.debug(JSON.stringify(tags)); | ||
Object.keys(tags).forEach(function(t) {swaggerMain.tags.push(tags[t])}); | ||
grunt.file.write(options.swagger + '/index.json', JSON.stringify(swaggerMain, null, 2)); | ||
done(); | ||
} | ||
}); | ||
}; | ||
}()); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
19980
350
94
2
+ Addedhtml-to-text@^1.2.1
+ Addedhtml-to-text@1.6.2(transitive)
+ Addedhtmlparser@1.7.7(transitive)
+ Addedminimist@0.0.10(transitive)
+ Addedoptimist@0.6.1(transitive)
+ Addedunderscore@1.13.7(transitive)
+ Addedwordwrap@0.0.3(transitive)