Skip to content

Commit 2e98859

Browse files
committedNov 29, 2017
chore(script): generate API docs
1 parent 21b234b commit 2e98859

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
 

‎scripts/generate-api-docs.js

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#!/usr/bin/env node
2+
3+
var writeFileSync = require('fs').writeFileSync
4+
var Path = require('path')
5+
6+
var debug = require('debug')('node-github')
7+
var toCamelCase = require('lodash/camelCase')
8+
var upperFirst = require('lodash/upperFirst')
9+
10+
var ROUTES = require('../lib/routes.json')
11+
var DEFINITIONS = require('../lib/definitions.json')
12+
13+
debug('Generating...')
14+
15+
var sections = {}
16+
var apidocs = ''
17+
18+
function prepareApi (struct, baseType) {
19+
if (!baseType) {
20+
baseType = ''
21+
}
22+
23+
var lastSection
24+
Object.keys(struct).sort().forEach(function (routePart) {
25+
var block = struct[routePart]
26+
if (!block) {
27+
return
28+
}
29+
var messageType = baseType + '/' + routePart
30+
if (block.url && block.params) {
31+
// we ended up at an API definition part!
32+
var parts = messageType.split('/')
33+
var section = toCamelCase(parts[1])
34+
35+
if (!block.method) {
36+
throw new Error('No HTTP method specified for ' + messageType +
37+
'in section ' + section)
38+
}
39+
40+
if (lastSection !== section) {
41+
apidocs += createSectionComment(section)
42+
lastSection = section
43+
}
44+
45+
// add the handler to the sections
46+
if (!sections[section]) {
47+
sections[section] = []
48+
}
49+
50+
parts.splice(0, 2)
51+
var funcName = toCamelCase(parts.join('-'))
52+
apidocs += createComment(section, funcName, block)
53+
} else {
54+
// recurse into this block next:
55+
prepareApi(block, messageType)
56+
}
57+
})
58+
}
59+
60+
function createSectionComment (section) {
61+
return [
62+
'/**',
63+
' * ' + upperFirst(section),
64+
' * @namespace ' + section,
65+
' */',
66+
'',
67+
''
68+
].join('\n')
69+
}
70+
71+
function createComment (section, funcName, block) {
72+
var method = block['method'].toUpperCase()
73+
var url = block['url']
74+
75+
var commentLines = [
76+
'/**',
77+
' * @api {' + method + '} ' + url + ' ' + funcName,
78+
' * @apiName ' + funcName,
79+
' * @apiDescription ' + block['description'],
80+
' * @apiGroup ' + section,
81+
' *'
82+
]
83+
84+
var paramsObj = block['params']
85+
86+
// sort params so Required come before Optional
87+
var paramKeys = Object.keys(paramsObj)
88+
paramKeys.sort(function (paramA, paramB) {
89+
var cleanParamA = paramA.replace(/^\$/, '')
90+
var cleanParamB = paramB.replace(/^\$/, '')
91+
92+
var paramInfoA = paramsObj[paramA] || DEFINITIONS['params'][cleanParamA]
93+
var paramInfoB = paramsObj[paramB] || DEFINITIONS['params'][cleanParamB]
94+
95+
var paramRequiredA = paramInfoA['required']
96+
var paramRequiredB = paramInfoB['required']
97+
98+
if (paramRequiredA && !paramRequiredB) return -1
99+
if (!paramRequiredA && paramRequiredB) return 1
100+
return 0
101+
})
102+
103+
paramKeys.forEach(function (param) {
104+
var cleanParam = param.replace(/^\$/, '')
105+
var paramInfo = paramsObj[param] || DEFINITIONS['params'][cleanParam]
106+
107+
var paramRequired = paramInfo['required']
108+
var paramType = paramInfo['type'].toLowerCase()
109+
var paramDescription = paramInfo['description']
110+
var paramDefaultVal = paramInfo['default']
111+
112+
var paramLabel = cleanParam
113+
114+
// add default value if there is one
115+
if (typeof paramDefaultVal !== 'undefined') {
116+
paramLabel += '=' + paramDefaultVal
117+
}
118+
119+
// show param as either required or optional
120+
if (!paramRequired) {
121+
paramLabel = '[' + paramLabel + ']'
122+
}
123+
124+
var allowedValues = ''
125+
if (paramInfo['enum']) {
126+
allowedValues = '=' + paramInfo['enum'].map(function (val) {
127+
return val // "\"" + val + "\"";
128+
}).join(',')
129+
}
130+
131+
commentLines.push(' * @apiParam {' + paramType + allowedValues + '} ' + paramLabel + ' ' + paramDescription)
132+
})
133+
134+
commentLines.push(' * @apiExample {js} ex:\ngithub.' + section + '.' + funcName + '({ ... })')
135+
136+
return commentLines.join('\n') + '\n */\n\n'
137+
}
138+
139+
debug('Converting routes to functions')
140+
prepareApi(ROUTES)
141+
142+
var apidocsPath = Path.join(__dirname, '..', 'doc', 'apidoc.js')
143+
writeFileSync(apidocsPath, apidocs.trim() + '\n')

0 commit comments

Comments
 (0)
Please sign in to comment.