@travetto/doc 3.0.0-rc.2 → 3.0.0-rc.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -26
- package/package.json +15 -9
- package/src/doc.ts +2 -2
- package/src/lib.ts +15 -2
- package/src/mod-mapping.ts +258 -0
- package/src/mod.ts +5 -70
- package/src/nodes.ts +60 -23
- package/src/render/code-highlight.ts +16 -23
- package/src/render/context.ts +12 -31
- package/src/render/html.ts +3 -2
- package/src/render/markdown.ts +2 -1
- package/src/render/prism.d.ts +14 -386
- package/src/render/util.ts +24 -7
- package/src/types.ts +4 -9
- package/src/util/file.ts +25 -18
- package/src/util/resolve.ts +14 -21
- package/src/util/run.ts +29 -21
- package/support/cli.doc.ts +84 -0
- package/bin/cli-doc.ts +0 -84
- /package/{index.ts → __index__.ts} +0 -0
package/src/nodes.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
|
|
3
|
+
import { path, RootIndex, PackageUtil } from '@travetto/manifest';
|
|
3
4
|
|
|
4
5
|
import { FileUtil, } from './util/file';
|
|
5
6
|
import { DocRunUtil, RunConfig } from './util/run';
|
|
@@ -18,6 +19,8 @@ const $n = <T extends string, U extends Record<string, unknown>>(t: T, values: U
|
|
|
18
19
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
19
20
|
({ _type: t, ...values } as { _type: T } & U);
|
|
20
21
|
|
|
22
|
+
type FormattedCommand = { formatCommand?(cmd: string, args: string[]): string };
|
|
23
|
+
|
|
21
24
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
22
25
|
|
|
23
26
|
/**
|
|
@@ -104,6 +107,11 @@ export const node = {
|
|
|
104
107
|
* @param content
|
|
105
108
|
*/
|
|
106
109
|
SubSection: (title: Content) => $n('subsection', { title: $c(title) }),
|
|
110
|
+
/**
|
|
111
|
+
* Sub-sub-section
|
|
112
|
+
* @param content
|
|
113
|
+
*/
|
|
114
|
+
SubSubSection: (title: Content) => $n('subsubsection', { title: $c(title) }),
|
|
107
115
|
/**
|
|
108
116
|
* Library reference
|
|
109
117
|
* @param content
|
|
@@ -156,27 +164,34 @@ export const node = {
|
|
|
156
164
|
* @param args
|
|
157
165
|
* @param cfg
|
|
158
166
|
*/
|
|
159
|
-
Execute: (title: Content, cmd: string, args: string[] = [], cfg: RunConfig = {}) => {
|
|
167
|
+
Execute: (title: Content, cmd: string, args: string[] = [], cfg: RunConfig & FormattedCommand = {}) => {
|
|
160
168
|
if (cmd !== 'trv') {
|
|
161
|
-
cmd = FileUtil.resolveFile(cmd).
|
|
169
|
+
cmd = FileUtil.resolveFile(cmd).replace(path.cwd(), '.');
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
const script = DocRunUtil.run(cmd, args, cfg);
|
|
165
|
-
const prefix = !/.*\/doc\/.*[.]ts$/.test(cmd) ? '$' :
|
|
166
|
-
|
|
173
|
+
const prefix = !/.*\/doc\/.*[.]ts$/.test(cmd) ? '$' : '$ node ';
|
|
174
|
+
|
|
175
|
+
const commandDisplay = cfg.formatCommand?.(cmd, args) ?? `${cmd} ${args.join(' ')}`;
|
|
167
176
|
|
|
168
|
-
return node.Terminal(title, `${prefix} ${
|
|
177
|
+
return node.Terminal(title, `${prefix} ${commandDisplay}\n\n${script}`);
|
|
169
178
|
},
|
|
170
179
|
|
|
171
180
|
/**
|
|
172
181
|
* Node Module Reference
|
|
173
|
-
* @param
|
|
174
|
-
*/
|
|
175
|
-
Mod(folder: string) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
* @param name
|
|
183
|
+
*/
|
|
184
|
+
Mod(name: string, cfg?: { folder: string, displayName: string, description: string }) {
|
|
185
|
+
if (!cfg) {
|
|
186
|
+
const folder = RootIndex.getModule(name)!.sourcePath;
|
|
187
|
+
const pkg = PackageUtil.readPackage(folder);
|
|
188
|
+
cfg = {
|
|
189
|
+
folder,
|
|
190
|
+
displayName: pkg.travetto!.displayName!,
|
|
191
|
+
description: pkg.description!
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return $n('mod', { title: $c(cfg.displayName), link: $c(cfg.folder), description: $c(cfg.description), name: $c(name) });
|
|
180
195
|
},
|
|
181
196
|
|
|
182
197
|
/**
|
|
@@ -184,7 +199,10 @@ export const node = {
|
|
|
184
199
|
* @param title
|
|
185
200
|
* @param file
|
|
186
201
|
*/
|
|
187
|
-
Ref: (title: Content, file: string) => {
|
|
202
|
+
Ref: (title: Content, file: string | Function) => {
|
|
203
|
+
if (typeof file === 'function') {
|
|
204
|
+
file = RootIndex.getFunctionMetadata(file)!.source;
|
|
205
|
+
}
|
|
188
206
|
const res = ResolveUtil.resolveRef(title, file);
|
|
189
207
|
return $n('ref', { title: $c(res.title), link: $c(res.file), line: res.line });
|
|
190
208
|
},
|
|
@@ -196,8 +214,14 @@ export const node = {
|
|
|
196
214
|
* @param outline
|
|
197
215
|
* @param language
|
|
198
216
|
*/
|
|
199
|
-
Code: (title: Content, content: Content, outline = false, language = 'typescript') => {
|
|
217
|
+
Code: (title: Content, content: Content | Function, outline = false, language = 'typescript', rewrite?: (text: string) => string) => {
|
|
218
|
+
if (typeof content === 'function') {
|
|
219
|
+
content = RootIndex.getFunctionMetadata(content)!.source;
|
|
220
|
+
}
|
|
200
221
|
const res = ResolveUtil.resolveCode(content, language, outline);
|
|
222
|
+
if (rewrite && typeof res.content === 'string') {
|
|
223
|
+
res.content = rewrite(res.content);
|
|
224
|
+
}
|
|
201
225
|
return $n('code', { title: $c(title), content: $c(res.content), language: res.language, file: $c(res.file) });
|
|
202
226
|
},
|
|
203
227
|
|
|
@@ -217,8 +241,13 @@ export const node = {
|
|
|
217
241
|
* @param install
|
|
218
242
|
* @param pkg
|
|
219
243
|
*/
|
|
220
|
-
Header: (
|
|
221
|
-
|
|
244
|
+
Header: (mod?: string, install = true) => {
|
|
245
|
+
if (!mod) {
|
|
246
|
+
mod = RootIndex.mainPackage.name;
|
|
247
|
+
}
|
|
248
|
+
const pkg = PackageUtil.readPackage(RootIndex.getModule(mod)!.sourcePath);
|
|
249
|
+
return $n('header', { title: $c(pkg.travetto?.displayName ?? pkg.name), description: $c(pkg.description), package: pkg.name, install });
|
|
250
|
+
},
|
|
222
251
|
|
|
223
252
|
/**
|
|
224
253
|
* Comment
|
|
@@ -235,7 +264,10 @@ export const node = {
|
|
|
235
264
|
* @param endPattern
|
|
236
265
|
* @param outline
|
|
237
266
|
*/
|
|
238
|
-
Snippet: (title: Content, file: string, startPattern: RegExp, endPattern?: RegExp, outline?: boolean) => {
|
|
267
|
+
Snippet: (title: Content, file: string | Function, startPattern: RegExp, endPattern?: RegExp, outline?: boolean) => {
|
|
268
|
+
if (typeof file !== 'string') {
|
|
269
|
+
file = RootIndex.getFunctionMetadata(file)!.source;
|
|
270
|
+
}
|
|
239
271
|
const res = ResolveUtil.resolveSnippet(file, startPattern, endPattern, outline);
|
|
240
272
|
return $n('code', {
|
|
241
273
|
title: $c(title), content: $c(res.text), line: res.line, file: $c(res.file), language: res.language,
|
|
@@ -244,13 +276,18 @@ export const node = {
|
|
|
244
276
|
},
|
|
245
277
|
|
|
246
278
|
/**
|
|
247
|
-
*
|
|
279
|
+
* Installing a package or program
|
|
248
280
|
* @param title
|
|
249
281
|
* @param pkg
|
|
250
282
|
*/
|
|
251
283
|
Install: (title: Content, pkg: Content) => {
|
|
252
|
-
|
|
253
|
-
|
|
284
|
+
if (typeof pkg === 'string' && !pkg.includes(' ')) {
|
|
285
|
+
return $n('install', {
|
|
286
|
+
title: $c(title), language: 'bash', content: $c(`npm install ${pkg}\n\n# or\n\nyarn add ${pkg}`)
|
|
287
|
+
});
|
|
288
|
+
} else {
|
|
289
|
+
return $n('install', { title: $c(title), language: 'bash', content: $c(pkg), subtype: undefined });
|
|
290
|
+
}
|
|
254
291
|
},
|
|
255
292
|
|
|
256
293
|
/**
|
|
@@ -284,7 +321,7 @@ export const node = {
|
|
|
284
321
|
* @param file
|
|
285
322
|
*/
|
|
286
323
|
Image: (title: Content, file: string) => {
|
|
287
|
-
if (!/^https?:/.test(file) && !
|
|
324
|
+
if (!/^https?:/.test(file) && !existsSync(file)) {
|
|
288
325
|
throw new Error(`${file} is not a valid location`);
|
|
289
326
|
}
|
|
290
327
|
return $n('image', { title: $c(title), link: $c(file) });
|
|
@@ -1,31 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import 'prismjs/
|
|
11
|
-
import 'prismjs/components/prism-
|
|
12
|
-
import 'prismjs/components/prism-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import 'prismjs/components/prism-yaml';
|
|
16
|
-
import 'prismjs/components/prism-json';
|
|
17
|
-
import 'prismjs/components/prism-sql';
|
|
18
|
-
import 'prismjs/components/prism-properties';
|
|
19
|
-
import 'prismjs/components/prism-bash';
|
|
20
|
-
|
|
21
|
-
Prism.plugins.NormalizeWhitespace.setDefaults({
|
|
1
|
+
import { default as prismjs } from 'prismjs';
|
|
2
|
+
|
|
3
|
+
import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace.js';
|
|
4
|
+
import 'prismjs/components/prism-typescript.js';
|
|
5
|
+
import 'prismjs/components/prism-javascript.js';
|
|
6
|
+
import 'prismjs/components/prism-css.js';
|
|
7
|
+
import 'prismjs/components/prism-scss.js';
|
|
8
|
+
import 'prismjs/components/prism-yaml.js';
|
|
9
|
+
import 'prismjs/components/prism-json.js';
|
|
10
|
+
import 'prismjs/components/prism-sql.js';
|
|
11
|
+
import 'prismjs/components/prism-properties.js';
|
|
12
|
+
import 'prismjs/components/prism-bash.js';
|
|
13
|
+
|
|
14
|
+
prismjs.plugins.NormalizeWhitespace.setDefaults({
|
|
22
15
|
'remove-trailing': true,
|
|
23
16
|
'remove-indent': true,
|
|
24
17
|
'left-trim': true,
|
|
25
18
|
'right-trim': true
|
|
26
19
|
});
|
|
27
20
|
|
|
28
|
-
const nw =
|
|
21
|
+
const nw = prismjs.plugins.NormalizeWhitespace;
|
|
29
22
|
|
|
30
23
|
const tokenMapping: { [key: string]: string } = {
|
|
31
24
|
gt: '>',
|
|
@@ -44,7 +37,7 @@ export function highlight(text: string, lang: string): string | undefined {
|
|
|
44
37
|
.replace(/&([a-z][^;]*);/g, (a, k) => tokenMapping[k] || a);
|
|
45
38
|
|
|
46
39
|
try {
|
|
47
|
-
return
|
|
40
|
+
return prismjs.highlight(text, prismjs.languages[lang], lang)
|
|
48
41
|
.replace(/(@\s*<span[^>]*)function("\s*>)/g, (a, pre, post) => `${pre}meta${post}`)
|
|
49
42
|
.replace(/[{}]/g, a => `{{'${a}'}}`);
|
|
50
43
|
} catch (err) {
|
package/src/render/context.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { PathUtil, FsUtil, Package, EnvUtil } from '@travetto/boot';
|
|
1
|
+
import { path } from '@travetto/manifest';
|
|
4
2
|
|
|
5
3
|
import { AllType, AllTypeMap, node as n } from '../nodes';
|
|
6
4
|
import { DocNode, RenderContextShape } from '../types';
|
|
@@ -13,31 +11,15 @@ export type AllChildren = AllType;
|
|
|
13
11
|
export class RenderContext implements RenderContextShape {
|
|
14
12
|
|
|
15
13
|
file: string;
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
travettoBaseUrl: string;
|
|
16
|
+
repoRoot: string;
|
|
16
17
|
|
|
17
|
-
constructor(file: string) {
|
|
18
|
-
this.file =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return (Package.repository?.url ?? '').replace(/[.]git$/, '');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
get gitBaseUrl(): string {
|
|
26
|
-
return `${this.#repoUrl}/tree/${EnvUtil.get('TRV_DOC_BRANCH', 'main')}`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
get travettoGitBaseUrl(): string {
|
|
30
|
-
return this.#repoUrl.includes('travetto/travetto') ? this.gitBaseUrl : 'https://github.com/travetto/travetto/main';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get gitFolder(): string {
|
|
34
|
-
let base = PathUtil.cwd;
|
|
35
|
-
|
|
36
|
-
while (base && !(FsUtil.existsSync(PathUtil.resolveUnix(base, '.git')))) {
|
|
37
|
-
base = path.dirname(base);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return `${this.gitBaseUrl}${PathUtil.cwd.replace(base, '')}`;
|
|
18
|
+
constructor(file: string, repoRoot: string, baseUrl: string, travettoBaseUrl: string) {
|
|
19
|
+
this.file = path.toPosix(file);
|
|
20
|
+
this.baseUrl = baseUrl;
|
|
21
|
+
this.repoRoot = repoRoot;
|
|
22
|
+
this.travettoBaseUrl = travettoBaseUrl;
|
|
41
23
|
}
|
|
42
24
|
|
|
43
25
|
toc(root: DocNode): AllTypeMap['Ordered'] {
|
|
@@ -57,15 +39,14 @@ export class RenderContext implements RenderContextShape {
|
|
|
57
39
|
return n.Group([
|
|
58
40
|
n.Comment('This file was generated by @travetto/doc and should not be modified directly'),
|
|
59
41
|
n.Text('\n'),
|
|
60
|
-
n.Comment(`Please modify ${this.file.replace(
|
|
42
|
+
n.Comment(`Please modify ${this.file.replace(this.repoRoot, this.baseUrl)} and execute "npx trv doc" to rebuild`),
|
|
61
43
|
]);
|
|
62
44
|
}
|
|
63
45
|
|
|
64
46
|
link(text: string, line?: number | { [key: string]: unknown, line?: number }): string {
|
|
65
47
|
const num = typeof line === 'number' ? line : line?.line;
|
|
66
|
-
text
|
|
67
|
-
|
|
68
|
-
.replace(/.*@travetto\//, `${this.travettoGitBaseUrl}/module/`)}${num ? `#L${num}` : ''}`;
|
|
48
|
+
return `${text.replace(this.repoRoot, this.baseUrl)
|
|
49
|
+
.replace(/.*@travetto\//, `${this.travettoBaseUrl}/module/`)}${num ? `#L${num}` : ''}`;
|
|
69
50
|
}
|
|
70
51
|
|
|
71
52
|
cleanText(a?: string): string {
|
package/src/render/html.ts
CHANGED
|
@@ -36,8 +36,9 @@ export const Html: Renderer = {
|
|
|
36
36
|
case 'mod': return `<a class="module-link" href="${context.link(recurse(c.link), c)}" title="${recurse(c.description)}">${recurse(c.title)}</a>`;
|
|
37
37
|
case 'image': return `<img src="${context.link(recurse(c.link), c)}" alt="${recurse(c.title)}">`;
|
|
38
38
|
case 'section':
|
|
39
|
-
case 'subsection':
|
|
40
|
-
|
|
39
|
+
case 'subsection':
|
|
40
|
+
case 'subsubsection': {
|
|
41
|
+
const tag = c._type === 'section' ? 'h2' : (c._type === 'subsection' ? 'h3' : 'h4');
|
|
41
42
|
const title = recurse(c.title);
|
|
42
43
|
return `<${tag} id="${context.getAnchorId(title)}">${title}</${tag}>`;
|
|
43
44
|
}
|
package/src/render/markdown.ts
CHANGED
|
@@ -30,6 +30,7 @@ ${context.cleanText(recurse(c.content))}
|
|
|
30
30
|
case 'image': return `, c)})`;
|
|
31
31
|
case 'section': return `## ${recurse(c.title)}`;
|
|
32
32
|
case 'subsection': return `### ${recurse(c.title)}`;
|
|
33
|
+
case 'subsubsection': return `#### ${recurse(c.title)}`;
|
|
33
34
|
case 'command':
|
|
34
35
|
case 'method':
|
|
35
36
|
case 'path':
|
|
@@ -60,7 +61,7 @@ ${context.cleanText(recurse(c.content))}
|
|
|
60
61
|
case 'header':
|
|
61
62
|
return `# ${recurse(c.title)}\n${c.description ? `## ${recurse(c.description)}\n` : ''}${'install' in c ? recurse(n.Install(c.package, c.package)) : ''}\n`;
|
|
62
63
|
case 'text':
|
|
63
|
-
return c.content;
|
|
64
|
+
return c.content.replace(/ /g, ' ');
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
};
|