@versatiles/release-tool 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,19 +46,34 @@ You need to configure the scripts in the package.json:
46
46
  $ vrt
47
47
  Usage: vrt [options] [command]
48
48
 
49
- versatiles release and documentaion tool
49
+ CLI tool for releasing packages and generating documentation for
50
+ Node.js/TypeScript projects.
50
51
 
51
52
  Options:
52
53
  -h, --help display help for command
53
54
 
54
55
  Commands:
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
56
+ check-package Check package.json for required scripts and other metadata.
57
+ deps-graph Analyze project files and output a dependency graph as Mermaid markup.
58
+ deps-upgrade Upgrade all dependencies in the current project to their latest versions.
59
+ doc-command <command> Generate Markdown documentation for a specified command and output the result.
60
+ doc-insert <readme> [heading] [foldable] Insert Markdown from stdin into a specified section of a Markdown file.
61
+ doc-toc <readme> [heading] Generate a Table of Contents (TOC) in a Markdown file.
62
+ doc-typescript [options] Generate documentation for a TypeScript project.
61
63
  help [command] display help for command
64
+ release-npm [path] Publish an npm package from the specified path to the npm registry.
65
+ ```
66
+
67
+ ## Subcommand: `vrt check-package`
68
+
69
+ ```console
70
+ $ vrt check-package
71
+ Usage: vrt check-package [options]
72
+
73
+ Check package.json for required scripts and other metadata.
74
+
75
+ Options:
76
+ -h, --help display help for command
62
77
  ```
63
78
 
64
79
  ## Subcommand: `vrt deps-graph`
@@ -67,7 +82,7 @@ Commands:
67
82
  $ vrt deps-graph
68
83
  Usage: vrt deps-graph [options]
69
84
 
70
- draws a graph of all files in the project and outputs it as mermaid
85
+ Analyze project files and output a dependency graph as Mermaid markup.
71
86
 
72
87
  Options:
73
88
  -h, --help display help for command
@@ -79,7 +94,7 @@ Options:
79
94
  $ vrt deps-upgrade
80
95
  Usage: vrt deps-upgrade [options]
81
96
 
82
- upgrades all dependencies to the latest version
97
+ Upgrade all dependencies in the current project to their latest versions.
83
98
 
84
99
  Options:
85
100
  -h, --help display help for command
@@ -91,10 +106,10 @@ Options:
91
106
  $ vrt doc-command
92
107
  Usage: vrt doc-command [options] <command>
93
108
 
94
- documents a runnable command and outputs it
109
+ Generate Markdown documentation for a specified command and output the result.
95
110
 
96
111
  Arguments:
97
- command command to run
112
+ command Command to document (e.g., "npm run build").
98
113
 
99
114
  Options:
100
115
  -h, --help display help for command
@@ -106,12 +121,14 @@ Options:
106
121
  $ vrt doc-insert
107
122
  Usage: vrt doc-insert [options] <readme> [heading] [foldable]
108
123
 
109
- takes Markdown from stdin and insert it into a Markdown file
124
+ Insert Markdown from stdin into a specified section of a Markdown file.
110
125
 
111
126
  Arguments:
112
- readme Markdown file, like a readme.md
113
- heading Heading in the Markdown file (default: "# API")
114
- foldable Make content foldable (default: false)
127
+ readme Path to the target Markdown file (e.g., README.md).
128
+ heading Heading in the Markdown file where content should be placed.
129
+ Default is "# API". (default: "# API")
130
+ foldable Whether to wrap the inserted content in a foldable section.
131
+ (default: false)
115
132
 
116
133
  Options:
117
134
  -h, --help display help for command
@@ -123,26 +140,44 @@ Options:
123
140
  $ vrt doc-toc
124
141
  Usage: vrt doc-toc [options] <readme> [heading]
125
142
 
126
- updates the TOC in a Markdown file
143
+ Generate a Table of Contents (TOC) in a Markdown file.
127
144
 
128
145
  Arguments:
129
- readme Markdown file, like a readme.md
130
- heading Heading in the Markdown file (default: "# Table of Content")
146
+ readme Path to the Markdown file (e.g., README.md).
147
+ heading Heading in the Markdown file where TOC should be inserted. Default
148
+ is "# Table of Content". (default: "# Table of Content")
131
149
 
132
150
  Options:
133
151
  -h, --help display help for command
134
152
  ```
