bigint-crypto-utils/node_modules/jsdoc-api/lib/jsdoc-command.js

150 lines
3.5 KiB
JavaScript

const arrayify = require('array-back')
const path = require('path')
/**
* @module jsdoc-command
*/
/**
* Command base class. The command `receiver` being the `child_process` module.
* @abstract
*/
class JsdocCommand {
constructor (options, cache) {
options = options || {}
options.files = arrayify(options.files)
this.cache = cache
this.tempFile = null
const TempFile = require('./temp-file')
if (options.source) this.tempFile = new TempFile(options.source)
const jsdocOptions = Object.assign({}, options)
delete jsdocOptions.files
delete jsdocOptions.source
delete jsdocOptions.cache
this.options = options
this.jsdocOptions = jsdocOptions
const walkBack = require('walk-back')
this.jsdocPath = walkBack(
path.join(__dirname, '..'),
path.join('node_modules', 'jsdoc', 'jsdoc.js')
)
}
/**
* Template method returning the jsdoc output. Invoke later (for example via a command-queuing system) or immediately as required.
*
* 1. preExecute
* 2. validate
* 3. getOutput
* 4. postExecute
*
*/
execute () {
this.preExecute()
const err = this.validate()
this.output = this.getOutput(err)
if (this.output instanceof Promise) {
return this.output
.then(result => {
this.postExecute()
return result
})
.catch(err => {
this.postExecute()
throw err
})
} else {
this.postExecute()
return this.output
}
}
/**
* Perform pre-execution processing here, e.g. expand input glob patterns.
*/
preExecute () {
const FileSet = require('file-set')
this.inputFileSet = new FileSet(this.options.files)
}
/**
* Return an Error instance if execution should not proceed.
* @returns {null|Error}
*/
validate () {
const assert = require('assert')
assert.ok(
this.options.files.length || this.options.source,
'Must set either .files or .source'
)
if (this.inputFileSet.notExisting.length) {
const err = new Error('These files do not exist: ' + this.inputFileSet.notExisting)
err.name = 'JSDOC_ERROR'
return err
}
}
/**
* perform post-execution cleanup
*/
postExecute () {
if (this.tempFile) {
this.tempFile.delete()
}
}
verifyOutput (code, output) {
let parseFailed = false
let parsedOutput
try {
parsedOutput = JSON.parse(output.stdout)
} catch (err) {
parseFailed = true
}
if (code > 0 || parseFailed) {
const firstLineOfStdout = output.stdout.split(/\r?\n/)[0]
const err = new Error(output.stderr.trim() || firstLineOfStdout || 'Jsdoc failed.')
err.name = 'JSDOC_ERROR'
throw err
} else {
return parsedOutput
}
}
/**
* Returns a cached recordset
* @returns {Promise}
* @fulfil {object[]}
*/
readCache () {
if (this.cache) {
const fs = require('fs-then-native')
const promises = this.inputFileSet.files.map(file => fs.readFile(file, 'utf8'))
return Promise.all(promises)
.then(contents => {
this.cacheKey = contents.concat(this.inputFileSet.files)
return this.cache.read(this.cacheKey)
})
} else {
return Promise.reject()
}
}
readCacheSync () {
if (this.cache) {
const fs = require('fs')
const contents = this.inputFileSet.files.map(file => fs.readFileSync(file, 'utf8'))
this.cacheKey = contents.concat(this.inputFileSet.files)
return this.cache.readSync(this.cacheKey)
}
}
}
module.exports = JsdocCommand