@hed-hog/cli 0.0.27 → 0.0.30

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.
@@ -38,7 +38,407 @@ let DeveloperService = class DeveloperService {
38
38
  console.log('\n', ...args);
39
39
  }
40
40
  }
41
+ suppressWarnings() {
42
+ const originalEmitWarning = process.emitWarning;
43
+ process.emitWarning = () => { };
44
+ return () => {
45
+ process.emitWarning = originalEmitWarning;
46
+ };
47
+ }
48
+ async syncPublish(path, verbose = false) {
49
+ const restoreWarnings = this.suppressWarnings();
50
+ this.verbose = verbose;
51
+ path = await this.getRootPath(path);
52
+ const spinner = ora('Syncing and publishing libraries...').start();
53
+ const startTime = Date.now();
54
+ try {
55
+ const librariesPath = pathModule.join(path, 'libraries');
56
+ if (!(0, fs_1.existsSync)(librariesPath)) {
57
+ spinner.fail('Libraries directory not found.');
58
+ console.log(chalk.yellow('\nNo libraries directory found. Please create some libraries first.'));
59
+ return;
60
+ }
61
+ spinner.text = 'Scanning libraries...';
62
+ const libraries = [];
63
+ const libraryDirs = (0, fs_1.readdirSync)(librariesPath, { withFileTypes: true })
64
+ .filter((entry) => entry.isDirectory())
65
+ .map((entry) => pathModule.join(librariesPath, entry.name));
66
+ for (const libDir of libraryDirs) {
67
+ const packageJsonPath = pathModule.join(libDir, 'package.json');
68
+ if (!(0, fs_1.existsSync)(packageJsonPath)) {
69
+ this.log(chalk.yellow(`Skipping ${libDir} - no package.json found`));
70
+ continue;
71
+ }
72
+ const packageJson = JSON.parse(await (0, promises_1.readFile)(packageJsonPath, 'utf8'));
73
+ if (!packageJson.name || !packageJson.version) {
74
+ this.log(chalk.yellow(`Skipping ${pathModule.basename(libDir)} - missing name or version in package.json`));
75
+ continue;
76
+ }
77
+ libraries.push({
78
+ path: packageJsonPath,
79
+ name: packageJson.name,
80
+ version: packageJson.version,
81
+ directory: libDir,
82
+ packageJsonPath,
83
+ });
84
+ }
85
+ if (libraries.length === 0) {
86
+ spinner.fail('No valid libraries found.');
87
+ console.log(chalk.yellow('\nNo valid libraries found in the libraries directory.'));
88
+ return;
89
+ }
90
+ spinner.succeed(`Found ${libraries.length} libraries.`);
91
+ // Display found libraries
92
+ console.log(chalk.green.bold('\nšŸ“¦ Found Libraries:\n'));
93
+ for (const lib of libraries) {
94
+ console.log(` ${chalk.cyan(lib.name)} - ${chalk.gray(`v${lib.version}`)}`);
95
+ }
96
+ // Find highest version
97
+ spinner.start('Calculating new version...');
98
+ let highestVersion = libraries[0].version;
99
+ for (const lib of libraries) {
100
+ if (this.compareVersions(lib.version, highestVersion) > 0) {
101
+ highestVersion = lib.version;
102
+ }
103
+ }
104
+ const newVersion = this.incrementPatchVersion(highestVersion);
105
+ spinner.succeed(`Version calculated: ${chalk.gray(`v${highestVersion}`)} → ${chalk.green(`v${newVersion}`)}`);
106
+ console.log(chalk.blue(`\nšŸŽÆ Current highest version: v${highestVersion}`));
107
+ console.log(chalk.green(`✨ New synchronized version: v${newVersion}\n`));
108
+ // Update all package.json files
109
+ spinner.start('Updating package.json files...');
110
+ for (const lib of libraries) {
111
+ const packageJson = JSON.parse(await (0, promises_1.readFile)(lib.packageJsonPath, 'utf8'));
112
+ packageJson.version = newVersion;
113
+ await (0, promises_1.writeFile)(lib.packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
114
+ this.log(chalk.gray(` āœ… ${lib.name} updated to v${newVersion}`));
115
+ }
116
+ spinner.succeed(`All libraries synchronized to version ${chalk.green(`v${newVersion}`)}`);
117
+ // Build and publish all libraries
118
+ console.log(chalk.green.bold('\nšŸ”Ø Building and Publishing Libraries:\n'));
119
+ let successCount = 0;
120
+ let failCount = 0;
121
+ const failedLibraries = [];
122
+ for (const lib of libraries) {
123
+ spinner.start(`Processing ${chalk.cyan(lib.name)}...`);
124
+ try {
125
+ // Install dependencies
126
+ spinner.text = `${chalk.cyan(lib.name)}: Installing dependencies...`;
127
+ await this.runner.executeCommand(runner_service_1.ProgramName.PNPM, ['install'], { cwd: lib.directory }, true);
128
+ // Build
129
+ spinner.text = `${chalk.cyan(lib.name)}: Building...`;
130
+ await this.runner.executeCommand(runner_service_1.ProgramName.PNPM, ['run', 'build'], { cwd: lib.directory }, true);
131
+ // Publish
132
+ spinner.text = `${chalk.cyan(lib.name)}: Publishing to npm...`;
133
+ await this.runner.executeCommand(runner_service_1.ProgramName.PNPM, ['publish', '--access', 'public', '--no-git-checks'], { cwd: lib.directory }, true);
134
+ successCount++;
135
+ spinner.succeed(`${chalk.cyan(lib.name)} ${chalk.green('āœ“')} Built and published successfully`);
136
+ }
137
+ catch (error) {
138
+ failCount++;
139
+ failedLibraries.push(lib.name);
140
+ spinner.fail(`${chalk.cyan(lib.name)} ${chalk.red('āœ—')} Failed`);
141
+ this.log(chalk.red(`Error: ${error.message}`));
142
+ }
143
+ }
144
+ // Summary
145
+ const endTime = Date.now();
146
+ const duration = ((endTime - startTime) / 1000).toFixed(2);
147
+ console.log(chalk.gray('\n' + '═'.repeat(60)));
148
+ console.log(chalk.green.bold('\nšŸ“Š Deployment Summary:\n'));
149
+ console.log(chalk.green(` āœ… Successfully published: ${successCount}/${libraries.length}`));
150
+ if (failCount > 0) {
151
+ console.log(chalk.red(` āŒ Failed: ${failCount}/${libraries.length}`));
152
+ console.log(chalk.red('\n Failed libraries:'));
153
+ for (const name of failedLibraries) {
154
+ console.log(chalk.red(` • ${name}`));
155
+ }
156
+ }
157
+ console.log(chalk.blue(` ā±ļø Total time: ${duration}s`));
158
+ console.log(chalk.gray('\n' + '═'.repeat(60) + '\n'));
159
+ if (failCount > 0) {
160
+ throw new Error(`${failCount} library(ies) failed to publish`);
161
+ }
162
+ await this.showLibraryVersions(path, verbose);
163
+ }
164
+ catch (error) {
165
+ spinner.fail('Failed to sync and publish libraries.');
166
+ console.error(chalk.red('Error syncing and publishing libraries:'), error);
167
+ throw error;
168
+ }
169
+ finally {
170
+ restoreWarnings();
171
+ spinner.stop();
172
+ }
173
+ }
174
+ async showLibraryVersions(path, verbose = false) {
175
+ const restoreWarnings = this.suppressWarnings();
176
+ this.verbose = verbose;
177
+ path = await this.getRootPath(path);
178
+ const spinner = ora('Checking library versions...').start();
179
+ try {
180
+ const librariesPath = pathModule.join(path, 'libraries');
181
+ if (!(0, fs_1.existsSync)(librariesPath)) {
182
+ spinner.fail('Libraries directory not found.');
183
+ console.log(chalk.yellow('\nNo libraries directory found. Please create some libraries first.'));
184
+ return;
185
+ }
186
+ spinner.text = 'Scanning libraries...';
187
+ // Get all library directories
188
+ const libraryDirs = (0, fs_1.readdirSync)(librariesPath, { withFileTypes: true })
189
+ .filter((entry) => entry.isDirectory())
190
+ .map((entry) => pathModule.join(librariesPath, entry.name));
191
+ if (libraryDirs.length === 0) {
192
+ spinner.fail('No libraries found.');
193
+ console.log(chalk.yellow('\nNo libraries found in the libraries directory.'));
194
+ return;
195
+ }
196
+ spinner.succeed(`Found ${libraryDirs.length} libraries.`);
197
+ spinner.start('Checking package versions...');
198
+ const results = [];
199
+ for (const libDir of libraryDirs) {
200
+ const packageJsonPath = pathModule.join(libDir, 'package.json');
201
+ if (!(0, fs_1.existsSync)(packageJsonPath)) {
202
+ this.log(chalk.yellow(`Skipping ${libDir} - no package.json found`));
203
+ continue;
204
+ }
205
+ const packageJson = JSON.parse(await (0, promises_1.readFile)(packageJsonPath, 'utf8'));
206
+ const libraryFolder = pathModule.basename(libDir);
207
+ const packageName = packageJson.name;
208
+ const currentVersion = packageJson.version;
209
+ if (!packageName || !currentVersion) {
210
+ this.log(chalk.yellow(`Skipping ${libraryFolder} - missing name or version in package.json`));
211
+ continue;
212
+ }
213
+ spinner.text = `Checking ${packageName}...`;
214
+ try {
215
+ // Get latest version from npm
216
+ const result = await this.runner.executeCommand(runner_service_1.ProgramName.NPM, ['view', packageName, 'version'], {}, true);
217
+ const latestVersion = result.stdout.trim();
218
+ const status = currentVersion === latestVersion ? 'ok' : 'outdated';
219
+ results.push({
220
+ libraryFolder,
221
+ packageName,
222
+ currentVersion,
223
+ latestVersion,
224
+ status,
225
+ });
226
+ }
227
+ catch (error) {
228
+ // Check if package is not published
229
+ if (error.message &&
230
+ (error.message.includes('404') ||
231
+ error.message.includes('E404') ||
232
+ error.message.includes('Not Found'))) {
233
+ results.push({
234
+ libraryFolder,
235
+ packageName,
236
+ currentVersion,
237
+ latestVersion: 'N/A',
238
+ status: 'unpublished',
239
+ });
240
+ }
241
+ else {
242
+ results.push({
243
+ libraryFolder,
244
+ packageName,
245
+ currentVersion,
246
+ latestVersion: 'N/A',
247
+ status: 'error',
248
+ });
249
+ }
250
+ }
251
+ }
252
+ spinner.succeed('Version check completed.');
253
+ // Display results in a table
254
+ console.log(chalk.green.bold('\nšŸ“¦ Library Package Versions:\n'));
255
+ if (results.length === 0) {
256
+ console.log(chalk.yellow('No packages found in libraries.'));
257
+ return;
258
+ }
259
+ console.log(chalk.gray('─'.repeat(100)));
260
+ // Table header
261
+ const folderHeader = 'Folder'.padEnd(20);
262
+ const nameHeader = 'Package Name'.padEnd(40);
263
+ const currentHeader = 'Current'.padEnd(15);
264
+ const latestHeader = 'Latest'.padEnd(15);
265
+ const statusHeader = 'Status';
266
+ console.log(chalk.white.bold(`${folderHeader} ${nameHeader} ${currentHeader} ${latestHeader} ${statusHeader}`));
267
+ console.log(chalk.gray('─'.repeat(100)));
268
+ // Table rows
269
+ for (const pkg of results) {
270
+ const folder = pkg.libraryFolder.padEnd(20);
271
+ const name = pkg.packageName.padEnd(40);
272
+ const current = pkg.currentVersion.padEnd(15);
273
+ const latest = pkg.latestVersion.padEnd(15);
274
+ let statusText = '';
275
+ if (pkg.status === 'ok') {
276
+ statusText = chalk.green('āœ“ Up to date');
277
+ }
278
+ else if (pkg.status === 'outdated') {
279
+ statusText = chalk.yellow('⚠ Update available');
280
+ }
281
+ else if (pkg.status === 'unpublished') {
282
+ statusText = chalk.blue('ℹ Not published');
283
+ }
284
+ else {
285
+ statusText = chalk.red('āœ— Error');
286
+ }
287
+ console.log(`${folder} ${name} ${current} ${latest} ${statusText}`);
288
+ }
289
+ // Summary
290
+ const outdatedCount = results.filter((r) => r.status === 'outdated').length;
291
+ const okCount = results.filter((r) => r.status === 'ok').length;
292
+ const unpublishedCount = results.filter((r) => r.status === 'unpublished').length;
293
+ const errorCount = results.filter((r) => r.status === 'error').length;
294
+ console.log(chalk.gray('\n' + '─'.repeat(100)));
295
+ console.log(chalk.white.bold('\nSummary:'));
296
+ console.log(chalk.green(` āœ“ Up to date: ${okCount}`));
297
+ console.log(chalk.yellow(` ⚠ Updates available: ${outdatedCount}`));
298
+ console.log(chalk.blue(` ℹ Not published: ${unpublishedCount}`));
299
+ if (errorCount > 0) {
300
+ console.log(chalk.red(` āœ— Errors: ${errorCount}`));
301
+ }
302
+ console.log('');
303
+ }
304
+ catch (error) {
305
+ spinner.fail('Failed to check library versions.');
306
+ console.error(chalk.red('Error checking library versions:'), error);
307
+ throw error;
308
+ }
309
+ finally {
310
+ restoreWarnings();
311
+ spinner.stop();
312
+ }
313
+ }
314
+ async updateBootstrapFiles(path, verbose = false) {
315
+ const restoreWarnings = this.suppressWarnings();
316
+ this.verbose = verbose;
317
+ const spinner = ora('Updating bootstrap files...').start();
318
+ try {
319
+ path = await this.getRootPath(path);
320
+ const templatePath = pathModule.join(pathModule.dirname(path), 'template');
321
+ this.log(chalk.blue(`Source path: ${path}`));
322
+ this.log(chalk.blue(`Template path: ${templatePath}`));
323
+ // Clean template directory but keep .git
324
+ spinner.start('Cleaning template directory...');
325
+ if ((0, fs_1.existsSync)(templatePath)) {
326
+ const gitPath = pathModule.join(templatePath, '.git');
327
+ const hasGit = (0, fs_1.existsSync)(gitPath);
328
+ // Remove all items except .git directory
329
+ const entries = (0, fs_1.readdirSync)(templatePath, { withFileTypes: true });
330
+ for (const entry of entries) {
331
+ if (entry.name === '.git') {
332
+ this.log(chalk.gray('Skipping .git directory'));
333
+ continue;
334
+ }
335
+ const fullPath = pathModule.join(templatePath, entry.name);
336
+ await this.fileSystem.remove(fullPath);
337
+ this.log(chalk.gray(`Removed: ${entry.name}`));
338
+ }
339
+ this.log(chalk.gray('Cleaned template directory (preserved .git)'));
340
+ }
341
+ else {
342
+ await (0, promises_1.mkdir)(templatePath, { recursive: true });
343
+ this.log(chalk.blue('Template directory created.'));
344
+ }
345
+ spinner.succeed('Template directory cleaned.');
346
+ // Get all files tracked by git (respects .gitignore)
347
+ spinner.start('Getting list of files from repository...');
348
+ const result = await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['ls-files'], { cwd: path }, true);
349
+ const allFiles = result.stdout
350
+ .trim()
351
+ .split('\n')
352
+ .filter((f) => f.length > 0);
353
+ spinner.succeed(`Found ${allFiles.length} files in repository.`);
354
+ spinner.start('Filtering files...');
355
+ // Filter files from apps folder - only keep api and admin
356
+ const allowedAppsFolders = ['api', 'admin'];
357
+ const ignoredAppsFolders = new Set();
358
+ const files = allFiles.filter((file) => {
359
+ // Check if file is in apps directory
360
+ if (file.startsWith('apps/') || file.startsWith('apps\\')) {
361
+ const parts = file.split(/[/\\]/);
362
+ if (parts.length > 1) {
363
+ const appFolder = parts[1];
364
+ if (!allowedAppsFolders.includes(appFolder)) {
365
+ ignoredAppsFolders.add(appFolder);
366
+ return false;
367
+ }
368
+ }
369
+ }
370
+ return true;
371
+ });
372
+ spinner.succeed('Files filtered.');
373
+ // Display ignored folders
374
+ if (ignoredAppsFolders.size > 0) {
375
+ spinner.info(chalk.blue(`Ignored apps folders: ${Array.from(ignoredAppsFolders).join(', ')}`));
376
+ spinner.start('Copying files...');
377
+ }
378
+ this.log(chalk.blue(`Found ${files.length} files to copy (${allFiles.length - files.length} files ignored)`));
379
+ // Copy each file maintaining directory structure
380
+ spinner.start('Copying files...');
381
+ let copiedCount = 0;
382
+ for (const file of files) {
383
+ const sourcePath = pathModule.join(path, file);
384
+ const destPath = pathModule.join(templatePath, file);
385
+ // Create directory if it doesn't exist
386
+ const destDir = pathModule.dirname(destPath);
387
+ if (!(0, fs_1.existsSync)(destDir)) {
388
+ await (0, promises_1.mkdir)(destDir, { recursive: true });
389
+ }
390
+ // Copy file
391
+ await this.fileSystem.copyFile(sourcePath, destPath);
392
+ copiedCount++;
393
+ if (verbose && copiedCount % 100 === 0) {
394
+ spinner.text = `Copying files... (${copiedCount}/${files.length})`;
395
+ }
396
+ }
397
+ // Commit and push changes to git
398
+ spinner.start('Committing changes to git...');
399
+ try {
400
+ await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['add', '.'], { cwd: templatePath }, true);
401
+ // Check if there are changes to commit
402
+ const statusResult = await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['status', '--porcelain'], { cwd: templatePath }, true);
403
+ if (statusResult.stdout.trim().length > 0) {
404
+ const now = new Date();
405
+ const dateStr = now.toLocaleDateString('en-US', {
406
+ year: 'numeric',
407
+ month: 'short',
408
+ day: 'numeric',
409
+ });
410
+ const timeStr = now.toLocaleTimeString('en-US', {
411
+ hour: '2-digit',
412
+ minute: '2-digit',
413
+ });
414
+ const commitMessage = `chore: update bootstrap files - ${dateStr} at ${timeStr}`;
415
+ await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['commit', '-m', commitMessage], { cwd: templatePath }, true);
416
+ spinner.text = 'Pushing changes to remote repository...';
417
+ await this.runner.executeCommand(runner_service_1.ProgramName.GIT, ['push'], { cwd: templatePath }, true);
418
+ spinner.succeed(`Bootstrap files updated successfully. ${copiedCount} files copied and pushed to ${templatePath}`);
419
+ }
420
+ else {
421
+ spinner.succeed(`Bootstrap files updated successfully. ${copiedCount} files copied (no changes to commit)`);
422
+ }
423
+ }
424
+ catch (gitError) {
425
+ spinner.warn(`Bootstrap files copied (${copiedCount} files) but git operations failed. You may need to commit manually.`);
426
+ this.log(chalk.yellow('Git error:'), gitError.message);
427
+ }
428
+ this.log(chalk.green(`Successfully copied ${copiedCount} files to template directory.`));
429
+ }
430
+ catch (error) {
431
+ spinner.fail('Failed to update bootstrap files.');
432
+ console.error(chalk.red('Error updating bootstrap files:'), error);
433
+ throw error;
434
+ }
435
+ finally {
436
+ restoreWarnings();
437
+ spinner.stop();
438
+ }
439
+ }
41
440
  async route(path, verbose = false) {
441
+ const restoreWarnings = this.suppressWarnings();
42
442
  this.verbose = verbose;
43
443
  const spinner = ora('Analyzing NestJS routes...').start();
44
444
  try {
@@ -94,6 +494,7 @@ let DeveloperService = class DeveloperService {
94
494
  throw error;
95
495
  }
96
496
  finally {
497
+ restoreWarnings();
97
498
  spinner.stop();
98
499
  }
99
500
  }
@@ -214,6 +615,32 @@ let DeveloperService = class DeveloperService {
214
615
  };
215
616
  return colors[method] || chalk.white;
216
617
  }