135
153
 
154
+ ## Subcommand: `vrt doc-typescript`
155
+
156
+ ```console
157
+ $ vrt doc-typescript
158
+ Usage: vrt doc-typescript [options]
159
+
160
+ Generate documentation for a TypeScript project.
161
+
162
+ Options:
163
+ -h, --help display help for command
164
+ -i <entryPoint> Entry point of the TypeScript project. Default is
165
+ "./src/index.ts".
166
+ -o <outputPath> Output path for the generated documentation. Default is
167
+ "./docs".
168
+ ```
169
+
136
170
  ## Subcommand: `vrt release-npm`
137
171
 
138
172
  ```console
139
173
  $ vrt release-npm
140
174
  Usage: vrt release-npm [options] [path]
141
175
 
142
- releases a npm package
176
+ Publish an npm package from the specified path to the npm registry.
143
177
 
144
178
  Arguments:
145
- path root path of the Node.js project
179
+ path Root path of the Node.js project. Defaults to the current
180
+ directory.
146
181
 
147
182
  Options:
148
183
  -h, --help display help for command
@@ -159,32 +194,38 @@ flowchart TB
159
194
 
160
195
  subgraph 0["src"]
161
196
  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"]
197
+ 2["check-package.ts"]
198
+ 5["deps-graph.ts"]
199
+ 6["deps-upgrade.ts"]
200
+ 8["doc-command.ts"]
201
+ A["doc-typescript.ts"]
202
+ B["markdown.ts"]
203
+ C["release-npm.ts"]
167
204
  end
168
205
  subgraph 3["lib"]
169
- 4["utils.ts"]
170
- 6["log.ts"]
171
- 9["git.ts"]
172
- A["shell.ts"]
206
+ 4["log.ts"]
207
+ 7["shell.ts"]
208
+ 9["utils.ts"]
209
+ D["git.ts"]
173
210
  end
174
- C["index.ts"]
211
+ E["index.ts"]
175
212
  end
176
213
  2-->4
177
- 5-->6
178
- 7-->4
214
+ 5-->4
215
+ 6-->4
216
+ 6-->7
179
217
  8-->9
180
- 8-->6
181
- 8-->A
182
- 9-->A
183
- B-->6
184
- B-->A
185
- C-->2
186
- C-->5
218
+ A-->4
219
+ B-->9
220
+ C-->D
221
+ C-->4
187
222
  C-->7
188
- C-->8
189
- C-->B
223
+ D-->7
224
+ E-->2
225
+ E-->5
226
+ E-->6
227
+ E-->8
228
+ E-->A
229
+ E-->B
230
+ E-->C
190
231
  ```
