Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Bahman Fakhr Sabahi
committed
Apr 1, 2015
1 parent
3cf73d3
commit c0e36ad
Showing
9 changed files
with
607 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.git/ | ||
node_modules/ | ||
test/ | ||
.gitignore | ||
.npmignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Copyright (c) 2013-2014 inveris OHG | ||
Author Peter Rottmann <rottmann@inveris.de> | ||
Licensed under the MIT license. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,42 @@ | ||
# apidoc-swagger | ||
apidoc and swagger are two nice projects which are focusing on documentation of APIs. This project is a middle tier which tries to bring them together in a sense that it uses apidoc to convert inline documentation comments into json schema and later convert it to swagger json schmea. | ||
apidoc and swagger are two nice projects which are focusing on documentation of APIs. | ||
This project is a middle tier which tries to bring them together in a sense that: | ||
> It uses apidoc to convert inline documentation comments into json schema and later convert it to swagger json schmea. | ||
Uses the [apidoc-core](https://github.com/apidoc/apidoc-core) library. | ||
|
||
## How It Works | ||
|
||
By putting in line comments in the source code like this in javascript, you will get `swagger.json` file which can be served to [swagger-ui](https://github.com/swagger-api/swagger-ui) to generate html overview of documentation. | ||
|
||
`/api/foo.js`: | ||
```js | ||
/** | ||
* @api {get} /user/id Request User information | ||
* @apiName GetUser | ||
* @apiGroup User | ||
* | ||
* @apiParam {Number} id Users unique ID. | ||
* | ||
* @apiSuccess {String} firstname Firstname of the User. | ||
* @apiSuccess {String} lastname Lastname of the User. | ||
*/ | ||
``` | ||
|
||
|
||
## Installation | ||
|
||
`npm install apidoc-swagger -g` | ||
|
||
|
||
Current version unlocks most of the basic capabilities of both projects and improvement is in progress. | ||
|
||
## Example | ||
|
||
`apidoc-swagger -i example/ -o doc/` | ||
|
||
|
||
|
||
Have a look at [apidoc](https://github.com/apidoc/apidoc) for full functionality overview and capabilities of apidoc. | ||
|
||
To read more about how swagger works refer to [swagger-ui](https://github.com/swagger-api/swagger-ui) and [swagger-spec](https://github.com/swagger-api/swagger-spec) for details of `swagger.json`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#!/usr/bin/env node | ||
|
||
'use strict'; | ||
|
||
/* | ||
* apidoc-swagger | ||
* | ||
* Copyright (c) 2015 Exact | ||
* Author Bahman Fakhr Sabahi <bahman.sabahi@exact.com> | ||
* Licensed under the MIT license. | ||
*/ | ||
|
||
var path = require('path'); | ||
var nomnom = require('nomnom'); | ||
var apidocSwagger = require('../lib/index'); | ||
|
||
var argv = nomnom | ||
.option('file-filters', { abbr: 'f', 'default': '.*\\.(clj|coffee|cs|dart|erl|go|java|js|php?|py|rb|ts|pm)$', | ||
help: 'RegEx-Filter to select files that should be parsed (multiple -f can be used).' }) | ||
|
||
.option('exclude-filters', { abbr: 'e', 'default': '', | ||
help: 'RegEx-Filter to select files / dirs that should not be parsed (many -e can be used).', }) | ||
|
||
.option('input', { abbr: 'i', 'default': './', help: 'Input / source dirname.' }) | ||
|
||
.option('output', { abbr: 'o', 'default': './doc/', help: 'Output dirname.' }) | ||
|
||
.option('verbose', { abbr: 'v', flag: true, 'default': false, help: 'Verbose debug output.' }) | ||
|
||
.option('help', { abbr: 'h', flag: true, help: 'Show this help information.' }) | ||
|
||
.option('debug', { flag: true, 'default': false, help: 'Show debug messages.' }) | ||
|
||
.option('color', { flag: true, 'default': true, help: 'Turn off log color.' }) | ||
|
||
.option('parse', { flag: true, 'default': false, | ||
help: 'Parse only the files and return the data, no file creation.' }) | ||
|
||
.option('parse-filters' , { help: 'Optional user defined filters. Format name=filename' }) | ||
.option('parse-languages', { help: 'Optional user defined languages. Format name=filename' }) | ||
.option('parse-parsers' , { help: 'Optional user defined parsers. Format name=filename' }) | ||
.option('parse-workers' , { help: 'Optional user defined workers. Format name=filename' }) | ||
|
||
.option('silent', { flag: true, 'default': false, help: 'Turn all output off.' }) | ||
|
||
.option('simulate', { flag: true, 'default': false, help: 'Execute but not write any file.' }) | ||
|
||
// markdown settings | ||
.option('markdown', { flag: true, 'default': true, help: 'Turn off markdown parser.' }) | ||
|
||
.option('marked-config', { 'default': '', | ||
help: 'Enable custom markdown parser configs. It will overwite all other marked settings.' }) | ||
|
||
.option('marked-gfm', { flag: true, 'default': true, | ||
help: 'Enable GitHub flavored markdown.' }) | ||
|
||
.option('marked-tables', { flag: true, 'default': true, | ||
help: 'Enable GFM tables. This option requires the gfm option to be true.' }) | ||
|
||
.option('marked-breaks', { flag: true, 'default': false, | ||
help: 'Enable GFM line breaks. This option requires the gfm option to be true.' }) | ||
|
||
.option('marked-pedantic', { flag: true, 'default': false, | ||
help: 'Conform to obscure parts of markdown.pl as much as possible.' }) | ||
|
||
.option('marked-sanitize', { flag: true, 'default': false, | ||
help: 'Sanitize the output. Ignore any HTML that has been input.' }) | ||
|
||
.option('marked-smartLists', { flag: true, 'default': false, | ||
help: 'Use smarter list behavior than the original markdown.' }) | ||
|
||
.option('marked-smartypants', { flag: true, 'default': false, | ||
help: 'Use \'smart\' typograhic punctuation for things like quotes and dashes.' }) | ||
|
||
.parse() | ||
; | ||
|
||
/** | ||
* Transform parameters to object | ||
* | ||
* @param {String|String[]} filters | ||
* @returns {Object} | ||
*/ | ||
function transformToObject(filters) { | ||
if ( ! filters) | ||
return; | ||
|
||
if (typeof(filters) === 'string') | ||
filters = [ filters ]; | ||
|
||
var result = {}; | ||
filters.forEach(function(filter) { | ||
var splits = filter.split('='); | ||
if (splits.length === 2) { | ||
var obj = {}; | ||
result[splits[0]] = path.resolve(splits[1], ''); | ||
} | ||
}); | ||
return result; | ||
} | ||
|
||
/** | ||
* Sets configuration for markdown | ||
* | ||
* @param {Array} argv | ||
* @returns {Object} | ||
*/ | ||
function resolveMarkdownOptions(argv) { | ||
if (argv['marked-config']) { | ||
return require(path.resolve(argv['marked-config'])); | ||
} else { | ||
return { | ||
gfm : argv['marked-gfm'], | ||
tables : argv['marked-tables'], | ||
breaks : argv['marked-breaks'], | ||
pedantic : argv['marked-pedantic'], | ||
sanitize : argv['marked-sanitize'], | ||
smartLists : argv['marked-smartLists'], | ||
smartypants: argv['marked-smartypants'] | ||
}; | ||
} | ||
} | ||
|
||
var options = { | ||
excludeFilters: argv['exclude-filters'], | ||
includeFilters: argv['file-filters'], | ||
src : argv['input'], | ||
dest : argv['output'], | ||
verbose : argv['verbose'], | ||
debug : argv['debug'], | ||
parse : argv['parse'], | ||
colorize : argv['color'], | ||
filters : transformToObject(argv['parse-filters']), | ||
languages : transformToObject(argv['parse-languages']), | ||
parsers : transformToObject(argv['parse-parsers']), | ||
workers : transformToObject(argv['parse-workers']), | ||
silent : argv['silent'], | ||
simulate : argv['simulate'], | ||
markdown : argv['markdown'], | ||
marked : resolveMarkdownOptions(argv) | ||
}; | ||
|
||
if (apidocSwagger.createApidocSwagger(options) === false) { | ||
process.exit(1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
var _ = require('lodash'); | ||
|
||
var swagger = { | ||
swagger : "2.0", | ||
info : {}, | ||
paths : {} | ||
}; | ||
|
||
function toSwagger(apidocJson, projectJson) { | ||
swagger.info = addInfo(projectJson); | ||
swagger.paths = extractPaths(apidocJson); | ||
return swagger; | ||
} | ||
|
||
|
||
function addInfo(projectJson) { | ||
var info = {}; | ||
info["title"] = projectJson.title; | ||
info["version"] = projectJson.version; | ||
info["description"] = projectJson.description; | ||
return info; | ||
} | ||
|
||
function extractPaths(apidocJson){ | ||
var apiPaths = groupByUrl(apidocJson); | ||
var paths = {}; | ||
for (var i = 0; i < apiPaths.length; i++) { | ||
paths[apiPaths[i].url] = extractVerbs(apiPaths[i].verbs); | ||
} | ||
return paths; | ||
} | ||
|
||
function extractVerbs(verbs){ | ||
var pathItemObject = {}; | ||
for (var i = 0; i < verbs.length; i++) { | ||
//TODO: if there are multiple version of documentation for same api/verb pick latest! | ||
pathItemObject[verbs[i].type] = createOperationObject(verbs[i]); | ||
} | ||
return pathItemObject; | ||
} | ||
|
||
function groupByUrl(apidocJson) { | ||
return _.chain(apidocJson) | ||
.groupBy("url") | ||
.pairs() | ||
.map(function (element) { | ||
return _.object(_.zip(["url", "verbs"], element)); | ||
}) | ||
.value(); | ||
} | ||
|
||
function createOperationObject(verb) { | ||
var operationObject = { | ||
description : verb.title, | ||
summary : verb.description, | ||
tags : [verb.group], | ||
parameters : verb.parameter ? createParameters(verb.parameter): {} | ||
}; | ||
return operationObject; | ||
} | ||
|
||
function createParameters(apiParameters) { | ||
var parameterArray = []; | ||
var parameters = []; | ||
for (field in apiParameters.fields) { | ||
if (Array.isArray(apiParameters.fields[field])) { | ||
parameterArray = apiParameters.fields[field]; | ||
} | ||
} | ||
for (var i = 0; i < parameterArray.length; i++) { | ||
var parameter = { | ||
name : parameterArray[i].field, | ||
in : "query", | ||
description : parameterArray[i].description, | ||
required : !parameterArray[i].optional, | ||
type : parameterArray[i].type, | ||
}; | ||
parameters.push(parameter); | ||
} | ||
return parameters; | ||
} | ||
|
||
module.exports = { | ||
toSwagger: toSwagger | ||
}; |
Oops, something went wrong.