@lvnt/release-radar 1.7.6 → 1.7.8

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/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvnt/release-radar-cli",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Interactive CLI for downloading tools through Nexus proxy",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/cli/src/index.ts CHANGED
@@ -7,7 +7,7 @@ import { DownloadTracker } from './tracker.js';
7
7
  import { loadVersions } from './versions.js';
8
8
  import { checkAndUpdate } from './updater.js';
9
9
  import { downloadFile, updateNpmPackage } from './downloader.js';
10
- import { promptSetup, promptToolSelection, type ToolChoice } from './ui.js';
10
+ import { promptSetup, promptToolSelection, renderTable, type ToolChoice, type TableRow } from './ui.js';
11
11
  import { isNpmTool } from './types.js';
12
12
 
13
13
  function getVersion(): string {
@@ -56,25 +56,28 @@ async function showStatus(): Promise<void> {
56
56
  const downloaded = tracker.getAll();
57
57
 
58
58
  console.log(chalk.bold('\nTool Status:\n'));
59
- console.log(chalk.bold(' Tool Latest Downloaded Status Type'));
60
- console.log(chalk.gray('─'.repeat(70)));
61
59
 
62
- for (const tool of versions.tools) {
60
+ const rows: TableRow[] = versions.tools.map(tool => {
63
61
  const record = downloaded[tool.name];
64
- const downloadedVersion = record?.version ?? '-';
65
-
66
- let status: string;
62
+ let status: 'new' | 'update' | 'current';
67
63
  if (!record) {
68
- status = chalk.blue('NEW');
64
+ status = 'new';
69
65
  } else if (record.version !== tool.version) {
70
- status = chalk.yellow('UPDATE');
66
+ status = 'update';
71
67
  } else {
72
- status = chalk.green('');
68
+ status = 'current';
73
69
  }
74
70
 
75
- const typeStr = isNpmTool(tool) ? chalk.magenta('npm') : chalk.cyan('wget');
76
- console.log(` ${tool.displayName.padEnd(18)} ${tool.version.padEnd(12)} ${downloadedVersion.padEnd(12)} ${status.padEnd(12)} ${typeStr}`);
77
- }
71
+ return {
72
+ displayName: tool.displayName,
73
+ version: tool.version,
74
+ downloadedVersion: record?.version ?? '-',
75
+ status,
76
+ type: isNpmTool(tool) ? 'npm' : 'download',
77
+ };
78
+ });
79
+
80
+ renderTable(rows);
78
81
  console.log('');
79
82
  }
80
83
 
package/cli/src/ui.ts CHANGED
@@ -126,24 +126,41 @@ function createToolChoice(tool: VersionsJsonTool, downloaded: DownloadedState):
126
126
  }
127
127
  }
128
128
 