@@ -0,0 +1 @@
1
+ export declare function checkPackage(directory: string): void;
@@ -0,0 +1,53 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { panic, info, warn } from '../lib/log.js';
3
+ import { resolve } from 'node:path';
4
+ export function checkPackage(directory) {
5
+ const pack = JSON.parse(readFileSync(resolve(directory, 'package.json'), 'utf8'));
6
+ const { scripts } = pack;
7
+ if (!scripts)
8
+ panic('scripts not found');
9
+ if (!scripts.test)
10
+ info('scripts.test is recommended');
11
+ if (!scripts.doc)
12
+ info('scripts.doc is recommended');
13
+ if (!scripts.build)
14
+ panic('scripts.build is required');
15
+ if (!scripts.check)
16
+ panic('scripts.check is required');
17
+ if (!scripts.check.includes('npm run build')) {
18
+ warn(`scripts.check should include "npm run build", but is "${scripts.check}"`);
19
+ }
20
+ if (!scripts.prepack)
21
+ panic('scripts.prepack is required');
22
+ if (scripts.prepack !== 'npm run build') {
23
+ warn(`scripts.prepack should be "npm run build", but is "${scripts.prepack}"`);
24
+ }
25
+ if (!scripts.release)
26
+ panic('scripts.release is required');
27
+ if (scripts.release !== 'vrt release-npm') {
28
+ warn(`scripts.release should be "vrt release-npm", but is "${scripts.release}"`);
29
+ }
30
+ if (!scripts.upgrade) {
31
+ warn('scripts.upgrade is recommended');
32
+ }
33
+ else if (scripts.upgrade !== 'vrt deps-upgrade') {
34
+ info(`scripts.upgrade should be "vrt deps-upgrade", but is "${scripts.upgrade}"`);
35
+ }
36
+ if (!scripts['doc-graph']) {
37
+ info(`scripts.doc-graph could be: "vrt deps-graph | vrt doc-insert README.md '## Dependency Graph'"`);
38
+ }
39
+ else {
40
+ if (scripts.doc && !scripts.doc.includes('npm run doc-graph')) {
41
+ info('scripts.doc should include "npm run doc-graph"');
42
+ }
43
+ }
44
+ ['npm-check-updates'].forEach((dep) => {
45
+ if (pack.dependencies?.[dep]) {
46
+ info(`dependencies "${dep}" is probably not needed`);
47
+ }
48
+ if (pack.devDependencies?.[dep]) {
49
+ info(`devDependencies "${dep}" is probably not needed`);
50
+ }
51
+ });
52
+ }
53
+ //# sourceMappingURL=check-package.js.map
@@ -18,4 +18,4 @@ export async function generateDependencyGraph(directory) {
18
18
  output = output.replace('flowchart LR', 'flowchart TB');
19
19
  process.stdout.write(Buffer.from('```mermaid\n' + output + '```\n'));
20
20
  }
