@travetto/doc 7.0.0-rc.1 → 7.0.0-rc.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/doc",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.2",
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": "^7.0.0-rc.1",
27
+ "@travetto/runtime": "^7.0.0-rc.2",
28
28
  "@types/prismjs": "^1.26.5",
29
29
  "prismjs": "^1.30.0"
30
30
  },
31
31
  "peerDependencies": {
32
- "@travetto/cli": "^7.0.0-rc.1"
32
+ "@travetto/cli": "^7.0.0-rc.2"
33
33
  },
34
34
  "peerDependenciesMeta": {
35
35
  "@travetto/cli": {
package/src/jsx.ts CHANGED
@@ -64,7 +64,7 @@ export type JSXElements = { [K in keyof C]: JSXElementByFn<K>; };
64
64
 
65
65
  export const EMPTY_ELEMENT = EMPTY;
66
66
 
67
- const invertedC = new Map<Function, string>(TypedObject.entries(c).map<[Function, string]>(p => [p[1], p[0]]));
67
+ const invertedC = new Map<Function, string>(TypedObject.entries(c).map<[Function, string]>(([name, cls]) => [cls, name]));
68
68
 
69
69
  export function getComponentName(fn: Function | string): string {
70
70
  if (typeof fn === 'string') {
@@ -34,18 +34,18 @@ export function highlight(text: string, lang: string): string | undefined {
34
34
  });
35
35
 
36
36
  text = text
37
- .replace(/&#(\d+);/g, (x, code) => String.fromCharCode(code))
37
+ .replace(/&#(\d+);/g, (_, code) => String.fromCharCode(code))
38
38
  .replace(/&[a-z][^;]*;/g, a => tokenMapping[a] || a);
39
39
 
40
40
  try {
41
41
  return prismJs.highlight(text, prismJs.languages[lang], lang)
42
42
  .replace(/(@\s*<span[^>]*)function("\s*>)/g, (a, pre, post) => `${pre}meta${post}`)
43
43
  .replace(/[{}]/g, a => `{{'${a}'}}`);
44
- } catch (err) {
45
- if (err instanceof Error) {
46
- console.error(err.message, { error: err });
44
+ } catch (error) {
45
+ if (error instanceof Error) {
46
+ console.error(error.message, { error });
47
47
  } else {
48
- throw err;
48
+ throw error;
49
49
  }
50
50
  }
51
51
  }
@@ -13,23 +13,23 @@ import { RenderContext } from './context.ts';
13
13
  import { DocResolveUtil } from '../util/resolve.ts';
14
14
 
15
15
  const ESCAPE_ENTITIES: Record<string, string> = { '<': '&lt;', '>': '&gt;', '&': '&amp;', '{': "{{'{'}}", '}': "{{'}'}}" };
16
- const ENTITY_RE = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join('')}]`, 'gm');
16
+ const ENTITY_REGEX = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join('')}]`, 'gm');
17
17
 
18
- const stdInline = async ({ recurse, el }: RenderState<JSXElement, RenderContext>): Promise<string> =>
19
- `<${el.type}>${await recurse()}</${el.type}>`;
18
+ const stdInline = async ({ recurse, node }: RenderState<JSXElement, RenderContext>): Promise<string> =>
19
+ `<${node.type}>${await recurse()}</${node.type}>`;
20
20
 
21
- const std = async ({ recurse, el }: RenderState<JSXElement, RenderContext>): Promise<string> =>
22
- `<${el.type}>${await recurse()}</${el.type}>\n`;
21
+ const std = async ({ recurse, node }: RenderState<JSXElement, RenderContext>): Promise<string> =>
22
+ `<${node.type}>${await recurse()}</${node.type}>\n`;
23
23
 
24
- const stdFull = async ({ recurse, el }: RenderState<JSXElement, RenderContext>): Promise<string> =>
25
- `\n<${el.type}>${await recurse()}</${el.type}>\n`;
24
+ const stdFull = async ({ recurse, node }: RenderState<JSXElement, RenderContext>): Promise<string> =>
25
+ `\n<${node.type}>${await recurse()}</${node.type}>\n`;
26
26
 
27
27
  export const Html: RenderProvider<RenderContext> = {
28
28
  ext: 'html',
29
29
  finalize: (text, context) => {
30
30
  const brand = `<!-- ${context.generatedStamp} -->\n<!-- ${context.rebuildStamp} -->`;
31
31
  const cleaned = text
32
- .replace(/(<[/](?:a)>)([A-Za-z0-9$])/g, (_, tag, v) => `${tag} ${v}`)
32
+ .replace(/(<[/](?:a)>)([A-Za-z0-9$])/g, (_, tag, value) => `${tag} ${value}`)
33
33
  .replace(/(<[uo]l>)(<li>)/g, (_, a, b) => `${a} ${b}`);
34
34
  return `${brand}\n${cleaned}`;
35
35
  },
@@ -39,10 +39,10 @@ export const Html: RenderProvider<RenderContext> = {
39
39
  h2: stdFull, h3: stdFull, h4: stdFull,
40
40
  li: std, ol: stdFull, ul: stdFull,
41
41
  table: stdFull, thead: std, tr: std, td: std, tbody: std,
42
- Execution: async ({ context, el, props, createState }) => {
43
- const output = await context.execute(el);
42
+ Execution: async ({ context, node, props, createState }) => {
43
+ const output = await context.execute(node);
44
44
  const displayCmd = props.config?.formatCommand?.(props.cmd, props.args ?? []) ??
45
- `${el.props.cmd} ${(el.props.args ?? []).join(' ')}`;
45
+ `${node.props.cmd} ${(node.props.args ?? []).join(' ')}`;
46
46
  const sub = createState('Terminal', {
47
47
  language: 'bash',
48
48
  title: props.title,
@@ -50,18 +50,18 @@ export const Html: RenderProvider<RenderContext> = {
50
50
  });
51
51
  return Html.Terminal(sub);
52
52
  },
53
- Install: async ({ context, el }) => {
53
+ Install: async ({ context, node }) => {
54
54
  const highlighted = highlight(`
55
- npm install ${el.props.pkg}
55
+ npm install ${node.props.pkg}
56
56
 
57
57
  # or
58
58
 
59
- yarn add ${el.props.pkg}
59
+ yarn add ${node.props.pkg}
60
60
  `, 'bash');
61
61
 
62
62
  return `\n
63
63
  <figure class="install">
64
- <figcaption class="install">Install ${el.props.title}
64
+ <figcaption class="install">Install ${node.props.title}
65
65
 
66
66
  </figcaption>
67
67
  <pre><code class="language-bash">${highlighted}</code></pre>
@@ -70,11 +70,11 @@ yarn add ${el.props.pkg}
70
70
  },
71
71
  Terminal: state => Html.Code(state),
72
72
  Config: state => Html.Code(state),
73
- Code: async ({ context, el, props }) => {
74
- DocResolveUtil.applyCodePropDefaults(el.props);
73
+ Code: async ({ context, node, props }) => {
74
+ DocResolveUtil.applyCodePropDefaults(node.props);
75
75
 
76
- const cls = getComponentName(el.type).replace(/^[A-Z]/g, v => v.toLowerCase());
77
- const content = await context.resolveCode(el);
76
+ const cls = getComponentName(node.type).replace(/^[A-Z]/g, value => value.toLowerCase());
77
+ const content = await context.resolveCode(node);
78
78
  let link: string = '';
79
79
  if ('src' in props && content.file) {
80
80
  let linkCtx: { file: string, line?: number } = { file: content.file! };
@@ -85,9 +85,9 @@ yarn add ${el.props.pkg}
85
85
  }
86
86
  let lang = props.language ?? content.language;
87
87
  if (!lang) {
88
- if (el.type === c.Terminal) {
88
+ if (node.type === c.Terminal) {
89
89
  lang = 'bash';
90
- } else if (el.type === c.Code) {
90
+ } else if (node.type === c.Code) {
91
91
  lang = 'typescript';
92
92
  }
93
93
  }
@@ -112,12 +112,12 @@ yarn add ${el.props.pkg}
112
112
  Path: state => Html.Input(state),
113
113
  Class: state => Html.Input(state),
114
114
  Field: state => Html.Input(state),
115
- Input: async ({ el, context }) => {
116
- const cls = getComponentName(el.type).replace(/^[A-Z]/g, v => v.toLowerCase());
117
- return `<code class="item ${cls}">${context.cleanText(el.props.name.replace(ENTITY_RE, k => ESCAPE_ENTITIES[k]))}</code>`;
115
+ Input: async ({ node, context }) => {
116
+ const cls = getComponentName(node.type).replace(/^[A-Z]/g, value => value.toLowerCase());
117
+ return `<code class="item ${cls}">${context.cleanText(node.props.name.replace(ENTITY_REGEX, key => ESCAPE_ENTITIES[key]))}</code>`;
118
118
  },
119
- CodeLink: async ({ context, props, el }) => {
120
- const target = await context.resolveCodeLink(el);
119
+ CodeLink: async ({ context, props, node }) => {
120
+ const target = await context.resolveCodeLink(node);
121
121
  return `<a target="_blank" class="source-link" href="${context.link(target.file, target)}">${props.title}</a>`;
122
122
  },
123
123
  Anchor: async ({ context, props }) =>
@@ -134,24 +134,24 @@ yarn add ${el.props.pkg}
134
134
  },
135
135
 
136
136
  Mod: async ({ context, props }) => {
137
- const cfg = MOD_MAPPING[props.name];
138
- return `<a class="module-link" href="${context.link(cfg.folder, cfg)}" title="${cfg.description}">${cfg.displayName}</a>`;
137
+ const config = MOD_MAPPING[props.name];
138
+ return `<a class="module-link" href="${context.link(config.folder, config)}" title="${config.description}">${config.displayName}</a>`;
139
139
  },
140
140
  Library: async ({ context, props }) => {
141
- const cfg = LIB_MAPPING[props.name];
142
- return `<a target="_blank" class="external-link" href="${context.link(cfg.href, cfg)}">${cfg.title}</a>`;
141
+ const config = LIB_MAPPING[props.name];
142
+ return `<a target="_blank" class="external-link" href="${context.link(config.href, config)}">${config.title}</a>`;
143
143
  },
144
144
 
145
145
  Note: async ({ recurse }) => `\n\n<p class="note"><strong>Note</strong> ${await recurse()}</p>\n`,
146
146
  Header: async ({ props }) => `<h1>${props.title} ${props.description ? `\n<small>${props.description}</small>\n` : ''}</h1>\n`,
147
147
 
148
148
  StdHeader: async state => {
149
- const mod = state.el.props.mod ?? Runtime.main.name;
149
+ const mod = state.node.props.mod ?? Runtime.main.name;
150
150
  const pkg = PackageUtil.readPackage(RuntimeIndex.getModule(mod)!.sourcePath);
151
151
  const title = pkg.travetto?.displayName ?? pkg.name;
152
152
  const desc = pkg.description;
153
153
  let install = '';
154
- if (state.el.props.install !== false) {
154
+ if (state.node.props.install !== false) {
155
155
  const sub = state.createState('Install', {
156
156
  title: pkg.name,
157
157
  pkg: pkg.name,
@@ -15,8 +15,8 @@ export const Markdown: RenderProvider<RenderContext> = {
15
15
  finalize: (text, context) => {
16
16
  const brand = `<!-- ${context.generatedStamp} -->\n<!-- ${context.rebuildStamp} -->`;
17
17
  const cleaned = text
18
- .replace(/(\[[^\]]+\]\([^)]+\))([A-Za-z0-9$]+)/g, (_, link, v) => v === 's' ? _ : `${link} ${v}`)
19
- .replace(/(\S)\n(#)/g, (_, l, r) => `${l}\n\n${r}`);
18
+ .replace(/(\[[^\]]+\]\([^)]+\))([A-Za-z0-9$]+)/g, (_, link, value) => value === 's' ? _ : `${link} ${value}`)
19
+ .replace(/(\S)\n(#)/g, (_, left, right) => `${left}\n\n${right}`);
20
20
  return `${brand}\n${cleaned}`;
21
21
  },
22
22
  strong: async ({ recurse }) => `**${await recurse()}**`,
@@ -26,8 +26,8 @@ export const Markdown: RenderProvider<RenderContext> = {
26
26
  ul: async ({ recurse }) => `\n${await recurse()}\n`,
27
27
  ol: async ({ recurse }) => `\n${await recurse()}\n`,
28
28
  li: async ({ recurse, stack }) => {
29
- const parent = stack.toReversed().find(x => x.type === 'ol' || x.type === 'ul');
30
- const depth = stack.filter(x => x.type === 'ol' || x.type === 'ul').length;
29
+ const parent = stack.toReversed().find(node => node.type === 'ol' || node.type === 'ul');
30
+ const depth = stack.filter(node => node.type === 'ol' || node.type === 'ul').length;
31
31
  return `${' '.repeat(depth)}${(parent && parent.type === 'ol') ? '1.' : '* '} ${await recurse()}\n`;
32
32
  },
33
33
  table: async ({ recurse }) => `${await recurse()}`,
@@ -41,37 +41,37 @@ export const Markdown: RenderProvider<RenderContext> = {
41
41
  h2: async ({ recurse }) => `\n## ${await recurse()}\n\n`,
42
42
  h3: async ({ recurse }) => `\n### ${await recurse()}\n\n`,
43
43
  h4: async ({ recurse }) => `\n#### ${await recurse()}\n\n`,
44
- Execution: async ({ context, el, props, createState }) => {
45
- const output = await context.execute(el);
44
+ Execution: async ({ context, node, props, createState }) => {
45
+ const output = await context.execute(node);
46
46
  const displayCmd = props.config?.formatCommand?.(props.cmd, props.args ?? []) ??
47
- `${el.props.cmd} ${(el.props.args ?? []).join(' ')}`;
47
+ `${node.props.cmd} ${(node.props.args ?? []).join(' ')}`;
48
48
  const state = createState('Terminal', {
49
49
  language: 'bash',
50
- title: el.props.title,
50
+ title: node.props.title,
51
51
  src: [`$ ${displayCmd}`, '', context.cleanText(output)].join('\n')
52
52
  });
53
53
  return Markdown.Terminal(state);
54
54
  },
55
- Install: async ({ context, el }) =>
56
- `\n\n**Install: ${el.props.title}**
55
+ Install: async ({ context, node }) =>
56
+ `\n\n**Install: ${node.props.title}**
57
57
  \`\`\`bash
58
- npm install ${el.props.pkg}
58
+ npm install ${node.props.pkg}
59
59
 
60
60
  # or
61
61
 
62
- yarn add ${el.props.pkg}
62
+ yarn add ${node.props.pkg}
63
63
  \`\`\`
64
64
  `,
65
- Code: async ({ context, el, props }) => {
66
- DocResolveUtil.applyCodePropDefaults(el.props);
65
+ Code: async ({ context, node, props }) => {
66
+ DocResolveUtil.applyCodePropDefaults(node.props);
67
67
 
68
- const name = getComponentName(el.type);
69
- const content = await context.resolveCode(el);
68
+ const name = getComponentName(node.type);
69
+ const content = await context.resolveCode(node);
70
70
  let lang = props.language ?? content.language;
71
71
  if (!lang) {
72
- if (el.type === c.Terminal) {
72
+ if (node.type === c.Terminal) {
73
73
  lang = 'bash';
74
- } else if (el.type === c.Code) {
74
+ } else if (node.type === c.Code) {
75
75
  lang = 'typescript';
76
76
  }
77
77
  }
@@ -83,9 +83,9 @@ ${context.cleanText(content.text)}
83
83
  Terminal: state => Markdown.Code(state),
84
84
  Config: state => Markdown.Code(state),
85
85
 
86
- Section: async ({ el, recurse }) => `\n## ${el.props.title}\n${await recurse()}\n`,
87
- SubSection: async ({ el, recurse }) => `\n### ${el.props.title}\n${await recurse()}\n`,
88
- SubSubSection: async ({ el, recurse }) => `\n#### ${el.props.title}\n${await recurse()}\n`,
86
+ Section: async ({ node, recurse }) => `\n## ${node.props.title}\n${await recurse()}\n`,
87
+ SubSection: async ({ node, recurse }) => `\n### ${node.props.title}\n${await recurse()}\n`,
88
+ SubSubSection: async ({ node, recurse }) => `\n#### ${node.props.title}\n${await recurse()}\n`,
89
89
 
90
90
  Command: state => Markdown.Input(state),
91
91
  Method: state => Markdown.Input(state),
@@ -98,8 +98,8 @@ ${context.cleanText(content.text)}
98
98
  File: state => Markdown.Ref(state),
99
99
  Ref: async ({ context, props }) => `[${props.title}](${context.link(props.href, props)})`,
100
100
 
101
- CodeLink: async ({ context, props, el }) => {
102
- const target = await context.resolveCodeLink(el);
101
+ CodeLink: async ({ context, props, node }) => {
102
+ const target = await context.resolveCodeLink(node);
103
103
  return `[${props.title}](${context.link(target.file, target)})`;
104
104
  },
105
105
 
@@ -113,23 +113,23 @@ ${context.cleanText(content.text)}
113
113
  Header: async ({ props }) => `# ${props.title}\n${props.description ? `## ${props.description}\n` : ''}\n`,
114
114
 
115
115
  StdHeader: async state => {
116
- const mod = state.el.props.mod ?? Runtime.main.name;
116
+ const mod = state.node.props.mod ?? Runtime.main.name;
117
117
  const pkg = PackageUtil.readPackage(RuntimeIndex.getModule(mod)!.sourcePath);
118
118
  const title = pkg.travetto?.displayName ?? pkg.name;
119
119
  const desc = pkg.description;
120
120
  let install = '';
121
- if (state.el.props.install !== false) {
121
+ if (state.node.props.install !== false) {
122
122
  const sub = state.createState('Install', { title: pkg.name, pkg: pkg.name });
123
123
  install = await Markdown.Install(sub);
124
124
  }
125
125
  return `# ${title}\n${desc ? `## ${desc}\n` : ''}${install}\n`;
126
126
  },
127
127
  Mod: async ({ props, context }) => {
128
- const cfg = MOD_MAPPING[props.name];
129
- return `[${cfg.displayName}](${context.link(cfg.folder, cfg)}#readme "${cfg.description}")`;
128
+ const config = MOD_MAPPING[props.name];
129
+ return `[${config.displayName}](${context.link(config.folder, config)}#readme "${config.description}")`;
130
130
  },
131
131
  Library: async ({ props }) => {
132
- const cfg = LIB_MAPPING[props.name];
133
- return `[${cfg.title}](${cfg.href})`;
132
+ const config = LIB_MAPPING[props.name];
133
+ return `[${config.title}](${config.href})`;
134
134
  }
135
135
  };
@@ -2,7 +2,7 @@ declare namespace PrismAlt {
2
2
  export interface Grammar { }
3
3
  export const languages: { [language: string]: Grammar; };
4
4
  export const plugins: Record<string, {
5
- setDefaults(cfg: Record<string, unknown>): void;
5
+ setDefaults(config: Record<string, unknown>): void;
6
6
  normalize(text: string, config?: unknown): string;
7
7
  }>;
8
8
  export function highlight(
@@ -20,10 +20,10 @@ const providers = { [Html.ext]: Html, [Markdown.ext]: Markdown };
20
20
  export class DocRenderer {
21
21
 
22
22
  static async get(file: string, manifest: Pick<ManifestContext, 'workspace'>): Promise<DocRenderer> {
23
- const res = await Runtime.importFrom<DocumentShape>(file);
23
+ const document = await Runtime.importFrom<DocumentShape>(file);
24
24
  const pkg = PackageUtil.readPackage(manifest.workspace.path);
25
25
  const repoBaseUrl = pkg.travetto?.doc?.baseUrl ?? manifest.workspace.path;
26
- return new DocRenderer(res,
26
+ return new DocRenderer(document,
27
27
  new RenderContext(file, repoBaseUrl, path.resolve(pkg.travetto?.doc?.root ?? manifest.workspace.path))
28
28
  );
29
29
  }
@@ -45,14 +45,14 @@ export class DocRenderer {
45
45
  const source = DocFileUtil.readSource(cls);
46
46
  if (source) {
47
47
  title = (await DocFileUtil.isDecorator(cls.name, source.file)) ? `@${title ?? cls.name}` : (title ?? cls.name);
48
- const el = this.#support.createElement('CodeLink', {
48
+ const node = this.#support.createElement('CodeLink', {
49
49
  src: source.file,
50
50
  startRe: new RegExp(`(class|function|interface)\\s+(${cls.name.replaceAll('$', '\\$')})`),
51
51
  title
52
52
  });
53
53
  // @ts-expect-error
54
54
  const state: RenderState<JSXElementByFn<'CodeLink'>, RenderContext> = {
55
- el, props: el.props, recurse: async () => '', context: this.#support, stack: []
55
+ node, props: node.props, recurse: async () => '', context: this.#support, stack: []
56
56
  };
57
57
  // @ts-expect-error
58
58
  state.createState = (key, props) => this.createState(state, key, props);
@@ -62,26 +62,26 @@ export class DocRenderer {
62
62
 
63
63
  async #render(
64
64
  renderer: RenderProvider<RenderContext>,
65
- node: JSXElement[] | JSXElement | string | bigint | object | number | boolean | null | undefined,
65
+ input: JSXElement[] | JSXElement | string | bigint | object | number | boolean | null | undefined,
66
66
  stack: JSXElement[] = []
67
67
  ): Promise<string | undefined> {
68
68
 
69
- if (node === null || node === undefined) {
69
+ if (input === null || input === undefined) {
70
70
  return '';
71
- } else if (Array.isArray(node)) {
71
+ } else if (Array.isArray(input)) {
72
72
  const out: string[] = [];
73
- for (const el of node) {
74
- const sub = await this.#render(renderer, el, stack);
73
+ for (const node of input) {
74
+ const sub = await this.#render(renderer, node, stack);
75
75
  if (sub) {
76
76
  out.push(sub);
77
77
  }
78
78
  }
79
79
  return out.join('');
80
- } else if (isJSXElement(node)) {
81
- let final: JSXElement = node;
80
+ } else if (isJSXElement(input)) {
81
+ let final: JSXElement = input;
82
82
  // Render simple element if needed
83
- if (typeof node.type === 'function' && node.type !== JSXFragmentType) {
84
- const out = castTo<Function>(node.type)(node.props);
83
+ if (typeof input.type === 'function' && input.type !== JSXFragmentType) {
84
+ const out = castTo<Function>(input.type)(input.props);
85
85
  final = out !== EMPTY_ELEMENT ? out : final;
86
86
  }
87
87
 
@@ -98,7 +98,7 @@ export class DocRenderer {
98
98
  const recurse = () => this.#render(renderer, final.props.children ?? [], [...stack, final]);
99
99
  // @ts-expect-error
100
100
  const state: RenderState<JSXElement, RenderContext> = {
101
- el: final, props: final.props, recurse, stack, context: this.#support
101
+ node: final, props: final.props, recurse, stack, context: this.#support
102
102
  };
103
103
  state.createState = (key, props) => this.createState(state, key, props);
104
104
  // @ts-expect-error
@@ -108,22 +108,22 @@ export class DocRenderer {
108
108
  throw new Error(`Unknown element: ${final.type}`);
109
109
  }
110
110
  } else {
111
- switch (typeof node) {
112
- case 'string': return node.replace(/&nbsp;/g, ' ');
111
+ switch (typeof input) {
112
+ case 'string': return input.replace(/&nbsp;/g, ' ');
113
113
  case 'number':
114
114
  case 'bigint':
115
- case 'boolean': return `${node}`;
115
+ case 'boolean': return `${input}`;
116
116
  case 'object': {
117
- if (node) {
118
- return await this.#buildLink(renderer, castTo(node.constructor), node.constructor.name.replace(/^[$]/, ''));
117
+ if (input) {
118
+ return await this.#buildLink(renderer, castTo(input.constructor), input.constructor.name.replace(/^[$]/, ''));
119
119
  }
120
120
  break;
121
121
  }
122
122
  case 'function': {
123
- return await this.#buildLink(renderer, castTo(node));
123
+ return await this.#buildLink(renderer, castTo(input));
124
124
  }
125
125
  }
126
- throw new Error(`Unknown object type: ${typeof node}`);
126
+ throw new Error(`Unknown object type: ${typeof input}`);
127
127
  }
128
128
  }
129
129
 
@@ -133,28 +133,28 @@ export class DocRenderer {
133
133
  props: JSXElementByFn<K>['props']
134
134
  // @ts-expect-error
135
135
  ): RenderState<JSXElementByFn<K>, RenderContext> {
136
- const el = this.#support.createElement(key, props);
137
- return { ...state, el, props: el.props };
136
+ const node = this.#support.createElement(key, props);
137
+ return { ...state, node, props: node.props };
138
138
  }
139
139
 
140
140
  /**
141
141
  * Render a context given a specific renderer
142
142
  * @param renderer
143
143
  */
144
- async render(fmt: keyof typeof providers): Promise<string> {
145
- if (!providers[fmt]) {
146
- throw new Error(`Unknown renderer with format: ${fmt}`);
144
+ async render(format: keyof typeof providers): Promise<string> {
145
+ if (!providers[format]) {
146
+ throw new Error(`Unknown renderer with format: ${format}`);
147
147
  }
148
148
  if (!this.#rootNode) {
149
149
  this.#rootNode = (Array.isArray(this.#root.text) || isJSXElement(this.#root.text)) ?
150
150
  this.#root.text : await (this.#root.text());
151
151
  }
152
152
 
153
- const text = await this.#render(providers[fmt], this.#rootNode);
153
+ const text = await this.#render(providers[format], this.#rootNode);
154
154
  let cleaned = `${text?.replace(/\n{3,100}/msg, '\n\n').trim()}\n`;
155
- if (this.#root.wrap?.[fmt]) {
156
- cleaned = this.#root.wrap[fmt](cleaned);
155
+ if (this.#root.wrap?.[format]) {
156
+ cleaned = this.#root.wrap[format](cleaned);
157
157
  }
158
- return providers[fmt].finalize(cleaned, this.#support);
158
+ return providers[format].finalize(cleaned, this.#support);
159
159
  }
160
160
  }
package/src/types.ts CHANGED
@@ -13,7 +13,7 @@ export interface DocumentShape {
13
13
  }
14
14
 
15
15
  export type RenderState<T extends JSXElement, C> = {
16
- el: T;
16
+ node: T;
17
17
  props: T['props'];
18
18
  recurse: () => Promise<string | undefined>;
19
19
  stack: JSXElement[];
package/src/util/file.ts CHANGED
@@ -31,40 +31,40 @@ export class DocFileUtil {
31
31
 
32
32
  static #decCache: Record<string, boolean> = {};
33
33
 
34
- static isFile(src: string): boolean {
35
- return /^[@:A-Za-z0-9\/\\\-_.]+[.]([a-z]{2,10})$/.test(src);
34
+ static isFile(file: string): boolean {
35
+ return /^[@:A-Za-z0-9\/\\\-_.]+[.]([a-z]{2,10})$/.test(file);
36
36
  }
37
37
 
38
- static readSource(src: string | Function): { content: string, language: string, file: string } {
38
+ static readSource(input: string | Function): { content: string, language: string, file: string } {
39
39
  let file: string | undefined;
40
40
  let content: string | undefined;
41
41
 
42
- if (typeof src === 'string') {
43
- if (src.includes('\n') || src.includes(' ')) {
44
- content = src;
42
+ if (typeof input === 'string') {
43
+ if (input.includes('\n') || input.includes(' ')) {
44
+ content = input;
45
45
  } else {
46
- const resolved = path.resolve(src);
46
+ const resolved = path.resolve(input);
47
47
  if (existsSync(resolved)) {
48
48
  content = readFileSync(resolved, 'utf8');
49
49
  file = resolved;
50
50
  } else {
51
- file = RuntimeIndex.getSourceFile(src);
51
+ file = RuntimeIndex.getSourceFile(input);
52
52
  content = readFileSync(file, 'utf8');
53
53
  }
54
54
  }
55
55
  } else {
56
- file = Runtime.getSourceFile(src);
56
+ file = Runtime.getSourceFile(input);
57
57
  if (!existsSync(file)) {
58
- throw new AppError(`Unknown file: ${typeof src === 'string' ? src : src.name} => ${file}`);
58
+ throw new AppError(`Unknown file: ${typeof input === 'string' ? input : input.name} => ${file}`);
59
59
  }
60
60
  content = readFileSync(file, 'utf8');
61
61
  }
62
62
 
63
63
  if (content) {
64
64
  content = content.split(/\n/)
65
- .map(x => x
65
+ .map(line => line
66
66
  .replace(ESLINT_PATTERN, '')
67
- .replace(ENV_KEY, (_, k) => `'${k}'`)
67
+ .replace(ENV_KEY, (_, key) => `'${key}'`)
68
68
  )
69
69
  .join('\n')
70
70
  .replace(/^\/\/# sourceMap.*$/gsm, '')
@@ -83,12 +83,12 @@ export class DocFileUtil {
83
83
  }
84
84
  }
85
85
 
86
- static async readCodeSnippet(src: string | Function, startPattern: RegExp): Promise<{ file: string, startIdx: number, lines: string[], language: string }> {
87
- const result = this.readSource(src);
86
+ static async readCodeSnippet(input: string | Function, startPattern: RegExp): Promise<{ file: string, startIdx: number, lines: string[], language: string }> {
87
+ const result = this.readSource(input);
88
88
  const lines = result.content.split(/\n/);
89
- const startIdx = lines.findIndex(l => startPattern.test(l));
89
+ const startIdx = lines.findIndex(line => startPattern.test(line));
90
90
  if (startIdx < 0) {
91
- throw new Error(`Pattern ${startPattern.source} not found in ${src}`);
91
+ throw new Error(`Pattern ${startPattern.source} not found in ${input}`);
92
92
  }
93
93
  return { file: result.file, startIdx, lines, language: result.language };
94
94
  }
@@ -106,7 +106,7 @@ export class DocFileUtil {
106
106
  const text = await this.readSource(file);
107
107
  const lines = text.content.split(/\n/g);
108
108
 
109
- const start = lines.findIndex(x => new RegExp(`function ${name}\\b`).test(x));
109
+ const start = lines.findIndex(line => new RegExp(`function ${name}\\b`).test(line));
110
110
  let found = false;
111
111
  if (start > 0) {
112
112
  for (let i = start - 1; i > start - 3; i--) {
@@ -126,30 +126,30 @@ export class DocFileUtil {
126
126
  */
127
127
  static buildOutline(code: string): string {
128
128
  let methodPrefix = '';
129
- code = code.split(/\n/).map((x) => {
129
+ code = code.split(/\n/).map((line) => {
130
130
  if (!methodPrefix) {
131
- const info = x.match(/^(\s{0,50})(?:(private|public)\s{1,10})?(?:static\s{1,10})?(?:async\s{1,10})?(?:[*]\s{0,10})?(?:(?:get|set)\s{1,10})?(\S{1,200})[<(](.{0,500})/);
131
+ const info = line.match(/^(\s{0,50})(?:(private|public)\s{1,10})?(?:static\s{1,10})?(?:async\s{1,10})?(?:[*]\s{0,10})?(?:(?:get|set)\s{1,10})?(\S{1,200})[<(](.{0,500})/);
132
132
  if (info) {
133
133
  const [, space, __name, rest] = info;
134
134
  if (!rest.endsWith(';')) {
135
- if (/\s{0,50}[{]\s{0,50}return.{0,200}$/.test(x)) {
136
- return x.replace(/\s{0,50}[{]\s{0,50}return.{0,200}$/, ';');
135
+ if (/\s{0,50}[{]\s{0,50}return.{0,200}$/.test(line)) {
136
+ return line.replace(/\s{0,50}[{]\s{0,50}return.{0,200}$/, ';');
137
137
  } else {
138
138
  methodPrefix = space;
139
- return x.replace(/\s{0,50}[{]\s{0,50}$/, ';');
139
+ return line.replace(/\s{0,50}[{]\s{0,50}$/, ';');
140
140
  }
141
141
  }
142
142
  }
143
- return x;
143
+ return line;
144
144
  } else {
145
- if (x.startsWith(`${methodPrefix}}`)) {
145
+ if (line.startsWith(`${methodPrefix}}`)) {
146
146
  methodPrefix = '';
147
147
  }
148
148
  return '';
149
149
  }
150
150
  })
151
- .filter(x => !/#|(\b(private|protected)\b)/.test(x))
152
- .filter(x => !!x)
151
+ .filter(line => !/#|(\b(private|protected)\b)/.test(line))
152
+ .filter(line => !!line)
153
153
  .join('\n');
154
154
 
155
155
  return code;
@@ -19,7 +19,7 @@ export class DocResolveUtil {
19
19
 
20
20
  if (result.content) {
21
21
  line = result.content.split(/\n/g)
22
- .findIndex(x => new RegExp(`(class|interface|function)[ ]+${title.replaceAll('$', '\\$')}`).test(x));
22
+ .findIndex(lineText => new RegExp(`(class|interface|function)[ ]+${title.replaceAll('$', '\\$')}`).test(lineText));
23
23
  if (line < 0) {
24
24
  line = 0;
25
25
  } else {
@@ -50,7 +50,7 @@ export class DocResolveUtil {
50
50
  static async resolveSnippet(file: Function | string, startPattern: RegExp, endPattern?: RegExp, outline = false): Promise<ResolvedSnippet> {
51
51
  const { lines, startIdx, language, file: resolvedFile } = await DocFileUtil.readCodeSnippet(file, startPattern);
52
52
 
53
- const endIdx = endPattern ? lines.findIndex((l, i) => i > startIdx && endPattern.test(l)) : lines.length;
53
+ const endIdx = endPattern ? lines.findIndex((line, i) => i > startIdx && endPattern.test(line)) : lines.length;
54
54
  let text = lines.slice(startIdx, endIdx + 1).join('\n');
55
55
 
56
56
  if (outline) {
package/src/util/run.ts CHANGED
@@ -25,7 +25,10 @@ class DocState {
25
25
 
26
26
  getId(id: string): string {
27
27
  if (!this.ids[id]) {
28
- this.ids[id] = ' '.repeat(id.length).split('').map(x => Math.trunc(this.rng() * 16).toString(16)).join('');
28
+ this.ids[id] = ' '.repeat(id.length)
29
+ .split('')
30
+ .map(_ => Math.trunc(this.rng() * 16).toString(16))
31
+ .join('');
29
32
  }
30
33
  return this.ids[id];
31
34
  }
@@ -37,18 +40,18 @@ class DocState {
37
40
  export class DocRunUtil {
38
41
  static #docState = new DocState();
39
42
 
40
- /** Build cwd from config */
41
- static cwd(cfg: RunConfig): string {
42
- return path.resolve(cfg.module ? RuntimeIndex.getModule(cfg.module)?.sourcePath! : Runtime.mainSourcePath);
43
+ /** Build working directory from config */
44
+ static workingDirectory(config: RunConfig): string {
45
+ return path.resolve(config.module ? RuntimeIndex.getModule(config.module)?.sourcePath! : Runtime.mainSourcePath);
43
46
  }
44
47
 
45
48
  /**
46
49
  * Clean run output
47
50
  */
48
- static cleanRunOutput(text: string, cfg: RunConfig): string {
49
- const cwd = this.cwd(cfg);
51
+ static cleanRunOutput(text: string, config: RunConfig): string {
52
+ const rootPath = this.workingDirectory(config);
50
53
  text = util.stripVTControlCharacters(text.trim())
51
- .replaceAll(cwd, '.')
54
+ .replaceAll(rootPath, '.')
52
55
  .replaceAll(os.tmpdir(), '/tmp')
53
56
  .replaceAll(Runtime.workspace.path, '<workspace-root>')
54
57
  .replace(/[/]tmp[/][a-z_A-Z0-9\/\-]+/g, '/tmp/<temp-folder>')
@@ -58,12 +61,12 @@ export class DocRunUtil {
58
61
  .replace(/[A-Za-z0-9_.\-\/\\]+\/travetto\/module\//g, '@travetto/')
59
62
  .replace(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([.]\d{3})?Z?/g, this.#docState.getDate.bind(this.#docState))
60
63
  .replace(/\b[0-9a-f]{4}[0-9a-f\-]{8,40}\b/ig, this.#docState.getId.bind(this.#docState))
61
- .replace(/(\d+[.]\d+[.]\d+)-(alpha|rc)[.]\d+/g, (all, v) => v);
62
- if (cfg.filter) {
63
- text = text.split(/\n/g).filter(cfg.filter).join('\n');
64
+ .replace(/(\d+[.]\d+[.]\d+)-(alpha|rc)[.]\d+/g, (all, value) => value);
65
+ if (config.filter) {
66
+ text = text.split(/\n/g).filter(config.filter).join('\n');
64
67
  }
65
- if (cfg.rewrite) {
66
- text = cfg.rewrite(text);
68
+ if (config.rewrite) {
69
+ text = config.rewrite(text);
67
70
  }
68
71
  return text;
69
72
  }
@@ -73,7 +76,7 @@ export class DocRunUtil {
73
76
  */
74
77
  static spawn(cmd: string, args: string[], config: RunConfig = {}): ChildProcess {
75
78
  return spawn(cmd, args, {
76
- cwd: config.cwd ?? this.cwd(config),
79
+ cwd: config.workingDirectory ?? this.workingDirectory(config),
77
80
  env: {
78
81
  ...process.env,
79
82
  ...Env.DEBUG.export(false),
@@ -95,17 +98,17 @@ export class DocRunUtil {
95
98
  static async run(cmd: string, args: string[], config: RunConfig = {}): Promise<string> {
96
99
  let final: string;
97
100
  try {
98
- const proc = this.spawn(cmd, args, config);
99
- const result = await ExecUtil.getResult(proc, { catch: true });
101
+ const subProcess = this.spawn(cmd, args, config);
102
+ const result = await ExecUtil.getResult(subProcess, { catch: true });
100
103
  if (!result.valid) {
101
104
  throw new Error(result.stderr);
102
105
  }
103
106
  final = util.stripVTControlCharacters(result.stdout).trim() || util.stripVTControlCharacters(result.stderr).trim();
104
- } catch (err) {
105
- if (err instanceof Error) {
106
- final = err.message;
107
+ } catch (error) {
108
+ if (error instanceof Error) {
109
+ final = error.message;
107
110
  } else {
108
- throw err;
111
+ throw error;
109
112
  }
110
113
  }
111
114
 
package/src/util/types.ts CHANGED
@@ -4,7 +4,7 @@ export type RunConfig = {
4
4
  module?: string;
5
5
  env?: Record<string, string>;
6
6
  envName?: string;
7
- cwd?: string;
7
+ workingDirectory?: string;
8
8
  };
9
9
 
10
10
  export type CodeProps = { title?: string, src: string | Function, language?: string, outline?: boolean, startRe?: RegExp, endRe?: RegExp };
@@ -52,15 +52,15 @@ export class DocCommand implements CliCommandShape {
52
52
  return;
53
53
  }
54
54
 
55
- const args = process.argv.slice(2).filter(x => !/(-w|--watch)/.test(x));
55
+ const args = process.argv.slice(2).filter(arg => !/(-w|--watch)/.test(arg));
56
56
  for await (const { action, file } of watchCompiler({ restartOnExit: true })) {
57
57
  if (action === 'update' && file === this.input) {
58
- const proc = spawn('npx', ['trv', ...args], {
58
+ const subProcess = spawn('npx', ['trv', ...args], {
59
59
  cwd: Runtime.mainSourcePath,
60
60
  env: { ...process.env, ...Env.TRV_QUIET.export(true) },
61
61
  stdio: 'inherit'
62
62
  });
63
- await ExecUtil.getResult(proc, { catch: true });
63
+ await ExecUtil.getResult(subProcess, { catch: true });
64
64
  }
65
65
  }
66
66
  }
@@ -73,8 +73,8 @@ export class DocCommand implements CliCommandShape {
73
73
  [output, null] as const
74
74
  );
75
75
 
76
- for (const [fmt, out] of outputs) {
77
- const result = await ctx.render(fmt);
76
+ for (const [format, out] of outputs) {
77
+ const result = await ctx.render(format);
78
78
  if (out) {
79
79
  const finalName = path.resolve(out);
80
80
  await fs.writeFile(finalName, result, 'utf8');