katax-cli 1.1.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.
Files changed (34) hide show
  1. package/dist/commands/add-endpoint.d.ts.map +1 -1
  2. package/dist/commands/add-endpoint.js +121 -97
  3. package/dist/commands/add-endpoint.js.map +1 -1
  4. package/dist/commands/deploy.d.ts +3 -0
  5. package/dist/commands/deploy.d.ts.map +1 -1
  6. package/dist/commands/deploy.js +287 -153
  7. package/dist/commands/deploy.js.map +1 -1
  8. package/dist/commands/generate-crud.d.ts.map +1 -1
  9. package/dist/commands/generate-crud.js +60 -56
  10. package/dist/commands/generate-crud.js.map +1 -1
  11. package/dist/commands/generate-docs.d.ts +8 -0
  12. package/dist/commands/generate-docs.d.ts.map +1 -0
  13. package/dist/commands/generate-docs.js +159 -0
  14. package/dist/commands/generate-docs.js.map +1 -0
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +506 -244
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/index.js +83 -69
  19. package/dist/index.js.map +1 -1
  20. package/dist/services/openapi-generator.service.d.ts +37 -0
  21. package/dist/services/openapi-generator.service.d.ts.map +1 -0
  22. package/dist/services/openapi-generator.service.js +333 -0
  23. package/dist/services/openapi-generator.service.js.map +1 -0
  24. package/dist/services/project-structure-generator.d.ts +1 -1
  25. package/dist/services/project-structure-generator.d.ts.map +1 -1
  26. package/dist/services/project-structure-generator.js +443 -445
  27. package/dist/services/project-structure-generator.js.map +1 -1
  28. package/dist/templates/generators/swagger-template.d.ts +3 -0
  29. package/dist/templates/generators/swagger-template.d.ts.map +1 -0
  30. package/dist/templates/generators/swagger-template.js +117 -0
  31. package/dist/templates/generators/swagger-template.js.map +1 -0
  32. package/dist/types/index.d.ts +19 -10
  33. package/dist/types/index.d.ts.map +1 -1
  34. package/package.json +1 -1