129
- export async function promptToolSelection(
130
- tools: VersionsJsonTool[],
131
- downloaded: DownloadedState,
132
- generatedAt: string
133
- ): Promise<ToolChoice[]> {
134
- const choices: ToolChoice[] = tools.map((tool) => createToolChoice(tool, downloaded));
135
-
136
- console.log(chalk.bold(`\nrelease-radar-cli`));
137
- console.log(chalk.gray(`Last updated: ${new Date(generatedAt).toLocaleString()}\n`));
129
+ export interface TableRow {
130
+ displayName: string;
131
+ version: string;
132
+ downloadedVersion: string;
133
+ status: 'new' | 'update' | 'current';
134
+ type: 'npm' | 'download';
135
+ }
138
136
 
139
- // Display table
140
- console.log(chalk.bold(' Tool Latest Downloaded Status Type'));
141
- console.log(chalk.gray('─'.repeat(70)));
137
+ export function renderTable(rows: TableRow[]): void {
138
+ // Calculate dynamic column widths
139
+ const colWidths = {
140
+ tool: Math.max(4, ...rows.map(r => r.displayName.length)) + 2,
141
+ latest: Math.max(6, ...rows.map(r => r.version.length)) + 2,
142
+ downloaded: Math.max(10, ...rows.map(r => r.downloadedVersion.length)) + 2,
143
+ status: 8,
144
+ type: 4,
145
+ };
142
146
 
143
- choices.forEach((choice) => {
144
- const downloadedStr = choice.downloadedVersion ?? '-';
147
+ const totalWidth = colWidths.tool + colWidths.latest + colWidths.downloaded + colWidths.status + colWidths.type + 2;
148
+
149
+ // Header
150
+ console.log(chalk.bold(
151
+ ' ' +
152
+ 'Tool'.padEnd(colWidths.tool) +
153
+ 'Latest'.padEnd(colWidths.latest) +
154
+ 'Downloaded'.padEnd(colWidths.downloaded) +
155
+ 'Status'.padEnd(colWidths.status) +
156
+ 'Type'
157
+ ));
158
+ console.log(chalk.gray('─'.repeat(totalWidth)));
159
+
160
+ // Rows
161
+ for (const row of rows) {
145
162
  let statusStr: string;
146
- switch (choice.status) {
163
+ switch (row.status) {
147
164
  case 'new':
148
165
  statusStr = chalk.blue('NEW');
149
166
  break;
@@ -154,12 +171,39 @@ export async function promptToolSelection(
154
171
  statusStr = chalk.green('✓');
155
172
  break;
156
173
  }
157
- const typeStr = choice.type === 'npm' ? chalk.magenta('npm') : chalk.cyan('wget');
174
+ const typeStr = row.type === 'npm' ? chalk.magenta('npm') : chalk.cyan('wget');
175
+
158
176
  console.log(
159
- ` ${choice.displayName.padEnd(18)} ${choice.version.padEnd(12)} ${downloadedStr.padEnd(12)} ${statusStr.padEnd(12)} ${typeStr}`
177
+ ' ' +
178
+ row.displayName.padEnd(colWidths.tool) +
179
+ row.version.padEnd(colWidths.latest) +
180
+ row.downloadedVersion.padEnd(colWidths.downloaded) +
181
+ statusStr.padEnd(colWidths.status + 5) + // +5 for chalk color codes
182
+ typeStr
160
183
  );
161
- });
184
+ }
185
+ }
186
+
187
+ export async function promptToolSelection(
188
+ tools: VersionsJsonTool[],
189
+ downloaded: DownloadedState,
190
+ generatedAt: string
191
+ ): Promise<ToolChoice[]> {
192
+ const choices: ToolChoice[] = tools.map((tool) => createToolChoice(tool, downloaded));
193
+
194
+ console.log(chalk.bold(`\nrelease-radar-cli`));
195
+ console.log(chalk.gray(`Last updated: ${new Date(generatedAt).toLocaleString()}\n`));
196
+
197
+ // Convert to table rows and display
198
+ const rows: TableRow[] = choices.map(choice => ({
199
+ displayName: choice.displayName,
200
+ version: choice.version,
201
+ downloadedVersion: choice.downloadedVersion ?? '-',
202
+ status: choice.status,
203
+ type: choice.type === 'npm' ? 'npm' : 'download',
204
+ }));
162
205
 
206
+ renderTable(rows);
163
207
  console.log('');
164
208
 
165
209
  const { selected } = await inquirer.prompt([
package/dist/index.js CHANGED
@@ -56,16 +56,25 @@ if (!existsSync(DATA_DIR)) {
56
56
  mkdirSync(DATA_DIR, { recursive: true });
57
57
  }
58
58
  console.log(`Data directory: ${DATA_DIR}`);
59
- // Copy cli/ to user directory for publishing (needs to be writable)
59
+ // Sync cli/ source from package to user directory for publishing
60
+ // Always sync to ensure updates from the package are reflected
60
61
  const PKG_CLI_DIR = join(PKG_ROOT, 'cli');
61
62
  const USER_CLI_DIR = join(DATA_DIR, 'cli');
62
- if (existsSync(PKG_CLI_DIR) && !existsSync(USER_CLI_DIR)) {
63
- console.log(`Copying CLI source to ${USER_CLI_DIR}...`);
64
- cpSync(PKG_CLI_DIR, USER_CLI_DIR, { recursive: true });
65
- console.log('CLI source copied successfully');
66
- }
67
- else if (existsSync(USER_CLI_DIR)) {
68
- console.log(`CLI source directory: ${USER_CLI_DIR}`);
63
+ if (existsSync(PKG_CLI_DIR)) {
64
+ // Create user CLI dir if it doesn't exist
65
+ if (!existsSync(USER_CLI_DIR)) {
66
+ mkdirSync(USER_CLI_DIR, { recursive: true });
67
+ }
68
+ // Sync source files (excluding node_modules which is installed separately)
69
+ const filesToSync = ['src', 'bin', 'package.json', 'tsconfig.json', 'README.md'];
70
+ for (const file of filesToSync) {
71
+ const srcPath = join(PKG_CLI_DIR, file);
72
+ const destPath = join(USER_CLI_DIR, file);
73
+ if (existsSync(srcPath)) {
74
+ cpSync(srcPath, destPath, { recursive: true, force: true });
75
+ }
76
+ }
77
+ console.log(`CLI source synced to ${USER_CLI_DIR}`);
69
78
  }
70
79
  // Initialize components
71
80
  const bot = new TelegramBot(BOT_TOKEN, { polling: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvnt/release-radar",
3
- "version": "1.7.6",
3
+ "version": "1.7.8",
4
4
  "description": "Monitor tool versions and notify via Telegram when updates are detected",
5
5
  "main": "dist/index.js",
6
6
  "bin": {