nestcraftx 0.2.5 → 0.3.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.
- package/AUDIT_ROADMAP.md +798 -0
- package/CHANGELOG.fr.md +22 -0
- package/CHANGELOG.md +22 -0
- package/CLI_USAGE.fr.md +331 -331
- package/CLI_USAGE.md +364 -364
- package/LICENSE +21 -21
- package/PROGRESS.md +258 -0
- package/bin/nestcraft.js +84 -64
- package/commands/demo.js +337 -330
- package/commands/generate.js +94 -0
- package/commands/generateConf.js +91 -0
- package/commands/help.js +29 -2
- package/commands/info.js +48 -48
- package/commands/new.js +340 -335
- package/commands/start.js +19 -19
- package/commands/test.js +7 -7
- package/package.json +1 -1
- package/utils/app-module.updater.js +96 -0
- package/utils/cliParser.js +88 -76
- package/utils/colors.js +62 -62
- package/utils/configs/configureDocker.js +120 -120
- package/utils/configs/setupCleanArchitecture.js +17 -15
- package/utils/configs/setupLightArchitecture.js +15 -9
- package/utils/file-system.js +75 -0
- package/utils/file-utils/saveProjectConfig.js +36 -0
- package/utils/fullModeInput.js +607 -607
- package/utils/generators/application/dtoGenerator.js +251 -0
- package/utils/generators/application/dtoUpdater.js +54 -0
- package/utils/generators/cleanModuleGenerator.js +475 -0
- package/utils/generators/database/setupDatabase.js +49 -0
- package/utils/generators/domain/entityGenerator.js +126 -0
- package/utils/generators/domain/entityUpdater.js +78 -0
- package/utils/generators/infrastructure/mapperGenerator.js +114 -0
- package/utils/generators/infrastructure/mapperUpdater.js +65 -0
- package/utils/generators/infrastructure/middlewareGenerator.js +645 -0
- package/utils/generators/infrastructure/mongooseSchemaGenerator.js +196 -0
- package/utils/generators/infrastructure/repositoryGenerator.js +334 -0
- package/utils/generators/lightModuleGenerator.js +131 -0
- package/utils/generators/presentation/controllerGenerator.js +142 -0
- package/utils/generators/relation/relation.engine.js +64 -0
- package/utils/helpers.js +109 -0
- package/utils/interactive/askEntityInputs.js +165 -0
- package/utils/loggers/logError.js +7 -7
- package/utils/loggers/logInfo.js +7 -7
- package/utils/loggers/logSuccess.js +7 -7
- package/utils/loggers/logWarning.js +7 -7
- package/utils/setups/orms/typeOrmSetup.js +630 -630
- package/utils/setups/setupAuth.js +33 -20
- package/utils/setups/setupDatabase.js +76 -75
- package/utils/setups/setupMongoose.js +22 -5
- package/utils/setups/setupPrisma.js +748 -630
- package/utils/shell.js +112 -32
- package/utils/spinner.js +57 -57
- package/utils/systemCheck.js +124 -124
- package/utils/userInput.js +357 -421
- package/utils/utils.js +29 -2164
package/utils/shell.js
CHANGED
|
@@ -1,32 +1,112 @@
|
|
|
1
|
-
const { execSync } = require("child_process");
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
const { logError } = require("./loggers/logError");
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
1
|
+
const { execSync } = require("child_process");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const { logError } = require("./loggers/logError");
|
|
4
|
+
const { logWarning } = require("./loggers/logWarning");
|
|
5
|
+
const { spinner } = require("./spinner");
|
|
6
|
+
const { warning, info } = require("./colors");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Accumulated warnings collected during a generation session.
|
|
10
|
+
* Displayed as a summary at the end via printSetupWarnings().
|
|
11
|
+
*/
|
|
12
|
+
const _warnings = [];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Runs a shell command synchronously.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} command - The shell command to execute.
|
|
18
|
+
* @param {string} errorMessage - Human-readable error message shown on failure.
|
|
19
|
+
* @param {object} [options] - Optional configuration.
|
|
20
|
+
* @param {boolean} [options.critical=true] - If true (default), a failure calls process.exit(1).
|
|
21
|
+
* If false, the failure is logged as a warning and execution continues.
|
|
22
|
+
* @param {string|null} [options.spinner] - Optional spinner label shown during execution.
|
|
23
|
+
* @returns {Promise<boolean>} Resolves to true on success, false on non-critical failure.
|
|
24
|
+
*/
|
|
25
|
+
async function runCommand(command, errorMessage, options = {}) {
|
|
26
|
+
// Support old call signature: runCommand(cmd, msg, spinnerText)
|
|
27
|
+
// New signature: runCommand(cmd, msg, { critical, spinner })
|
|
28
|
+
let critical = true;
|
|
29
|
+
let spinnerText = null;
|
|
30
|
+
|
|
31
|
+
if (typeof options === "string") {
|
|
32
|
+
// Legacy: third arg was spinnerText string
|
|
33
|
+
spinnerText = options;
|
|
34
|
+
} else if (typeof options === "object" && options !== null) {
|
|
35
|
+
critical = options.critical !== false; // default true
|
|
36
|
+
spinnerText = options.spinner || null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const spin = spinnerText ? spinner(spinnerText) : null;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (spin) spin.start();
|
|
43
|
+
execSync(command, { stdio: spinnerText ? "pipe" : "inherit" });
|
|
44
|
+
if (spin) spin.succeed(spinnerText);
|
|
45
|
+
return true;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (spin) spin.fail(errorMessage);
|
|
48
|
+
|
|
49
|
+
const logLine = `[${new Date().toISOString()}] ${errorMessage}: ${error.message}\n`;
|
|
50
|
+
fs.appendFileSync("setup.log", logLine);
|
|
51
|
+
|
|
52
|
+
if (critical) {
|
|
53
|
+
// Fatal — stop everything
|
|
54
|
+
logError(`${errorMessage}`);
|
|
55
|
+
logError(`Run: ${command}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
} else {
|
|
58
|
+
// Non-critical — warn and continue
|
|
59
|
+
logWarning(`${errorMessage} (non-fatal, continuing...)`);
|
|
60
|
+
logWarning(` Command: ${command}`);
|
|
61
|
+
logWarning(` See setup.log for details`);
|
|
62
|
+
_warnings.push({ command, errorMessage });
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Silent command — returns stdout string or null on failure. Never exits.
|
|
70
|
+
* @param {string} command
|
|
71
|
+
* @returns {string|null}
|
|
72
|
+
*/
|
|
73
|
+
async function runCommandSilent(command) {
|
|
74
|
+
try {
|
|
75
|
+
return execSync(command, { stdio: "pipe" }).toString();
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Prints a summary of all non-critical warnings accumulated during the session.
|
|
83
|
+
* Call this at the very end of the generation pipeline.
|
|
84
|
+
*/
|
|
85
|
+
function printSetupWarnings() {
|
|
86
|
+
if (_warnings.length === 0) return;
|
|
87
|
+
|
|
88
|
+
console.log(
|
|
89
|
+
`\n${warning("⚠️ Setup completed with")} ${warning(String(_warnings.length))} ${warning("warning(s):")}`,
|
|
90
|
+
);
|
|
91
|
+
_warnings.forEach((w, i) => {
|
|
92
|
+
console.log(` ${info(`${i + 1}.`)} ${w.errorMessage}`);
|
|
93
|
+
console.log(` ${info("Command:")} ${w.command}`);
|
|
94
|
+
});
|
|
95
|
+
console.log(
|
|
96
|
+
`\n ${info("➜")} Full details in: ${info("setup.log")}\n`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Clears the warnings accumulator (useful between test runs).
|
|
102
|
+
*/
|
|
103
|
+
function clearSetupWarnings() {
|
|
104
|
+
_warnings.length = 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = {
|
|
108
|
+
runCommand,
|
|
109
|
+
runCommandSilent,
|
|
110
|
+
printSetupWarnings,
|
|
111
|
+
clearSetupWarnings,
|
|
112
|
+
};
|
package/utils/spinner.js
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
const { info, success, error: errorColor } = require('./colors');
|
|
2
|
-
|
|
3
|
-
class Spinner {
|
|
4
|
-
constructor(text = 'Loading...') {
|
|
5
|
-
this.text = text;
|
|
6
|
-
this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
7
|
-
this.currentFrame = 0;
|
|
8
|
-
this.intervalId = null;
|
|
9
|
-
this.isSpinning = false;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
start() {
|
|
13
|
-
if (this.isSpinning) return;
|
|
14
|
-
|
|
15
|
-
this.isSpinning = true;
|
|
16
|
-
this.currentFrame = 0;
|
|
17
|
-
|
|
18
|
-
process.stdout.write('\n');
|
|
19
|
-
|
|
20
|
-
this.intervalId = setInterval(() => {
|
|
21
|
-
const frame = this.frames[this.currentFrame];
|
|
22
|
-
process.stdout.write(`\r${info(frame)} ${this.text}`);
|
|
23
|
-
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
|
|
24
|
-
}, 80);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
stop() {
|
|
28
|
-
if (!this.isSpinning) return;
|
|
29
|
-
|
|
30
|
-
this.isSpinning = false;
|
|
31
|
-
if (this.intervalId) {
|
|
32
|
-
clearInterval(this.intervalId);
|
|
33
|
-
this.intervalId = null;
|
|
34
|
-
}
|
|
35
|
-
process.stdout.write('\r' + ' '.repeat(this.text.length + 10) + '\r');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
succeed(text) {
|
|
39
|
-
this.stop();
|
|
40
|
-
console.log(success('✓') + ` ${text || this.text}`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
fail(text) {
|
|
44
|
-
this.stop();
|
|
45
|
-
console.log(errorColor('✗') + ` ${text || this.text}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
update(text) {
|
|
49
|
-
this.text = text;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function spinner(text) {
|
|
54
|
-
return new Spinner(text);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
module.exports = { Spinner, spinner };
|
|
1
|
+
const { info, success, error: errorColor } = require('./colors');
|
|
2
|
+
|
|
3
|
+
class Spinner {
|
|
4
|
+
constructor(text = 'Loading...') {
|
|
5
|
+
this.text = text;
|
|
6
|
+
this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
7
|
+
this.currentFrame = 0;
|
|
8
|
+
this.intervalId = null;
|
|
9
|
+
this.isSpinning = false;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
start() {
|
|
13
|
+
if (this.isSpinning) return;
|
|
14
|
+
|
|
15
|
+
this.isSpinning = true;
|
|
16
|
+
this.currentFrame = 0;
|
|
17
|
+
|
|
18
|
+
process.stdout.write('\n');
|
|
19
|
+
|
|
20
|
+
this.intervalId = setInterval(() => {
|
|
21
|
+
const frame = this.frames[this.currentFrame];
|
|
22
|
+
process.stdout.write(`\r${info(frame)} ${this.text}`);
|
|
23
|
+
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
|
|
24
|
+
}, 80);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
stop() {
|
|
28
|
+
if (!this.isSpinning) return;
|
|
29
|
+
|
|
30
|
+
this.isSpinning = false;
|
|
31
|
+
if (this.intervalId) {
|
|
32
|
+
clearInterval(this.intervalId);
|
|
33
|
+
this.intervalId = null;
|
|
34
|
+
}
|
|
35
|
+
process.stdout.write('\r' + ' '.repeat(this.text.length + 10) + '\r');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
succeed(text) {
|
|
39
|
+
this.stop();
|
|
40
|
+
console.log(success('✓') + ` ${text || this.text}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fail(text) {
|
|
44
|
+
this.stop();
|
|
45
|
+
console.log(errorColor('✗') + ` ${text || this.text}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
update(text) {
|
|
49
|
+
this.text = text;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function spinner(text) {
|
|
54
|
+
return new Spinner(text);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = { Spinner, spinner };
|
package/utils/systemCheck.js
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
const { execSync } = require("child_process");
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
|
|
4
|
-
function checkCommand(cmd) {
|
|
5
|
-
try {
|
|
6
|
-
execSync(`${cmd} --version`, { stdio: "pipe" });
|
|
7
|
-
return true;
|
|
8
|
-
} catch {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function getVersion(cmd) {
|
|
14
|
-
try {
|
|
15
|
-
const output = execSync(`${cmd} --version`, {
|
|
16
|
-
encoding: "utf8",
|
|
17
|
-
stdio: "pipe",
|
|
18
|
-
});
|
|
19
|
-
return output.trim().split("\n")[0];
|
|
20
|
-
} catch {
|
|
21
|
-
return "not installed";
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function checkSystemRequirements() {
|
|
26
|
-
const checks = {
|
|
27
|
-
node: {
|
|
28
|
-
installed: checkCommand("node"),
|
|
29
|
-
version: getVersion("node"),
|
|
30
|
-
},
|
|
31
|
-
npm: {
|
|
32
|
-
installed: checkCommand("npm"),
|
|
33
|
-
version: getVersion("npm"),
|
|
34
|
-
},
|
|
35
|
-
nestCli: {
|
|
36
|
-
installed: checkCommand("nest"),
|
|
37
|
-
version: getVersion("nest"),
|
|
38
|
-
},
|
|
39
|
-
git: {
|
|
40
|
-
installed: checkCommand("git"),
|
|
41
|
-
version: getVersion("git"),
|
|
42
|
-
},
|
|
43
|
-
docker: {
|
|
44
|
-
installed: checkCommand("docker"),
|
|
45
|
-
version: getVersion("docker"),
|
|
46
|
-
},
|
|
47
|
-
npx: {
|
|
48
|
-
installed: checkCommand("npx"),
|
|
49
|
-
version: "npx available",
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const envExists = fs.existsSync(".env");
|
|
54
|
-
|
|
55
|
-
let postgresStatus = "not detected locally";
|
|
56
|
-
if (envExists) {
|
|
57
|
-
try {
|
|
58
|
-
const envContent = fs.readFileSync(".env", "utf8");
|
|
59
|
-
if (
|
|
60
|
-
envContent.includes("POSTGRES_") ||
|
|
61
|
-
envContent.includes("DATABASE_URL")
|
|
62
|
-
) {
|
|
63
|
-
postgresStatus = "configured in .env";
|
|
64
|
-
}
|
|
65
|
-
} catch {}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
checks.postgres = {
|
|
69
|
-
installed: false,
|
|
70
|
-
version: postgresStatus,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
return checks;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function displaySystemCheck() {
|
|
77
|
-
console.log("\n🔍 NestCraftX System Check");
|
|
78
|
-
console.log("--------------------------------");
|
|
79
|
-
|
|
80
|
-
const checks = checkSystemRequirements();
|
|
81
|
-
let successCount = 0;
|
|
82
|
-
let totalCount = 0;
|
|
83
|
-
|
|
84
|
-
Object.entries(checks).forEach(([name, info]) => {
|
|
85
|
-
totalCount++;
|
|
86
|
-
const displayName =
|
|
87
|
-
name.charAt(0).toUpperCase() + name.slice(1).replace(/([A-Z])/g, " $1");
|
|
88
|
-
|
|
89
|
-
if (info.installed || info.version.includes("configured")) {
|
|
90
|
-
console.log(`✅ ${displayName}: ${info.version}`);
|
|
91
|
-
successCount++;
|
|
92
|
-
} else {
|
|
93
|
-
console.log(`⚠️ ${displayName}: ${info.version}`);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
console.log("--------------------------------");
|
|
98
|
-
|
|
99
|
-
const status =
|
|
100
|
-
successCount === totalCount
|
|
101
|
-
? "✅ Ready"
|
|
102
|
-
: successCount >= totalCount - 2
|
|
103
|
-
? "⚠️ Almost Ready"
|
|
104
|
-
: "❌ Missing Requirements";
|
|
105
|
-
|
|
106
|
-
console.log(`System status: ${status} (${successCount}/${totalCount} OK)`);
|
|
107
|
-
|
|
108
|
-
if (successCount < totalCount) {
|
|
109
|
-
console.log("\n💡 Tips:");
|
|
110
|
-
if (!checks.nestCli.installed) {
|
|
111
|
-
console.log(" - Install Nest CLI: npm install -g @nestjs/cli");
|
|
112
|
-
}
|
|
113
|
-
if (!checks.docker.installed) {
|
|
114
|
-
console.log(" - Install Docker: https://docs.docker.com/get-docker/");
|
|
115
|
-
}
|
|
116
|
-
if (!checks.git.installed) {
|
|
117
|
-
console.log(" - Install Git: https://git-scm.com/downloads");
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
console.log("");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
module.exports = { checkSystemRequirements, displaySystemCheck };
|
|
1
|
+
const { execSync } = require("child_process");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
|
|
4
|
+
function checkCommand(cmd) {
|
|
5
|
+
try {
|
|
6
|
+
execSync(`${cmd} --version`, { stdio: "pipe" });
|
|
7
|
+
return true;
|
|
8
|
+
} catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getVersion(cmd) {
|
|
14
|
+
try {
|
|
15
|
+
const output = execSync(`${cmd} --version`, {
|
|
16
|
+
encoding: "utf8",
|
|
17
|
+
stdio: "pipe",
|
|
18
|
+
});
|
|
19
|
+
return output.trim().split("\n")[0];
|
|
20
|
+
} catch {
|
|
21
|
+
return "not installed";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function checkSystemRequirements() {
|
|
26
|
+
const checks = {
|
|
27
|
+
node: {
|
|
28
|
+
installed: checkCommand("node"),
|
|
29
|
+
version: getVersion("node"),
|
|
30
|
+
},
|
|
31
|
+
npm: {
|
|
32
|
+
installed: checkCommand("npm"),
|
|
33
|
+
version: getVersion("npm"),
|
|
34
|
+
},
|
|
35
|
+
nestCli: {
|
|
36
|
+
installed: checkCommand("nest"),
|
|
37
|
+
version: getVersion("nest"),
|
|
38
|
+
},
|
|
39
|
+
git: {
|
|
40
|
+
installed: checkCommand("git"),
|
|
41
|
+
version: getVersion("git"),
|
|
42
|
+
},
|
|
43
|
+
docker: {
|
|
44
|
+
installed: checkCommand("docker"),
|
|
45
|
+
version: getVersion("docker"),
|
|
46
|
+
},
|
|
47
|
+
npx: {
|
|
48
|
+
installed: checkCommand("npx"),
|
|
49
|
+
version: "npx available",
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const envExists = fs.existsSync(".env");
|
|
54
|
+
|
|
55
|
+
let postgresStatus = "not detected locally";
|
|
56
|
+
if (envExists) {
|
|
57
|
+
try {
|
|
58
|
+
const envContent = fs.readFileSync(".env", "utf8");
|
|
59
|
+
if (
|
|
60
|
+
envContent.includes("POSTGRES_") ||
|
|
61
|
+
envContent.includes("DATABASE_URL")
|
|
62
|
+
) {
|
|
63
|
+
postgresStatus = "configured in .env";
|
|
64
|
+
}
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
checks.postgres = {
|
|
69
|
+
installed: false,
|
|
70
|
+
version: postgresStatus,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return checks;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function displaySystemCheck() {
|
|
77
|
+
console.log("\n🔍 NestCraftX System Check");
|
|
78
|
+
console.log("--------------------------------");
|
|
79
|
+
|
|
80
|
+
const checks = checkSystemRequirements();
|
|
81
|
+
let successCount = 0;
|
|
82
|
+
let totalCount = 0;
|
|
83
|
+
|
|
84
|
+
Object.entries(checks).forEach(([name, info]) => {
|
|
85
|
+
totalCount++;
|
|
86
|
+
const displayName =
|
|
87
|
+
name.charAt(0).toUpperCase() + name.slice(1).replace(/([A-Z])/g, " $1");
|
|
88
|
+
|
|
89
|
+
if (info.installed || info.version.includes("configured")) {
|
|
90
|
+
console.log(`✅ ${displayName}: ${info.version}`);
|
|
91
|
+
successCount++;
|
|
92
|
+
} else {
|
|
93
|
+
console.log(`⚠️ ${displayName}: ${info.version}`);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
console.log("--------------------------------");
|
|
98
|
+
|
|
99
|
+
const status =
|
|
100
|
+
successCount === totalCount
|
|
101
|
+
? "✅ Ready"
|
|
102
|
+
: successCount >= totalCount - 2
|
|
103
|
+
? "⚠️ Almost Ready"
|
|
104
|
+
: "❌ Missing Requirements";
|
|
105
|
+
|
|
106
|
+
console.log(`System status: ${status} (${successCount}/${totalCount} OK)`);
|
|
107
|
+
|
|
108
|
+
if (successCount < totalCount) {
|
|
109
|
+
console.log("\n💡 Tips:");
|
|
110
|
+
if (!checks.nestCli.installed) {
|
|
111
|
+
console.log(" - Install Nest CLI: npm install -g @nestjs/cli");
|
|
112
|
+
}
|
|
113
|
+
if (!checks.docker.installed) {
|
|
114
|
+
console.log(" - Install Docker: https://docs.docker.com/get-docker/");
|
|
115
|
+
}
|
|
116
|
+
if (!checks.git.installed) {
|
|
117
|
+
console.log(" - Install Git: https://git-scm.com/downloads");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
console.log("");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = { checkSystemRequirements, displaySystemCheck };
|