@@ -1,96 +1,96 @@
1
- import chalk from 'chalk';
2
- import inquirer from 'inquirer';
3
- import ora from 'ora';
4
- import path from 'path';
5
- import { execa } from 'execa';
6
- import { success, error, warning, title, info, gray } from '../utils/logger.js';
7
- import { directoryExists, writeFile } from '../utils/file-utils.js';
1
+ import chalk from "chalk";
2
+ import inquirer from "inquirer";
3
+ import ora from "ora";
4
+ import path from "path";
5
+ import { execa } from "execa";
6
+ import { success, error, warning, title, info, gray } from "../utils/logger.js";
7
+ import { directoryExists, writeFile, fileExists } from "../utils/file-utils.js";
8
8
  export async function deployInitCommand() {
9
- title('šŸš€ Katax Deploy - Initial Setup');
9
+ title("šŸš€ Katax Deploy - Initial Setup");
10
10
  const pm2Installed = await checkPM2Installation();
11
11
  if (!pm2Installed) {
12
- error('PM2 is not installed globally!');
13
- info('Install with: npm install -g pm2');
12
+ error("PM2 is not installed globally!");
13
+ info("Install with: npm install -g pm2");
14
14
  process.exit(1);
15
15
  }
16
16
  const answers = await inquirer.prompt([
17
17
  {
18
- type: 'input',
19
- name: 'appName',
20
- message: 'Application name for PM2:',
21
- default: 'my-api',
18
+ type: "input",
19
+ name: "appName",
20
+ message: "Application name for PM2:",
21
+ default: "my-api",
22
22
  validate: (input) => {
23
23
  if (!/^[a-z0-9-_]+$/i.test(input)) {
24
- return 'App name can only contain letters, numbers, hyphens, and underscores';
24
+ return "App name can only contain letters, numbers, hyphens, and underscores";
25
25
  }
26
26
  return true;
27
- }
27
+ },
28
28
  },
29
29
  {
30
- type: 'list',
31
- name: 'repoType',
32
- message: 'Repository connection type:',
30
+ type: "list",
31
+ name: "repoType",
32
+ message: "Repository connection type:",
33
33
  choices: [
34
- { name: 'HTTPS (username/password or token)', value: 'https' },
35
- { name: 'SSH (requires SSH key setup)', value: 'ssh' }
34
+ { name: "HTTPS (username/password or token)", value: "https" },
35
+ { name: "SSH (requires SSH key setup)", value: "ssh" },
36
36
  ],
37
- default: 'https'
37
+ default: "https",
38
38
  },
39
39
  {
40
- type: 'input',
41
- name: 'repoUrl',
42
- message: 'Git repository URL:',
40
+ type: "input",
41
+ name: "repoUrl",
42
+ message: "Git repository URL:",
43
43
  validate: (input) => {
44
44
  if (!input)
45
- return 'Repository URL is required';
46
- if (!input.includes('git') && !input.includes('.git')) {
47
- return 'Please provide a valid Git repository URL';
45
+ return "Repository URL is required";
46
+ if (!input.includes("git") && !input.includes(".git")) {
47
+ return "Please provide a valid Git repository URL";
48
48
  }
49
49
  return true;
50
- }
50
+ },
51
51
  },
52
52
  {
53
- type: 'input',
54
- name: 'branch',
55
- message: 'Branch to deploy:',
56
- default: 'main'
53
+ type: "input",
54
+ name: "branch",
55
+ message: "Branch to deploy:",
56
+ default: "main",
57
57
  },
58
58
  {
59
- type: 'input',
60
- name: 'installPath',
61
- message: 'Installation path (absolute):',
62
- default: `/home/${process.env.USER || 'ubuntu'}/apps`,
59
+ type: "input",
60
+ name: "installPath",
61
+ message: "Installation path (absolute):",
62
+ default: `/home/${process.env.USER || "ubuntu"}/apps`,
63
63
  validate: (input) => {
64
64
  if (!path.isAbsolute(input)) {
65
- return 'Please provide an absolute path';
65
+ return "Please provide an absolute path";
66
66
  }
67
67
  return true;
68
- }
68
+ },
69
69
  },
70
70
  {
71
- type: 'list',
72
- name: 'instances',
73
- message: 'PM2 instances (cluster mode):',
71
+ type: "list",
72
+ name: "instances",
73
+ message: "PM2 instances (cluster mode):",
74
74
  choices: [
75
- { name: 'Max (use all CPU cores)', value: 'max' },
76
- { name: '1 instance', value: 1 },
77
- { name: '2 instances', value: 2 },
78
- { name: '4 instances', value: 4 }
75
+ { name: "Max (use all CPU cores)", value: "max" },
76
+ { name: "1 instance", value: 1 },
77
+ { name: "2 instances", value: 2 },
78
+ { name: "4 instances", value: 4 },
79
79
  ],
80
- default: 'max'
80
+ default: "max",
81
81
  },
82
82
  {
83
- type: 'input',
84
- name: 'maxMemory',
85
- message: 'Max memory per instance (e.g., 512M, 1G):',
86
- default: '512M'
83
+ type: "input",
84
+ name: "maxMemory",
85
+ message: "Max memory per instance (e.g., 512M, 1G):",
86
+ default: "512M",
87
87
  },
88
88
  {
89
- type: 'confirm',
90
- name: 'addEnvVars',
91
- message: 'Add environment variables?',
92
- default: true
93
- }
89
+ type: "confirm",
90
+ name: "addEnvVars",
91
+ message: "Add environment variables?",
92
+ default: true,
93
+ },
94
94
  ]);
95
95
  let envVars = {};
96
96
  if (answers.addEnvVars) {
@@ -104,108 +104,180 @@ export async function deployInitCommand() {
104
104
  pm2Config: {
105
105
  instances: answers.instances,
106
106
  maxMemory: answers.maxMemory,
107
- env: envVars
108
- }
107
+ env: envVars,
108
+ },
109
109
  };
110
110
  await executeInitialDeploy(deployConfig);
111
111
  }