21
- //# sourceMappingURL=dependency-graph.js.map
21
+ //# sourceMappingURL=deps-graph.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Upgrades the dependencies in a package.json file to their latest versions, removes existing
3
+ * installed modules, and reinstalls them in the specified directory.
4
+ *
5
+ * This function performs the following steps:
6
+ * 1. Checks for outdated dependencies by running `npm outdated --all --json`.
7
+ * 2. Reads the project's package.json file and updates any existing dependencies to their latest versions.
8
+ * 3. Removes all installed modules (`node_modules`) and the lock file (`package-lock.json`).
9
+ * 4. Reinstalls and updates all dependencies.
10
+ * 5. Logs a message indicating that all dependencies are up to date.
11
+ *
12
+ * @param directory - The path to the directory containing the Node.js project.
13
+ * @returns A promise that resolves when the process is complete.
14
+ */
15
+ export declare function upgradeDependencies(directory: string): Promise<void>;
@@ -0,0 +1,97 @@
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import { check, info } from '../lib/log.js';
3
+ import { getShell } from '../lib/shell.js';
4
+ /**
5
+ * Upgrades the dependencies in a package.json file to their latest versions, removes existing
6
+ * installed modules, and reinstalls them in the specified directory.
7
+ *
8
+ * This function performs the following steps:
9
+ * 1. Checks for outdated dependencies by running `npm outdated --all --json`.
10
+ * 2. Reads the project's package.json file and updates any existing dependencies to their latest versions.
11
+ * 3. Removes all installed modules (`node_modules`) and the lock file (`package-lock.json`).
12
+ * 4. Reinstalls and updates all dependencies.
13
+ * 5. Logs a message indicating that all dependencies are up to date.
14
+ *
15
+ * @param directory - The path to the directory containing the Node.js project.
16
+ * @returns A promise that resolves when the process is complete.
17
+ */
18
+ export async function upgradeDependencies(directory) {
19
+ const shell = getShell(directory);
20
+ // Step 1: Check and upgrade all versions
21
+ await check('Upgrade all versions', async () => {
22
+ const { stdout } = await shell.run('npm outdated --all --json', false);
23
+ const outdated = JSON.parse(stdout);
24
+ const latestVersion = new Map();
25
+ // Collect the latest version for each dependency
26
+ for (const [name, entry] of Object.entries(outdated)) {
27
+ let version = '0.0.0';
28
+ if (Array.isArray(entry)) {
29
+ for (const item of entry) {
30
+ if (isGreaterSemver(item.latest, version))
31
+ version = item.latest;
32
+ }
33
+ }
34
+ else {
35
+ version = entry.latest;
36
+ }
37
+ latestVersion.set(name, version);
38
+ }
39
+ // Load package.json
40
+ const pack = JSON.parse(readFileSync('package.json', 'utf8'));
41
+ // Update dependencies to their latest versions
42
+ patch(pack.dependencies);
43
+ patch(pack.devDependencies);
44
+ patch(pack.optionalDependencies);
45
+ patch(pack.peerDependencies);
46
+ // Write the updated package.json
47
+ writeFileSync('package.json', JSON.stringify(pack, null, 2) + '\n');
48
+ /**
49
+ * Mutates the provided dependency object by updating
50
+ * each dependency to the latest known version (if available).
51
+ *
52
+ * @param dependencies - A mapping of dependency names to their currently specified versions.
53
+ */
54
+ function patch(dependencies) {
55
+ if (!dependencies)
56
+ return;
57
+ for (const name of Object.keys(dependencies)) {
58
+ dependencies[name] = latestVersion.get(name) ?? dependencies[name];
59
+ }
60
+ }
61
+ });
62
+ // Step 2: Remove existing dependencies and lock file
63
+ await check('Remove all dependencies', async () => {
64
+ await shell.run('rm -rf node_modules');
65
+ await shell.run('rm -f package-lock.json');
66
+ });
67
+ // Step 3: Reinstall/upgrade all dependencies
68
+ await check('Upgrade all dependencies', shell.stdout('npm update --save'));
69
+ // Final log message
70
+ info('All dependencies are up to date');
71
+ }
72
+ /**
73
+ * Compares two semantic version strings (major.minor.patch) and checks if `a` is greater than `b`.
74
+ *
75
+ * @param a - A semantic version string (e.g., "1.2.3").
76
+ * @param b - Another semantic version string (e.g., "1.2.4").
77
+ * @returns `true` if `a` is greater than `b`, otherwise `false`.
78
+ * @throws If either version string is invalid (i.e., not in "x.x.x" format).
79
+ */
80
+ function isGreaterSemver(a, b) {
81
+ const pa = a.split('.');
82
+ const pb = b.split('.');
83
+ for (let i = 0; i < 3; i++) {
84
+ const na = Number(pa[i]);
85
+ const nb = Number(pb[i]);
86
+ if (isNaN(na))
87
+ throw new Error('Invalid version number: ' + a);
88
+ if (isNaN(nb))
89
+ throw new Error('Invalid version number: ' + b);
90
+ if (na > nb)
91
+ return true;
92
+ if (na < nb)
93
+ return false;
94
+ }
95
+ return false;
96
+ }
97
+ //# sourceMappingURL=deps-upgrade.js.map
@@ -31,7 +31,13 @@ export async function generateCommandDocumentation(command) {
31
31
  */
32
32
  async function getCommandResults(command) {
33
33
  return new Promise((resolve, reject) => {
34
- const env = { ...process.env, NODE_ENV: undefined };
34
+ const env = {
35
+ ...process.env,
36
+ NODE_ENV: undefined,
37
+ NODE_DISABLE_COLORS: '1',
38
+ NO_COLORS: '1',
39
+ FORCE_COLOR: '0'
40
+ };
35
41
  // Spawn a child process to run the command with the '--help' flag.
36
42
  const childProcess = cp.spawn('npx', [...command.split(' '), '--help'], { env });
37
43
  let output = '';
@@ -81,4 +87,4 @@ function extractSubcommands(result) {
81
87
  return [subcommand];
82
88
  });
83
89
  }
84
- //# sourceMappingURL=command.js.map
90
+ //# sourceMappingURL=doc-command.js.map
@@ -0,0 +1,4 @@
1
+ export declare function generateTypescriptDocs(options: {
2
+ entryPoint?: string;
3
+ outputPath?: string;
4
+ }): Promise<void>;
@@ -0,0 +1,43 @@
1
+ import * as td from 'typedoc';
2
+ import * as tdMarkdown from 'typedoc-plugin-markdown';
3
+ import * as tdTheme from 'typedoc-github-wiki-theme';
4
+ import { panic, warn } from '../lib/log.js';
5
+ export async function generateTypescriptDocs(options) {
6
+ const app = await td.Application.bootstrapWithPlugins({
7
+ entryPoints: [options.entryPoint ?? './src/index.ts'],
8
+ gitRevision: 'main',
9
+ outputs: [{ name: 'markdown', path: options.outputPath ?? './docs' }],
10
+ }, [
11
+ new td.ArgumentsReader(0),
12
+ new td.TypeDocReader(),
13
+ new td.PackageJsonReader(),
14
+ new td.TSConfigReader(),
15
+ new td.ArgumentsReader(300),
16
+ ]);
17
+ tdMarkdown.load(app);
18
+ tdTheme.load(app);
19
+ app.options.setValue('readme', 'none');
20
+ app.options.setValue('hidePageHeader', true);
21
+ app.options.setValue('classPropertiesFormat', 'table');
22
+ app.options.setValue('enumMembersFormat', 'table');
23
+ app.options.setValue('indexFormat', 'table');
24
+ app.options.setValue('interfacePropertiesFormat', 'table');
25
+ app.options.setValue('parametersFormat', 'table');
26
+ app.options.setValue('propertiesFormat', 'table');
27
+ app.options.setValue('propertyMembersFormat', 'table');
28
+ app.options.setValue('typeDeclarationFormat', 'table');
29
+ const project = await app.convert();
30
+ if (!project)
31
+ panic('Failed to convert project');
32
+ app.validate(project);
33
+ if (app.logger.hasWarnings())
34
+ warn('Warnings found during validation');
35
+ if (app.logger.hasErrors())
36
+ panic('Errors found during validation');
37
+ await app.generateOutputs(project);
38
+ if (app.logger.hasWarnings())
39
+ warn('Warnings found during validation');
40
+ if (app.logger.hasErrors())
41
+ panic('Errors found during validation');
42
+ }
43
+ //# sourceMappingURL=doc-typescript.js.map
@@ -126,4 +126,4 @@ export async function release(directory, branch = 'main') {
126
126
  }
127
127
  }
128
128
  }
