@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.
- package/dist/package.json +1 -1
- package/dist/src/app.module.js +8 -0
- package/dist/src/app.module.js.map +1 -1
- package/dist/src/commands/dev.command/library-version.subcommand.d.ts +10 -0
- package/dist/src/commands/dev.command/library-version.subcommand.js +47 -0
- package/dist/src/commands/dev.command/library-version.subcommand.js.map +1 -0
- package/dist/src/commands/dev.command/list-packages.subcommand.d.ts +7 -0
- package/dist/src/commands/dev.command/list-packages.subcommand.js +34 -0
- package/dist/src/commands/dev.command/list-packages.subcommand.js.map +1 -0
- package/dist/src/commands/dev.command/sync-publish.subcommand.d.ts +10 -0
- package/dist/src/commands/dev.command/sync-publish.subcommand.js +47 -0
- package/dist/src/commands/dev.command/sync-publish.subcommand.js.map +1 -0
- package/dist/src/commands/dev.command/update-bootstrap.subcommand.d.ts +10 -0
- package/dist/src/commands/dev.command/update-bootstrap.subcommand.js +47 -0
- package/dist/src/commands/dev.command/update-bootstrap.subcommand.js.map +1 -0
- package/dist/src/commands/dev.command.js +8 -0
- package/dist/src/commands/dev.command.js.map +1 -1
- package/dist/src/modules/developer/developer.service.d.ts +8 -0
- package/dist/src/modules/developer/developer.service.js +474 -0
- package/dist/src/modules/developer/developer.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -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([
|