112
112
  export async function deployUpdateCommand(options) {
113
- title('šŸ”„ Katax Deploy - Update Application');
113
+ title("šŸ”„ Katax Deploy - Update Application");
114
114
  const isGitRepo = await checkGitRepository();
115
115
  if (!isGitRepo) {
116
- error('Not a git repository! Run this command from your project directory.');
117
- info('Or use: katax deploy init');
116
+ error("Not a git repository! Run this command from your project directory.");
117
+ info("Or use: katax deploy init");
118
118
  process.exit(1);
119
119
  }
120
120
  const pm2Installed = await checkPM2Installation();
121
121
  if (!pm2Installed) {
122
- error('PM2 is not installed globally!');
123
- info('Install with: npm install -g pm2');
122
+ error("PM2 is not installed globally!");
123
+ info("Install with: npm install -g pm2");
124
124
  process.exit(1);
125
125
  }
126
126
  const currentDir = process.cwd();
127
- const appName = path.basename(currentDir);
127
+ let appName = options.appName;
128
+ let wasAutoDiscovered = false;
129
+ if (!appName) {
130
+ const discovered = await discoverPM2AppName(currentDir);
131
+ if (discovered) {
132
+ appName = discovered;
133
+ wasAutoDiscovered = true;
134
+ info(`šŸ” Discovered PM2 app: ${chalk.cyan(appName)}`);
135
+ }
136
+ }
137
+ if (!appName) {
138
+ const configPath = path.join(currentDir, ".katax-deploy.json");
139
+ if (fileExists(configPath)) {
140
+ try {
141
+ const fs = await import("fs");
142
+ const configContent = fs.readFileSync(configPath, "utf-8");
143
+ const config = JSON.parse(configContent);
144
+ appName = config.appName;
145
+ info(`šŸ“ Using app name from config: ${chalk.cyan(appName)}`);
146
+ }
147
+ catch (err) {
148
+ }
149
+ }
150
+ }
151
+ if (!appName) {
152
+ appName = path.basename(currentDir);
153
+ warning(`āš ļø Using directory name as fallback: ${chalk.yellow(appName)}`);
154
+ info(`šŸ’” Tip: Run ${chalk.cyan("pm2 list")} to verify the app name`);
155
+ }
128
156
  let targetBranch = options.branch;
129
157
  if (!targetBranch) {
130
- const branchResult = await execa('git', ['branch', '--show-current']);
158
+ const branchResult = await execa("git", ["branch", "--show-current"]);
131
159
  targetBranch = branchResult.stdout.trim();
132
160
  }
161
+ if (wasAutoDiscovered && appName) {
162
+ await saveAppNameToConfig(currentDir, appName, targetBranch);
163
+ }
133
164
  info(`šŸ“¦ Application: ${chalk.cyan(appName)}`);
134
165
  info(`🌿 Branch: ${chalk.cyan(targetBranch)}`);
135
166
  if (options.hard) {
136
- warning('āš ļø Hard reset enabled - all local changes will be lost!');
167
+ warning("āš ļø Hard reset enabled - all local changes will be lost!");
137
168
  }
138
169
  const { confirm } = await inquirer.prompt([
139
170
  {
140
- type: 'confirm',
141
- name: 'confirm',
142
- message: 'Proceed with update?',
143
- default: true
144
- }
171
+ type: "confirm",
172
+ name: "confirm",
173
+ message: "Proceed with update?",
174
+ default: true,
175
+ },
145
176
  ]);
146
177
  if (!confirm) {
147
- warning('Update cancelled');
178
+ warning("Update cancelled");
148
179
  return;
149
180
  }
150
181
  await executeUpdate(appName, targetBranch, options.hard || false);
182
+ if (!wasAutoDiscovered) {
183
+ await saveAppNameToConfig(currentDir, appName, targetBranch, true);
184
+ }
151
185
  }
152
186
  export async function deployRollbackCommand(options) {
153
- title('ā®ļø Katax Deploy - Rollback');
187
+ title("ā®ļø Katax Deploy - Rollback");
154
188
  const isGitRepo = await checkGitRepository();
155
189
  if (!isGitRepo) {
156
- error('Not a git repository!');
190
+ error("Not a git repository!");
157
191
  process.exit(1);
158
192
  }
159
193
  const commits = options.commits || 1;
160
194
  const currentDir = process.cwd();
161
- const appName = path.basename(currentDir);
195
+ let appName = options.appName;
196
+ if (!appName) {
197
+ appName = (await discoverPM2AppName(currentDir)) || undefined;
198
+ }
199
+ if (!appName) {
200
+ const configPath = path.join(currentDir, ".katax-deploy.json");
201
+ if (fileExists(configPath)) {
202
+ try {
203
+ const fs = await import("fs");
204
+ const configContent = fs.readFileSync(configPath, "utf-8");
205
+ const config = JSON.parse(configContent);
206
+ appName = config.appName;
207
+ }
208
+ catch (err) {
209
+ }
210
+ }
211
+ }
212
+ if (!appName) {
213
+ appName = path.basename(currentDir);
214
+ }
162
215
  warning(`Rolling back ${commits} commit(s) for ${appName}`);
163
216
  const { confirm } = await inquirer.prompt([
164
217
  {
165
- type: 'confirm',
166
- name: 'confirm',
167
- message: 'This will reset your code. Continue?',
168
- default: false
169
- }
218
+ type: "confirm",
219
+ name: "confirm",
220
+ message: "This will reset your code. Continue?",
221
+ default: false,
222
+ },
170
223
  ]);
