@versatiles/release-tool 1.0.3 → 1.2.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
@@ -1,3 +1,6 @@
1
+ [![Code Coverage](https://codecov.io/gh/versatiles-org/node-release-tool/branch/main/graph/badge.svg?token=IDHAI13M0K)](https://codecov.io/gh/versatiles-org/node-release-tool)
2
+ [![GitHub Workflow Status)](https://img.shields.io/github/actions/workflow/status/versatiles-org/node-release-tool/ci.yml)](https://github.com/versatiles-org/node-release-tool/actions/workflows/ci.yml)
3
+
1
4
  # VersaTiles Release Tools
2
5
 
3
6
  Tools used internally for:
@@ -6,6 +9,35 @@ Tools used internally for:
6
9
  * creating Markdown documentation of executables: [`vrt cmd2md`](#subcommand-vrt-cmd2md)
7
10
  * inserting Markdown into documents: [`vrt insertmd`](#subcommand-vrt-insertmd)
8
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)
13
+
14
+ # Installation
15
+
16
+ ```bash
17
+ npm i -D @versatiles/release-tool
18
+ ```
19
+
20
+ # configure scripts
21
+
22
+ You need to configure the scripts in the package.json:
23
+
24
+ ```JSON
25
+ {
26
+ "scripts": {
27
+ "check": "npm run lint && npm run build && npm run test",
28
+ "prepack": "npm run build && npm run doc",
29
+ "release": "vrt release-npm",
30
+ ...
31
+ },
32
+ ...
33
+ }
34
+ ```
35
+
36
+ * `scripts.check` is **required** by the release command. Here you can lint, build and test your code.
37
+ * `scripts.prepack` is **recommended** to ensure that all files are up-to-date before releasing. Here you can build code and documentation.
38
+ * `scripts.release` is **recommended** to make it easy to release a new version.
39
+
40
+ Have a look at this [package.json](https://github.com/versatiles-org/node-release-tool/blob/main/package.json) as an example.
9
41
 
10
42
  # Command `vrt`
11
43
 
@@ -25,6 +57,7 @@ Commands:
25
57
  cmd2md <command> documents a runnable command and outputs it to stdout
26
58
  insertmd <readme> [heading] [foldable] takes Markdown from stdin and insert it into a Markdown file
27
59
  inserttoc <readme> [heading] updates the TOC in a Markdown file
60
+ release-npm [path] release a npm package
28
61
  help [command] display help for command
29
62
  ```
30
63
 
@@ -91,3 +124,18 @@ Arguments:
91
124
  Options:
92
125
  -h, --help display help for command
93
126
  ```
127
+
128
+ ## Subcommand: `vrt release-npm`
129
+
130
+ ```console
131
+ $ vrt release-npm
132
+ Usage: vrt release-npm [options] [path]
133
+
134
+ release a npm package
135
+
136
+ Arguments:
137
+ path root path of the Node.js project
138
+
139
+ Options:
140
+ -h, --help display help for command
141
+ ```
@@ -1,5 +1,5 @@
1
1
  import cp from 'child_process';
2
- import { getErrorMessage } from './utils.js';
2
+ import { getErrorMessage } from '../lib/utils.js';
3
3
  /**
4
4
  * Generates documentation for a CLI command and its subcommands.
5
5
  * @param command The base CLI command to document.
@@ -31,8 +31,10 @@ export async function generateCommandDocumentation(command) {
31
31
  */
32
32
  async function getCommandResults(command) {
33
33
  return new Promise((resolve, reject) => {
34
+ // eslint-disable-next-line @typescript-eslint/naming-convention
35
+ const env = { ...process.env, NODE_ENV: undefined };
34
36
  // Spawn a child process to run the command with the '--help' flag.
35
- const childProcess = cp.spawn('npx', [...command.split(' '), '--help']);
37
+ const childProcess = cp.spawn('npx', [...command.split(' '), '--help'], { env });
36
38
  let output = '';
37
39
  // Collect output data from the process.
38
40
  childProcess.stdout.on('data', data => output += String(data));
@@ -1,6 +1,6 @@
1
1
  import { remark } from 'remark';
2
2
  import remarkGfm from 'remark-gfm';
3
- import { getErrorMessage } from './utils.js';
3
+ import { getErrorMessage } from '../lib/utils.js';
4
4
  /**
5
5
  * Injects a Markdown segment under a specified heading in a Markdown document.
6
6
  * Optionally, the injected segment can be made foldable for better readability.
@@ -24,8 +24,7 @@ export function injectMarkdown(document, segment, heading, foldable) {
24
24
  }
25
25
  catch (error) {
26
26
  // Handle errors during the search for the start index.
27
- console.error(`Error while searching for segment "${heading}": ${getErrorMessage(error)}`);
28
- throw error;
27
+ throw new Error(`Error while searching for segment "${heading}": ${getErrorMessage(error)}`);
29
28
  }
30
29
  // Get the depth of the specified heading to maintain the structure.
31
30
  const depth = getHeadingDepth(documentAst, startIndex);
@@ -110,7 +109,7 @@ function findNextHeadingIndex(mainAst, startIndex, depth) {
110
109
  for (let i = startIndex; i < mainAst.children.length; i++) {
111
110
  const child = mainAst.children[i];
112
111
  // Return the index of the next heading at the same depth.
113
- if (child.type === 'heading' && child.depth === depth)
112
+ if (child.type === 'heading' && child.depth <= depth)
114
113
  return i;
115
114
  }
116
115
  return mainAst.children.length;
@@ -269,10 +268,6 @@ export function nodeToHtml(node) {
269
268
  return `<strong>${nodesToHtml(node.children)}</strong>`;
270
269
  case 'link':
271
270
  return `<a href="${node.url}"${node.title == null ? '' : ` title="${node.title}"`}>${nodesToHtml(node.children)}</a>`;
272
- case 'linkReference':
273
- throw new Error('"linkReference to html" not implemented');
274
- case 'footnoteReference':
275
- throw new Error('"footnoteReference to html" not implemented');
276
271
  case 'image':
277
272
  const attributes = [`src="${node.url}"`];
278
273
  if (node.alt ?? '')
@@ -280,8 +275,6 @@ export function nodeToHtml(node) {
280
275
  if (node.title ?? '')
281
276
  attributes.push(`title="${node.title}"`);
282
277
  return `<img ${attributes.join(' ')} />`;
283
- case 'imageReference':
284
- throw new Error('"imageReference to html" not implemented');
285
278
  default:
286
279
  console.log(node);
287
280
  throw Error('unknown type');
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env npx tsx
2
+ export declare function release(directory: string, branch?: string): Promise<void>;
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env npx tsx
2
+ import { readFileSync, writeFileSync } from 'node:fs';
3
+ import inquirer from 'inquirer';
4
+ import { check, info, panic, warn } from '../lib/log.js';
5
+ import { getShell } from '../lib/shell.js';
6
+ import { getGit } from '../lib/git.js';
7
+ import { resolve } from 'node:path';
8
+ export async function release(directory, branch = 'main') {
9
+ const shell = getShell(directory);
10
+ const { getCommitsBetween, getCurrentGitHubCommit, getLastGitHubTag } = getGit(directory);
11
+ info('starting release process');
12
+ // git: check if in the correct branch
13
+ const currentBranch = await check('get branch name', shell.stdout('git rev-parse --abbrev-ref HEAD'));
14
+ if (currentBranch !== branch)
15
+ panic(`current branch is "${currentBranch}" but should be "${branch}"`);
16
+ // git: check if no changes
17
+ await check('are all changes committed?', checkThatNoUncommittedChanges());
18
+ // git: pull
19
+ await check('git pull', shell.run('git pull -t'));
20
+ // check package.json
21
+ const pkg = JSON.parse(readFileSync(resolve(directory, 'package.json'), 'utf8'));
22
+ if (typeof pkg !== 'object' || pkg === null)
23
+ panic('package.json is not valid');
24
+ if (!('version' in pkg) || (typeof pkg.version !== 'string'))
25
+ panic('package.json is missing "version"');
26
+ if (!('scripts' in pkg) || (typeof pkg.scripts !== 'object') || (pkg.scripts == null))
27
+ panic('package.json is missing "scripts"');
28
+ if (!('check' in pkg.scripts))
29
+ panic('missing npm script "check" in package.json');
30
+ // get last version
31
+ const tag = await check('get last github tag', getLastGitHubTag());
32
+ const shaLast = tag?.sha;
33
+ const versionLastGithub = tag?.version;
34
+ const versionLastPackage = String(pkg.version);
35
+ if (versionLastPackage !== versionLastGithub)
36
+ warn(`versions differ in package.json (${versionLastPackage}) and last GitHub tag (${versionLastGithub})`);
37
+ // get current sha
38
+ const { sha: shaCurrent } = await check('get current github commit', getCurrentGitHubCommit());
39
+ // handle version
40
+ const nextVersion = await editVersion(versionLastPackage);
41
+ // prepare release notes
42
+ const releaseNotes = await check('prepare release notes', getReleaseNotes(nextVersion, shaLast, shaCurrent));
43
+ // update version
44
+ await check('update version', setNextVersion(nextVersion));
45
+ // test
46
+ await check('run checks', shell.run('npm run check'));
47
+ // npm publish
48
+ await check('npm publish', shell.run('npm publish --access public'));
49
+ // git push
50
+ await check('git add', shell.run('git add .'));
51
+ await check('git commit', shell.run(`git commit -m "v${nextVersion}"`, false));
52
+ await check('git tag', shell.run(`git tag -f -a "v${nextVersion}" -m "new release: v${nextVersion}"`));
53
+ await check('git push', shell.run('git push --no-verify --follow-tags'));
54
+ // github release
55
+ const releaseNotesPipe = `echo -e '${releaseNotes.replace(/[^a-z0-9,.?!:_<> -]/gi, c => '\\x' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))}'`;
56
+ if (await check('check github release', shell.ok('gh release view v' + nextVersion))) {
57
+ await check('edit release', shell.run(`${releaseNotesPipe} | gh release edit "v${nextVersion}" -F -`));
58
+ }
59
+ else {
60
+ await check('create release', shell.run(`${releaseNotesPipe} | gh release create "v${nextVersion}" --draft --prerelease -F -`));
61
+ }
62
+ info('Finished');
63
+ return;
64
+ async function checkThatNoUncommittedChanges() {
65
+ if ((await shell.stdout('git status --porcelain')).length < 3)
66
+ return;
67
+ throw Error('please commit all changes before releasing');
68
+ }
69
+ async function setNextVersion(version) {
70
+ // set new version in package.json
71
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
72
+ const packageJSON = JSON.parse(readFileSync(resolve(directory, 'package.json'), 'utf8'));
73
+ packageJSON.version = version;
74
+ writeFileSync(resolve(directory, 'package.json'), JSON.stringify(packageJSON, null, ' ') + '\n');
75
+ // rebuild package.json
76
+ await shell.run('npm i --package-lock-only');
77
+ }
78
+ async function getReleaseNotes(version, hashLast, hashCurrent) {
79
+ const commits = await getCommitsBetween(hashLast, hashCurrent);
80
+ let notes = commits.reverse()
81
+ .map(commit => '- ' + commit.message.replace(/\s+/g, ' '))
82
+ .join('\n');
83
+ notes = `# Release v${version}\n\nchanges: \n${notes}\n\n`;
84
+ return notes;
85
+ }
86
+ async function editVersion(versionPackage) {
87
+ // ask for new version
88
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
89
+ const versionNew = (await inquirer.prompt({
90
+ message: 'What should be the new version?',
91
+ name: 'versionNew',
92
+ type: 'list',
93
+ choices: [versionPackage, bump(2), bump(1), bump(0)],
94
+ default: 1,
95
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
96
+ })).versionNew;
97
+ if (!versionNew)
98
+ throw Error();
99
+ return versionNew;
100
+ function bump(index) {
101
+ const p = versionPackage.split('.').map(v => parseInt(v, 10));
102
+ if (p.length !== 3)
103
+ throw Error();
104
+ switch (index) {
105
+ case 0:
106
+ p[0]++;
107
+ p[1] = 0;
108
+ p[2] = 0;
109
+ break;
110
+ case 1:
111
+ p[1]++;
112
+ p[2] = 0;
113
+ break;
114
+ case 2:
115
+ p[2]++;
116
+ break;
117
+ }
118
+ const name = p.map((n, i) => (i == index) ? `\x1b[1m${n}` : `${n}`).join('.') + '\x1b[22m';
119
+ const value = p.join('.');
120
+ return { name, value };
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=release.js.map
@@ -206,10 +206,10 @@ function formatTypeDeclaration(someType) {
206
206
  if (some.reflection)
207
207
  result = `[${result}](#${createAnchorId(some.reflection)})`;
208
208
  if (some.typeArguments?.length ?? 0)
209
- result += '<'
209
+ result += '&lt;'
210
210
  + (some.typeArguments ?? [])
211
211
  .map(getTypeRec).join(',')
212
- + '>';
212
+ + '&gt;';
213
213
  return result;
214
214
  case 'reflection':
215
215
  switch (some.declaration.kind) {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  #!/usr/bin/env -S node --enable-source-maps
2
- export {};
2
+ import { Command } from 'commander';
3
+ export declare const program: Command;
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
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 './lib/typedoc.js';
5
- import { injectMarkdown, updateTOC } from './lib/markdown.js';
4
+ import { generateTsMarkdownDoc } from './commands/typedoc.js';
5
+ import { injectMarkdown, updateTOC } from './commands/markdown.js';
6
6
  import { Command, InvalidArgumentError } from 'commander';
7
7
  import { cwd } from 'node:process';
8
- import { generateCommandDocumentation } from './lib/command.js';
9
- const program = new Command();
8
+ import { generateCommandDocumentation } from './commands/command.js';
9
+ import { release } from './commands/release.js';
10
+ export const program = new Command();
10
11
  program
11
12
  .name('vrt')
12
13
  .description('versatiles release and documentaion tool');
@@ -48,7 +49,15 @@ program.command('inserttoc')
48
49
  mdFile = updateTOC(mdFile, heading);
49
50
  writeFileSync(mdFilename, mdFile);
50
51
  });
51
- program.parse();
52
+ program.command('release-npm')
53
+ .description('release a npm package')
54
+ .argument('[path]', 'root path of the Node.js project')
55
+ .action((path) => {
56
+ void release(resolve(path ?? ',', process.cwd()), 'main');
57
+ });
58
+ if (process.env.NODE_ENV !== 'test') {
59
+ await program.parseAsync();
60
+ }
52
61
  function checkFilename(filename) {
53
62
  const fullname = resolve(cwd(), filename);
54
63
  if (!existsSync(fullname)) {
@@ -0,0 +1,14 @@
1
+ export interface Commit {
2
+ sha: string;
3
+ message: string;
4
+ tag?: string;
5
+ }
6
+ export interface Git {
7
+ getLastGitHubTag: () => Promise<{
8
+ sha: string;
9
+ version: string;
10
+ } | undefined>;
11
+ getCurrentGitHubCommit: () => Promise<Commit>;
12
+ getCommitsBetween: (shaLast?: string, shaCurrent?: string) => Promise<Commit[]>;
13
+ }
14
+ export declare function getGit(cwd: string): Git;
@@ -0,0 +1,47 @@
1
+ import { getShell } from './shell.js';
2
+ export function getGit(cwd) {
3
+ const shell = getShell(cwd);
4
+ return {
5
+ getLastGitHubTag,
6
+ getCurrentGitHubCommit,
7
+ getCommitsBetween,
8
+ };
9
+ async function getLastGitHubTag() {
10
+ const commits = await getAllCommits();
11
+ const result = commits
12
+ .map(commit => ({
13
+ sha: commit.sha,
14
+ version: commit.tag?.match(/^v(\d+\.\d+\.\d+)$/)?.[1],
15
+ }))
16
+ .find(r => r.version);
17
+ return result;
18
+ }
19
+ async function getAllCommits() {
20
+ const result = await shell.stdout('git log --pretty=format:\'⍃%H⍄%s⍄%D⍄\'');
21
+ return result
22
+ .split('⍃')
23
+ .filter(line => line.length > 2)
24
+ .map(line => {
25
+ const obj = line.split('⍄');
26
+ return {
27
+ sha: obj[0],
28
+ message: obj[1],
29
+ tag: /tag: ([a-z0-9.]+)/.exec(obj[2])?.[1],
30
+ };
31
+ });
32
+ }
33
+ async function getCurrentGitHubCommit() {
34
+ return (await getAllCommits())[0];
35
+ }
36
+ async function getCommitsBetween(shaLast, shaCurrent) {
37
+ let commits = await getAllCommits();
38
+ const start = commits.findIndex(commit => commit.sha === shaCurrent);
39
+ if (start >= 0)
40
+ commits = commits.slice(start);
41
+ const end = commits.findIndex(commit => commit.sha === shaLast);
42
+ if (end >= 0)
43
+ commits = commits.slice(0, end);
44
+ return commits;
45
+ }
46
+ }
47
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1,5 @@
1
+ export declare function panic(text: string): never;
2
+ export declare function warn(text: string): void;
3
+ export declare function info(text: string): void;
4
+ export declare function abort(): never;
5
+ export declare function check<T>(message: string, promise: Promise<T>): Promise<T>;
@@ -0,0 +1,28 @@
1
+ export function panic(text) {
2
+ process.stderr.write(`\x1b[1;31m! ERROR: ${text}\x1b[0m\n`);
3
+ abort();
4
+ }
5
+ export function warn(text) {
6
+ process.stderr.write(`\x1b[1;33m! warning: ${text}\x1b[0m\n`);
7
+ }
8
+ export function info(text) {
9
+ process.stderr.write(`\x1b[0mi ${text}\n`);
10
+ }
11
+ export function abort() {
12
+ info('abort');
13
+ process.exit();
14
+ }
15
+ export async function check(message, promise) {
16
+ process.stderr.write(`\x1b[0;90m\u2B95 ${message}\x1b[0m`);
17
+ try {
18
+ const result = await promise;
19
+ process.stderr.write(`\r\x1b[0;92m\u2714 ${message}\x1b[0m\n`);
20
+ return result;
21
+ }
22
+ catch (error) {
23
+ process.stderr.write(`\r\x1b[0;91m\u2718 ${message}\x1b[0m\n`);
24
+ panic(error.message);
25
+ throw Error();
26
+ }
27
+ }
28
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1,12 @@
1
+ export interface Shell {
2
+ run: (command: string, errorOnCodeNonZero?: boolean) => Promise<{
3
+ code: number | null;
4
+ signal: string | null;
5
+ stdout: string;
6
+ stderr: string;
7
+ }>;
8
+ stderr: (command: string, errorOnCodeZero?: boolean) => Promise<string>;
9
+ stdout: (command: string, errorOnCodeZero?: boolean) => Promise<string>;
10
+ ok: (command: string) => Promise<boolean>;
11
+ }
12
+ export declare function getShell(cwd: string): Shell;
@@ -0,0 +1,42 @@
1
+ import { spawn } from 'child_process';
2
+ export function getShell(cwd) {
3
+ async function run(command, errorOnCodeNonZero) {
4
+ try {
5
+ return await new Promise((resolve, reject) => {
6
+ const stdout = [];
7
+ const stderr = [];
8
+ const cp = spawn('bash', ['-c', command], { cwd })
9
+ .on('error', error => {
10
+ reject(error);
11
+ })
12
+ .on('close', (code, signal) => {
13
+ const result = {
14
+ code,
15
+ signal,
16
+ stdout: Buffer.concat(stdout).toString(),
17
+ stderr: Buffer.concat(stderr).toString(),
18
+ };
19
+ if ((errorOnCodeNonZero ?? true) && (code !== 0)) {
20
+ reject(result);
21
+ }
22
+ else {
23
+ resolve(result);
24
+ }
25
+ });
26
+ cp.stdout.on('data', (chunk) => stdout.push(chunk));
27
+ cp.stderr.on('data', (chunk) => stderr.push(chunk));
28
+ });
29
+ }
30
+ catch (error) {
31
+ console.error(error);
32
+ throw error;
33
+ }
34
+ }
35
+ return {
36
+ run,
37
+ stderr: async (command, errorOnCodeZero) => (await run(command, errorOnCodeZero)).stderr.trim(),
38
+ stdout: async (command, errorOnCodeZero) => (await run(command, errorOnCodeZero)).stdout.trim(),
39
+ ok: async (command) => (await run(command, false)).code === 0,
40
+ };
41
+ }
42
+ //# sourceMappingURL=shell.js.map
@@ -1 +1,2 @@
1
1
  export declare function getErrorMessage(error: unknown): string;
2
+ export declare function prettyStyleJSON(inputData: unknown): string;
package/dist/lib/utils.js CHANGED
@@ -2,9 +2,38 @@ export function getErrorMessage(error) {
2
2
  if (error == null)
3
3
  return 'unknown';
4
4
  if (typeof error === 'object') {
5
- if ('message' in error)
6
- return String(error.message);
5
+ if ('message' in error) {
6
+ if (typeof error.message === 'string')
7
+ return error.message;
8
+ return JSON.stringify(error.message);
9
+ }
7
10
  }
8
11
  return 'unknown';
9
12
  }
13
+ export function prettyStyleJSON(inputData) {
14
+ return recursive(inputData);
15
+ function recursive(data, prefix = '', path = '') {
16
+ if (path.endsWith('.bounds'))
17
+ return singleLine(data);
18
+ //if (path.includes('.vector_layers[].')) return singleLine(data);
19
+ if (path.startsWith('.layers[].filter'))
20
+ return singleLine(data);
21
+ if (path.startsWith('.layers[].paint.'))
22
+ return singleLine(data);
23
+ if (path.startsWith('.layers[].layout.'))
24
+ return singleLine(data);
25
+ if (typeof data === 'object') {
26
+ if (Array.isArray(data)) {
27
+ return '[\n\t' + prefix + data.map((value) => recursive(value, prefix + '\t', path + '[]')).join(',\n\t' + prefix) + '\n' + prefix + ']';
28
+ }
29
+ if (data) {
30
+ return '{\n\t' + prefix + Object.entries(data).map(([key, value]) => '"' + key + '": ' + recursive(value, prefix + '\t', path + '.' + key)).join(',\n\t' + prefix) + '\n' + prefix + '}';
31
+ }
32
+ }
33
+ return singleLine(data);
34
+ }
35
+ function singleLine(data) {
36
+ return JSON.stringify(data, null, '\t').replace(/[\t\n]+/g, ' ');
37
+ }
38
+ }
10
39
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/release-tool",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "description": "VersaTiles release and documentation tools",
5
5
  "bin": {
6
6
  "vrt": "./dist/index.js"
@@ -11,11 +11,14 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/index.js",
14
- "check": "npm run lint && npm run test && npm run build",
14
+ "check": "npm run lint && npm run build && npm run test",
15
15
  "doc": "npx vrt cmd2md vrt | npx vrt insertmd README.md '# Command'",
16
16
  "lint": "eslint . --color",
17
17
  "prepack": "npm run build && npm run doc",
18
- "test": "cd ..; NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern versatiles-release-tool"
18
+ "release": "npx vrt release-npm",
19
+ "test-coverage": "NODE_OPTIONS=--experimental-vm-modules jest --coverage",
20
+ "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"
19
22
  },
20
23
  "author": "yetzt <node@yetzt.me>, Michael Kreil <versatiles@michael-kreil.de>",
21
24
  "license": "Unlicense",
@@ -26,14 +29,23 @@
26
29
  },
27
30
  "homepage": "https://github.com/versatiles-org/node-versatiles/blob/main/versatiles-release-tool/README.md",
28
31
  "devDependencies": {
29
- "@types/node": "^20.10.0",
30
- "tsx": "^4.4.0",
31
- "typescript": "^5.2.2"
32
+ "@types/inquirer": "^9.0.7",
33
+ "@types/jest": "^29.5.11",
34
+ "@types/node": "^20.11.15",
35
+ "@typescript-eslint/eslint-plugin": "^6.20.0",
36
+ "@typescript-eslint/parser": "^6.20.0",
37
+ "eslint": "^8.56.0",
38
+ "jest": "^29.7.0",
39
+ "ts-jest": "^29.1.2",
40
+ "ts-node": "^10.9.2",
41
+ "tsx": "^4.7.0",
42
+ "typescript": "^5.3.3"
32
43
  },
33
44
  "dependencies": {
34
45
  "commander": "^11.1.0",
46
+ "inquirer": "^9.2.13",
35
47
  "remark": "^15.0.1",
36
48
  "remark-gfm": "^4.0.0",
37
- "typedoc": "^0.25.3"
49
+ "typedoc": "^0.25.7"
38
50
  }
39
51
  }
File without changes
File without changes
File without changes