618
+ parseVersion(version) {
619
+ const match = version.match(/^(\d+)\.(\d+)\.(\d+)/);
620
+ if (!match) {
621
+ throw new Error(`Invalid version format: ${version}`);
622
+ }
623
+ return {
624
+ major: parseInt(match[1], 10),
625
+ minor: parseInt(match[2], 10),
626
+ patch: parseInt(match[3], 10),
627
+ };
628
+ }
629
+ compareVersions(v1, v2) {
630
+ const parsed1 = this.parseVersion(v1);
631
+ const parsed2 = this.parseVersion(v2);
632
+ if (parsed1.major !== parsed2.major) {
633
+ return parsed1.major - parsed2.major;
634
+ }
635
+ if (parsed1.minor !== parsed2.minor) {
636
+ return parsed1.minor - parsed2.minor;
637
+ }
638
+ return parsed1.patch - parsed2.patch;
639
+ }
640
+ incrementPatchVersion(version) {
641
+ const parsed = this.parseVersion(version);
642
+ return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
643
+ }
217
644
  async createLibrary(path, libraryName, force = false, verbose = false, skipInstall = false) {
218
645
  this.verbose = verbose;
219
646
  this.log(chalk.blue('Starting library creation...'));
@@ -388,6 +815,7 @@ let DeveloperService = class DeveloperService {
388
815
  .replace(/-/g, '_');
389
816
  }
390
817
  async resetDevelopmentEnvironment(cwd, verbose = false) {
818
+ const restoreWarnings = this.suppressWarnings();
391
819
  this.verbose = verbose;
392
820
  const spinner = ora('Resetting development environment...').start();
393
821
  try {
@@ -404,6 +832,7 @@ let DeveloperService = class DeveloperService {
404
832
  throw error;
405
833
  }
406
834
  finally {
835
+ restoreWarnings();
407
836
  spinner.stop();
408
837
  }
409
838
  }
@@ -553,6 +982,7 @@ let DeveloperService = class DeveloperService {
553
982
  }
554
983
  }
555
984
  async backupDatabase(cwd, verbose = false) {
985
+ const restoreWarnings = this.suppressWarnings();
556
986
  this.verbose = verbose;
557
987
  this.log('Backing up database...');
558
988
  const spinner = ora('Backing up database...').start();
@@ -624,10 +1054,12 @@ let DeveloperService = class DeveloperService {
624
1054
  throw error;
625
1055
  }
626
1056
  finally {
1057
+ restoreWarnings();
627
1058
  spinner.stop();
628
1059
  }
629
1060
  }
630
1061
  async initDatabase(cwd, verbose = false) {
1062
+ const restoreWarnings = this.suppressWarnings();
631
1063
  this.verbose = verbose;
632
1064
  this.log('Initializing database...');
633
1065
  const spinner = ora('Initializing database...').start();
@@ -687,10 +1119,12 @@ let DeveloperService = class DeveloperService {
687
1119
  throw error;
688
1120
  }
689
1121
  finally {
1122
+ restoreWarnings();
690
1123
  spinner.stop();
691
1124
  }
692
1125
  }
693
1126
  async restoreDatabase(cwd, verbose = false) {
1127
+ const restoreWarnings = this.suppressWarnings();
694
1128
  this.verbose = verbose;
695
1129
  this.log('Restoring database from backup...');
696
1130
  const spinner = ora('Restoring database from backup...').start();
@@ -886,9 +1320,49 @@ let DeveloperService = class DeveloperService {
886
1320
  throw error;
887
1321
  }
888
1322
  finally {
1323
+ restoreWarnings();
889
1324
  spinner.stop();
890
1325
  }
891
1326
  }
1327
+ async listHedHogPackages() {
1328
+ const restoreWarnings = this.suppressWarnings();
1329
+ const spinner = ora('Fetching @hed-hog packages...').start();
1330
+ try {
1331
+ // Fetch packages from npm registry
1332
+ const response = await fetch('https://registry.npmjs.org/-/v1/search?text=scope:hed-hog&size=250');
1333
+ if (!response.ok) {
1334
+ throw new Error(`HTTP error! status: ${response.status}`);
1335
+ }
1336
+ const data = await response.json();
1337
+ const packages = data.objects;
1338
+ spinner.succeed(chalk.green(`Found ${packages.length} package(s) in @hed-hog:`));
1339
+ if (packages.length === 0) {
1340
+ console.log(chalk.yellow('\nNo packages found.'));
1341
+ return;
1342
+ }
1343
+ console.log('');
1344
+ // Sort packages alphabetically by name
1345
+ packages.sort((a, b) => a.package.name.localeCompare(b.package.name));
1346
+ // Display packages in a formatted table
1347
+ packages.forEach((pkg) => {
1348
+ const name = chalk.cyan(pkg.package.name);
1349
+ const version = chalk.gray(`v${pkg.package.version}`);
1350
+ const description = pkg.package.description || chalk.gray('No description');
1351
+ console.log(`${name} ${version}`);
1352
+ console.log(` ${description}`);
1353
+ console.log('');
1354
+ });
1355
+ console.log(chalk.gray(`Total: ${packages.length} package(s)`));
1356
+ }
1357
+ catch (error) {
1358
+ spinner.fail('Failed to fetch packages.');
1359
+ console.error(chalk.red('Error:'), error.message);
1360
+ throw error;
1361
+ }
1362
+ finally {
1363
+ restoreWarnings();
1364
+ }
1365
+ }
892
1366
  };
893
1367
  exports.DeveloperService = DeveloperService;
894
1368
  exports.DeveloperService = DeveloperService = __decorate([