@travetto/doc 7.1.4 → 8.0.0-alpha.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/doc",
3
- "version": "7.1.4",
3
+ "version": "8.0.0-alpha.0",
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.1.4",
28
- "@types/prismjs": "^1.26.5",
27
+ "@travetto/runtime": "^8.0.0-alpha.0",
28
+ "@types/prismjs": "^1.26.6",
29
29
  "prismjs": "^1.30.0"
30
30
  },
31
31
  "peerDependencies": {
32
- "@travetto/cli": "^7.1.4"
32
+ "@travetto/cli": "^8.0.0-alpha.0"
33
33
  },
34
34
  "peerDependenciesMeta": {
35
35
  "@travetto/cli": {
package/src/jsx.ts CHANGED
@@ -2,7 +2,7 @@ import { castTo, TypedObject } from '@travetto/runtime';
2
2
 
3
3
  import type { LIBRARIES } from './mapping/library.ts';
4
4
  import type { MODULES } from './mapping/module.ts';
5
- import type { CodeProps, RunConfig } from './util/types.ts';
5
+ import type { CodeProps, CodeSourceInput, RunConfig } from './util/types.ts';
6
6
 
7
7
  import { createElement, type JSXElement, type JSXComponentFunction as CompFn } from '../support/jsx-runtime.ts';
8
8
  import { PackageDocUtil } from './util/package.ts';
@@ -14,7 +14,7 @@ type HeaderProps = { title: string, description?: string };
14
14
  type ModuleProps = { name: keyof typeof MODULES };
15
15
  type LibraryProps = { name: keyof typeof LIBRARIES };
16
16
  type LinkProps = { title: string, href: string, line?: number };
17
- type CodeLinkProps = { title: string, src: string | Function, startRe: RegExp };
17
+ type CodeLinkProps = { title: string, src: CodeSourceInput, startRe: RegExp };
18
18
  type Named = { name: string };
19
19
  type Titled = { title: string };
20
20
 
@@ -83,7 +83,7 @@ function CodeLinker(titleOrNode: string | JSXElement, src?: string, startRe?: Re
83
83
  props = { title: titleOrNode, src: src!, startRe: startRe! };
84
84
  } else if (titleOrNode.type === Code) {
85
85
  const node: JSXElementByFn<'Code'> = castTo(titleOrNode);
86
- const srcName = typeof node.props.src === 'string' ? node.props.src : node.props.src.name;
86
+ const srcName = typeof node.props.src === 'string' ? node.props.src : (typeof node.props.src === 'function' ? node.props.src.name : '<UNNAMED>');
87
87
  props = {
88
88
  title: node.props.title ?? srcName,
89
89
  src: node.props.src,
@@ -45,10 +45,10 @@ export class DocRenderer {
45
45
  ) {
46
46
  const source = DocFileUtil.readSource(cls);
47
47
  if (source) {
48
- title = (await DocFileUtil.isDecorator(cls.name, source.file)) ? `@${title ?? cls.name}` : (title ?? cls.name);
48
+ title = DocFileUtil.isDecorator(cls.name, source.file) ? `@${title ?? cls.name}` : (title ?? cls.name);
49
49
  const node = this.#support.createElement('CodeLink', {
50
50
  src: source.file,
51
- startRe: new RegExp(`(class|function|interface)\\s+(${cls.name.replaceAll('$', '\\$')})`),
51
+ startRe: new RegExp(`(class|function|interface)\\s+(${RegExp.escape(cls.name)})`),
52
52
  title
53
53
  });
54
54
  // @ts-expect-error
package/src/util/file.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { readFileSync, existsSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
- import { AppError, Runtime, RuntimeIndex } from '@travetto/runtime';
4
+ import { RuntimeError, Runtime, RuntimeIndex } from '@travetto/runtime';
5
5
  import { type ManifestModuleFileType, ManifestModuleUtil } from '@travetto/manifest';
6
6
 
7
+ import type { CodeSourceInput } from './types.ts';
8
+
7
9
  const ESLINT_PATTERN = /\s{0,10}\/\/ eslint.{0,300}$/g;
8
10
  const ENV_KEY = /Env.([^.]{1,100})[.]key/g;
9
11
 
@@ -24,6 +26,9 @@ const EXT_TO_LANG: Record<string, string> = {
24
26
  '.sh': 'bash',
25
27
  };
26
28
 
29
+ type SourceOutput = { content: string, language: string, file: string };
30
+ type SnippetOutput = { file: string, startIdx: number, lines: string[], language: string };
31
+
27
32
  /**
28
33
  * Standard file utilities
29
34
  */
@@ -35,7 +40,7 @@ export class DocFileUtil {
35
40
  return /^[@:A-Za-z0-9\/\\\-_.]+[.]([a-z]{2,10})$/.test(file);
36
41
  }
37
42
 
38
- static readSource(input: string | Function): { content: string, language: string, file: string } {
43
+ static readSource(input: Exclude<CodeSourceInput, Promise<string>>): SourceOutput {
39
44
  let file: string | undefined;
40
45
  let content: string | undefined;
41
46
 
@@ -55,7 +60,7 @@ export class DocFileUtil {
55
60
  } else {
56
61
  file = Runtime.getSourceFile(input);
57
62
  if (!existsSync(file)) {
58
- throw new AppError(`Unknown file: ${typeof input === 'string' ? input : input.name} => ${file}`);
63
+ throw new RuntimeError(`Unknown file: ${typeof input === 'string' ? input : input.name} => ${file}`);
59
64
  }
60
65
  content = readFileSync(file, 'utf8');
61
66
  }
@@ -83,8 +88,8 @@ export class DocFileUtil {
83
88
  }
84
89
  }
85
90
 
86
- static async readCodeSnippet(input: string | Function, startPattern: RegExp): Promise<{ file: string, startIdx: number, lines: string[], language: string }> {
87
- const result = this.readSource(input);
91
+ static async readCodeSnippet(input: CodeSourceInput, startPattern: RegExp): Promise<SnippetOutput> {
92
+ const result = this.readSource(await input);
88
93
  const lines = result.content.split(/\n/);
89
94
  const startIdx = lines.findIndex(line => startPattern.test(line));
90
95
  if (startIdx < 0) {
@@ -96,14 +101,14 @@ export class DocFileUtil {
96
101
  /**
97
102
  * Determine if a file is a decorator
98
103
  */
99
- static async isDecorator(name: string, file: string): Promise<boolean> {
104
+ static isDecorator(name: string, file: string): boolean {
100
105
 
101
106
  const key = `${name}:${file}`;
102
107
  if (key in this.#decCache) {
103
108
  return this.#decCache[key];
104
109
  }
105
110
 
106
- const text = await this.readSource(file);
111
+ const text = this.readSource(file);
107
112
  const lines = text.content.split(/\n/g);
108
113
 
109
114
  const start = lines.findIndex(line => new RegExp(`function ${name}\\b`).test(line));
@@ -1,5 +1,5 @@
1
1
  import { DocFileUtil } from './file.ts';
2
- import type { CodeProps } from './types.ts';
2
+ import type { CodeProps, CodeSourceInput } from './types.ts';
3
3
 
4
4
  export type ResolvedRef = { title: string, file: string, line: number };
5
5
  export type ResolvedCode = { text: string, language: string, file?: string };
@@ -14,26 +14,26 @@ export class DocResolveUtil {
14
14
  static async resolveRef(title: string, file: string): Promise<ResolvedRef> {
15
15
 
16
16
  let line = 0;
17
- const result = await DocFileUtil.readSource(file);
17
+ const result = DocFileUtil.readSource(file);
18
18
  file = result.file;
19
19
 
20
20
  if (result.content) {
21
21
  line = result.content.split(/\n/g)
22
- .findIndex(lineText => new RegExp(`(class|interface|function)[ ]+${title.replaceAll('$', '\\$')}`).test(lineText));
22
+ .findIndex(lineText => new RegExp(`(class|interface|function)[ ]+${RegExp.escape(title)}`).test(lineText));
23
23
  if (line < 0) {
24
24
  line = 0;
25
25
  } else {
26
26
  line += 1;
27
27
  }
28
- if (await DocFileUtil.isDecorator(title, file)) {
28
+ if (DocFileUtil.isDecorator(title, file)) {
29
29
  title = `@${title}`;
30
30
  }
31
31
  }
32
32
  return { title, file, line };
33
33
  }
34
34
 
35
- static async resolveCode(content: string | Function, language?: string, outline = false): Promise<ResolvedCode> {
36
- const result = DocFileUtil.readSource(content);
35
+ static async resolveCode(content: CodeSourceInput, language?: string, outline = false): Promise<ResolvedCode> {
36
+ const result = DocFileUtil.readSource(await content);
37
37
  let text = result.content;
38
38
 
39
39
  let file: string | undefined;
@@ -47,7 +47,7 @@ export class DocResolveUtil {
47
47
  return { text, language: language!, file };
48
48
  }
49
49
 
50
- static async resolveSnippet(file: Function | string, startPattern: RegExp, endPattern?: RegExp, outline = false): Promise<ResolvedSnippet> {
50
+ static async resolveSnippet(file: CodeSourceInput, startPattern: RegExp, endPattern?: RegExp, outline = false): Promise<ResolvedSnippet> {
51
51
  const { lines, startIdx, language, file: resolvedFile } = await DocFileUtil.readCodeSnippet(file, startPattern);
52
52
 
53
53
  const endIdx = endPattern ? lines.findIndex((line, i) => i > startIdx && endPattern.test(line)) : lines.length;
@@ -60,14 +60,14 @@ export class DocResolveUtil {
60
60
  return { text, language, line: startIdx + 1, file: resolvedFile };
61
61
  }
62
62
 
63
- static async resolveCodeLink(file: Function | string, startPattern: RegExp): Promise<ResolvedSnippetLink> {
63
+ static async resolveCodeLink(file: CodeSourceInput, startPattern: RegExp): Promise<ResolvedSnippetLink> {
64
64
  const { startIdx, file: resolvedFile } = await DocFileUtil.readCodeSnippet(file, startPattern);
65
65
  return { file: resolvedFile, line: startIdx + 1 };
66
66
  }
67
67
 
68
- static applyCodePropDefaults(props: CodeProps) {
68
+ static applyCodePropDefaults(props: CodeProps): void {
69
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);
70
+ props.startRe ??= (type ? new RegExp(`^(export)?\\s*(interface|class)\\s+${RegExp.escape(type.name)}\\b`) : undefined);
71
71
  props.language ??= (type ? 'typescript' : undefined);
72
72
  props.endRe ??= (type ? /^[}]/ : undefined);
73
73
  props.title ??= typeof props.src == 'function' ? props.src.name.replace(/^[$]/, '') : undefined;
package/src/util/run.ts CHANGED
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import { Env, ExecUtil, Runtime, RuntimeIndex } from '@travetto/runtime';
7
7
  import type { RunConfig } from './types.ts';
8
8
 
9
- export const COMMON_DATE = new Date('2029-03-14T00:00:00.000').getTime();
9
+ export const COMMON_DATE = new Date('2029-03-14T00:00:00.000-0400').getTime();
10
10
 
11
11
  class DocState {
12
12
  baseline = COMMON_DATE;
package/src/util/types.ts CHANGED
@@ -9,4 +9,6 @@ export type RunConfig = {
9
9
  spawn?: (cmd: string, args: string[], options: SpawnOptions) => ChildProcess;
10
10
  };
11
11
 
12
- export type CodeProps = { title?: string, src: string | Function, language?: string, outline?: boolean, startRe?: RegExp, endRe?: RegExp };
12
+ export type CodeSourceInput = string | Promise<string> | Function;
13
+
14
+ export type CodeProps = { title?: string, src: CodeSourceInput, language?: string, outline?: boolean, startRe?: RegExp, endRe?: RegExp };