@travetto/doc 2.1.1 → 2.2.0
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 +1 -1
- package/bin/cli-doc.ts +6 -3
- package/package.json +4 -4
- package/src/doc.ts +2 -1
- package/src/lib.ts +1 -1
- package/src/mod.ts +8 -4
- package/src/nodes.ts +8 -3
- package/src/render/code-highlight.ts +9 -5
- package/src/render/context.ts +11 -9
- package/src/render/html.ts +2 -1
- package/src/render/markdown.ts +3 -2
- package/src/render/util.ts +5 -3
- package/src/util/file.ts +4 -4
- package/src/util/resolve.ts +5 -5
- package/src/util/run.ts +20 -10
package/README.md
CHANGED
|
@@ -142,7 +142,7 @@ Sample documentation for fictional module. This module fictitiously relies upon
|
|
|
142
142
|
<cite><a target="_blank" href="https://github.com/travetto/travetto/tree/main/module/doc/docs/test.ts">Source</a></cite>
|
|
143
143
|
</figcaption>
|
|
144
144
|
<pre><code class="language-typescript"><span class="token keyword">class</span> <span class="token class-name">TestFile</span> <span class="token punctuation">{{'{'}}</span>
|
|
145
|
-
<span class="token keyword">static</span> <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{{'{'}}</span> <span class="token punctuation">{{'}'}}</span>
|
|
145
|
+
<span class="token keyword">static</span> <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{{'{'}}</span> <span class="token punctuation">{{'}'}}</span>
|
|
146
146
|
<span class="token punctuation">{{'}'}}</span></code></pre>
|
|
147
147
|
</figure>
|
|
148
148
|
|
package/bin/cli-doc.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { PathUtil } from '@travetto/boot';
|
|
|
11
11
|
export class DocPlugin extends BasePlugin {
|
|
12
12
|
name = 'doc';
|
|
13
13
|
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
14
15
|
getOptions() {
|
|
15
16
|
return {
|
|
16
17
|
input: this.option({ desc: 'Input File', def: 'doc.ts' }),
|
|
@@ -20,7 +21,7 @@ export class DocPlugin extends BasePlugin {
|
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
async envInit() {
|
|
24
|
+
async envInit(): Promise<void> {
|
|
24
25
|
EnvInit.init({
|
|
25
26
|
debug: '0',
|
|
26
27
|
append: {
|
|
@@ -35,7 +36,9 @@ export class DocPlugin extends BasePlugin {
|
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
async action() {
|
|
39
|
+
async action(): Promise<void> {
|
|
40
|
+
console.error(process.env);
|
|
41
|
+
|
|
39
42
|
const { PhaseManager } = await import('@travetto/base');
|
|
40
43
|
// Standard compile
|
|
41
44
|
await PhaseManager.run('init');
|
|
@@ -46,7 +49,7 @@ export class DocPlugin extends BasePlugin {
|
|
|
46
49
|
|
|
47
50
|
// If specifying output
|
|
48
51
|
if (this.cmd.output.length) {
|
|
49
|
-
const write = async () => {
|
|
52
|
+
const write = async (): Promise<void> => {
|
|
50
53
|
RenderUtil.purge(docFile);
|
|
51
54
|
for (const out of this.cmd.output) {
|
|
52
55
|
const fmt = path.extname(out) ?? this.cmd.format;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/doc",
|
|
3
3
|
"displayName": "Documentation",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.2.0",
|
|
5
5
|
"description": "Documentation support for the travetto framework",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"docs",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"directory": "module/doc"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@travetto/base": "^2.
|
|
29
|
-
"prismjs": "^1.
|
|
28
|
+
"@travetto/base": "^2.2.0",
|
|
29
|
+
"prismjs": "^1.28.0"
|
|
30
30
|
},
|
|
31
31
|
"optionalPeerDependencies": {
|
|
32
|
-
"@travetto/cli": "^2.
|
|
32
|
+
"@travetto/cli": "^2.2.0"
|
|
33
33
|
},
|
|
34
34
|
"private": false,
|
|
35
35
|
"publishConfig": {
|
package/src/doc.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AllType, node } from './nodes';
|
|
2
2
|
|
|
3
|
-
export function doc(values: TemplateStringsArray, ...keys: (AllType | { ᚕfile: string, name: string } | string)[]) {
|
|
3
|
+
export function doc(values: TemplateStringsArray, ...keys: (AllType | { ᚕfile: string, name: string } | string)[]): AllType {
|
|
4
4
|
const out: AllType[] = [];
|
|
5
5
|
|
|
6
6
|
keys.forEach((el, i) =>
|
|
@@ -20,4 +20,5 @@ export function doc(values: TemplateStringsArray, ...keys: (AllType | { ᚕfile:
|
|
|
20
20
|
|
|
21
21
|
Object.assign(doc, node);
|
|
22
22
|
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
23
24
|
export const d = doc as (typeof doc) & (typeof node);
|
package/src/lib.ts
CHANGED
|
@@ -88,7 +88,7 @@ export const lib = {
|
|
|
88
88
|
Busboy: Library('busboy', 'https://github.com/mscdex/busboy'),
|
|
89
89
|
Cookies: Library('cookies', 'https://www.npmjs.com/package/cookies'),
|
|
90
90
|
ServerlessExpress: Library('aws-serverless-express', 'https://github.com/awslabs/aws-serverless-express/blob/master/README.md'),
|
|
91
|
-
AwsLambdaFastify: Library('aws-lambda
|
|
91
|
+
AwsLambdaFastify: Library('@fastify/aws-lambda', 'https://github.com/fastify/aws-lambda-fastify/blob/master/README.md'),
|
|
92
92
|
Fastify: Library('fastify', 'https://www.fastify.io/'),
|
|
93
93
|
Koa: Library('koa', 'https://koajs.com/'),
|
|
94
94
|
};
|
package/src/mod.ts
CHANGED
|
@@ -47,8 +47,12 @@ const MAPPING = {
|
|
|
47
47
|
Yaml: '@travetto/yaml'
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
export const mod = new Proxy
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
export const mod = new Proxy<Record<keyof typeof MAPPING, AllTypeMap['Mod']>>(
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
52
|
+
{} as Record<keyof typeof MAPPING, AllTypeMap['Mod']>,
|
|
53
|
+
{
|
|
54
|
+
get(tgt, p: keyof typeof MAPPING): AllTypeMap['Mod'] {
|
|
55
|
+
return node.Mod(MAPPING[p]);
|
|
56
|
+
}
|
|
53
57
|
}
|
|
54
|
-
|
|
58
|
+
);
|
package/src/nodes.ts
CHANGED
|
@@ -10,15 +10,20 @@ function $c(val: string): TextType;
|
|
|
10
10
|
function $c(val: DocNode | string): DocNode;
|
|
11
11
|
function $c(val: DocNode | string | undefined): DocNode | undefined;
|
|
12
12
|
function $c(val: string | DocNode | undefined): DocNode | undefined {
|
|
13
|
-
return val === undefined ? undefined : typeof val === 'string' ?
|
|
13
|
+
return val === undefined ? undefined : typeof val === 'string' ?
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
15
|
+
{ _type: 'text' as const, content: val } as TextType : val;
|
|
14
16
|
}
|
|
15
|
-
const $n = <T extends string, U extends Record<string, unknown>>(t: T,
|
|
17
|
+
const $n = <T extends string, U extends Record<string, unknown>>(t: T, values: U): { _type: T } & U =>
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
19
|
+
({ _type: t, ...values } as { _type: T } & U);
|
|
20
|
+
|
|
21
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
16
22
|
|
|
17
23
|
/**
|
|
18
24
|
* All Node Types
|
|
19
25
|
*/
|
|
20
26
|
export const node = {
|
|
21
|
-
|
|
22
27
|
buildList(items: Content[], ordered = false) {
|
|
23
28
|
return $n('list', {
|
|
24
29
|
items: items.map(x => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
type Lang = {};
|
|
2
2
|
|
|
3
3
|
// TODO: Get proper typings
|
|
4
|
-
const Prism
|
|
4
|
+
const Prism: {
|
|
5
5
|
plugins: { NormalizeWhitespace: Record<string, Function> };
|
|
6
6
|
languages: Record<string, Lang>;
|
|
7
7
|
highlight(text: string, grammar: Lang, language: string): string;
|
|
8
|
-
};
|
|
8
|
+
} = require('prismjs');
|
|
9
9
|
|
|
10
10
|
import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace';
|
|
11
11
|
import 'prismjs/components/prism-typescript';
|
|
@@ -34,7 +34,7 @@ const tokenMapping: { [key: string]: string } = {
|
|
|
34
34
|
apos: "'"
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
export function highlight(text: string, lang: string) {
|
|
37
|
+
export function highlight(text: string, lang: string): string | undefined {
|
|
38
38
|
text = nw.normalize(text, {
|
|
39
39
|
indent: 0
|
|
40
40
|
});
|
|
@@ -47,8 +47,12 @@ export function highlight(text: string, lang: string) {
|
|
|
47
47
|
return Prism.highlight(text, Prism.languages[lang], lang)
|
|
48
48
|
.replace(/(@\s*<span[^>]*)function("\s*>)/g, (a, pre, post) => `${pre}meta${post}`)
|
|
49
49
|
.replace(/[{}]/g, a => `{{'${a}'}}`);
|
|
50
|
-
} catch (
|
|
51
|
-
|
|
50
|
+
} catch (err) {
|
|
51
|
+
if (err instanceof Error) {
|
|
52
|
+
console.error(err.message, { error: err });
|
|
53
|
+
} else {
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
|
package/src/render/context.ts
CHANGED
|
@@ -18,19 +18,19 @@ export class RenderContext implements RenderContextShape {
|
|
|
18
18
|
this.file = PathUtil.resolveUnix(file);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
get #repoUrl() {
|
|
21
|
+
get #repoUrl(): string {
|
|
22
22
|
return (Package.repository?.url ?? '').replace(/[.]git$/, '');
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
get gitBaseUrl() {
|
|
25
|
+
get gitBaseUrl(): string {
|
|
26
26
|
return `${this.#repoUrl}/tree/${EnvUtil.get('TRV_DOC_BRANCH', 'main')}`;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
get travettoGitBaseUrl() {
|
|
29
|
+
get travettoGitBaseUrl(): string {
|
|
30
30
|
return this.#repoUrl.includes('travetto/travetto') ? this.gitBaseUrl : 'https://github.com/travetto/travetto/main';
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
get gitFolder() {
|
|
33
|
+
get gitFolder(): string {
|
|
34
34
|
let base = PathUtil.cwd;
|
|
35
35
|
|
|
36
36
|
while (base && !(FsUtil.existsSync(PathUtil.resolveUnix(base, '.git')))) {
|
|
@@ -40,18 +40,20 @@ export class RenderContext implements RenderContextShape {
|
|
|
40
40
|
return `${this.gitBaseUrl}${PathUtil.cwd.replace(base, '')}`;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
toc(root: DocNode) {
|
|
43
|
+
toc(root: DocNode): AllTypeMap['Ordered'] {
|
|
44
44
|
return n.Ordered(
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
45
46
|
...(root as AllTypeMap['Group']).nodes
|
|
46
47
|
.filter(x => x._type === 'section')
|
|
47
48
|
.map(x => {
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
48
50
|
const { title } = x as AllTypeMap['Section'];
|
|
49
51
|
return n.Anchor(title, title);
|
|
50
52
|
})
|
|
51
53
|
);
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
get preamble() {
|
|
56
|
+
get preamble(): AllTypeMap['Group'] {
|
|
55
57
|
return n.Group([
|
|
56
58
|
n.Comment('This file was generated by @travetto/doc and should not be modified directly'),
|
|
57
59
|
n.Text('\n'),
|
|
@@ -59,18 +61,18 @@ export class RenderContext implements RenderContextShape {
|
|
|
59
61
|
]);
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
link(text: string, line?: number | { [key: string]: unknown, line?: number }) {
|
|
64
|
+
link(text: string, line?: number | { [key: string]: unknown, line?: number }): string {
|
|
63
65
|
const num = typeof line === 'number' ? line : line?.line;
|
|
64
66
|
text = PathUtil.normalizeFrameworkPath(text);
|
|
65
67
|
return `${text.replace(PathUtil.cwd, this.gitBaseUrl)
|
|
66
68
|
.replace(/.*@travetto\//, `${this.travettoGitBaseUrl}/module/`)}${num ? `#L${num}` : ''}`;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
cleanText(a?: string) {
|
|
71
|
+
cleanText(a?: string): string {
|
|
70
72
|
return a ? a.replace(/^[\n ]+|[\n ]+$/gs, '') : '';
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
getAnchorId(a: string) {
|
|
75
|
+
getAnchorId(a: string): string {
|
|
74
76
|
return a.toLowerCase().replace(/<[^>]+>/g, ' ').replace(/[^a-z0-9]+/g, ' ').trim().replace(/ /g, '-');
|
|
75
77
|
}
|
|
76
78
|
}
|
package/src/render/html.ts
CHANGED
|
@@ -9,7 +9,8 @@ const ENTITY_RE = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join('')}]`, 'gm')
|
|
|
9
9
|
export const Html: Renderer = {
|
|
10
10
|
ext: 'html',
|
|
11
11
|
render(c: AllChildren, context: RenderContext, root = c) {
|
|
12
|
-
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13
|
+
const recurse = (s: AllChildren | DocNode): string => this.render(s as AllChildren, context, root);
|
|
13
14
|
switch (c._type) {
|
|
14
15
|
case 'toc': {
|
|
15
16
|
const content = recurse(n.Group([n.SubSection(c.title), context.toc(root)]));
|
package/src/render/markdown.ts
CHANGED
|
@@ -2,12 +2,13 @@ import { AllType, node as n } from '../nodes';
|
|
|
2
2
|
import { DocNode, Renderer } from '../types';
|
|
3
3
|
import { AllChildren, RenderContext } from './context';
|
|
4
4
|
|
|
5
|
-
const titleCase = (a: string) => a.replace(/^[a-z]/, v => v.toUpperCase());
|
|
5
|
+
const titleCase = (a: string): string => a.replace(/^[a-z]/, v => v.toUpperCase());
|
|
6
6
|
|
|
7
7
|
export const Markdown: Renderer = {
|
|
8
8
|
ext: 'md',
|
|
9
9
|
render(c: AllChildren, context: RenderContext, root: AllType = c) {
|
|
10
|
-
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
11
|
+
const recurse = (s: AllChildren | DocNode): string => this.render(s as AllChildren, context, root);
|
|
11
12
|
switch (c._type) {
|
|
12
13
|
case 'toc': return recurse(n.Group([n.SubSection(c.title), context.toc(root)]));
|
|
13
14
|
case 'strong': return `**${recurse(c.content)}**`;
|
package/src/render/util.ts
CHANGED
|
@@ -13,7 +13,7 @@ export class RenderUtil {
|
|
|
13
13
|
|
|
14
14
|
static #imported = new Map<string, { root: AllType, wrap?: Wrapper }>();
|
|
15
15
|
|
|
16
|
-
static purge(file: string) {
|
|
16
|
+
static purge(file: string): void {
|
|
17
17
|
this.#imported.delete(file);
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -23,17 +23,19 @@ export class RenderUtil {
|
|
|
23
23
|
* @param fmt
|
|
24
24
|
* @returns
|
|
25
25
|
*/
|
|
26
|
-
static async render(file: string, fmt: string = Markdown.ext) {
|
|
26
|
+
static async render(file: string, fmt: string = Markdown.ext): Promise<string> {
|
|
27
27
|
fmt = fmt.replace(/^[.]/, ''); // Strip leading .
|
|
28
28
|
if (!renderers[fmt]) {
|
|
29
29
|
throw new Error(`Unknown renderer with format: ${fmt}`);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
32
33
|
const res = (await import(file)) as DocumentShape;
|
|
33
34
|
|
|
34
35
|
if (!this.#imported.has(file)) {
|
|
35
36
|
this.#imported.set(file, {
|
|
36
37
|
wrap: res.wrap,
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37
39
|
root: ('_type' in res.text ? res.text : await res.text()) as AllType
|
|
38
40
|
});
|
|
39
41
|
}
|
|
@@ -41,7 +43,7 @@ export class RenderUtil {
|
|
|
41
43
|
const { wrap, root } = this.#imported.get(file)!;
|
|
42
44
|
|
|
43
45
|
const ctx = new RenderContext(file);
|
|
44
|
-
const content = renderers[fmt].render(root
|
|
46
|
+
const content = renderers[fmt].render(root, ctx).replace(/\n{3,100}/msg, '\n\n').trim();
|
|
45
47
|
const preamble = renderers[fmt].render(ctx.preamble, ctx);
|
|
46
48
|
return `${preamble}\n${wrap?.[fmt]?.(content) ?? content}\n`;
|
|
47
49
|
}
|
package/src/util/file.ts
CHANGED
|
@@ -23,7 +23,7 @@ export class FileUtil {
|
|
|
23
23
|
* @param file
|
|
24
24
|
* @returns
|
|
25
25
|
*/
|
|
26
|
-
static resolveFile(file: string) {
|
|
26
|
+
static resolveFile(file: string): { resolved: string, cleaned: string } {
|
|
27
27
|
if (!FsUtil.existsSync(PathUtil.resolveUnix(file))) {
|
|
28
28
|
file = require.resolve(file);
|
|
29
29
|
}
|
|
@@ -37,7 +37,7 @@ export class FileUtil {
|
|
|
37
37
|
* @param file
|
|
38
38
|
* @returns
|
|
39
39
|
*/
|
|
40
|
-
static read(file: string) {
|
|
40
|
+
static read(file: string): { content: string, language: string, file: string } {
|
|
41
41
|
const { resolved, cleaned } = this.resolveFile(file);
|
|
42
42
|
|
|
43
43
|
const ext = path.extname(resolved).replace(/^[.]/, '');
|
|
@@ -65,7 +65,7 @@ export class FileUtil {
|
|
|
65
65
|
/**
|
|
66
66
|
* Determine if a file is a decorator
|
|
67
67
|
*/
|
|
68
|
-
static isDecorator(name: string, file: string) {
|
|
68
|
+
static isDecorator(name: string, file: string): boolean {
|
|
69
69
|
const { resolved } = this.resolveFile(file);
|
|
70
70
|
|
|
71
71
|
const key = `${name}:${resolved}`;
|
|
@@ -94,7 +94,7 @@ export class FileUtil {
|
|
|
94
94
|
* Clean code snippet
|
|
95
95
|
* @returns
|
|
96
96
|
*/
|
|
97
|
-
static buildOutline(code: string) {
|
|
97
|
+
static buildOutline(code: string): string {
|
|
98
98
|
let methodPrefix = '';
|
|
99
99
|
code = code.split(/\n/).map((x) => {
|
|
100
100
|
if (!methodPrefix) {
|
package/src/util/resolve.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { FileUtil } from './file';
|
|
|
6
6
|
*/
|
|
7
7
|
export class ResolveUtil {
|
|
8
8
|
|
|
9
|
-
static resolveRef<T>(title: string | T, file: string) {
|
|
9
|
+
static resolveRef<T>(title: string | T, file: string): { title: string | T, file: string, line: number } {
|
|
10
10
|
|
|
11
11
|
let line = 0;
|
|
12
12
|
const { resolved } = FileUtil.resolveFile(file);
|
|
@@ -35,7 +35,7 @@ export class ResolveUtil {
|
|
|
35
35
|
return { title, file, line };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
static resolveCode<T>(content: string | T, language: string, outline = false) {
|
|
38
|
+
static resolveCode<T>(content: string | T, language: string, outline = false): { content: string | T, language: string, file?: string } {
|
|
39
39
|
let file: string | undefined;
|
|
40
40
|
if (typeof content === 'string') {
|
|
41
41
|
if (/^[@:A-Za-z0-9\/\\\-_.]+[.]([a-z]{2,4})$/.test(content)) {
|
|
@@ -52,7 +52,7 @@ export class ResolveUtil {
|
|
|
52
52
|
return { content, language, file };
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
static resolveConfig<T>(content: string | T, language: string) {
|
|
55
|
+
static resolveConfig<T>(content: string | T, language: string): { content: string | T, language: string, file?: string } {
|
|
56
56
|
let file: string | undefined;
|
|
57
57
|
if (typeof content === 'string') {
|
|
58
58
|
if (/^[@:A-Za-z0-9\/\\\-_.]+[.](ya?ml|properties)$/.test(content)) {
|
|
@@ -65,7 +65,7 @@ export class ResolveUtil {
|
|
|
65
65
|
return { content, language, file };
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
static resolveSnippet(file: string, startPattern: RegExp, endPattern?: RegExp, outline = false) {
|
|
68
|
+
static resolveSnippet(file: string, startPattern: RegExp, endPattern?: RegExp, outline = false): { text: string, language: string, file: string, line: number } {
|
|
69
69
|
const res = FileUtil.read(file);
|
|
70
70
|
const language = res.language;
|
|
71
71
|
file = res.file;
|
|
@@ -85,7 +85,7 @@ export class ResolveUtil {
|
|
|
85
85
|
return { text, language, line: startIdx + 1, file };
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
static resolveSnippetLink(file: string, startPattern: RegExp) {
|
|
88
|
+
static resolveSnippetLink(file: string, startPattern: RegExp): { file: string, line: number } {
|
|
89
89
|
const res = FileUtil.read(file);
|
|
90
90
|
const line = res.content.split(/\n/g).findIndex(l => startPattern.test(l));
|
|
91
91
|
if (line < 0) {
|
package/src/util/run.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from 'child_process';
|
|
2
2
|
|
|
3
|
-
import { PathUtil, ExecUtil, EnvUtil } from '@travetto/boot';
|
|
3
|
+
import { PathUtil, ExecUtil, EnvUtil, ExecutionOptions, ExecutionState } from '@travetto/boot';
|
|
4
4
|
|
|
5
5
|
export type RunConfig = {
|
|
6
6
|
filter?: (line: string) => boolean;
|
|
@@ -9,22 +9,28 @@ export type RunConfig = {
|
|
|
9
9
|
cwd?: string;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
type RunState = {
|
|
13
|
+
cmd: string;
|
|
14
|
+
args: string[];
|
|
15
|
+
opts: ExecutionOptions;
|
|
16
|
+
};
|
|
17
|
+
|
|
12
18
|
class DocState {
|
|
13
19
|
baseline = new Date(`${new Date().getFullYear()}-03-14T00:00:00.000`).getTime();
|
|
14
20
|
_s = 37;
|
|
15
21
|
ids: Record<string, string> = {};
|
|
16
22
|
|
|
17
|
-
rng() {
|
|
23
|
+
rng(): number {
|
|
18
24
|
this._s = Math.sin(this._s) * 10000;
|
|
19
25
|
return this._s - Math.floor(this._s);
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
getDate(d: string) {
|
|
28
|
+
getDate(d: string): string {
|
|
23
29
|
this.baseline += this.rng() * 1000;
|
|
24
30
|
return new Date(this.baseline).toISOString();
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
getId(id: string) {
|
|
33
|
+
getId(id: string): string {
|
|
28
34
|
if (!this.ids[id]) {
|
|
29
35
|
this.ids[id] = ' '.repeat(id.length).split('').map(x => Math.trunc(this.rng() * 16).toString(16)).join('');
|
|
30
36
|
}
|
|
@@ -38,7 +44,7 @@ class DocState {
|
|
|
38
44
|
export class DocRunUtil {
|
|
39
45
|
static #docState = new DocState();
|
|
40
46
|
|
|
41
|
-
static runState(cmd: string, args: string[], config: RunConfig = {}) {
|
|
47
|
+
static runState(cmd: string, args: string[], config: RunConfig = {}): RunState {
|
|
42
48
|
args = [...args];
|
|
43
49
|
if (cmd.endsWith('.ts')) {
|
|
44
50
|
const mod = config.module ?? 'base';
|
|
@@ -64,7 +70,7 @@ export class DocRunUtil {
|
|
|
64
70
|
/**
|
|
65
71
|
* Clean run output
|
|
66
72
|
*/
|
|
67
|
-
static cleanRunOutput(text: string, cfg: RunConfig) {
|
|
73
|
+
static cleanRunOutput(text: string, cfg: RunConfig): string {
|
|
68
74
|
text = text.trim()
|
|
69
75
|
// eslint-disable-next-line no-control-regex
|
|
70
76
|
.replace(/\x1b\[[?]?[0-9]{1,2}[a-z]/gi, '')
|
|
@@ -83,7 +89,7 @@ export class DocRunUtil {
|
|
|
83
89
|
/**
|
|
84
90
|
* Run process in the background
|
|
85
91
|
*/
|
|
86
|
-
static runBackground(cmd: string, args: string[], config: RunConfig = {}) {
|
|
92
|
+
static runBackground(cmd: string, args: string[], config: RunConfig = {}): ExecutionState {
|
|
87
93
|
const state = this.runState(cmd, args, config);
|
|
88
94
|
return ExecUtil.spawn(state.cmd, state.args, {
|
|
89
95
|
...state.opts,
|
|
@@ -94,7 +100,7 @@ export class DocRunUtil {
|
|
|
94
100
|
/**
|
|
95
101
|
* Run command synchronously and return output
|
|
96
102
|
*/
|
|
97
|
-
static run(cmd: string, args: string[], config: RunConfig = {}) {
|
|
103
|
+
static run(cmd: string, args: string[], config: RunConfig = {}): string {
|
|
98
104
|
let final: string;
|
|
99
105
|
try {
|
|
100
106
|
const state = this.runState(cmd, args, config);
|
|
@@ -110,8 +116,12 @@ export class DocRunUtil {
|
|
|
110
116
|
}
|
|
111
117
|
final = res.stdout.toString() || res.stderr.toString();
|
|
112
118
|
} catch (err) {
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
if (err instanceof Error) {
|
|
120
|
+
console.log('Found!', cmd, args, '\n', err);
|
|
121
|
+
final = err.message;
|
|
122
|
+
} else {
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
115
125
|
}
|
|
116
126
|
|
|
117
127
|
return this.cleanRunOutput(final, config);
|