Added documentation generator
This commit is contained in:
@ -7,7 +7,13 @@ const semver = require('semver')
|
|||||||
const ora = require('ora')
|
const ora = require('ora')
|
||||||
const rimraf = require('rimraf')
|
const rimraf = require('rimraf')
|
||||||
const standard = require('standard')
|
const standard = require('standard')
|
||||||
const { generate, cloneAndCheckout, genFactory, generateRequestTypes } = require('./utils')
|
const {
|
||||||
|
generate,
|
||||||
|
cloneAndCheckout,
|
||||||
|
genFactory,
|
||||||
|
generateRequestTypes,
|
||||||
|
generateDocs
|
||||||
|
} = require('./utils')
|
||||||
|
|
||||||
start(minimist(process.argv.slice(2), {
|
start(minimist(process.argv.slice(2), {
|
||||||
string: ['tag']
|
string: ['tag']
|
||||||
@ -23,6 +29,7 @@ function start (opts) {
|
|||||||
const apiOutputFolder = join(packageFolder, 'api')
|
const apiOutputFolder = join(packageFolder, 'api')
|
||||||
const mainOutputFile = join(packageFolder, 'index.js')
|
const mainOutputFile = join(packageFolder, 'index.js')
|
||||||
const typesOutputFile = join(packageFolder, 'generated.d.ts')
|
const typesOutputFile = join(packageFolder, 'generated.d.ts')
|
||||||
|
const docOutputFile = join(__dirname, '..', 'docs', 'reference.asciidoc')
|
||||||
const requestParamsOutputFile = join(packageFolder, 'requestParams.d.ts')
|
const requestParamsOutputFile = join(packageFolder, 'requestParams.d.ts')
|
||||||
const allSpec = []
|
const allSpec = []
|
||||||
|
|
||||||
@ -35,8 +42,11 @@ function start (opts) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
readdirSync(apiFolder).forEach(generateApiFile(apiFolder, log))
|
const apiFolderContents = readdirSync(apiFolder)
|
||||||
readdirSync(xPackFolder).forEach(generateApiFile(xPackFolder, log))
|
const xPackFolderContents = readdirSync(xPackFolder)
|
||||||
|
|
||||||
|
apiFolderContents.forEach(generateApiFile(apiFolder, log))
|
||||||
|
xPackFolderContents.forEach(generateApiFile(xPackFolder, log))
|
||||||
|
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
requestParamsOutputFile,
|
requestParamsOutputFile,
|
||||||
@ -55,7 +65,21 @@ function start (opts) {
|
|||||||
types,
|
types,
|
||||||
{ encoding: 'utf8' }
|
{ encoding: 'utf8' }
|
||||||
)
|
)
|
||||||
lintFiles(log)
|
|
||||||
|
lintFiles(log, () => {
|
||||||
|
log.text = 'Generating documentation'
|
||||||
|
const allSpec = apiFolderContents.filter(f => f !== '_common.json')
|
||||||
|
.map(f => require(join(apiFolder, f)))
|
||||||
|
.concat(xPackFolderContents.map(f => require(join(xPackFolder, f))))
|
||||||
|
writeFileSync(
|
||||||
|
docOutputFile,
|
||||||
|
generateDocs(require(join(apiFolder, '_common.json')), allSpec),
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
|
||||||
|
log.succeed('Done!')
|
||||||
|
console.log('Remember to copy the generated types into the index.d.ts file')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function generateApiFile (apiFolder, log) {
|
function generateApiFile (apiFolder, log) {
|
||||||
@ -77,15 +101,14 @@ function start (opts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lintFiles (log) {
|
function lintFiles (log, cb) {
|
||||||
log.text = 'Linting...'
|
log.text = 'Linting...'
|
||||||
const files = [join(packageFolder, '*.js'), join(apiOutputFolder, '*.js')]
|
const files = [join(packageFolder, '*.js'), join(apiOutputFolder, '*.js')]
|
||||||
standard.lintFiles(files, { fix: true }, err => {
|
standard.lintFiles(files, { fix: true }, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return log.fail(err.message)
|
return log.fail(err.message)
|
||||||
}
|
}
|
||||||
log.succeed('Done!')
|
cb()
|
||||||
console.log('Remember to copy the generated types into the index.d.ts file')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
142
scripts/utils/generateDocs.js
Normal file
142
scripts/utils/generateDocs.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const dedent = require('dedent')
|
||||||
|
|
||||||
|
function generateDocs (common, spec) {
|
||||||
|
var doc = '= API Reference\n\n'
|
||||||
|
doc += commonParameters(common)
|
||||||
|
spec.forEach(s => {
|
||||||
|
doc += '\n' + generateApiDoc(s)
|
||||||
|
})
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
function commonParameters (spec) {
|
||||||
|
var doc = dedent`
|
||||||
|
=== Common parameters
|
||||||
|
Parameters that are accepted by all API endpoints.
|
||||||
|
https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html
|
||||||
|
[cols=2*]
|
||||||
|
|===\n`
|
||||||
|
Object.keys(spec.params).forEach(key => {
|
||||||
|
const name = isSnakeCased(key) && key !== camelify(key)
|
||||||
|
? '`' + key + '` or `' + camelify(key) + '`'
|
||||||
|
: '`' + key + '`'
|
||||||
|
|
||||||
|
doc += dedent`
|
||||||
|
|${name}
|
||||||
|
|${'`' + spec.params[key].type + '`'} - ${spec.params[key].description}`
|
||||||
|
if (spec.params[key].default) {
|
||||||
|
doc += ` +
|
||||||
|
_Default:_ ${'`' + spec.params[key].default + '`'}`
|
||||||
|
}
|
||||||
|
doc += '\n\n'
|
||||||
|
})
|
||||||
|
|
||||||
|
doc += dedent`
|
||||||
|
|===
|
||||||
|
`
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateApiDoc (spec) {
|
||||||
|
const name = Object.keys(spec)[0]
|
||||||
|
const documentationUrl = spec[name].documentation
|
||||||
|
const params = []
|
||||||
|
// url params
|
||||||
|
const urlParts = spec[name].url.parts
|
||||||
|
if (urlParts) {
|
||||||
|
Object.keys(urlParts).forEach(param => {
|
||||||
|
params.push({
|
||||||
|
name: param,
|
||||||
|
type: getType(urlParts[param].type, urlParts[param].options),
|
||||||
|
description: urlParts[param].description,
|
||||||
|
default: urlParts[param].default
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// query params
|
||||||
|
const urlParams = spec[name].url.params
|
||||||
|
if (urlParams) {
|
||||||
|
Object.keys(urlParams).forEach(param => {
|
||||||
|
params.push({
|
||||||
|
name: param,
|
||||||
|
type: getType(urlParams[param].type, urlParams[param].options),
|
||||||
|
description: urlParams[param].description,
|
||||||
|
default: urlParams[param].default
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// body params
|
||||||
|
const body = spec[name].body
|
||||||
|
if (body) {
|
||||||
|
params.push({
|
||||||
|
name: 'body',
|
||||||
|
type: 'object',
|
||||||
|
description: body.description,
|
||||||
|
default: body.default
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var doc = dedent`
|
||||||
|
=== ${camelify(name)}
|
||||||
|
[source,js]
|
||||||
|
----
|
||||||
|
client.${camelify(name)}([params] [, options] [, callback])
|
||||||
|
----
|
||||||
|
${documentationUrl || ''}
|
||||||
|
[cols=2*]
|
||||||
|
|===`
|
||||||
|
|
||||||
|
doc += '\n' + params.reduce((acc, val) => {
|
||||||
|
const name = isSnakeCased(val.name) && val.name !== camelify(val.name)
|
||||||
|
? '`' + val.name + '` or `' + camelify(val.name) + '`'
|
||||||
|
: '`' + val.name + '`'
|
||||||
|
acc += dedent`
|
||||||
|
|${name}
|
||||||
|
|${'`' + val.type + '`'} - ${val.description}`
|
||||||
|
if (val.default) {
|
||||||
|
acc += ` +
|
||||||
|
_Default:_ ${'`' + val.default + '`'}`
|
||||||
|
}
|
||||||
|
return acc + '\n\n'
|
||||||
|
}, '')
|
||||||
|
|
||||||
|
doc += dedent`
|
||||||
|
|===
|
||||||
|
`
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
function getType (type, options) {
|
||||||
|
switch (type) {
|
||||||
|
case 'list':
|
||||||
|
return 'string, string[]'
|
||||||
|
case 'date':
|
||||||
|
case 'time':
|
||||||
|
case 'timeout':
|
||||||
|
return 'string'
|
||||||
|
case 'enum':
|
||||||
|
return options.map(k => `'${k}'`).join(', ')
|
||||||
|
case 'int':
|
||||||
|
case 'double':
|
||||||
|
case 'long':
|
||||||
|
return 'number'
|
||||||
|
default:
|
||||||
|
return type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function camelify (str) {
|
||||||
|
return str[0] === '_'
|
||||||
|
? '_' + str.slice(1).replace(/_([a-z])/g, k => k[1].toUpperCase())
|
||||||
|
: str.replace(/_([a-z])/g, k => k[1].toUpperCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSnakeCased (str) {
|
||||||
|
return !!~str.indexOf('_')
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = generateDocs
|
||||||
@ -4,5 +4,12 @@ const generate = require('./generate')
|
|||||||
const generateRequestTypes = require('./generateRequestTypes')
|
const generateRequestTypes = require('./generateRequestTypes')
|
||||||
const cloneAndCheckout = require('./clone-es')
|
const cloneAndCheckout = require('./clone-es')
|
||||||
const genFactory = require('./genMain')
|
const genFactory = require('./genMain')
|
||||||
|
const generateDocs = require('./generateDocs')
|
||||||
|
|
||||||
module.exports = { generate, cloneAndCheckout, genFactory, generateRequestTypes }
|
module.exports = {
|
||||||
|
generate,
|
||||||
|
cloneAndCheckout,
|
||||||
|
genFactory,
|
||||||
|
generateRequestTypes,
|
||||||
|
generateDocs
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user