129
- //# sourceMappingURL=release.js.map
129
+ //# sourceMappingURL=release-npm.js.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
1
  #!/usr/bin/env -S node --enable-source-maps
2
2
  import { Command } from 'commander';
3
+ /**
4
+ * Main CLI program, configured with custom text styling for titles, commands, options, etc.
5
+ */
3
6
  export declare const program: Command;
package/dist/index.js CHANGED
@@ -1,70 +1,140 @@
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 { styleText } from 'node:util';
4
5
  import { injectMarkdown, updateTOC } from './commands/markdown.js';
5
6
  import { Command, InvalidArgumentError } from 'commander';
6
7
  import { cwd } from 'node:process';
7
- import { generateCommandDocumentation } from './commands/command.js';
8
- import { release } from './commands/release.js';
9
- import { upgradeDependencies } from './commands/upgrade-dependencies.js';
10
- import { generateDependencyGraph } from './commands/dependency-graph.js';
8
+ import { generateCommandDocumentation } from './commands/doc-command.js';
9
+ import { release } from './commands/release-npm.js';
10
+ import { upgradeDependencies } from './commands/deps-upgrade.js';
11
+ import { generateDependencyGraph } from './commands/deps-graph.js';
12
+ import { checkPackage } from './commands/check-package.js';
13
+ import { generateTypescriptDocs } from './commands/doc-typescript.js';
14
+ /**
15
+ * Main CLI program, configured with custom text styling for titles, commands, options, etc.
16
+ */
11
17
  export const program = new Command();
18
+ program.configureHelp({
19
+ styleTitle: (str) => styleText('bold', str),
20
+ styleCommandText: (str) => styleText('bold', str),
21
+ styleOptionText: (str) => styleText('cyan', str),
22
+ styleArgumentText: (str) => styleText('green', str),
23
+ styleSubcommandText: (str) => styleText('yellow', str),
24
+ sortOptions: true,
25
+ sortSubcommands: true,
26
+ });
12
27
  program
13
28
  .name('vrt')