171
224
  if (!confirm) {
172
- warning('Rollback cancelled');
225
+ warning("Rollback cancelled");
173
226
  return;
174
227
  }
175
228
  await executeRollback(appName, commits);
176
229
  }
177
230
  export async function deployLogsCommand(options) {
178
231
  const currentDir = process.cwd();
179
- const appName = path.basename(currentDir);
232
+ let appName = options.appName;
233
+ if (!appName) {
234
+ appName = (await discoverPM2AppName(currentDir)) || undefined;
235
+ }
236
+ if (!appName) {
237
+ const configPath = path.join(currentDir, ".katax-deploy.json");
238
+ if (fileExists(configPath)) {
239
+ try {
240
+ const fs = await import("fs");
241
+ const configContent = fs.readFileSync(configPath, "utf-8");
242
+ const config = JSON.parse(configContent);
243
+ appName = config.appName;
244
+ }
245
+ catch (err) {
246
+ }
247
+ }
248
+ }
249
+ if (!appName) {
250
+ appName = path.basename(currentDir);
251
+ }
180
252
  title(`šŸ“‹ PM2 Logs - ${appName}`);
181
- const args = ['logs', appName];
253
+ const args = ["logs", appName];
182
254
  if (options.lines) {
183
- args.push('--lines', options.lines.toString());
255
+ args.push("--lines", options.lines.toString());
184
256
  }
185
257
  if (!options.follow) {
186
- args.push('--nostream');
258
+ args.push("--nostream");
187
259
  }
188
260
  try {
189
- await execa('pm2', args, { stdio: 'inherit' });
261
+ await execa("pm2", args, { stdio: "inherit" });
190
262
  }
191
263
  catch (err) {
192
- error('Failed to fetch logs');
264
+ error("Failed to fetch logs");
193
265
  console.error(err);
194
266
  }
195
267
  }
196
268
  export async function deployStatusCommand() {
197
- title('šŸ“Š PM2 Status');
269
+ title("šŸ“Š PM2 Status");
198
270
  try {
199
- await execa('pm2', ['list'], { stdio: 'inherit' });
271
+ await execa("pm2", ["list"], { stdio: "inherit" });
200
272
  }
201
273
  catch (err) {
202
- error('Failed to get PM2 status');
274
+ error("Failed to get PM2 status");
203
275
  console.error(err);
204
276
  }
205
277
  }
