forked from ionic-team/ionic-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
91 lines (74 loc) · 3.84 KB
/
Copy pathindex.ts
File metadata and controls
91 lines (74 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { ProjectType, generateContext, loadExecutor } from '@ionic/cli';
import { Command, CommandHelpSchemaFootnote, CommandHelpSchemaInput, CommandHelpSchemaOption, CommandLineInputs, CommandLineOptions, CommandMetadata } from '@ionic/cli-framework';
import { strcmp } from '@ionic/cli-framework/utils/string';
import { CommandHelpSchema, NamespaceSchemaHelpFormatter } from '@ionic/cli/lib/help';
import { mkdirp, remove, writeFile } from '@ionic/utils-fs';
import chalk from 'chalk';
import * as lodash from 'lodash';
import * as path from 'path';
import stripAnsi = require('strip-ansi');
import { ansi2md, convertHTMLEntities, links2md } from './utils';
const PROJECTS_DIRECTORY = path.resolve(__dirname, '..', '..', 'projects');
const STAGING_DIRECTORY = path.resolve(__dirname, '..', '..', '..', '..', 'docs');
export class DocsCommand extends Command {
async getMetadata(): Promise<CommandMetadata> {
return {
name: 'docs',
summary: '',
};
}
async run(inputs: CommandLineInputs, options: CommandLineOptions) {
await remove(STAGING_DIRECTORY);
await mkdirp(STAGING_DIRECTORY);
const projectTypes: ProjectType[] = ['angular'];
const baseCtx = await generateContext();
for (const projectType of projectTypes) {
// TODO: possible to do this without a physical directory?
const ctx = { ...baseCtx, execPath: path.resolve(PROJECTS_DIRECTORY, projectType) };
const executor = await loadExecutor(ctx, []);
const location = await executor.namespace.locate([]);
const formatter = new NamespaceSchemaHelpFormatter({ location, namespace: executor.namespace });
const formatted = await formatter.serialize();
const projectJson = { type: projectType, ...formatted };
// TODO: `serialize()` from base formatter isn't typed properly
projectJson.commands = await Promise.all(projectJson.commands.map(async cmd => this.extractCommand(cmd as CommandHelpSchema)));
projectJson.commands.sort((a, b) => strcmp(a.name, b.name));
await writeFile(path.resolve(STAGING_DIRECTORY, `${projectType}.json`), JSON.stringify(projectJson, undefined, 2) + '\n', { encoding: 'utf8' });
}
process.stdout.write(`${chalk.green('Done.')}\n`);
}
private async extractCommand(command: CommandHelpSchema): Promise<CommandHelpSchema> {
const processText = lodash.flow([ansi2md, stripAnsi, links2md, convertHTMLEntities, text => text.trim()]);
return {
...command,
summary: processText(command.summary),
description: await this.formatFootnotes(processText(command.description), command.footnotes),
footnotes: command.footnotes.filter(footnote => footnote.type !== 'link'), // we format link footnotes in `formatFootnotes()`
inputs: await Promise.all(command.inputs.map(input => this.extractInput(input))),
options: await Promise.all(command.options.map(opt => this.extractOption(opt))),
};
}
private async formatFootnotes(description: string, footnotes: readonly CommandHelpSchemaFootnote[]): Promise<string> {
return description.replace(/(\S+)\[\^([A-z0-9-]+)\]/g, (match, p1, p2) => {
const m = Number.parseInt(p2, 10);
const id = !Number.isNaN(m) ? m : p2;
const foundFootnote = footnotes.find(footnote => footnote.id === id);
if (!foundFootnote) {
throw new Error('Bad footnote.');
}
return foundFootnote.type === 'link' ? `[${p1}](${foundFootnote.url})` : match; // TODO: handle text footnotes
});
}
private async extractInput(input: CommandHelpSchemaInput): Promise<CommandHelpSchemaInput> {
return {
...input,
summary: stripAnsi(links2md(ansi2md(input.summary))).trim(),
};
}
private async extractOption(option: CommandHelpSchemaOption): Promise<CommandHelpSchemaOption> {
return {
...option,
summary: stripAnsi(links2md(ansi2md(option.summary))).trim(),
};
}
}