14
- .description('versatiles release and documentaion tool');
29
+ .description('CLI tool for releasing packages and generating documentation for Node.js/TypeScript projects.');
30
+ /**
31
+ * Command: check-package
32
+ * Checks that the project's package.json includes certain required scripts/fields.
33
+ */
34
+ program.command('check-package')
35
+ .description('Check package.json for required scripts and other metadata.')
36
+ .action(() => {
37
+ void checkPackage(process.cwd());
38
+ });
39
+ /**
40
+ * Command: deps-graph
41
+ * Analyzes the project’s files to produce a dependency graph (in Mermaid format).
42
+ */
15
43
  program.command('deps-graph')
16
- .description('draws a graph of all files in the project and outputs it as mermaid')
44
+ .description('Analyze project files and output a dependency graph as Mermaid markup.')
17
45
  .action(() => {
18
46
  void generateDependencyGraph(process.cwd());
19
47
  });
48
+ /**
49
+ * Command: deps-upgrade
50
+ * Upgrades project dependencies in package.json to their latest versions and reinstalls them.
51
+ */
20
52
  program.command('deps-upgrade')
21
- .description('upgrades all dependencies to the latest version')
53
+ .description('Upgrade all dependencies in the current project to their latest versions.')
22
54
  .action(() => {
23
55
  void upgradeDependencies(process.cwd());
24
56
  });
57
+ /**
58
+ * Command: doc-command
59
+ * Generates Markdown documentation for a given CLI command.
60
+ */
25
61
  program.command('doc-command')
26
- .description('documents a runnable command and outputs it')
27
- .argument('<command>', 'command to run')
62
+ .description('Generate Markdown documentation for a specified command and output the result.')
63
+ .argument('<command>', 'Command to document (e.g., "npm run build").')
28
64
  .action(async (command) => {
29
65
  const mdDocumentation = await generateCommandDocumentation(command);
30
66
  process.stdout.write(mdDocumentation);
31
67
  });
68
+ /**
69
+ * Command: doc-insert
70
+ * Inserts Markdown content from stdin into a specified Markdown file under a given heading.
71
+ * Optionally makes the inserted content foldable.
72
+ */
32
73
  program.command('doc-insert')
33
- .description('takes Markdown from stdin and insert it into a Markdown file')
34
- .argument('<readme>', 'Markdown file, like a readme.md', checkFilename)
35
- .argument('[heading]', 'Heading in the Markdown file', '# API')
36
- .argument('[foldable]', 'Make content foldable', false)
74
+ .description('Insert Markdown from stdin into a specified section of a Markdown file.')
75
+ .argument('<readme>', 'Path to the target Markdown file (e.g., README.md).', checkFilename)
76
+ .argument('[heading]', 'Heading in the Markdown file where content should be placed. Default is "# API".', '# API')
77
+ .argument('[foldable]', 'Whether to wrap the inserted content in a foldable section.', false)
37
78
  .action(async (mdFilename, heading, foldable) => {
38
79
  const buffers = [];
39
- for await (const data of process.stdin)
80
+ for await (const data of process.stdin) {
40
81
  buffers.push(data);
41
- const mdContent = '<!--- This chapter is generated automatically --->\n' + Buffer.concat(buffers).toString();
82
+ }
83
+ const mdContent = '<!--- This chapter is generated automatically --->\n'
84
+ + Buffer.concat(buffers).toString();
42
85
  let mdFile = readFileSync(mdFilename, 'utf8');
43
86
  mdFile = injectMarkdown(mdFile, mdContent, heading, foldable);
44
87
  writeFileSync(mdFilename, mdFile);
45
88
  });
89
+ /**
90
+ * Command: doc-toc
91
+ * Updates or generates a Table of Contents in a Markdown file under a specified heading.
92
+ */
46
93
  program.command('doc-toc')
47
- .description('updates the TOC in a Markdown file')
48
- .argument('<readme>', 'Markdown file, like a readme.md', checkFilename)
49
- .argument('[heading]', 'Heading in the Markdown file', '# Table of Content')
94
+ .description('Generate a Table of Contents (TOC) in a Markdown file.')
95
+ .argument('<readme>', 'Path to the Markdown file (e.g., README.md).', checkFilename)
96
+ .argument('[heading]', 'Heading in the Markdown file where TOC should be inserted. Default is "# Table of Content".', '# Table of Content')
50
97
  .action((mdFilename, heading) => {
51
98
  let mdFile = readFileSync(mdFilename, 'utf8');
52
99
  mdFile = updateTOC(mdFile, heading);
53
100
  writeFileSync(mdFilename, mdFile);
54
101
  });