206
278
  async function checkPM2Installation() {
207
279
  try {
208
- await execa('pm2', ['--version']);
280
+ await execa("pm2", ["--version"]);
209
281
  return true;
210
282
  }
211
283
  catch {
@@ -214,32 +286,80 @@ async function checkPM2Installation() {
214
286
  }
215
287
  async function checkGitRepository() {
216
288
  try {
217
- await execa('git', ['rev-parse', '--git-dir']);
289
+ await execa("git", ["rev-parse", "--git-dir"]);
218
290
  return true;
219
291
  }
220
292
  catch {
221
293
  return false;
222
294
  }
223
295
  }
296
+ async function saveAppNameToConfig(projectDir, appName, branch, silent = false) {
297
+ try {
298
+ const configPath = path.join(projectDir, ".katax-deploy.json");
299
+ if (fileExists(configPath)) {
300
+ return;
301
+ }
302
+ const config = {
303
+ appName: appName,
304
+ createdAt: new Date().toISOString(),
305
+ branch: branch,
306
+ autoDiscovered: true,
307
+ };
308
+ await writeFile(configPath, JSON.stringify(config, null, 2));
309
+ if (!silent) {
310
+ success(`šŸ’¾ Saved app name to .katax-deploy.json for future deployments`);
311
+ }
312
+ }
313
+ catch (err) {
314
+ }
315
+ }
316
+ async function discoverPM2AppName(targetDir) {
317
+ try {
318
+ const { stdout } = await execa("pm2", ["jlist"]);
319
+ const processes = JSON.parse(stdout);
320
+ const normalizedTargetDir = path.resolve(targetDir).toLowerCase();
321
+ for (const proc of processes) {
322
+ if (proc.pm2_env && proc.pm2_env.pm_cwd) {
323
+ const procDir = path.resolve(proc.pm2_env.pm_cwd).toLowerCase();
324
+ if (procDir === normalizedTargetDir) {
325
+ return proc.name;
326
+ }
327
+ }
328
+ if (proc.pm2_env && proc.pm2_env.pm_exec_path) {
329
+ const execDir = path
330
+ .resolve(path.dirname(proc.pm2_env.pm_exec_path))
331
+ .toLowerCase();
332
+ if (execDir === normalizedTargetDir ||
333
+ execDir.startsWith(normalizedTargetDir)) {
334
+ return proc.name;
335
+ }
336
+ }
337
+ }
338
+ return null;
339
+ }
340
+ catch (err) {
341
+ return null;
342
+ }
343
+ }
224
344
  async function collectEnvVars() {
225
345
  const envVars = {};
226
- info('\nšŸ“ Add environment variables (leave empty to finish):\n');
346
+ info("\nšŸ“ Add environment variables (leave empty to finish):\n");
227
347
  while (true) {
228
348
  const { key } = await inquirer.prompt([
229
349
  {
230
- type: 'input',
231
- name: 'key',
232
- message: 'Variable name:',
233
- }
350
+ type: "input",
351
+ name: "key",
352
+ message: "Variable name:",
353
+ },
234
354
  ]);
235
355
  if (!key)
236
356
  break;
237
357
  const { value } = await inquirer.prompt([
238
358
  {
239
- type: 'input',
240
- name: 'value',
359
+ type: "input",
360
+ name: "value",
241
361
  message: `Value for ${key}:`,
242
- }
362
+ },
243
363
  ]);
244
364
  envVars[key] = value;
245
365
  success(`āœ“ ${key} added`);
@@ -252,124 +372,138 @@ async function executeInitialDeploy(config) {
252
372
  error(`Directory ${fullPath} already exists!`);
253
373
  process.exit(1);
254
374
  }
255
- const cloneSpinner = ora('Cloning repository...').start();
375
+ const deployConfigFile = {
376
+ appName: config.appName,
377
+ createdAt: new Date().toISOString(),
378
+ branch: config.branch,
379
+ };
380
+ await writeFile(path.join(fullPath, ".katax-deploy.json"), JSON.stringify(deployConfigFile, null, 2));
381
+ const cloneSpinner = ora("Cloning repository...").start();
256
382
  try {
257
- await execa('git', ['clone', '--branch', config.branch, config.repoUrl, fullPath]);
258
- cloneSpinner.succeed('Repository cloned');
383
+ await execa("git", [
384
+ "clone",
385
+ "--branch",
386
+ config.branch,
387
+ config.repoUrl,
388
+ fullPath,
389
+ ]);
390
+ cloneSpinner.succeed("Repository cloned");
259
391
  }
260
392
  catch (err) {
261
- cloneSpinner.fail('Failed to clone repository');
393
+ cloneSpinner.fail("Failed to clone repository");
262
394
  console.error(err);
263
395
  process.exit(1);
264
396
  }
265
- const installSpinner = ora('Installing dependencies...').start();
397
+ const installSpinner = ora("Installing dependencies...").start();
266
398
  try {
267
- await execa('npm', ['install'], { cwd: fullPath });
268
- installSpinner.succeed('Dependencies installed');
399
+ await execa("npm", ["install"], { cwd: fullPath });
400
+ installSpinner.succeed("Dependencies installed");
269
401
  }
270
402
  catch (err) {
271
- installSpinner.fail('Failed to install dependencies');
403
+ installSpinner.fail("Failed to install dependencies");
272
404
  console.error(err);
273
405
  process.exit(1);
274
406
  }
275
- const buildSpinner = ora('Building project...').start();
407
+ const buildSpinner = ora("Building project...").start();
276
408
  try {
277
- await execa('npm', ['run', 'build'], { cwd: fullPath });
278
- buildSpinner.succeed('Project built');
409
+ await execa("npm", ["run", "build"], { cwd: fullPath });
410
+ buildSpinner.succeed("Project built");
279
411
  }
280
412
  catch (err) {
281
- buildSpinner.fail('Failed to build project');
413
+ buildSpinner.fail("Failed to build project");
282
414
  console.error(err);
283
415
  process.exit(1);
284
416
  }
285
417
  await generatePM2Config(fullPath, config);
286
- const pm2Spinner = ora('Starting with PM2...').start();
418
+ const pm2Spinner = ora("Starting with PM2...").start();
287
419
  try {
288
- await execa('pm2', ['start', 'ecosystem.config.cjs', '--env', 'production'], { cwd: fullPath });
289
- await execa('pm2', ['save']);
290
- pm2Spinner.succeed('Application started with PM2');
420
+ await execa("pm2", ["start", "ecosystem.config.cjs", "--env", "production"], { cwd: fullPath });
421
+ await execa("pm2", ["save"]);
422
+ pm2Spinner.succeed("Application started with PM2");
291
423
  }
292
424
  catch (err) {
293
- pm2Spinner.fail('Failed to start with PM2');
425
+ pm2Spinner.fail("Failed to start with PM2");
294
426
  console.error(err);
295
427
  process.exit(1);
296
428
  }
297
429
  success(`\nāœ… Deployment completed successfully!`);
298
430
  info(`\nšŸ“ Location: ${fullPath}`);
299
431
  info(`šŸ”§ PM2 App Name: ${config.appName}`);
432
+ info(`šŸ“ Config saved: .katax-deploy.json`);
300
433
  info(`\nUseful commands:`);
301
434
  gray(` pm2 logs ${config.appName} # View logs`);
302
435
  gray(` pm2 restart ${config.appName} # Restart app`);
303
436
  gray(` pm2 stop ${config.appName} # Stop app`);
304
- gray(` katax deploy update # Update deployment\n`);
437
+ gray(` katax deploy update # Update deployment`);
438
+ gray(` katax deploy update --app-name ${config.appName} # Specify app name\n`);
305
439
  }
306
440
  async function executeUpdate(appName, branch, hard) {
307
441
  const currentDir = process.cwd();
308
- const gitSpinner = ora('Updating code from git...').start();
442
+ const gitSpinner = ora("Updating code from git...").start();
309
443
  try {
310
- await execa('git', ['fetch', 'origin', branch]);
444
+ await execa("git", ["fetch", "origin", branch]);
311
445
  if (hard) {
312
- await execa('git', ['reset', '--hard', `origin/${branch}`]);
446
+ await execa("git", ["reset", "--hard", `origin/${branch}`]);
313
447
  }
314
448
  else {
315
- await execa('git', ['pull', 'origin', branch]);
449
+ await execa("git", ["pull", "origin", branch]);
316
450
  }
317
- gitSpinner.succeed('Code updated');
451
+ gitSpinner.succeed("Code updated");
318
452
  }
319
453
  catch (err) {
320
- gitSpinner.fail('Git update failed');
454
+ gitSpinner.fail("Git update failed");
321
455
  error(err.message);
322
456
  process.exit(1);
323
457
  }
324
- const installSpinner = ora('Installing dependencies...').start();
458
+ const installSpinner = ora("Installing dependencies...").start();
325
459
  try {
326
- await execa('npm', ['install'], { cwd: currentDir });
327
- installSpinner.succeed('Dependencies updated');
460
+ await execa("npm", ["install"], { cwd: currentDir });
461
+ installSpinner.succeed("Dependencies updated");
328
462
  }
329
463
  catch (err) {
330
- installSpinner.fail('Failed to install dependencies');
464
+ installSpinner.fail("Failed to install dependencies");
331
465
  console.error(err);
332
466
  process.exit(1);
333
467
  }
334
- const buildSpinner = ora('Building project...').start();
468
+ const buildSpinner = ora("Building project...").start();
335
469
  try {
336
- await execa('npm', ['run', 'build'], { cwd: currentDir });
337
- buildSpinner.succeed('Project rebuilt');
470
+ await execa("npm", ["run", "build"], { cwd: currentDir });
471
+ buildSpinner.succeed("Project rebuilt");
338
472
  }
339
473
  catch (err) {
340
- buildSpinner.fail('Build failed');
474
+ buildSpinner.fail("Build failed");
341
475
  console.error(err);
342
476
  process.exit(1);
343
477
  }
344
- const pm2Spinner = ora('Restarting PM2...').start();
478
+ const pm2Spinner = ora("Restarting PM2...").start();
345
479
  try {
346
- await execa('pm2', ['restart', appName]);
347
- pm2Spinner.succeed('Application restarted');
480
+ await execa("pm2", ["restart", appName]);
481
+ pm2Spinner.succeed("Application restarted");
348
482
  }
349
483
  catch (err) {
350
- pm2Spinner.fail('PM2 restart failed');
484
+ pm2Spinner.fail("PM2 restart failed");
351
485
  console.error(err);
352
486
  process.exit(1);
353
487
  }
354
- success('\nāœ… Update completed successfully!');
488
+ success("\nāœ… Update completed successfully!");
355
489
  info(`\nView logs with: pm2 logs ${appName}\n`);
356
490
  }
357
491
  async function executeRollback(appName, commits) {
358
492
  const rollbackSpinner = ora(`Rolling back ${commits} commit(s)...`).start();
359
493
  try {
360
- await execa('git', ['reset', '--hard', `HEAD~${commits}`]);
361
- rollbackSpinner.succeed('Code rolled back');
362
- const buildSpinner = ora('Rebuilding...').start();
363
- await execa('npm', ['install']);
364
- await execa('npm', ['run', 'build']);
365
- buildSpinner.succeed('Project rebuilt');
366
- const pm2Spinner = ora('Restarting PM2...').start();
367
- await execa('pm2', ['restart', appName]);
368
- pm2Spinner.succeed('Application restarted');
369
- success('\nāœ… Rollback completed successfully!');
494
+ await execa("git", ["reset", "--hard", `HEAD~${commits}`]);
495
+ rollbackSpinner.succeed("Code rolled back");
496
+ const buildSpinner = ora("Rebuilding...").start();
497
+ await execa("npm", ["install"]);
498
+ await execa("npm", ["run", "build"]);
499
+ buildSpinner.succeed("Project rebuilt");
500
+ const pm2Spinner = ora("Restarting PM2...").start();
501
+ await execa("pm2", ["restart", appName]);
502
+ pm2Spinner.succeed("Application restarted");
503
+ success("\nāœ… Rollback completed successfully!");
370
504
  }
371
505
  catch (err) {
372
- rollbackSpinner.fail('Rollback failed');
506
+ rollbackSpinner.fail("Rollback failed");
373
507
  console.error(err);
374
508
  process.exit(1);
375
509
  }
@@ -384,7 +518,7 @@ module.exports = {
384
518
  script: './dist/index.js',
385
519
 
386
520
  // Cluster mode
387
- instances: ${typeof config.pm2Config.instances === 'number' ? config.pm2Config.instances : `'${config.pm2Config.instances}'`},
521
+ instances: ${typeof config.pm2Config.instances === "number" ? config.pm2Config.instances : `'${config.pm2Config.instances}'`},
388
522
  exec_mode: 'cluster',
389
523
 
390
524
  // Resource limits
@@ -404,13 +538,13 @@ module.exports = {
404
538
 
405
539
  // Environment variables
406
540
  env_production: ${JSON.stringify({
407
- NODE_ENV: 'production',
408
- ...config.pm2Config.env
541
+ NODE_ENV: "production",
542
+ ...config.pm2Config.env,
409
543
  }, null, 6)}
410
544
  }]
411
545
  };
412
546
  `;
413
- await writeFile(path.join(projectPath, 'ecosystem.config.cjs'), ecosystem);
414
- success('āœ“ PM2 ecosystem.config.cjs generated');
547
+ await writeFile(path.join(projectPath, "ecosystem.config.cjs"), ecosystem);
548
+ success("āœ“ PM2 ecosystem.config.cjs generated");
415
549
  }
416
550
  //# sourceMappingURL=deploy.js.map