@travetto/doc 6.0.0-rc.2 → 6.0.0-rc.4
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/__index__.ts +5 -4
- package/package.json +4 -4
- package/src/jsx.ts +5 -5
- package/src/mapping/lib-mapping.ts +15 -9
- package/src/mapping/mod-mapping.ts +40 -56
- package/src/render/context.ts +4 -4
- package/src/render/html.ts +9 -7
- package/src/render/markdown.ts +17 -14
- package/src/render/renderer.ts +42 -26
- package/src/types.ts +3 -2
- package/src/util/file.ts +25 -15
- package/src/util/resolve.ts +20 -11
- package/src/util/run.ts +5 -13
- package/src/util/types.ts +10 -0
- package/support/cli.doc.ts +1 -1
package/__index__.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { JSXElement as DocJSXElement, isJSXElement as isDocJSXElement } from './jsx-runtime';
|
|
2
|
-
export { c, d, JSXElementByFn as DocJSXElementByFn } from './src/jsx';
|
|
3
|
-
export { MOD_MAPPING as mod } from './src/mapping/mod-mapping';
|
|
4
|
-
export { DocFileUtil } from './src/util/file';
|
|
1
|
+
export { JSXElement as DocJSXElement, isJSXElement as isDocJSXElement } from './jsx-runtime.ts';
|
|
2
|
+
export { c, d, JSXElementByFn as DocJSXElementByFn } from './src/jsx.ts';
|
|
3
|
+
export { MOD_MAPPING as mod } from './src/mapping/mod-mapping.ts';
|
|
4
|
+
export { DocFileUtil } from './src/util/file.ts';
|
|
5
|
+
export { DocRunUtil, COMMON_DATE } from './src/util/run.ts';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/doc",
|
|
3
|
-
"version": "6.0.0-rc.
|
|
3
|
+
"version": "6.0.0-rc.4",
|
|
4
4
|
"description": "Documentation support for the Travetto framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"directory": "module/doc"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@travetto/runtime": "^6.0.0-rc.
|
|
27
|
+
"@travetto/runtime": "^6.0.0-rc.2",
|
|
28
28
|
"@types/prismjs": "^1.26.5",
|
|
29
|
-
"prismjs": "^1.
|
|
29
|
+
"prismjs": "^1.30.0"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@travetto/cli": "^6.0.0-rc.
|
|
32
|
+
"@travetto/cli": "^6.0.0-rc.3"
|
|
33
33
|
},
|
|
34
34
|
"peerDependenciesMeta": {
|
|
35
35
|
"@travetto/cli": {
|
package/src/jsx.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { createElement, JSXElement, JSXComponentFunction as CompFn } from '@travetto/doc/jsx-runtime';
|
|
2
2
|
import { castTo, TypedObject } from '@travetto/runtime';
|
|
3
3
|
|
|
4
|
-
import { LIB_MAPPING } from './mapping/lib-mapping';
|
|
5
|
-
import { MOD_MAPPING } from './mapping/mod-mapping';
|
|
6
|
-
import { RunConfig } from './util/
|
|
4
|
+
import { LIB_MAPPING } from './mapping/lib-mapping.ts';
|
|
5
|
+
import { MOD_MAPPING } from './mapping/mod-mapping.ts';
|
|
6
|
+
import { CodeProps, RunConfig } from './util/types.ts';
|
|
7
7
|
|
|
8
|
-
type CodeProps = { title: string, src: string | Function, language?: string, outline?: boolean, startRe?: RegExp, endRe?: RegExp };
|
|
9
8
|
type InstallProps = { title: string, pkg: string };
|
|
10
9
|
type ExecProps = { title: string, cmd: string, args?: string[], config?: RunConfig & { formatCommand?(cmd: string, args: string[]): string } };
|
|
11
10
|
type StdHeaderProps = { mod?: string, install?: boolean };
|
|
@@ -82,8 +81,9 @@ function CodeLinker(titleOrNode: string | JSXElement, src?: string, startRe?: Re
|
|
|
82
81
|
props = { title: titleOrNode, src: src!, startRe: startRe! };
|
|
83
82
|
} else if (titleOrNode.type === Code) {
|
|
84
83
|
const node: JSXElementByFn<'Code'> = castTo(titleOrNode);
|
|
84
|
+
const srcName = typeof node.props.src === 'string' ? node.props.src : node.props.src.name;
|
|
85
85
|
props = {
|
|
86
|
-
title: node.props.title,
|
|
86
|
+
title: node.props.title ?? srcName,
|
|
87
87
|
src: node.props.src,
|
|
88
88
|
startRe: node.props.startRe!
|
|
89
89
|
};
|
|
@@ -39,17 +39,22 @@ export const LIB_MAPPING = {
|
|
|
39
39
|
UUID: { title: 'UUID', href: 'https://en.wikipedia.org/wiki/Universally_unique_identifier' },
|
|
40
40
|
|
|
41
41
|
// Node
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
NodeProcess: { title: 'process', href: 'https://nodejs.org/api/process.html' },
|
|
43
|
+
NodeChildProcess: { title: 'child_process', href: 'https://nodejs.org/api/child_process.html' },
|
|
44
|
+
NodeAsyncHooks: { title: 'async_hooks', href: 'https://nodejs.org/api/async_hooks.html' },
|
|
45
|
+
NodeHttp: { title: 'http', href: 'https://nodejs.org/api/http.html' },
|
|
46
|
+
NodePath: { title: 'path', href: 'https://nodejs.org/api/path.html' },
|
|
47
|
+
NodeHttps: { title: 'https', href: 'https://nodejs.org/api/https.html' },
|
|
48
|
+
NodeConsole: { title: 'console', href: 'https://nodejs.org/api/console.html' },
|
|
49
|
+
NodeAssert: { title: 'assert', href: 'https://nodejs.org/api/assert.html' },
|
|
50
|
+
NodeEventEmitter: { title: 'EventEmitter', href: 'https://nodejs.org/api/events.html#class-eventemitter' },
|
|
51
|
+
NodeBuffer: { title: 'Buffer', href: 'https://nodejs.org/api/buffer.html' },
|
|
52
|
+
NodeZlib: { title: 'Buffer', href: 'https://nodejs.org/api/zlib.html' },
|
|
53
|
+
NodeFile: { title: 'Buffer', href: 'https://nodejs.org/api/buffer.html#class-file' },
|
|
50
54
|
|
|
51
55
|
// Cloud
|
|
52
56
|
AwsCloudwatch: { title: 'AWS Cloudwatch', href: 'https://aws.amazon.com/cloudwatch/' },
|
|
57
|
+
AwsLambda: { title: 'AWS Lambda', href: 'https://aws.amazon.com/lambda/' },
|
|
53
58
|
|
|
54
59
|
// Utils
|
|
55
60
|
Lodash: { title: 'lodash', href: 'https://lodash.com' },
|
|
@@ -97,7 +102,8 @@ export const LIB_MAPPING = {
|
|
|
97
102
|
Firestore: { title: 'Firestore', href: 'https://firebase.google.com/docs/firestore' },
|
|
98
103
|
SQLite: { title: 'SQLite', href: 'https://www.sqlite.org/' },
|
|
99
104
|
|
|
100
|
-
//
|
|
105
|
+
// Web
|
|
106
|
+
Connect: { title: 'connect', href: 'https://github.com/senchalabs/connect' },
|
|
101
107
|
Express: { title: 'express', href: 'https://expressjs.com' },
|
|
102
108
|
Passport: { title: 'passport', href: 'http://passportjs.org' },
|
|
103
109
|
Busboy: { title: '@fastify/busboy', href: 'https://github.com/fastify/busboy' },
|
|
@@ -7,22 +7,22 @@ export const MOD_MAPPING = {
|
|
|
7
7
|
name: '@travetto/auth-model', folder: '@travetto/auth-model', displayName: 'Authentication Model',
|
|
8
8
|
description: 'Authentication model support for the Travetto framework'
|
|
9
9
|
},
|
|
10
|
-
AuthRest: {
|
|
11
|
-
name: '@travetto/auth-rest', folder: '@travetto/auth-rest', displayName: 'Rest Auth',
|
|
12
|
-
description: 'Rest authentication integration support for the Travetto framework'
|
|
13
|
-
},
|
|
14
|
-
AuthRestPassport: {
|
|
15
|
-
name: '@travetto/auth-rest-passport', folder: '@travetto/auth-rest-passport', displayName: 'Rest Auth Passport',
|
|
16
|
-
description: 'Rest authentication integration support for the Travetto framework'
|
|
17
|
-
},
|
|
18
|
-
AuthRestSession: {
|
|
19
|
-
name: '@travetto/auth-rest-session', folder: '@travetto/auth-rest-session', displayName: 'Rest Auth Session',
|
|
20
|
-
description: 'Rest authentication session integration support for the Travetto framework'
|
|
21
|
-
},
|
|
22
10
|
AuthSession: {
|
|
23
11
|
name: '@travetto/auth-session', folder: '@travetto/auth-session', displayName: 'Auth Session',
|
|
24
12
|
description: 'Session provider for the travetto auth module.'
|
|
25
13
|
},
|
|
14
|
+
AuthWeb: {
|
|
15
|
+
name: '@travetto/auth-web', folder: '@travetto/auth-web', displayName: 'Web Auth',
|
|
16
|
+
description: 'Web authentication integration support for the Travetto framework'
|
|
17
|
+
},
|
|
18
|
+
AuthWebPassport: {
|
|
19
|
+
name: '@travetto/auth-web-passport', folder: '@travetto/auth-web-passport', displayName: 'Web Auth Passport',
|
|
20
|
+
description: 'Web authentication integration support for the Travetto framework'
|
|
21
|
+
},
|
|
22
|
+
AuthWebSession: {
|
|
23
|
+
name: '@travetto/auth-web-session', folder: '@travetto/auth-web-session', displayName: 'Web Auth Session',
|
|
24
|
+
description: 'Web authentication session integration support for the Travetto framework'
|
|
25
|
+
},
|
|
26
26
|
Cache: {
|
|
27
27
|
name: '@travetto/cache', folder: '@travetto/cache', displayName: 'Caching',
|
|
28
28
|
description: 'Caching functionality with decorators for declarative use.'
|
|
@@ -159,50 +159,6 @@ export const MOD_MAPPING = {
|
|
|
159
159
|
name: '@travetto/repo', folder: '@travetto/repo', displayName: 'Repo',
|
|
160
160
|
description: 'Monorepo utilities'
|
|
161
161
|
},
|
|
162
|
-
Rest: {
|
|
163
|
-
name: '@travetto/rest', folder: '@travetto/rest', displayName: 'RESTful API',
|
|
164
|
-
description: 'Declarative api for RESTful APIs with support for the dependency injection module.'
|
|
165
|
-
},
|
|
166
|
-
RestAwsLambda: {
|
|
167
|
-
name: '@travetto/rest-aws-lambda', folder: '@travetto/rest-aws-lambda', displayName: 'RESTful AWS Lambda',
|
|
168
|
-
description: 'RESTful APIs entry point support for AWS Lambdas.'
|
|
169
|
-
},
|
|
170
|
-
RestClient: {
|
|
171
|
-
name: '@travetto/rest-client', folder: '@travetto/rest-client', displayName: 'RESTful Client Support',
|
|
172
|
-
description: 'RESTful support for generating clients for controller endpoints'
|
|
173
|
-
},
|
|
174
|
-
RestExpress: {
|
|
175
|
-
name: '@travetto/rest-express', folder: '@travetto/rest-express', displayName: 'Express REST Source',
|
|
176
|
-
description: 'Express provider for the travetto rest module.'
|
|
177
|
-
},
|
|
178
|
-
RestExpressLambda: {
|
|
179
|
-
name: '@travetto/rest-express-lambda', folder: '@travetto/rest-express-lambda', displayName: 'Express REST AWS Lambda Source',
|
|
180
|
-
description: 'Express AWS Lambda provider for the travetto rest module.'
|
|
181
|
-
},
|
|
182
|
-
RestFastify: {
|
|
183
|
-
name: '@travetto/rest-fastify', folder: '@travetto/rest-fastify', displayName: 'Fastify REST Source',
|
|
184
|
-
description: 'Fastify provider for the travetto rest module.'
|
|
185
|
-
},
|
|
186
|
-
RestFastifyLambda: {
|
|
187
|
-
name: '@travetto/rest-fastify-lambda', folder: '@travetto/rest-fastify-lambda', displayName: 'Fastify REST AWS Lambda Source',
|
|
188
|
-
description: 'Fastify AWS Lambda provider for the travetto rest module.'
|
|
189
|
-
},
|
|
190
|
-
RestKoa: {
|
|
191
|
-
name: '@travetto/rest-koa', folder: '@travetto/rest-koa', displayName: 'Koa REST Source',
|
|
192
|
-
description: 'Koa provider for the travetto rest module.'
|
|
193
|
-
},
|
|
194
|
-
RestKoaLambda: {
|
|
195
|
-
name: '@travetto/rest-koa-lambda', folder: '@travetto/rest-koa-lambda', displayName: 'Koa REST AWS Lambda Source',
|
|
196
|
-
description: 'Koa provider for the travetto rest module.'
|
|
197
|
-
},
|
|
198
|
-
RestRpc: {
|
|
199
|
-
name: '@travetto/rest-rpc', folder: '@travetto/rest-rpc', displayName: 'RESTful RPC Support',
|
|
200
|
-
description: 'RESTful RPC support for a module'
|
|
201
|
-
},
|
|
202
|
-
RestUpload: {
|
|
203
|
-
name: '@travetto/rest-upload', folder: '@travetto/rest-upload', displayName: 'Rest Upload Support',
|
|
204
|
-
description: 'Provides integration between the travetto asset and rest module.'
|
|
205
|
-
},
|
|
206
162
|
Runtime: {
|
|
207
163
|
name: '@travetto/runtime', folder: '@travetto/runtime', displayName: 'Runtime',
|
|
208
164
|
description: 'Runtime for travetto applications.'
|
|
@@ -235,6 +191,34 @@ export const MOD_MAPPING = {
|
|
|
235
191
|
name: '@travetto/transformer', folder: '@travetto/transformer', displayName: 'Transformation',
|
|
236
192
|
description: 'Functionality for AST transformations, with transformer registration, and general utils'
|
|
237
193
|
},
|
|
194
|
+
Web: {
|
|
195
|
+
name: '@travetto/web', folder: '@travetto/web', displayName: 'Web API',
|
|
196
|
+
description: 'Declarative api for Web Applications with support for the dependency injection.'
|
|
197
|
+
},
|
|
198
|
+
WebAwsLambda: {
|
|
199
|
+
name: '@travetto/web-aws-lambda', folder: '@travetto/web-aws-lambda', displayName: 'Web AWS Lambda',
|
|
200
|
+
description: 'Web APIs entry point support for AWS Lambdas.'
|
|
201
|
+
},
|
|
202
|
+
WebConnect: {
|
|
203
|
+
name: '@travetto/web-connect', folder: '@travetto/web-connect', displayName: 'Web Connect Support',
|
|
204
|
+
description: 'Web integration for Connect-Like Resources'
|
|
205
|
+
},
|
|
206
|
+
WebHttp: {
|
|
207
|
+
name: '@travetto/web-http', folder: '@travetto/web-http', displayName: 'Web HTTP Server Support',
|
|
208
|
+
description: 'Web HTTP Server Support'
|
|
209
|
+
},
|
|
210
|
+
WebNode: {
|
|
211
|
+
name: '@travetto/web-node', folder: '@travetto/web-node', displayName: 'Node Web Server',
|
|
212
|
+
description: 'Node provider for the travetto web module.'
|
|
213
|
+
},
|
|
214
|
+
WebRpc: {
|
|
215
|
+
name: '@travetto/web-rpc', folder: '@travetto/web-rpc', displayName: 'Web RPC Support',
|
|
216
|
+
description: 'RPC support for a Web Application'
|
|
217
|
+
},
|
|
218
|
+
WebUpload: {
|
|
219
|
+
name: '@travetto/web-upload', folder: '@travetto/web-upload', displayName: 'Web Upload Support',
|
|
220
|
+
description: 'Provides integration between the travetto asset and web module.'
|
|
221
|
+
},
|
|
238
222
|
Worker: {
|
|
239
223
|
name: '@travetto/worker', folder: '@travetto/worker', displayName: 'Worker',
|
|
240
224
|
description: 'Process management utilities, with a focus on inter-process communication'
|
package/src/render/context.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { createElement, JSXRuntimeTag } from '@travetto/doc/jsx-runtime';
|
|
|
5
5
|
import { PackageUtil } from '@travetto/manifest';
|
|
6
6
|
import { castTo, RuntimeIndex } from '@travetto/runtime';
|
|
7
7
|
|
|
8
|
-
import { JSXElementByFn, c } from '../jsx';
|
|
9
|
-
import { DocResolveUtil, ResolvedCode, ResolvedRef, ResolvedSnippetLink } from '../util/resolve';
|
|
10
|
-
import { DocRunUtil } from '../util/run';
|
|
8
|
+
import { JSXElementByFn, c } from '../jsx.ts';
|
|
9
|
+
import { DocResolveUtil, ResolvedCode, ResolvedRef, ResolvedSnippetLink } from '../util/resolve.ts';
|
|
10
|
+
import { DocRunUtil } from '../util/run.ts';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Render Context
|
|
@@ -66,7 +66,7 @@ export class RenderContext {
|
|
|
66
66
|
link(text: string, line?: number | { [key: string]: unknown, line?: number }): string {
|
|
67
67
|
const num = typeof line === 'number' ? line : line?.line;
|
|
68
68
|
return `${text.replace(this.repoRoot, this.baseUrl)
|
|
69
|
-
.replace(/.*@travetto\//, `${this.travettoBaseUrl}/module/`)}${num ? `#L${num}` : ''}`;
|
|
69
|
+
.replace(/.*@travetto\//, `${this.travettoBaseUrl}/module/`)}${num && num > 1 ? `#L${num}` : ''}`;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
package/src/render/html.ts
CHANGED
|
@@ -4,13 +4,13 @@ import { JSXElement } from '@travetto/doc/jsx-runtime';
|
|
|
4
4
|
import { Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
5
5
|
import { PackageUtil } from '@travetto/manifest';
|
|
6
6
|
|
|
7
|
-
import { highlight } from './code-highlight';
|
|
8
|
-
import { RenderProvider, RenderState } from '../types';
|
|
9
|
-
import { c, getComponentName } from '../jsx';
|
|
10
|
-
import { MOD_MAPPING } from '../mapping/mod-mapping';
|
|
11
|
-
import { LIB_MAPPING } from '../mapping/lib-mapping';
|
|
12
|
-
import { RenderContext } from './context';
|
|
13
|
-
import { DocResolveUtil } from '../util/resolve';
|
|
7
|
+
import { highlight } from './code-highlight.ts';
|
|
8
|
+
import { RenderProvider, RenderState } from '../types.ts';
|
|
9
|
+
import { c, getComponentName } from '../jsx.ts';
|
|
10
|
+
import { MOD_MAPPING } from '../mapping/mod-mapping.ts';
|
|
11
|
+
import { LIB_MAPPING } from '../mapping/lib-mapping.ts';
|
|
12
|
+
import { RenderContext } from './context.ts';
|
|
13
|
+
import { DocResolveUtil } from '../util/resolve.ts';
|
|
14
14
|
|
|
15
15
|
const ESCAPE_ENTITIES: Record<string, string> = { '<': '<', '>': '>', '&': '&', '{': "{{'{'}}", '}': "{{'}'}}" };
|
|
16
16
|
const ENTITY_RE = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join('')}]`, 'gm');
|
|
@@ -71,6 +71,8 @@ yarn add ${el.props.pkg}
|
|
|
71
71
|
Terminal: state => Html.Code(state),
|
|
72
72
|
Config: state => Html.Code(state),
|
|
73
73
|
Code: async ({ context, el, props }) => {
|
|
74
|
+
DocResolveUtil.applyCodePropDefaults(el.props);
|
|
75
|
+
|
|
74
76
|
const cls = getComponentName(el.type).replace(/^[A-Z]/g, v => v.toLowerCase());
|
|
75
77
|
const content = await context.resolveCode(el);
|
|
76
78
|
let link: string = '';
|
package/src/render/markdown.ts
CHANGED
|
@@ -3,11 +3,12 @@ import fs from 'node:fs/promises';
|
|
|
3
3
|
import { Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
4
4
|
import { PackageUtil } from '@travetto/manifest';
|
|
5
5
|
|
|
6
|
-
import { RenderProvider } from '../types';
|
|
7
|
-
import { c, getComponentName } from '../jsx';
|
|
8
|
-
import { MOD_MAPPING } from '../mapping/mod-mapping';
|
|
9
|
-
import { LIB_MAPPING } from '../mapping/lib-mapping';
|
|
10
|
-
import { RenderContext } from './context';
|
|
6
|
+
import { RenderProvider } from '../types.ts';
|
|
7
|
+
import { c, getComponentName } from '../jsx.ts';
|
|
8
|
+
import { MOD_MAPPING } from '../mapping/mod-mapping.ts';
|
|
9
|
+
import { LIB_MAPPING } from '../mapping/lib-mapping.ts';
|
|
10
|
+
import { RenderContext } from './context.ts';
|
|
11
|
+
import { DocResolveUtil } from '../util/resolve.ts';
|
|
11
12
|
|
|
12
13
|
export const Markdown: RenderProvider<RenderContext> = {
|
|
13
14
|
ext: 'md',
|
|
@@ -22,20 +23,20 @@ export const Markdown: RenderProvider<RenderContext> = {
|
|
|
22
23
|
hr: async () => '\n------------------\n',
|
|
23
24
|
br: async () => '\n\n',
|
|
24
25
|
em: async ({ recurse }) => `*${await recurse()}*`,
|
|
25
|
-
ul: async ({ recurse }) => `\n${await recurse()}`,
|
|
26
|
-
ol: async ({ recurse }) => `\n${await recurse()}`,
|
|
26
|
+
ul: async ({ recurse }) => `\n${await recurse()}\n`,
|
|
27
|
+
ol: async ({ recurse }) => `\n${await recurse()}\n`,
|
|
27
28
|
li: async ({ recurse, stack }) => {
|
|
28
|
-
const parent = stack.
|
|
29
|
+
const parent = stack.toReversed().find(x => x.type === 'ol' || x.type === 'ul');
|
|
29
30
|
const depth = stack.filter(x => x.type === 'ol' || x.type === 'ul').length;
|
|
30
31
|
return `${' '.repeat(depth)}${(parent && parent.type === 'ol') ? '1.' : '* '} ${await recurse()}\n`;
|
|
31
32
|
},
|
|
32
|
-
table: async ({ recurse }) => recurse()
|
|
33
|
-
tbody: async ({ recurse }) => recurse()
|
|
33
|
+
table: async ({ recurse }) => `${await recurse()}`,
|
|
34
|
+
tbody: async ({ recurse }) => `${await recurse()}`,
|
|
34
35
|
td: async ({ recurse }) => `|${await recurse()}`,
|
|
35
36
|
tr: async ({ recurse }) => `${await recurse()}|\n`,
|
|
36
37
|
thead: async ({ recurse }) => {
|
|
37
38
|
const row = await recurse();
|
|
38
|
-
return `${row}${row
|
|
39
|
+
return `${row}${row?.replace(/[^|\n]/g, '-')}`;
|
|
39
40
|
},
|
|
40
41
|
h2: async ({ recurse }) => `\n## ${await recurse()}\n\n`,
|
|
41
42
|
h3: async ({ recurse }) => `\n### ${await recurse()}\n\n`,
|
|
@@ -61,10 +62,12 @@ npm install ${el.props.pkg}
|
|
|
61
62
|
yarn add ${el.props.pkg}
|
|
62
63
|
\`\`\`
|
|
63
64
|
`,
|
|
64
|
-
Code: async ({ context, el }) => {
|
|
65
|
+
Code: async ({ context, el, props }) => {
|
|
66
|
+
DocResolveUtil.applyCodePropDefaults(el.props);
|
|
67
|
+
|
|
65
68
|
const name = getComponentName(el.type);
|
|
66
69
|
const content = await context.resolveCode(el);
|
|
67
|
-
let lang =
|
|
70
|
+
let lang = props.language ?? content.language;
|
|
68
71
|
if (!lang) {
|
|
69
72
|
if (el.type === c.Terminal) {
|
|
70
73
|
lang = 'bash';
|
|
@@ -72,7 +75,7 @@ yarn add ${el.props.pkg}
|
|
|
72
75
|
lang = 'typescript';
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
|
-
return `\n\n**${name}: ${
|
|
78
|
+
return `\n\n**${name}: ${props.title}**
|
|
76
79
|
\`\`\`${lang}
|
|
77
80
|
${context.cleanText(content.text)}
|
|
78
81
|
\`\`\`\n\n`;
|
package/src/render/renderer.ts
CHANGED
|
@@ -2,15 +2,15 @@ import path from 'node:path';
|
|
|
2
2
|
|
|
3
3
|
import { type ManifestContext, PackageUtil } from '@travetto/manifest';
|
|
4
4
|
import { isJSXElement, JSXElement, JSXFragmentType } from '@travetto/doc/jsx-runtime';
|
|
5
|
-
import { castTo, Runtime } from '@travetto/runtime';
|
|
5
|
+
import { castTo, Class, Runtime } from '@travetto/runtime';
|
|
6
6
|
|
|
7
|
-
import { EMPTY_ELEMENT, getComponentName, JSXElementByFn, c } from '../jsx';
|
|
8
|
-
import { DocumentShape, RenderProvider, RenderState } from '../types';
|
|
9
|
-
import { DocFileUtil } from '../util/file';
|
|
7
|
+
import { EMPTY_ELEMENT, getComponentName, JSXElementByFn, c } from '../jsx.ts';
|
|
8
|
+
import { DocumentShape, RenderProvider, RenderState } from '../types.ts';
|
|
9
|
+
import { DocFileUtil } from '../util/file.ts';
|
|
10
10
|
|
|
11
|
-
import { RenderContext } from './context';
|
|
12
|
-
import { Html } from './html';
|
|
13
|
-
import { Markdown } from './markdown';
|
|
11
|
+
import { RenderContext } from './context.ts';
|
|
12
|
+
import { Html } from './html.ts';
|
|
13
|
+
import { Markdown } from './markdown.ts';
|
|
14
14
|
|
|
15
15
|
const providers = { [Html.ext]: Html, [Markdown.ext]: Markdown };
|
|
16
16
|
|
|
@@ -37,18 +37,44 @@ export class DocRenderer {
|
|
|
37
37
|
this.#support = support;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
async #buildLink(
|
|
41
|
+
renderer: RenderProvider<RenderContext>,
|
|
42
|
+
cls: Class,
|
|
43
|
+
title?: string
|
|
44
|
+
) {
|
|
45
|
+
const source = DocFileUtil.readSource(cls);
|
|
46
|
+
if (source) {
|
|
47
|
+
title = (await DocFileUtil.isDecorator(cls.name, source.file)) ? `@${title ?? cls.name}` : (title ?? cls.name);
|
|
48
|
+
const el = this.#support.createElement('CodeLink', {
|
|
49
|
+
src: source.file,
|
|
50
|
+
startRe: new RegExp(`(class|function|interface)\\s+(${cls.name.replaceAll('$', '\\$')})`),
|
|
51
|
+
title
|
|
52
|
+
});
|
|
53
|
+
// @ts-expect-error
|
|
54
|
+
const state: RenderState<JSXElementByFn<'CodeLink'>, RenderContext> = {
|
|
55
|
+
el, props: el.props, recurse: async () => '', context: this.#support, stack: []
|
|
56
|
+
};
|
|
57
|
+
// @ts-expect-error
|
|
58
|
+
state.createState = (key, props) => this.createState(state, key, props);
|
|
59
|
+
return renderer.CodeLink(state);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
40
63
|
async #render(
|
|
41
64
|
renderer: RenderProvider<RenderContext>,
|
|
42
65
|
node: JSXElement[] | JSXElement | string | bigint | object | number | boolean | null | undefined,
|
|
43
66
|
stack: JSXElement[] = []
|
|
44
|
-
): Promise<string> {
|
|
67
|
+
): Promise<string | undefined> {
|
|
45
68
|
|
|
46
69
|
if (node === null || node === undefined) {
|
|
47
70
|
return '';
|
|
48
71
|
} else if (Array.isArray(node)) {
|
|
49
72
|
const out: string[] = [];
|
|
50
73
|
for (const el of node) {
|
|
51
|
-
|
|
74
|
+
const sub = await this.#render(renderer, el, stack);
|
|
75
|
+
if (sub) {
|
|
76
|
+
out.push(sub);
|
|
77
|
+
}
|
|
52
78
|
}
|
|
53
79
|
return out.join('');
|
|
54
80
|
} else if (isJSXElement(node)) {
|
|
@@ -87,25 +113,15 @@ export class DocRenderer {
|
|
|
87
113
|
case 'number':
|
|
88
114
|
case 'bigint':
|
|
89
115
|
case 'boolean': return `${node}`;
|
|
90
|
-
case '
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const title = (await DocFileUtil.isDecorator(node.name, source.file)) ? `@${node.name}` : node.name;
|
|
94
|
-
const el = this.#support.createElement('CodeLink', {
|
|
95
|
-
src: source.file,
|
|
96
|
-
startRe: new RegExp(`(class|function)\\s+(${node.name})`),
|
|
97
|
-
title
|
|
98
|
-
});
|
|
99
|
-
// @ts-expect-error
|
|
100
|
-
const state: RenderState<JSXElementByFn<'CodeLink'>, RenderContext> = {
|
|
101
|
-
el, props: el.props, recurse: async () => '', context: this.#support, stack: []
|
|
102
|
-
};
|
|
103
|
-
// @ts-expect-error
|
|
104
|
-
state.createState = (key, props) => this.createState(state, key, props);
|
|
105
|
-
return await renderer.CodeLink(state);
|
|
116
|
+
case 'object': {
|
|
117
|
+
if (node) {
|
|
118
|
+
return await this.#buildLink(renderer, castTo(node.constructor), node.constructor.name.replace(/^[$]/, ''));
|
|
106
119
|
}
|
|
107
120
|
break;
|
|
108
121
|
}
|
|
122
|
+
case 'function': {
|
|
123
|
+
return await this.#buildLink(renderer, castTo(node));
|
|
124
|
+
}
|
|
109
125
|
}
|
|
110
126
|
throw new Error(`Unknown object type: ${typeof node}`);
|
|
111
127
|
}
|
|
@@ -135,7 +151,7 @@ export class DocRenderer {
|
|
|
135
151
|
}
|
|
136
152
|
|
|
137
153
|
const text = await this.#render(providers[fmt], this.#rootNode);
|
|
138
|
-
let cleaned = `${text
|
|
154
|
+
let cleaned = `${text?.replace(/\n{3,100}/msg, '\n\n').trim()}\n`;
|
|
139
155
|
if (this.#root.wrap?.[fmt]) {
|
|
140
156
|
cleaned = this.#root.wrap[fmt](cleaned);
|
|
141
157
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { JSXElement, ValidHtmlTags } from '@travetto/doc/jsx-runtime';
|
|
2
|
-
import { JSXElementByFn, c } from './jsx';
|
|
2
|
+
import { JSXElementByFn, c } from './jsx.ts';
|
|
3
3
|
|
|
4
4
|
export type Wrapper = Record<string, (cnt: string) => string>;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Document file shape
|
|
8
|
+
* @concrete
|
|
8
9
|
*/
|
|
9
10
|
export interface DocumentShape {
|
|
10
11
|
text: JSXElement | JSXElement[] | (() => Promise<JSXElement | JSXElement[]>);
|
|
@@ -14,7 +15,7 @@ export interface DocumentShape {
|
|
|
14
15
|
export type RenderState<T extends JSXElement, C> = {
|
|
15
16
|
el: T;
|
|
16
17
|
props: T['props'];
|
|
17
|
-
recurse: () => Promise<string>;
|
|
18
|
+
recurse: () => Promise<string | undefined>;
|
|
18
19
|
stack: JSXElement[];
|
|
19
20
|
// @ts-expect-error
|
|
20
21
|
createState: <K extends keyof typeof c>(key: K, props: JSXElementByFn<K>['props']) => RenderState<JSXElementByFn<K>, C>;
|
package/src/util/file.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync, existsSync } from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { AppError, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
5
|
+
import { ManifestModuleFileType, ManifestModuleUtil } from '@travetto/manifest';
|
|
5
6
|
|
|
6
7
|
const ESLINT_PATTERN = /\s{0,10}\/\/ eslint.{0,300}$/g;
|
|
7
8
|
const ENV_KEY = /Env.([^.]{1,100})[.]key/g;
|
|
@@ -12,10 +13,18 @@ const ENV_KEY = /Env.([^.]{1,100})[.]key/g;
|
|
|
12
13
|
export class DocFileUtil {
|
|
13
14
|
|
|
14
15
|
static #decCache: Record<string, boolean> = {};
|
|
16
|
+
static #modFileTypeToLang: Record<ManifestModuleFileType, string | undefined> = {
|
|
17
|
+
ts: 'typescript',
|
|
18
|
+
js: 'javascript',
|
|
19
|
+
md: 'markdown',
|
|
20
|
+
json: 'json',
|
|
21
|
+
typings: 'typescript',
|
|
22
|
+
'package-json': 'json',
|
|
23
|
+
fixture: undefined,
|
|
24
|
+
unknown: undefined
|
|
25
|
+
};
|
|
15
26
|
static #extToLang: Record<string, string> = {
|
|
16
|
-
'.
|
|
17
|
-
'.tsx': 'typescript',
|
|
18
|
-
'.js': 'javascript',
|
|
27
|
+
'.yaml': 'yaml',
|
|
19
28
|
'.yml': 'yaml',
|
|
20
29
|
'.sh': 'bash',
|
|
21
30
|
};
|
|
@@ -64,7 +73,8 @@ export class DocFileUtil {
|
|
|
64
73
|
|
|
65
74
|
if (file !== undefined) {
|
|
66
75
|
const ext = path.extname(file);
|
|
67
|
-
const
|
|
76
|
+
const type = ManifestModuleUtil.getFileType(file);
|
|
77
|
+
const language = this.#modFileTypeToLang[type] ?? this.#extToLang[ext] ?? ext.replace('.', '');
|
|
68
78
|
return { content, file, language };
|
|
69
79
|
} else {
|
|
70
80
|
return { content, file: '', language: '' };
|
|
@@ -72,13 +82,13 @@ export class DocFileUtil {
|
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
static async readCodeSnippet(src: string | Function, startPattern: RegExp): Promise<{ file: string, startIdx: number, lines: string[], language: string }> {
|
|
75
|
-
const
|
|
76
|
-
const lines =
|
|
85
|
+
const result = this.readSource(src);
|
|
86
|
+
const lines = result.content.split(/\n/);
|
|
77
87
|
const startIdx = lines.findIndex(l => startPattern.test(l));
|
|
78
88
|
if (startIdx < 0) {
|
|
79
89
|
throw new Error(`Pattern ${startPattern.source} not found in ${src}`);
|
|
80
90
|
}
|
|
81
|
-
return { file:
|
|
91
|
+
return { file: result.file, startIdx, lines, language: result.language };
|
|
82
92
|
}
|
|
83
93
|
|
|
84
94
|
/**
|
|
@@ -91,21 +101,21 @@ export class DocFileUtil {
|
|
|
91
101
|
return this.#decCache[key];
|
|
92
102
|
}
|
|
93
103
|
|
|
94
|
-
const
|
|
95
|
-
const
|
|
104
|
+
const text = await this.readSource(file);
|
|
105
|
+
const lines = text.content.split(/\n/g);
|
|
96
106
|
|
|
97
|
-
const start =
|
|
98
|
-
let
|
|
107
|
+
const start = lines.findIndex(x => new RegExp(`function ${name}\\b`).test(x));
|
|
108
|
+
let found = false;
|
|
99
109
|
if (start > 0) {
|
|
100
110
|
for (let i = start - 1; i > start - 3; i--) {
|
|
101
|
-
if (
|
|
102
|
-
|
|
111
|
+
if (lines[i].includes('@augments')) {
|
|
112
|
+
found = true;
|
|
103
113
|
break;
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
|
-
this.#decCache[key] =
|
|
108
|
-
return
|
|
117
|
+
this.#decCache[key] = found;
|
|
118
|
+
return found;
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
/**
|
package/src/util/resolve.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DocFileUtil } from './file';
|
|
1
|
+
import { DocFileUtil } from './file.ts';
|
|
2
|
+
import { CodeProps } from './types.ts';
|
|
2
3
|
|
|
3
4
|
export type ResolvedRef = { title: string, file: string, line: number };
|
|
4
5
|
export type ResolvedCode = { text: string, language: string, file?: string };
|
|
@@ -13,12 +14,12 @@ export class DocResolveUtil {
|
|
|
13
14
|
static async resolveRef(title: string, file: string): Promise<ResolvedRef> {
|
|
14
15
|
|
|
15
16
|
let line = 0;
|
|
16
|
-
const
|
|
17
|
-
file =
|
|
17
|
+
const result = await DocFileUtil.readSource(file);
|
|
18
|
+
file = result.file;
|
|
18
19
|
|
|
19
|
-
if (
|
|
20
|
-
line =
|
|
21
|
-
.findIndex(x => new RegExp(`(class|function)[ ]+${title}`).test(x));
|
|
20
|
+
if (result.content) {
|
|
21
|
+
line = result.content.split(/\n/g)
|
|
22
|
+
.findIndex(x => new RegExp(`(class|interface|function)[ ]+${title.replaceAll('$', '\\$')}`).test(x));
|
|
22
23
|
if (line < 0) {
|
|
23
24
|
line = 0;
|
|
24
25
|
} else {
|
|
@@ -32,13 +33,13 @@ export class DocResolveUtil {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
static async resolveCode(content: string | Function, language?: string, outline = false): Promise<ResolvedCode> {
|
|
35
|
-
const
|
|
36
|
-
let text =
|
|
36
|
+
const result = DocFileUtil.readSource(content);
|
|
37
|
+
let text = result.content;
|
|
37
38
|
|
|
38
39
|
let file: string | undefined;
|
|
39
|
-
if (
|
|
40
|
-
language =
|
|
41
|
-
file =
|
|
40
|
+
if (result.file) {
|
|
41
|
+
language = result.language;
|
|
42
|
+
file = result.file;
|
|
42
43
|
if (outline) {
|
|
43
44
|
text = DocFileUtil.buildOutline(text);
|
|
44
45
|
}
|
|
@@ -63,4 +64,12 @@ export class DocResolveUtil {
|
|
|
63
64
|
const { startIdx, file: resolvedFile } = await DocFileUtil.readCodeSnippet(file, startPattern);
|
|
64
65
|
return { file: resolvedFile, line: startIdx + 1 };
|
|
65
66
|
}
|
|
67
|
+
|
|
68
|
+
static applyCodePropDefaults(props: CodeProps) {
|
|
69
|
+
const type = typeof props.src === 'function' ? props.src : undefined;
|
|
70
|
+
props.startRe ??= (type ? new RegExp(`^(export)?\\s*(interface|class)\\s+${type.name.replaceAll('$', '\\$')}\\b`) : undefined);
|
|
71
|
+
props.language ??= (type ? 'typescript' : undefined);
|
|
72
|
+
props.endRe ??= (type ? /^[}]/ : undefined);
|
|
73
|
+
props.title ??= typeof props.src == 'function' ? props.src.name.replace(/^[$]/, '') : undefined;
|
|
74
|
+
}
|
|
66
75
|
}
|
package/src/util/run.ts
CHANGED
|
@@ -4,18 +4,10 @@ import { spawn, ChildProcess } from 'node:child_process';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
6
|
import { Env, ExecUtil, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
7
|
+
import { RunConfig } from './types.ts';
|
|
7
8
|
|
|
8
9
|
export const COMMON_DATE = new Date('2029-03-14T00:00:00.000').getTime();
|
|
9
10
|
|
|
10
|
-
export type RunConfig = {
|
|
11
|
-
filter?: (line: string) => boolean;
|
|
12
|
-
rewrite?: (text: string) => string;
|
|
13
|
-
module?: string;
|
|
14
|
-
env?: Record<string, string>;
|
|
15
|
-
envName?: string;
|
|
16
|
-
cwd?: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
11
|
class DocState {
|
|
20
12
|
baseline = COMMON_DATE;
|
|
21
13
|
_s = 37;
|
|
@@ -105,11 +97,11 @@ export class DocRunUtil {
|
|
|
105
97
|
let final: string;
|
|
106
98
|
try {
|
|
107
99
|
const proc = this.spawn(cmd, args, config);
|
|
108
|
-
const
|
|
109
|
-
if (!
|
|
110
|
-
throw new Error(
|
|
100
|
+
const result = await ExecUtil.getResult(proc, { catch: true });
|
|
101
|
+
if (!result.valid) {
|
|
102
|
+
throw new Error(result.stderr);
|
|
111
103
|
}
|
|
112
|
-
final = util.stripVTControlCharacters(
|
|
104
|
+
final = util.stripVTControlCharacters(result.stdout).trim() || util.stripVTControlCharacters(result.stderr).trim();
|
|
113
105
|
} catch (err) {
|
|
114
106
|
if (err instanceof Error) {
|
|
115
107
|
final = err.message;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type RunConfig = {
|
|
2
|
+
filter?: (line: string) => boolean;
|
|
3
|
+
rewrite?: (text: string) => string;
|
|
4
|
+
module?: string;
|
|
5
|
+
env?: Record<string, string>;
|
|
6
|
+
envName?: string;
|
|
7
|
+
cwd?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type CodeProps = { title?: string, src: string | Function, language?: string, outline?: boolean, startRe?: RegExp, endRe?: RegExp };
|
package/support/cli.doc.ts
CHANGED
|
@@ -67,7 +67,7 @@ export class DocCommand implements CliCommandShape {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
async render(): Promise<void> {
|
|
70
|
-
const { DocRenderer } = await import('../src/render/renderer');
|
|
70
|
+
const { DocRenderer } = await import('../src/render/renderer.ts');
|
|
71
71
|
const ctx = await DocRenderer.get(this.input, Runtime);
|
|
72
72
|
const outputs = this.outputs.map(output =>
|
|
73
73
|
output.includes('.') ? [path.extname(output).replace('.', ''), path.resolve(output)] :
|