nestcraftx 0.3.0 → 0.4.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.
@@ -1,5 +1,5 @@
1
1
  const fs = require("fs");
2
- const { execSync } = require("child_process");
2
+ const { runCommand } = require("../shell");
3
3
  const { logInfo } = require("../loggers/logInfo");
4
4
  const { logSuccess } = require("../loggers/logSuccess");
5
5
 
@@ -7,13 +7,17 @@ async function setupSwagger(inputs) {
7
7
  logInfo("Installation et Configuration de Swagger...");
8
8
 
9
9
  // installation de swagger
10
- try {
11
- execSync("npm install @nestjs/swagger swagger-ui-express", {
12
- stdio: "inherit",
13
- });
14
- } catch (error) {
15
- console.error("❌ Échec de l'installation de Swagger :", error);
16
- process.exit(1);
10
+ await runCommand(
11
+ "npm install @nestjs/swagger swagger-ui-express",
12
+ "Échec de l'installation de Swagger",
13
+ { spinner: "Installing Swagger..." }
14
+ );
15
+
16
+ const isDryRun = process.argv.includes("--dry-run");
17
+ if (isDryRun) {
18
+ console.log("[DRY-RUN] Simulated: write Swagger configuration to src/main.ts");
19
+ logSuccess(" Swagger configuré avec succès !");
20
+ return;
17
21
  }
18
22
 
19
23
  // Modification de main.ts pour intégrer Swagger
package/utils/shell.js CHANGED
@@ -20,44 +20,79 @@ const _warnings = [];
20
20
  * @param {boolean} [options.critical=true] - If true (default), a failure calls process.exit(1).
21
21
  * If false, the failure is logged as a warning and execution continues.
22
22
  * @param {string|null} [options.spinner] - Optional spinner label shown during execution.
23
+ * @param {number} [options.timeout] - Custom timeout in milliseconds.
23
24
  * @returns {Promise<boolean>} Resolves to true on success, false on non-critical failure.
24
25
  */
25
26
  async function runCommand(command, errorMessage, options = {}) {
26
- // Support old call signature: runCommand(cmd, msg, spinnerText)
27
- // New signature: runCommand(cmd, msg, { critical, spinner })
28
27
  let critical = true;
29
28
  let spinnerText = null;
29
+ let customTimeout = undefined;
30
30
 
31
31
  if (typeof options === "string") {
32
- // Legacy: third arg was spinnerText string
33
32
  spinnerText = options;
34
33
  } else if (typeof options === "object" && options !== null) {
35
- critical = options.critical !== false; // default true
34
+ critical = options.critical !== false;
36
35
  spinnerText = options.spinner || null;
36
+ customTimeout = options.timeout;
37
+ }
38
+
39
+ // Determine Timeout
40
+ let timeoutVal = 30000; // default 30 seconds
41
+ if (
42
+ command.includes("install") ||
43
+ command.includes("add") ||
44
+ command.includes(" new ") ||
45
+ command.includes("prisma migrate")
46
+ ) {
47
+ timeoutVal = 300000; // 5 minutes for heavy setup commands
48
+ }
49
+ if (customTimeout !== undefined) {
50
+ timeoutVal = customTimeout;
51
+ }
52
+
53
+ // Dry-Run Simulation Check
54
+ const isDryRun = process.argv.includes("--dry-run");
55
+ if (isDryRun) {
56
+ if (spinnerText) {
57
+ const spin = spinner(spinnerText);
58
+ spin.start();
59
+ spin.succeed(`[DRY-RUN] Simulated: ${command}`);
60
+ } else {
61
+ console.log(`[DRY-RUN] Simulated: ${command}`);
62
+ }
63
+ return true;
37
64
  }
38
65
 
39
66
  const spin = spinnerText ? spinner(spinnerText) : null;
40
67
 
41
68
  try {
42
69
  if (spin) spin.start();
43
- execSync(command, { stdio: spinnerText ? "pipe" : "inherit" });
70
+ execSync(command, {
71
+ stdio: spinnerText ? "pipe" : "inherit",
72
+ timeout: timeoutVal,
73
+ });
44
74
  if (spin) spin.succeed(spinnerText);
45
75
  return true;
46
76
  } catch (error) {
47
77
  if (spin) spin.fail(errorMessage);
48
78
 
49
- const logLine = `[${new Date().toISOString()}] ${errorMessage}: ${error.message}\n`;
79
+ let errorDetail = error.message;
80
+ if (error.code === "ETIMEDOUT" || error.signal === "SIGTERM") {
81
+ errorDetail = `Command timed out after ${timeoutVal / 1000}s`;
82
+ }
83
+
84
+ const logLine = `[${new Date().toISOString()}] ${errorMessage}: ${errorDetail}\n`;
50
85
  fs.appendFileSync("setup.log", logLine);
51
86
 
52
87
  if (critical) {
53
- // Fatal — stop everything
54
88
  logError(`${errorMessage}`);
55
89
  logError(`Run: ${command}`);
90
+ logError(`Detail: ${errorDetail}`);
56
91
  process.exit(1);
57
92
  } else {
58
- // Non-critical — warn and continue
59
93
  logWarning(`${errorMessage} (non-fatal, continuing...)`);
60
94
  logWarning(` Command: ${command}`);
95
+ logWarning(` Detail: ${errorDetail}`);
61
96
  logWarning(` See setup.log for details`);
62
97
  _warnings.push({ command, errorMessage });
63
98
  return false;
@@ -72,7 +107,7 @@ async function runCommand(command, errorMessage, options = {}) {
72
107
  */
73
108
  async function runCommandSilent(command) {
74
109
  try {
75
- return execSync(command, { stdio: "pipe" }).toString();
110
+ return execSync(command, { stdio: "pipe", timeout: 10000 }).toString();
76
111
  } catch (error) {
77
112
  return null;
78
113
  }