This commit is contained in:
bipproduction
2025-09-25 12:08:35 +08:00
parent 7e6f48f63a
commit 6086aa31c2
5 changed files with 469 additions and 375 deletions

View File

@@ -7,22 +7,33 @@ import checkPort from "./src/port";
import route from "./src/route";
import compose from "./src/compose";
import generateDockerfile from "./src/docker-file";
import frp from "./src/frp";
interface CheckPortResult {
port: number;
open: boolean;
}
const args = minimist(process.argv.slice(2));
// Default constants (12-Factor App)
const DEFAULTS = {
ENV_FILE: ".env",
ENV_OUT: "types/env.d.ts",
PORT_START: 3000,
PORT_END: 4000,
HOST: "127.0.0.1",
};
const help = `
// CLI Help
const HELP_TEXT = `
g3n [command] [options]
Commands:
env Generate env.d.ts from .env file
env Generate env.d.ts from .env file
scan-port Scan port range (default 3000-4000)
route Generate routes.ts from AppRoutes.tsx
compose Generate compose.yml from name
route Generate routes.ts from AppRoutes.tsx
compose Generate compose.yml from name
docker-file Generate Dockerfile
Options:
--env Path ke file .env (default: .env)
--out Path file output (default: types/env.d.ts)
@@ -34,64 +45,105 @@ Examples:
g3n env --env .env.local --out src/types/env.d.ts
g3n scan-port --start 7700 --end 7800 --host 127.0.0.1
g3n route
g3n compose <name>`;
g3n compose <name>
g3n docker-file
`;
(async () => {
const cmd = args._[0];
// Parse CLI arguments
const args = minimist(process.argv.slice(2));
if (cmd === "env") {
generateEnvTypes({
envFilePath: args.env,
outputDir: args.out ? path.dirname(args.out) : undefined,
outputFileName: args.out ? path.basename(args.out) : undefined,
});
/**
* Main CLI handler
*/
async function main(): Promise<void> {
const [command, name] = args._;
switch (command) {
case "env":
handleEnv();
break;
case "scan-port":
await handleScanPort();
break;
case "route":
route();
break;
case "compose":
handleCompose(name);
break;
case "docker-file":
generateDockerfile();
break;
case "frp":
frp().catch((err) => {
console.error("❌ Error:", err);
process.exit(1);
});
break;
default:
console.error(HELP_TEXT);
break;
}
}
/**
* Handle "env" command
*/
function handleEnv(): void {
const envFile = args.env || DEFAULTS.ENV_FILE;
const output = args.out || DEFAULTS.ENV_OUT;
generateEnvTypes({
envFilePath: envFile,
outputDir: path.dirname(output),
outputFileName: path.basename(output),
});
console.log(`✅ Env types generated at ${output}`);
}
/**
* Handle "scan-port" command
*/
async function handleScanPort(): Promise<void> {
const start = Number(args.start) || DEFAULTS.PORT_START;
const end = Number(args.end) || DEFAULTS.PORT_END;
const host = args.host || DEFAULTS.HOST;
console.log(`🔍 Scanning ports ${start}-${end} on host ${host}...`);
const ports = Array.from({ length: end - start + 1 }, (_, i) => start + i);
const results: CheckPortResult[] = await Promise.all(
ports.map((port) => checkPort(port, host))
);
const openPorts = results.filter((r) => r.open);
openPorts.forEach((r) => console.log(`✅ Port ${r.port} is open`));
console.log("✅ Scan completed");
}
/**
* Handle "compose" command
*/
function handleCompose(name?: string): void {
if (!name) {
console.error("❌ Compose name is required");
return;
}
if (cmd === "scan-port") {
const start: number = args.start ? parseInt(args.start, 10) : 3000;
const end: number = args.end ? parseInt(args.end, 10) : 4000;
const host: string = args.host || "localhost";
console.log(`🔍 Scan port ${start}-${end} di host ${host} ...`);
const ports: number[] = Array.from(
{ length: end - start + 1 },
(_, i) => start + i
);
const results: CheckPortResult[] = await Promise.all(
ports.map((p) => checkPort(p, host))
);
results.filter((r) => r.open).forEach((r) => {
console.log(`✅ Port ${r.port} sedang digunakan`);
});
console.log("✅ Selesai");
return;
}
if (cmd === "route") {
route();
return;
}
if (cmd === "compose") {
if (!args._[1]) {
console.error("❌ Name is required");
return;
}
compose(args._[1] as string);
return;
}
if (cmd === "docker-file") {
generateDockerfile();
return;
}
console.error(help);
})();
compose(name);
console.log(`✅ Compose file generated for ${name}`);
}
// Execute CLI
main().catch((err) => {
console.error("❌ Unexpected error:", err);
process.exit(1);
});