Skip to content

Commit

Permalink
fix: re-introduced the docs command and updated to ESM modules (ipfs#…
Browse files Browse the repository at this point in the history
  • Loading branch information
maschad committed Nov 23, 2022
1 parent 704599e commit 3d714dc
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@
"strip-bom": "^5.0.0",
"strip-json-comments": "^5.0.0",
"tempy": "^2.0.0",
"typedoc": "^0.23.21",
"typescript": "^4.6.3",
"uint8arrays": "^4.0.2",
"undici": "^5.0.0",
Expand Down
45 changes: 45 additions & 0 deletions src/cmds/docs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { loadUserConfig } from '../config/user.js'
import docs from '../docs.js'

/**
* @typedef {import("yargs").Argv} Argv
*/
const EPILOG = `
Typescript config file is required to generated docs. Try \`aegir ts --preset config > tsconfig.json\`
`

export default {
command: 'docs',
desc: 'Generate documentation from TS type declarations.',
/**
* @param {Argv} yargs
*/
builder: async (yargs) => {
const userConfig = await loadUserConfig()

yargs
.epilog(EPILOG)
.example('aegir docs', 'Build HTML documentation.')
.example('aegir docs -p', 'Build HTML documentation and publish to Github Pages.')
.options({
publish: {
alias: 'p',
type: 'boolean',
describe: 'Publish to GitHub Pages',
default: userConfig.docs.publish
},
entryPoint: {
type: 'string',
describe:
'Specifies the entry points to be documented by TypeDoc. TypeDoc will examine the exports of these files and create documentation according to the exports. Either files or directories may be specified. If a directory is specified, all source files within the directory will be included as an entry point.',
default: userConfig.docs.entryPoint
}
})
},
/**
* @param {(import("../types").GlobalOptions & import("../types").DocsOptions) | undefined} argv
*/
async handler (argv) {
await docs.run(argv)
}
}
142 changes: 142 additions & 0 deletions src/docs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@

import { hasTsconfig, fromAegir, fromRoot, readJson } from './utils'
import Listr from 'listr'
import kleur from 'kleur'
import fs from 'fs-extra'
import path from 'path'
import { execa } from 'execa'
import merge from 'merge-options'
import { promisify } from 'util'
import ghPages from 'gh-pages'
import { premove as del } from 'premove/sync'
import resolve from '../utils/resolve.js'

const publishPages = promisify(ghPages.publish)

/**
* @typedef {import("./types").GlobalOptions} GlobalOptions
* @typedef {import("./types").DocsOptions} DocsOptions
* @typedef {import("listr").ListrTaskWrapper} Task
*
* @typedef {object} Options
* @property {string} entryPoint - Entry point for typedoc (defaults: 'src/index.js')
* @property {string[]} forwardOptions - Extra options to forward to the backend
*/

/**
* Docs command
*
* @param {GlobalOptions & DocsOptions} ctx
* @param {Task} task
*/
const docs = async (ctx, task) => {
let userTSConfig = readJson(fromRoot('tsconfig.json'))
const configPath = fromRoot('tsconfig-docs.aegir.json')

try {
if (userTSConfig.extends) {
const extendedConf = readJson(path.resolve(userTSConfig.extends))

userTSConfig = merge.apply({ concatArrays: true }, [extendedConf, userTSConfig])

delete userTSConfig.extends
}

const config = {
...userTSConfig
}

if (config.compilerOptions) {
// remove config options that cause tsdoc to fail
delete config.compilerOptions.emitDeclarationOnly
}

fs.writeJsonSync(configPath, config)

/** @type {Options} */
const opts = {
forwardOptions: ctx['--'] ? ctx['--'] : [],
entryPoint: ctx.entryPoint
}
if (!hasTsconfig) {
// eslint-disable-next-line no-console
console.error(
kleur.yellow('Documentation requires typescript config.\nTry running `aegir ts --preset config > tsconfig.json`')
)
return
}
// run typedoc
const proc = execa(
'typedoc',
[
fromRoot(opts.entryPoint),
'--tsconfig',
configPath,
'--out',
'docs',
'--hideGenerator',
'--includeVersion',
'--gitRevision',
'master',
'--plugin',
fromAegir('src/ts/typedoc-plugin.js'),
...opts.forwardOptions
],
{
localDir: path.join(__dirname, '..'),
preferLocal: true
}
)
proc.all?.on('data', (chunk) => {
task.output = chunk.toString().replace('\n', '')
})
await proc

// write .nojekyll file
fs.writeFileSync('docs/.nojekyll', '')
} finally {
fs.removeSync(configPath)
}
}

const publishDocs = () => {
return publishPages(
'docs',
// @ts-ignore - promisify returns wrong type
{
dotfiles: true,
message: 'chore: update documentation'
}
)
}

const tasks = new Listr(
[
{
title: 'Clean ./docs',
task: () => {
del('docs')
del('dist')
}
},
{
title: 'Generating documentation',
/**
*
* @param {GlobalOptions & DocsOptions} ctx
* @param {Task} task
*/
task: docs
},
{
title: 'Publish to GitHub Pages',
task: publishDocs,
enabled: (ctx) => ctx.publish && hasTsconfig
}
],
{
renderer: 'verbose'
}
)

export default tasks
39 changes: 39 additions & 0 deletions src/docs/typedoc-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Converter } from 'typedoc'
import path from 'path'
import fs from 'fs'

/**
* @param {import("typedoc/dist/lib/application").Application} Application
*/
const plugin = function (Application) {
const app = Application.owner
const pkg = path.join(process.cwd(), 'package.json')
/** @type {any} */
let pkgJson

try {
pkgJson = JSON.parse(fs.readFileSync(pkg).toString())
} catch (err) {
throw new Error('cant find package.json')
}
/**
* @param {import("typedoc/dist/lib/converter/context")} context
* @param {import("typedoc/dist/lib/models/reflections/abstract").Reflection} reflection
* @param {import("typescript").Node} node
*/
const cb = (context, reflection, node) => {
if (pkgJson && reflection.name === 'export=') {
let name
if (node) {
// @ts-ignore
name = node.symbol.escapedName
}
reflection.name = `${name || 'default'}`
}
}
app.converter.on(Converter.EVENT_CREATE_DECLARATION, cb)
}

module.exports = {
load: plugin
}

0 comments on commit 3d714dc

Please sign in to comment.