102
+ /**
103
+ * Command: doc-typescript
104
+ * Generates documentation for a TypeScript project.
105
+ * Allows specifying entry point and output location.
106
+ */
107
+ program.command('doc-typescript')
108
+ .description('Generate documentation for a TypeScript project.')
109
+ .option('-i <entryPoint>', 'Entry point of the TypeScript project. Default is "./src/index.ts".')
110
+ .option('-o <outputPath>', 'Output path for the generated documentation. Default is "./docs".')
111
+ .action(async (options) => {
112
+ await generateTypescriptDocs(options);
113
+ });
114
+ /**
115
+ * Command: release-npm
116
+ * Releases/publishes an npm package from a specified project path to the npm registry.
117
+ */
55
118
  program.command('release-npm')
56
- .description('releases a npm package')
57
- .argument('[path]', 'root path of the Node.js project')
119
+ .description('Publish an npm package from the specified path to the npm registry.')
120
+ .argument('[path]', 'Root path of the Node.js project. Defaults to the current directory.')
58
121
  .action((path) => {
59
122
  void release(resolve(path ?? '.', process.cwd()), 'main');
60
123
  });
61
124
  if (process.env.NODE_ENV !== 'test') {
62
125
  await program.parseAsync();
63
126
  }
127
+ /**
128
+ * Validates that the given filename exists.
129
+ * Throws an InvalidArgumentError if the file cannot be found.
130
+ *
131
+ * @param filename - The filename to check.
132
+ * @returns The resolved full path if the file exists.
133
+ */
64
134
  function checkFilename(filename) {
65
135
  const fullname = resolve(cwd(), filename);
66
136
  if (!existsSync(fullname)) {
67
- throw new InvalidArgumentError('file not found');
137
+ throw new InvalidArgumentError(`File not found: ${filename}`);
68
138
  }
69
139
  return fullname;
70
140
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/release-tool",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "VersaTiles release and documentation tools",
5
5
  "bin": {
6
6
  "vrt": "./dist/index.js"
@@ -10,7 +10,8 @@
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 && npm run doc",
13
+ "build": "npm run build-node && npm run doc",
14
+ "build-node": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/index.js",
14
15
  "check": "npm run lint && npm run build && npm run test",
15
16
  "dev": "tsx src/index.ts",
16
17
  "doc": "npm run doc-command && npm run doc-graph",
@@ -18,7 +19,7 @@
18
19
  "doc-graph": "tsx src/index.ts deps-graph | tsx src/index.ts doc-insert README.md '## Dependency Graph'",
19
20
  "lint": "eslint . --color",
20
21
  "prepack": "npm run build",
21
- "release": "npm run build && tsx src/index.ts release-npm",
22
+ "release": "tsx src/index.ts release-npm",
22
23
  "test-coverage": "NODE_OPTIONS=--experimental-vm-modules jest --coverage",
23
24
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
24
25
  "upgrade": "tsx src/index.ts deps-upgrade"
@@ -32,6 +33,7 @@
32
33
  },
33
34
  "homepage": "https://github.com/versatiles-org/node-release-tool",
34
35
  "devDependencies": {
36
+ "@schemastore/package": "^0.0.10",
35
37
  "@types/jest": "^29.5.14",
36
38
  "@types/node": "^22.13.5",
37
39
  "@typescript-eslint/eslint-plugin": "^8.22.0",
@@ -48,6 +50,9 @@
48
50
  "commander": "^13.1.0",
49
51
  "dependency-cruiser": "^16.10.0",
50
52
  "remark": "^15.0.1",
51
- "remark-gfm": "^4.0.1"
53
+ "remark-gfm": "^4.0.1",
54
+ "typedoc": "^0.27.8",
55
+ "typedoc-github-wiki-theme": "^2.1.0",
56
+ "typedoc-plugin-markdown": "^4.4.2"
52
57
  }
53
58
  }
@@ -1 +0,0 @@
1
- export declare function upgradeDependencies(directory: string): Promise<void>;
@@ -1,12 +0,0 @@
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