@versatiles/release-tool 1.2.7 → 2.0.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/LICENSE CHANGED
@@ -1,21 +1,24 @@
1
- MIT License
1
+ This is free and unencumbered software released into the public domain.
2
2
 
3
- Copyright (c) 2024 VersaTiles
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
4
7
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
11
15
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
14
23
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
24
+ For more information, please refer to [unlicense.org](https://unlicense.org/)
package/README.md CHANGED
@@ -3,13 +3,14 @@
3
3
 
4
4
  # VersaTiles Release Tools
5
5
 
6
- Tools used internally for:
6
+ Tools used for:
7
7
 
8
- * creating Markdown documentation of TypeScript libraries: [`vrt ts2md`](#subcommand-vrt-ts2md)
9
- * creating Markdown documentation of executables: [`vrt cmd2md`](#subcommand-vrt-cmd2md)
10
- * inserting Markdown into documents: [`vrt insertmd`](#subcommand-vrt-insertmd)
11
- * updating "Table of Content" in Markdown files: [`vrt inserttoc`](#subcommand-vrt-inserttoc)
12
- * releasing the current version as npm package: [`vrt release-npm`](#subcommand-vrt-release-npm)
8
+ * creating a graph of the source code as mermaid: [`vrt deps-graph`](#subcommand-vrt-deps-graph)
9
+ * upgrading all package dependencies: [`vrt deps-upgrade`](#subcommand-vrt-deps-upgrade)
10
+ * creating Markdown documentation of executables: [`vrt doc-command`](#subcommand-vrt-doc-command)
11
+ * inserting Markdown into documents: [`vrt doc-insert`](#subcommand-vrt-doc-insert)
12
+ * updating "Table of Content" in Markdown files: [`vrt doc-toc`](#subcommand-vrt-doc-toc)
13
+ * releasing the project as npm package: [`vrt release-npm`](#subcommand-vrt-release-npm)
13
14
 
14
15
  # Installation
15
16
 
@@ -37,8 +38,6 @@ You need to configure the scripts in the package.json:
37
38
  * `scripts.prepack` is **recommended** to ensure that all files are up-to-date before releasing. Here you can build code and documentation.
38
39
  * `scripts.release` is **recommended** to make it easy to release a new version.
39
40
 
40
- Have a look at this [package.json](https://github.com/versatiles-org/node-release-tool/blob/main/package.json) as an example.
41
-
42
41
  # Command `vrt`
43
42
 
44
43
  <!--- This chapter is generated automatically --->
@@ -50,40 +49,49 @@ Usage: vrt [options] [command]
50
49
  versatiles release and documentaion tool
51
50
 
52
51
  Options:
53
- -h, --help display help for command
52
+ -h, --help display help for command
54
53
 
55
54
  Commands:
56
- ts2md <typescript> <tsconfig> documents a TypeScript file and outputs it to stdout
57
- cmd2md <command> documents a runnable command and outputs it to stdout
58
- insertmd <readme> [heading] [foldable] takes Markdown from stdin and insert it into a Markdown file
59
- inserttoc <readme> [heading] updates the TOC in a Markdown file
60
- release-npm [path] release a npm package
61
- help [command] display help for command
55
+ deps-graph draws a graph of all files in the project and outputs it as mermaid
56
+ deps-upgrade upgrades all dependencies to the latest version
57
+ doc-command <command> documents a runnable command and outputs it
58
+ doc-insert <readme> [heading] [foldable] takes Markdown from stdin and insert it into a Markdown file
59
+ doc-toc <readme> [heading] updates the TOC in a Markdown file
60
+ release-npm [path] releases a npm package
61
+ help [command] display help for command
62
62
  ```
63
63
 
64
- ## Subcommand: `vrt ts2md`
64
+ ## Subcommand: `vrt deps-graph`
65
65
 
66
66
  ```console
67
- $ vrt ts2md
68
- Usage: vrt ts2md [options] <typescript> <tsconfig>
67
+ $ vrt deps-graph
68
+ Usage: vrt deps-graph [options]
69
69
 
70
- documents a TypeScript file and outputs it to stdout
70
+ draws a graph of all files in the project and outputs it as mermaid
71
71
 
72
- Arguments:
73
- typescript Filename of the TypeScript file
74
- tsconfig Filename of tsconfig.json
72
+ Options:
73
+ -h, --help display help for command
74
+ ```
75
+
76
+ ## Subcommand: `vrt deps-upgrade`
77
+
78
+ ```console
79
+ $ vrt deps-upgrade
80
+ Usage: vrt deps-upgrade [options]
81
+
82
+ upgrades all dependencies to the latest version
75
83
 
76
84
  Options:
77
85
  -h, --help display help for command
78
86
  ```
79
87
 
80
- ## Subcommand: `vrt cmd2md`
88
+ ## Subcommand: `vrt doc-command`
81
89
 
82
90
  ```console
83
- $ vrt cmd2md
84
- Usage: vrt cmd2md [options] <command>
91
+ $ vrt doc-command
92
+ Usage: vrt doc-command [options] <command>
85
93
 
86
- documents a runnable command and outputs it to stdout
94
+ documents a runnable command and outputs it
87
95
 
88
96
  Arguments:
89
97
  command command to run
@@ -92,11 +100,11 @@ Options:
92
100
  -h, --help display help for command
93
101
  ```
94
102
 
95
- ## Subcommand: `vrt insertmd`
103
+ ## Subcommand: `vrt doc-insert`
96
104
 
97
105
  ```console
98
- $ vrt insertmd
99
- Usage: vrt insertmd [options] <readme> [heading] [foldable]
106
+ $ vrt doc-insert
107
+ Usage: vrt doc-insert [options] <readme> [heading] [foldable]
100
108
 
101
109
  takes Markdown from stdin and insert it into a Markdown file
102
110
 
@@ -109,11 +117,11 @@ Options:
109
117
  -h, --help display help for command
110
118
  ```
111
119
 
112
- ## Subcommand: `vrt inserttoc`
120
+ ## Subcommand: `vrt doc-toc`
113
121
 
114
122
  ```console
115
- $ vrt inserttoc
116
- Usage: vrt inserttoc [options] <readme> [heading]
123
+ $ vrt doc-toc
124
+ Usage: vrt doc-toc [options] <readme> [heading]
117
125
 
118
126
  updates the TOC in a Markdown file
119
127
 
@@ -131,7 +139,7 @@ Options:
131
139
  $ vrt release-npm
132
140
  Usage: vrt release-npm [options] [path]
133
141
 
134
- release a npm package
142
+ releases a npm package
135
143
 
136
144
  Arguments:
137
145
  path root path of the Node.js project
@@ -139,3 +147,44 @@ Arguments:
139
147
  Options:
140
148
  -h, --help display help for command
141
149
  ```
150
+
151
+ # Development
152
+
153
+ ## Dependency Graph
154
+
155
+ <!--- This chapter is generated automatically --->
156
+
157
+ ```mermaid
158
+ flowchart TB
159
+
160
+ subgraph 0["src"]
161
+ subgraph 1["commands"]
162
+ 2["command.ts"]
163
+ 5["dependency-graph.ts"]
164
+ 7["markdown.ts"]
165
+ 8["release.ts"]
166
+ B["upgrade-dependencies.ts"]
167
+ end
168
+ subgraph 3["lib"]
169
+ 4["utils.ts"]
170
+ 6["log.ts"]
171
+ 9["git.ts"]
172
+ A["shell.ts"]
173
+ end
174
+ C["index.ts"]
175
+ end
176
+ 2-->4
177
+ 5-->6
178
+ 7-->4
179
+ 8-->9
180
+ 8-->6
181
+ 8-->A
182
+ 9-->A
183
+ B-->6
184
+ B-->A
185
+ C-->2
186
+ C-->5
187
+ C-->7
188
+ C-->8
189
+ C-->B
190
+ ```
@@ -0,0 +1 @@
1
+ export declare function generateDependencyGraph(directory: string): Promise<void>;
@@ -0,0 +1,21 @@
1
+ import { cruise } from 'dependency-cruiser';
2
+ import { panic } from '../lib/log.js';
3
+ export async function generateDependencyGraph(directory) {
4
+ let cruiseResult;
5
+ try {
6
+ cruiseResult = await cruise([directory], {
7
+ includeOnly: '^src',
8
+ outputType: 'mermaid',
9
+ exclude: ["\\.(test|d)\\.ts$", "node_modules"],
10
+ });
11
+ }
12
+ catch (pError) {
13
+ panic(String(pError));
14
+ }
15
+ let { output } = cruiseResult;
16
+ if (typeof output !== 'string')
17
+ panic('no output');
18
+ output = output.replace('flowchart LR', 'flowchart TB');
19
+ process.stdout.write(Buffer.from('```mermaid\n' + output + '```\n'));
20
+ }
21
+ //# sourceMappingURL=dependency-graph.js.map
@@ -0,0 +1 @@
1
+ export declare function upgradeDependencies(directory: string): Promise<void>;
@@ -0,0 +1,12 @@
1
+ import { check, info } from '../lib/log.js';
2
+ import { getShell } from '../lib/shell.js';
3
+ export async function upgradeDependencies(directory) {
4
+ const shell = getShell(directory);
5
+ await check('Remove all dependencies', async () => {
6
+ await shell.run('rm -rf node_modules');
7
+ await shell.run('rm -f package-lock.json');
8
+ });
9
+ await check('Upgrade all dependencies', shell.stdout('npm update --save'));
10
+ info('All dependencies are up to date');
11
+ }
12
+ //# sourceMappingURL=upgrade-dependencies.js.map
package/dist/index.js CHANGED
@@ -1,32 +1,35 @@
1
1
  #!/usr/bin/env -S node --enable-source-maps
2
2
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
- import { generateTsMarkdownDoc } from './commands/typedoc.js';
5
4
  import { injectMarkdown, updateTOC } from './commands/markdown.js';
6
5
  import { Command, InvalidArgumentError } from 'commander';
7
6
  import { cwd } from 'node:process';
8
7
  import { generateCommandDocumentation } from './commands/command.js';
9
8
  import { release } from './commands/release.js';
9
+ import { upgradeDependencies } from './commands/upgrade-dependencies.js';
10
+ import { generateDependencyGraph } from './commands/dependency-graph.js';
10
11
  export const program = new Command();
11
12
  program
12
13
  .name('vrt')
13
14
  .description('versatiles release and documentaion tool');
14
- program.command('ts2md')
15
- .description('documents a TypeScript file and outputs it to stdout')
16
- .argument('<typescript>', 'Filename of the TypeScript file', checkFilename)
17
- .argument('<tsconfig>', 'Filename of tsconfig.json', checkFilename)
18
- .action(async (tsFilename, tsConfig) => {
19
- const mdDocumentation = await generateTsMarkdownDoc([tsFilename], tsConfig);
20
- process.stdout.write(mdDocumentation);
15
+ program.command('deps-graph')
16
+ .description('draws a graph of all files in the project and outputs it as mermaid')
17
+ .action(() => {
18
+ void generateDependencyGraph(process.cwd());
19
+ });
20
+ program.command('deps-upgrade')
21
+ .description('upgrades all dependencies to the latest version')
22
+ .action(() => {
23
+ void upgradeDependencies(process.cwd());
21
24
  });
22
- program.command('cmd2md')
23
- .description('documents a runnable command and outputs it to stdout')
25
+ program.command('doc-command')
26
+ .description('documents a runnable command and outputs it')
24
27
  .argument('<command>', 'command to run')
25
28
  .action(async (command) => {
26
29
  const mdDocumentation = await generateCommandDocumentation(command);
27
30
  process.stdout.write(mdDocumentation);
28
31
  });
29
- program.command('insertmd')
32
+ program.command('doc-insert')
30
33
  .description('takes Markdown from stdin and insert it into a Markdown file')
31
34
  .argument('<readme>', 'Markdown file, like a readme.md', checkFilename)
32
35
  .argument('[heading]', 'Heading in the Markdown file', '# API')
@@ -40,7 +43,7 @@ program.command('insertmd')
40
43
  mdFile = injectMarkdown(mdFile, mdContent, heading, foldable);
41
44
  writeFileSync(mdFilename, mdFile);
42
45
  });
43
- program.command('inserttoc')
46
+ program.command('doc-toc')
44
47
  .description('updates the TOC in a Markdown file')
45
48
  .argument('<readme>', 'Markdown file, like a readme.md', checkFilename)
46
49
  .argument('[heading]', 'Heading in the Markdown file', '# Table of Content')
@@ -50,10 +53,10 @@ program.command('inserttoc')
50
53
  writeFileSync(mdFilename, mdFile);
51
54
  });
52
55
  program.command('release-npm')
53
- .description('release a npm package')
56
+ .description('releases a npm package')
54
57
  .argument('[path]', 'root path of the Node.js project')
55
58
  .action((path) => {
56
- void release(resolve(path ?? ',', process.cwd()), 'main');
59
+ void release(resolve(path ?? '.', process.cwd()), 'main');
57
60
  });
58
61
  if (process.env.NODE_ENV !== 'test') {
59
62
  await program.parseAsync();
package/dist/lib/log.d.ts CHANGED
@@ -2,4 +2,4 @@ export declare function panic(text: string): never;
2
2
  export declare function warn(text: string): void;
3
3
  export declare function info(text: string): void;
4
4
  export declare function abort(): never;
5
- export declare function check<T>(message: string, promise: Promise<T>): Promise<T>;
5
+ export declare function check<T>(message: string, promise: (Promise<T>) | (() => Promise<T>)): Promise<T>;
package/dist/lib/log.js CHANGED
@@ -15,14 +15,14 @@ export function abort() {
15
15
  export async function check(message, promise) {
16
16
  process.stderr.write(`\x1b[0;90m\u2B95 ${message}\x1b[0m`);
17
17
  try {
18
- const result = await promise;
18
+ const result = await (typeof promise === 'function' ? promise() : promise);
19
19
  process.stderr.write(`\r\x1b[0;92m\u2714 ${message}\x1b[0m\n`);
20
20
  return result;
21
21
  }
22
22
  catch (error) {
23
23
  process.stderr.write(`\r\x1b[0;91m\u2718 ${message}\x1b[0m\n`);
24
24
  panic(error.message);
25
- throw Error();
25
+ throw error;
26
26
  }
27
27
  }
28
28
  //# sourceMappingURL=log.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/release-tool",
3
- "version": "1.2.7",
3
+ "version": "2.0.0",
4
4
  "description": "VersaTiles release and documentation tools",
5
5
  "bin": {
6
6
  "vrt": "./dist/index.js"
@@ -10,44 +10,44 @@
10
10
  "dist/**/*.d.ts"
11
11
  ],
12
12
  "scripts": {
13
- "build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/index.js",
13
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/index.js && npm run doc",
14
14
  "check": "npm run lint && npm run build && npm run test",
15
- "doc": "npx vrt cmd2md vrt | npx vrt insertmd README.md '# Command'",
15
+ "dev": "tsx src/index.ts",
16
+ "doc": "npm run doc-command && npm run doc-graph",
17
+ "doc-command": "tsx src/index.ts doc-command vrt | tsx src/index.ts doc-insert README.md '# Command'",
18
+ "doc-graph": "tsx src/index.ts deps-graph | tsx src/index.ts doc-insert README.md '## Dependency Graph'",
16
19
  "lint": "eslint . --color",
17
- "prepack": "npm run build && npm run doc",
18
- "release": "npm run build && npx vrt release-npm",
20
+ "prepack": "npm run build",
21
+ "release": "npm run build && tsx src/index.ts release-npm",
19
22
  "test-coverage": "NODE_OPTIONS=--experimental-vm-modules jest --coverage",
20
23
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
21
- "upgrade": "npm-check-updates -u && rm -f package-lock.json; rm -rf node_modules; npm i && npm update"
24
+ "upgrade": "tsx src/index.ts deps-upgrade"
22
25
  },
23
- "author": "yetzt <node@yetzt.me>, Michael Kreil <versatiles@michael-kreil.de>",
26
+ "author": "Michael Kreil <versatiles@michael-kreil.de>",
24
27
  "license": "Unlicense",
25
28
  "type": "module",
26
29
  "repository": {
27
30
  "type": "git",
28
- "url": "git+https://github.com/versatiles-org/node-versatiles.git"
31
+ "url": "git+https://github.com/versatiles-org/node-release-tool.git"
29
32
  },
30
- "homepage": "https://github.com/versatiles-org/node-versatiles/blob/main/versatiles-release-tool/README.md",
33
+ "homepage": "https://github.com/versatiles-org/node-release-tool",
31
34
  "devDependencies": {
32
- "@types/inquirer": "^9.0.7",
33
35
  "@types/jest": "^29.5.14",
34
- "@types/node": "^22.13.0",
36
+ "@types/node": "^22.13.5",
35
37
  "@typescript-eslint/eslint-plugin": "^8.22.0",
36
38
  "@typescript-eslint/parser": "^8.22.0",
37
- "eslint": "^9.19.0",
39
+ "eslint": "^9.21.0",
38
40
  "jest": "^29.7.0",
39
- "npm-check-updates": "^17.1.14",
40
41
  "ts-jest": "^29.2.5",
41
- "ts-node": "^10.9.2",
42
- "tsx": "^4.19.2",
42
+ "tsx": "^4.19.3",
43
43
  "typescript": "^5.7.3",
44
- "typescript-eslint": "^8.22.0"
44
+ "typescript-eslint": "^8.24.1"
45
45
  },
46
46
  "dependencies": {
47
- "@inquirer/select": "^4.0.7",
47
+ "@inquirer/select": "^4.0.9",
48
48
  "commander": "^13.1.0",
49
+ "dependency-cruiser": "^16.10.0",
49
50
  "remark": "^15.0.1",
50
- "remark-gfm": "^4.0.0",
51
- "typedoc": "^0.27.6"
51
+ "remark-gfm": "^4.0.1"
52
52
  }
53
53
  }
package/LICENSE.md DELETED
@@ -1,24 +0,0 @@
1
- This is free and unencumbered software released into the public domain.
2
-
3
- Anyone is free to copy, modify, publish, use, compile, sell, or
4
- distribute this software, either in source code form or as a compiled
5
- binary, for any purpose, commercial or non-commercial, and by any
6
- means.
7
-
8
- In jurisdictions that recognize copyright laws, the author or authors
9
- of this software dedicate any and all copyright interest in the
10
- software to the public domain. We make this dedication for the benefit
11
- of the public at large and to the detriment of our heirs and
12
- successors. We intend this dedication to be an overt act of
13
- relinquishment in perpetuity of all present and future rights to this
14
- software under copyright law.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- For more information, please refer to [unlicense.org](https://unlicense.org/)
@@ -1,6 +0,0 @@
1
- /**
2
- * Generate markdown documentation from TypeScript files.
3
- * @param sourceFilePaths - Array of absolute TypeScript file paths.
4
- * @param tsConfigPath - Absolute file path of tsconfig.json.
5
- */
6
- export declare function generateTsMarkdownDoc(sourceFilePaths: string[], tsConfigPath: string): Promise<string>;
@@ -1,282 +0,0 @@
1
- import { Application, ReflectionKind, } from 'typedoc';
2
- /**
3
- * Generate markdown documentation from TypeScript files.
4
- * @param sourceFilePaths - Array of absolute TypeScript file paths.
5
- * @param tsConfigPath - Absolute file path of tsconfig.json.
6
- */
7
- export async function generateTsMarkdownDoc(sourceFilePaths, tsConfigPath) {
8
- const app = await Application.bootstrap({ entryPoints: sourceFilePaths, tsconfig: tsConfigPath });
9
- const project = await app.convert();
10
- if (!project) {
11
- throw new Error('Failed to convert TypeScript project.');
12
- }
13
- return Array.from(documentProject(project)).join('\n');
14
- }
15
- function* documentProject(project) {
16
- if (!project.groups) {
17
- throw new Error('No TypeScript code to document found! Is this a lib?');
18
- }
19
- for (const group of project.groups) {
20
- yield '\n# ' + group.title;
21
- for (const d of group.children) {
22
- const declaration = d;
23
- switch (declaration.kind) {
24
- case ReflectionKind.Class:
25
- yield* documentClass(declaration);
26
- break;
27
- case ReflectionKind.Function:
28
- yield* documentMethod(declaration, 2);
29
- break;
30
- case ReflectionKind.Interface:
31
- yield* documentInterface(declaration);
32
- break;
33
- case ReflectionKind.TypeAlias:
34
- yield* documentType(declaration);
35
- break;
36
- case ReflectionKind.Variable:
37
- yield* documentVariable(declaration);
38
- break;
39
- default:
40
- throw new Error('implement ' + declaration.kind);
41
- }
42
- }
43
- }
44
- }
45
- function* documentInterface(declaration) {
46
- yield `\n## Interface: \`${declaration.name}\`<a id="${createAnchorId(declaration)}"></a>`;
47
- yield '\n```typescript';
48
- yield 'interface {';
49
- for (const child of declaration.children ?? []) {
50
- if (child.kind !== ReflectionKind.Property)
51
- throw Error('should be a property inside an interface');
52
- if (child.type == null)
53
- throw Error('should have a type');
54
- const name = child.name + (child.flags.isOptional ? '?' : '');
55
- yield ` ${name}: ${formatTypeDeclaration(child.type)};`;
56
- }
57
- yield '}';
58
- yield '```';
59
- }
60
- function* documentType(declaration) {
61
- yield `\n## Type: \`${declaration.name}\`<a id="${createAnchorId(declaration)}"></a>`;
62
- if (declaration.type) {
63
- yield `\n**Type:** <code>${formatTypeDeclaration(declaration.type)}</code>`;
64
- }
65
- }
66
- function* documentClass(declaration) {
67
- yield `\n## Class: \`${declaration.name}\`<a id="${createAnchorId(declaration)}"></a>`;
68
- yield* documentSummaryBlock(declaration);
69
- for (const group of declaration.groups ?? []) {
70
- const publicMembers = group.children.filter(member => !member.flags.isPrivate && !member.flags.isProtected);
71
- if (publicMembers.length === 0)
72
- continue;
73
- // Sort by order in code
74
- publicMembers.sort((a, b) => a.id - b.id);
75
- switch (group.title) {
76
- case 'Constructors':
77
- if (publicMembers.length !== 1)
78
- throw Error('publicMembers.length !== 1');
79
- yield* documentMethod(publicMembers[0], 3, true);
80
- continue;
81
- case 'Accessors':
82
- yield '\n### Accessors';
83
- for (const member of publicMembers)
84
- yield documentAccessor(member);
85
- continue;
86
- case 'Properties':
87
- yield '\n### Properties';
88
- for (const member of publicMembers)
89
- yield documentProperty(member);
90
- continue;
91
- case 'Methods':
92
- for (const member of publicMembers)
93
- yield* documentMethod(member, 3);
94
- continue;
95
- default:
96
- console.log(group);
97
- throw Error('Unknown group title');
98
- }
99
- }
100
- }
101
- function* documentMethod(method, depth, isConstructor = false) {
102
- if (method.signatures?.length !== 1)
103
- throw Error('should be 1');
104
- const [signature] = method.signatures;
105
- const parameters = formatMethodParameters(signature.parameters ?? []);
106
- if (isConstructor) {
107
- yield `\n${'#'.repeat(depth)} Constructor: \`new ${signature.name}(${parameters})\``;
108
- }
109
- else {
110
- yield `\n${'#'.repeat(depth)} Method: \`${signature.name}(${parameters})\``;
111
- }
112
- yield* documentSummaryBlock(signature);
113
- if (signature.parameters && signature.parameters.length > 0) {
114
- yield '';
115
- yield '**Parameters:**';
116
- for (const parameter of signature.parameters) {
117
- yield documentProperty(parameter);
118
- }
119
- }
120
- if (signature.type && !isConstructor) {
121
- yield `\n**Returns:** <code>${formatTypeDeclaration(signature.type)}</code>`;
122
- }
123
- }
124
- function formatMethodParameters(parameters) {
125
- return parameters.map(param => param.name).join(', ');
126
- }
127
- // Helper Functions
128
- function getDeclarationKindName(kind) {
129
- switch (kind) {
130
- case ReflectionKind.Class: return 'Class';
131
- case ReflectionKind.Function: return 'Function';
132
- case ReflectionKind.Interface: return 'Interface';
133
- case ReflectionKind.TypeAlias: return 'Type';
134
- case ReflectionKind.Variable: return 'Variable';
135
- default: throw new Error(`Unknown reflection kind: ${kind}`);
136
- }
137
- }
138
- function documentProperty(ref) {
139
- let line = ` - <code>${ref.name}${resolveTypeDeclaration(ref.type)}</code>`;
140
- if (ref.flags.isOptional)
141
- line += ' (optional)';
142
- const summary = extractSummary(ref.comment);
143
- if (summary != null)
144
- line += ' \n ' + summary;
145
- return line;
146
- }
147
- function* documentVariable(ref) {
148
- const prefix = ref.flags.isConst ? 'const' : 'let';
149
- yield `\n## \`${prefix} ${ref.name}\``;
150
- const summary = extractSummary(ref.comment);
151
- if (summary != null)
152
- yield summary;
153
- }
154
- function documentAccessor(ref) {
155
- let line = ` - <code>${ref.name}${resolveTypeDeclaration(ref.type)}</code>`;
156
- const summary = extractSummary(ref.comment);
157
- if (summary != null)
158
- line += ' \n ' + summary;
159
- return line;
160
- }
161
- function extractSummary(comment) {
162
- if (!comment)
163
- return null;
164
- return comment.summary.map(line => line.text).join('');
165
- }
166
- function* documentSummaryBlock(ref) {
167
- yield '';
168
- if (ref.comment) {
169
- yield formatComment(ref.comment);
170
- return;
171
- }
172
- const { type } = ref;
173
- if (type?.type === 'reflection') {
174
- if (type.declaration.signatures?.length !== 1)
175
- throw Error('type.declaration.signatures?.length !== 1');
176
- const [signature] = type.declaration.signatures;
177
- if (signature.comment) {
178
- yield formatComment(signature.comment);
179
- return;
180
- }
181
- }
182
- const sourceLink = createSourceLink(ref);
183
- if (sourceLink != null)
184
- yield sourceLink;
185
- return;
186
- function formatComment(comment) {
187
- let summary = extractSummary(comment) ?? '';
188
- const link = createSourceLink(ref);
189
- if (link != null)
190
- summary += ' ' + link;
191
- return summary.replace(/\n/mg, ' \n') + '\n';
192
- }
193
- }
194
- function resolveTypeDeclaration(someType) {
195
- if (!someType)
196
- return '';
197
- return `: ${formatTypeDeclaration(someType)}`;
198
- }
199
- function formatTypeDeclaration(someType) {
200
- return getTypeRec(someType);
201
- function getTypeRec(some) {
202
- switch (some.type) {
203
- case 'intrinsic':
204
- return some.name;
205
- case 'literal':
206
- return JSON.stringify(some.value);
207
- case 'reference': {
208
- let result = some.name;
209
- if (some.reflection)
210
- result = `[${result}](#${createAnchorId(some.reflection)})`;
211
- if (some.typeArguments?.length ?? 0)
212
- result += '&lt;'
213
- + (some.typeArguments ?? [])
214
- .map(getTypeRec).join(',')
215
- + '&gt;';
216
- return result;
217
- }
218
- case 'reflection':
219
- switch (some.declaration.kind) {
220
- case ReflectionKind.TypeLiteral: return decodeReflectionTypeLiteral(some.declaration);
221
- default:
222
- console.log('declarationKindName', getDeclarationKindName(some.declaration.kind));
223
- console.dir(some, { depth: 4 });
224
- throw Error();
225
- }
226
- case 'tuple':
227
- return `[${some.elements.map(getTypeRec).join(', ')}]`;
228
- case 'union':
229
- return some.types.map(getTypeRec).join(' | ');
230
- case 'array':
231
- return getTypeRec(some.elementType) + '[]';
232
- default:
233
- console.log(some);
234
- throw Error(some.type);
235
- }
236
- function decodeReflectionTypeLiteral(ref) {
237
- try {
238
- if (ref.variant !== 'declaration')
239
- throw Error();
240
- if (ref.groups && !ref.signatures) {
241
- if (!Array.isArray(ref.groups))
242
- throw Error();
243
- if (ref.groups.length !== 1)
244
- throw Error();
245
- const [group] = ref.groups;
246
- if (group.title !== 'Properties')
247
- throw Error();
248
- const properties = group.children.map(r => r.escapedName + ':?');
249
- return `{${properties.join(', ')}}`;
250
- }
251
- if (!ref.groups && ref.signatures) {
252
- if (ref.signatures.length !== 1)
253
- throw Error('ref.signatures.length !== 1');
254
- const [signature] = ref.signatures;
255
- const returnType = signature.type ? getTypeRec(signature.type) : 'void';
256
- const parameters = (signature.parameters ?? [])
257
- .map(p => {
258
- return p.name + (p.type ? ': ' + getTypeRec(p.type) : '');
259
- }).join(', ');
260
- return `(${parameters}) => ${returnType}`;
261
- }
262
- throw Error();
263
- }
264
- catch (error) {
265
- console.dir(ref, { depth: 3 });
266
- throw error;
267
- }
268
- }
269
- }
270
- }
271
- function createSourceLink(reference) {
272
- if (!reference.sources || reference.sources.length < 1)
273
- return null;
274
- if (reference.sources.length > 1)
275
- throw Error('ref.sources.length > 1');
276
- const [source] = reference.sources;
277
- return `<sup><a href="${source.url}">[src]</a></sup>`;
278
- }
279
- function createAnchorId(reference) {
280
- return `${getDeclarationKindName(reference.kind)}_${reference.name}`.toLowerCase();
281
- }
282
- //# sourceMappingURL=typedoc.js.map