kitsui-cli 1.0.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/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # 🦊 Kitsui CLI
2
+
3
+ > A powerful command-line assistant to kickstart new projects and streamline your development workflow.
4
+
5
+ ![inspiration](https://static.wikia.nocookie.net/sewayaki-kitsune-no-senkosan/images/0/0a/Senko.png/revision/latest/scale-to-width-down/1200?cb=20190425152125)
6
+
7
+ Kitsui (Kitsu CLI) is a versatile CLI tool packed with helpful utilities like project initialization, local tunneling, static file serving, API mocking, deployment, and git automation.
8
+
9
+ ---
10
+
11
+ ## 📦 Installation
12
+
13
+ You can install Kitsui globally using npm:
14
+
15
+ ```bash
16
+ npm install -g kitsui-cli
17
+ ```
18
+
19
+ _(Note: If you haven't published it yet, you can link it locally by running `npm link` inside the project directory)._
20
+
21
+ ---
22
+
23
+ ## 🚀 Usage
24
+
25
+ Using Kitsui is very straightforward. Simply type `kitsui` followed by the command you want to run:
26
+
27
+ ```bash
28
+ kitsui <command> [options]
29
+ ```
30
+
31
+ To see the list of all available commands directly in your terminal, run:
32
+
33
+ ```bash
34
+ kitsui help
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 🛠️ Available Commands
40
+
41
+ Here are the commands you can use to boost your productivity:
42
+
43
+ ### 🌟 Core Commands
44
+
45
+ - **`kitsui init`**
46
+ Initialize and create a new project. Sets up the boilerplate so you can start coding right away.
47
+ - **`kitsui deploy`**
48
+ Deploy your project to a hosting provider quickly and easily.
49
+
50
+ ### 🌐 Development Tools
51
+
52
+ - **`kitsui tunnel`**
53
+ Expose your local development server to the internet. Perfect for testing webhooks or sharing your work with clients.
54
+ - **`kitsui live`**
55
+ Starts a `live-server` with hot-reload for lightning-fast frontend development.
56
+ - **`kitsui serve`**
57
+ Spins up a simple static file server for the current directory.
58
+ - **`kitsui json`**
59
+ Mock a REST API based on a `db.json` file. Instantly get a fake backend to test your frontend against.
60
+
61
+ ### ⚙️ Utilities
62
+
63
+ - **`kitsui git`**
64
+ Git automation tools to help you commit and push without the hassle.
65
+ - **`kitsui ignore`**
66
+ Automatically generate `.gitignore` files tailored for your specific tech stack.
67
+
68
+ - **`kitsui hello`**
69
+ Display a friendly hello message! 🦊
70
+
71
+ - **`kitsui test`**
72
+ Run testing tools configured for your project.
73
+
74
+ ---
75
+
76
+ ## 🤝 Contributing
77
+
78
+ Contributions, issues, and feature requests are welcome! Feel free to check the [issues page](../../issues).
79
+
80
+ ## 📄 License
81
+
82
+ This project is licensed under the **ISC License**.
83
+
84
+ ---
85
+
86
+ _Built with ❤️ by revananda._
package/bin/index.js ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require("commander");
4
+ const init = require("../commands/init");
5
+ const deploy = require("../commands/deploy");
6
+ const git = require("../commands/git");
7
+ const ignore = require("../commands/ignore");
8
+
9
+ const tunnel = require("../commands/tools/tunnel");
10
+ const live = require("../commands/tools/live");
11
+ const serve = require("../commands/tools/serve");
12
+ const json = require("../commands/tools/json");
13
+ const hello = require("../hello/hello");
14
+ const test = require("../commands/test");
15
+
16
+ const program = new Command();
17
+
18
+ program.name("kitsui").description("🦊 Kitsui Beta v1.0.0").version("1.0.0");
19
+
20
+ program.command("hello").description("Display hello").action(hello);
21
+
22
+ program.command("init").description("Creating a new project").action(init);
23
+
24
+ program.command("test").description("Testing").action(test);
25
+
26
+ program
27
+ .command("tunnel")
28
+ .description("Expose localhost to the internet")
29
+ .action(tunnel);
30
+ program
31
+ .command("live")
32
+ .description("Starts live-server for development")
33
+ .action(live);
34
+ program
35
+ .command("serve")
36
+ .description("Starts a static file server")
37
+ .action(serve);
38
+ program
39
+ .command("json")
40
+ .description("Mock a REST API from db.json")
41
+ .action(json);
42
+
43
+ program
44
+ .command("deploy")
45
+ .description("Deploy project to hosting provider")
46
+ .action(deploy);
47
+
48
+ program.command("git").description("Git automation tools").action(git);
49
+
50
+ program
51
+ .command("ignore")
52
+ .description("Generate .gitignore files")
53
+ .action(ignore);
54
+
55
+ program
56
+ .command("help")
57
+ .description("Display help and available commands")
58
+ .action(() => {
59
+ program.outputHelp();
60
+ });
61
+
62
+ program.parse(process.argv);
63
+
64
+ if (!process.argv.slice(2).length) {
65
+ program.outputHelp();
66
+ }
@@ -0,0 +1,121 @@
1
+ const inquirer = require("inquirer").default;
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ const chalk = require("chalk");
5
+ const spawn = require("cross-spawn");
6
+
7
+ module.exports = async function backend() {
8
+ const { projectName } = await inquirer.prompt([
9
+ {
10
+ type: "input",
11
+ name: "projectName",
12
+ pageSize: 8,
13
+ message: "What is the name of your project?",
14
+ default: "backend",
15
+ },
16
+ ]);
17
+
18
+ const { buildTools } = await inquirer.prompt([
19
+ {
20
+ type: "list",
21
+ name: "buildTools",
22
+ pageSize: 8,
23
+ message: "What build tools do you want to use?",
24
+ choices: [
25
+ { name: chalk.hex("#fcd12a")("Node.js"), value: "Node.js" },
26
+ { name: chalk.hex("#fbc72b")("Express.js"), value: "Express.js" },
27
+ { name: chalk.hex("#fabd2c")("Nest.js"), value: "Nest.js" },
28
+ { name: chalk.hex("#f9b32c")("Fastify"), value: "Fastify" },
29
+ { name: chalk.hex("#f8a92d")("Golang"), value: "Golang" },
30
+ { name: chalk.hex("#f79f2e")("Django"), value: "Django" },
31
+ { name: chalk.hex("#f6952e")("Flask"), value: "Flask" },
32
+ { name: chalk.hex("#f58b2f")("FastAPI"), value: "FastAPI" },
33
+ { name: chalk.hex("#f48130")("Laravel"), value: "Laravel" },
34
+ { name: chalk.hex("#f37731")("Nuxt.js"), value: "Nuxt.js" },
35
+ ],
36
+ },
37
+ ]);
38
+
39
+ const projectPath = path.join(process.cwd(), projectName);
40
+
41
+ switch (buildTools) {
42
+ case "Node.js":
43
+ if (!fs.existsSync(projectPath))
44
+ fs.mkdirSync(projectPath, { recursive: true });
45
+ spawn("npm", ["init", "-y"], {
46
+ stdio: "inherit",
47
+ cwd: projectPath,
48
+ shell: true,
49
+ });
50
+ break;
51
+ case "Express.js":
52
+ spawn("npx", ["express-generator", projectName], {
53
+ stdio: "inherit",
54
+ shell: true,
55
+ });
56
+ break;
57
+ case "Nest.js":
58
+ spawn("npx", ["@nestjs/cli", "new", projectName], {
59
+ stdio: "inherit",
60
+ shell: true,
61
+ });
62
+ break;
63
+ case "Nuxt.js":
64
+ spawn("npx", ["nuxi@latest", "init", projectName], {
65
+ stdio: "inherit",
66
+ shell: true,
67
+ });
68
+ break;
69
+ case "Fastify":
70
+ spawn("npx", ["fastify-cli", "generate", projectName], {
71
+ stdio: "inherit",
72
+ shell: true,
73
+ });
74
+ break;
75
+ case "Golang":
76
+ if (!fs.existsSync(projectPath))
77
+ fs.mkdirSync(projectPath, { recursive: true });
78
+ spawn("go", ["mod", "init", projectName], {
79
+ stdio: "inherit",
80
+ cwd: projectPath,
81
+ shell: true,
82
+ });
83
+ break;
84
+ case "Django":
85
+ spawn("django-admin", ["startproject", projectName], {
86
+ stdio: "inherit",
87
+ shell: true,
88
+ });
89
+ break;
90
+ case "Flask":
91
+ if (!fs.existsSync(projectPath))
92
+ fs.mkdirSync(projectPath, { recursive: true });
93
+ fs.writeFileSync(
94
+ path.join(projectPath, "app.py"),
95
+ "from flask import Flask\\n\\napp = Flask(__name__)\\n\\n@app.route('/')\\ndef hello_world():\\n return 'Hello, World!'\\n",
96
+ );
97
+ console.log(`Created Flask project in ${projectName}`);
98
+ break;
99
+ case "FastAPI":
100
+ if (!fs.existsSync(projectPath))
101
+ fs.mkdirSync(projectPath, { recursive: true });
102
+ fs.writeFileSync(
103
+ path.join(projectPath, "main.py"),
104
+ "from fastapi import FastAPI\\n\\napp = FastAPI()\\n\\n@app.get('/')\\ndef read_root():\\n return {'Hello': 'World'}\\n",
105
+ );
106
+ console.log(`Created FastAPI project in ${projectName}`);
107
+ break;
108
+ case "Laravel":
109
+ spawn(
110
+ "composer",
111
+ ["create-project", "laravel/laravel", projectName],
112
+ {
113
+ stdio: "inherit",
114
+ shell: true,
115
+ },
116
+ );
117
+ break;
118
+ }
119
+
120
+ console.log("Selected:", buildTools);
121
+ };
@@ -0,0 +1,40 @@
1
+ const inquirer = require("inquirer").default;
2
+ const { execSync } = require("child_process");
3
+
4
+ module.exports = async function deploy() {
5
+ const { provider } = await inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "provider",
9
+ message: "Where do you want to deploy?",
10
+ choices: ["Vercel", "Netlify", "Surge", "Firebase Hosting"],
11
+ },
12
+ ]);
13
+
14
+ try {
15
+ switch (provider) {
16
+ case "Vercel":
17
+ console.log("Deploying to Vercel...");
18
+ execSync("npx vercel", { stdio: "inherit" });
19
+ break;
20
+ case "Netlify":
21
+ console.log("Deploying to Netlify...");
22
+ execSync("npx netlify-cli deploy", { stdio: "inherit" });
23
+ break;
24
+ case "Surge":
25
+ console.log("Deploying to Surge...");
26
+ execSync("npx surge", { stdio: "inherit" });
27
+ break;
28
+ case "Firebase Hosting":
29
+ console.log("Deploying to Firebase...");
30
+ execSync("npx firebase-tools deploy --only hosting", {
31
+ stdio: "inherit",
32
+ });
33
+ break;
34
+ }
35
+ } catch (error) {
36
+ console.error(
37
+ `\\nFailed to deploy to ${provider}. Make sure you are logged in and the project is configured correctly.`,
38
+ );
39
+ }
40
+ };
@@ -0,0 +1,86 @@
1
+ const inquirer = require("inquirer").default;
2
+ const chalk = require("chalk");
3
+ const spawn = require("cross-spawn");
4
+
5
+ module.exports = async function frontend() {
6
+ const { projectName } = await inquirer.prompt([
7
+ {
8
+ type: "input",
9
+ name: "projectName",
10
+ message: "What is the name of your project?",
11
+ default: "frontend",
12
+ },
13
+ ]);
14
+
15
+ const { buildTools } = await inquirer.prompt([
16
+ {
17
+ type: "list",
18
+ name: "buildTools",
19
+ pageSize: 8,
20
+ message: "What build tools do you want to use?",
21
+ choices: [
22
+ { name: chalk.hex("#fcd12a")("Vite"), value: "Vite" },
23
+ { name: chalk.hex("#fbc22b")("Next.js"), value: "Next.js" },
24
+ { name: chalk.hex("#fab32c")("Astro"), value: "Astro" },
25
+ { name: chalk.hex("#f9a42d")("Remix"), value: "Remix" },
26
+ { name: chalk.hex("#f8952e")("SvelteKit"), value: "SvelteKit" },
27
+ { name: chalk.hex("#f7862f")("Nuxt.js"), value: "Nuxt.js" },
28
+ { name: chalk.hex("#f67730")("Gatsby"), value: "Gatsby" },
29
+ { name: chalk.hex("#f56831")("Angular"), value: "Angular" },
30
+ ],
31
+ },
32
+ ]);
33
+
34
+ switch (buildTools) {
35
+ case "Vite":
36
+ spawn("npm", ["create", "vite@latest", projectName], {
37
+ stdio: "inherit",
38
+ shell: true,
39
+ });
40
+ break;
41
+ case "Next.js":
42
+ spawn("npx", ["create-next-app@latest", projectName], {
43
+ stdio: "inherit",
44
+ shell: true,
45
+ });
46
+ break;
47
+ case "Astro":
48
+ spawn("npm", ["create", "astro@latest", projectName], {
49
+ stdio: "inherit",
50
+ shell: true,
51
+ });
52
+ break;
53
+ case "Remix":
54
+ spawn("npx", ["create-remix@latest", projectName], {
55
+ stdio: "inherit",
56
+ shell: true,
57
+ });
58
+ break;
59
+ case "SvelteKit":
60
+ spawn("npm", ["create", "svelte@latest", projectName], {
61
+ stdio: "inherit",
62
+ shell: true,
63
+ });
64
+ break;
65
+ case "Nuxt.js":
66
+ spawn("npx", ["nuxi@latest", "init", projectName], {
67
+ stdio: "inherit",
68
+ shell: true,
69
+ });
70
+ break;
71
+ case "Gatsby":
72
+ spawn("npx", ["gatsby", "new", projectName], {
73
+ stdio: "inherit",
74
+ shell: true,
75
+ });
76
+ break;
77
+ case "Angular":
78
+ spawn("npx", ["@angular/cli", "new", projectName], {
79
+ stdio: "inherit",
80
+ shell: true,
81
+ });
82
+ break;
83
+ }
84
+
85
+ console.log("Selected:", buildTools);
86
+ };
@@ -0,0 +1,53 @@
1
+ const inquirer = require("inquirer").default;
2
+ const { execSync } = require("child_process");
3
+
4
+ module.exports = async function git() {
5
+ const { action } = await inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "action",
9
+ message: "What git action do you want to perform?",
10
+ choices: [
11
+ { name: "Add All & Commit & Push", value: "push" },
12
+ { name: "Initialize Repository", value: "init" },
13
+ { name: "Check Status", value: "status" },
14
+ ],
15
+ },
16
+ ]);
17
+
18
+ try {
19
+ switch (action) {
20
+ case "push":
21
+ const { commitMessage } = await inquirer.prompt([
22
+ {
23
+ type: "input",
24
+ name: "commitMessage",
25
+ message: "Enter commit message:",
26
+ validate: (input) =>
27
+ input.trim() !== "" || "Commit message cannot be empty!",
28
+ },
29
+ ]);
30
+
31
+ console.log("Adding files...");
32
+ execSync("git add .", { stdio: "inherit" });
33
+
34
+ console.log("Committing changes...");
35
+ execSync(`git commit -m "${commitMessage}"`, { stdio: "inherit" });
36
+
37
+ console.log("Pushing to remote...");
38
+ execSync("git push", { stdio: "inherit" });
39
+ break;
40
+ case "init":
41
+ console.log("Initializing git repository...");
42
+ execSync("git init", { stdio: "inherit" });
43
+ break;
44
+ case "status":
45
+ execSync("git status", { stdio: "inherit" });
46
+ break;
47
+ }
48
+ } catch (error) {
49
+ console.error(
50
+ "\nGit command failed. Make sure you are in a git repository or have git installed.",
51
+ );
52
+ }
53
+ };
@@ -0,0 +1,48 @@
1
+ const inquirer = require("inquirer").default;
2
+ const { execSync } = require("child_process");
3
+
4
+ module.exports = async function ignore() {
5
+ const { type } = await inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "type",
9
+ message: "Which .gitignore template do you want to generate?",
10
+ choices: [
11
+ "Node.js",
12
+ "Python",
13
+ "Go",
14
+ "Java",
15
+ "C++",
16
+ "React",
17
+ "Vue",
18
+ "Laravel",
19
+ { name: "Custom (using npx gitignore)", value: "custom" },
20
+ ],
21
+ },
22
+ ]);
23
+
24
+ try {
25
+ if (type === "custom") {
26
+ const { customType } = await inquirer.prompt([
27
+ {
28
+ type: "input",
29
+ name: "customType",
30
+ message:
31
+ "Enter the environments/tools (comma separated, e.g. node,react,macos):",
32
+ },
33
+ ]);
34
+ console.log(`Generating .gitignore for ${customType}...`);
35
+ execSync(`npx gitignore ${customType}`, { stdio: "inherit" });
36
+ } else {
37
+ let searchType = type.toLowerCase();
38
+ if (searchType === "node.js") searchType = "node";
39
+ if (searchType === "c++") searchType = "c++";
40
+
41
+ console.log(`Generating .gitignore for ${type}...`);
42
+ execSync(`npx gitignore ${searchType}`, { stdio: "inherit" });
43
+ }
44
+ console.log(".gitignore generated successfully!");
45
+ } catch (error) {
46
+ console.error("\\nFailed to generate .gitignore. Ensure npx is available.");
47
+ }
48
+ };
@@ -0,0 +1,22 @@
1
+ const inquirer = require("inquirer").default;
2
+ const chalk = require("chalk");
3
+
4
+ module.exports = async function init() {
5
+ const { projectType } = await inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "projectType",
9
+ message: "What type of project do you want to create?",
10
+ choices: [
11
+ { name: chalk.hex("#FEE140")("Frontend"), value: "Frontend" },
12
+ { name: chalk.hex("#FA709A")("Backend"), value: "Backend" },
13
+ ],
14
+ },
15
+ ]);
16
+
17
+ if (projectType === "Frontend") {
18
+ require("./frontend")();
19
+ } else {
20
+ require("./backend")();
21
+ }
22
+ };
@@ -0,0 +1,85 @@
1
+ const inquirer = require("inquirer").default;
2
+ const chalk = require("chalk");
3
+ const spawn = require("cross-spawn");
4
+
5
+ module.exports = async function test() {
6
+ const { testTool } = await inquirer.prompt([
7
+ {
8
+ type: "list",
9
+ name: "testTool",
10
+ pageSize: 8,
11
+ message: "Which testing tool do you want to setup or run?",
12
+ choices: [
13
+ { name: chalk.hex("#fcd12a")("Jest (Unit Testing)"), value: "Jest" },
14
+ { name: chalk.hex("#fbc22b")("Mocha (Unit Testing)"), value: "Mocha" },
15
+ {
16
+ name: chalk.hex("#fab32c")("Chai (Assertion Library)"),
17
+ value: "Chai",
18
+ },
19
+ {
20
+ name: chalk.hex("#f9a42d")("Cypress (E2E Testing)"),
21
+ value: "Cypress",
22
+ },
23
+ {
24
+ name: chalk.hex("#f8952e")("Vitest (Unit Testing)"),
25
+ value: "Vitest",
26
+ },
27
+ ],
28
+ },
29
+ ]);
30
+
31
+ try {
32
+ switch (testTool) {
33
+ case "Jest":
34
+ console.log("Setting up & running Jest...");
35
+ spawn("npm", ["install", "--save-dev", "jest"], {
36
+ stdio: "inherit",
37
+ shell: true,
38
+ });
39
+ spawn("npx", ["jest", "--init"], {
40
+ stdio: "inherit",
41
+ shell: true,
42
+ });
43
+ break;
44
+ case "Vitest":
45
+ console.log("Setting up Vitest...");
46
+ spawn("npm", ["install", "--save-dev", "vitest"], {
47
+ stdio: "inherit",
48
+ shell: true,
49
+ });
50
+ spawn("npx", ["vitest"], {
51
+ stdio: "inherit",
52
+ shell: true,
53
+ });
54
+ break;
55
+ case "Cypress":
56
+ console.log("Opening Cypress...");
57
+ spawn("npm", ["install", "--save-dev", "cypress"], {
58
+ stdio: "inherit",
59
+ shell: true,
60
+ });
61
+ spawn("npx", ["cypress", "open"], {
62
+ stdio: "inherit",
63
+ shell: true,
64
+ });
65
+ break;
66
+ case "Playwright":
67
+ console.log("Initializing Playwright...");
68
+ spawn("npm", ["init", "playwright@latest"], {
69
+ stdio: "inherit",
70
+ shell: true,
71
+ });
72
+ break;
73
+ case "Mocha":
74
+ console.log("Installing Mocha & Chai...");
75
+ spawn("npm", ["install", "--save-dev", "mocha", "chai"], {
76
+ stdio: "inherit",
77
+ shell: true,
78
+ });
79
+ break;
80
+ }
81
+ console.log(chalk.green(`\nSuccessfully initialized ${testTool}!`));
82
+ } catch (error) {
83
+ console.error(chalk.red(`\nFailed to setup or run ${testTool}.`));
84
+ }
85
+ };
@@ -0,0 +1,22 @@
1
+ const inquirer = require("inquirer").default;
2
+ const chalk = require("chalk");
3
+ const { execSync } = require("child_process");
4
+
5
+ module.exports = async function json() {
6
+ const { port } = await inquirer.prompt([
7
+ {
8
+ type: "input",
9
+ name: "port",
10
+ message: chalk.cyan("Which port do you want to use for JSON server?"),
11
+ default: "3000",
12
+ },
13
+ ]);
14
+ console.log(
15
+ chalk.green(
16
+ `\nStarting JSON Server on port ${port}... (Make sure db.json exists)`,
17
+ ),
18
+ );
19
+ execSync(`npx json-server --watch db.json --port ${port}`, {
20
+ stdio: "inherit",
21
+ });
22
+ };
@@ -0,0 +1,11 @@
1
+ const chalk = require("chalk");
2
+ const { execSync } = require("child_process");
3
+
4
+ module.exports = function live() {
5
+ try {
6
+ console.log(chalk.green("\nStarting Live Server..."));
7
+ execSync("npx live-server", { stdio: "inherit" });
8
+ } catch (error) {
9
+ console.error(chalk.red(`\nFailed to start Live Server.`));
10
+ }
11
+ };
@@ -0,0 +1,16 @@
1
+ const inquirer = require("inquirer").default;
2
+ const chalk = require("chalk");
3
+ const { execSync } = require("child_process");
4
+
5
+ module.exports = async function serve() {
6
+ const { port } = await inquirer.prompt([
7
+ {
8
+ type: "input",
9
+ name: "port",
10
+ message: chalk.cyan("Which port do you want to use?"),
11
+ default: "3000",
12
+ },
13
+ ]);
14
+ console.log(chalk.green(`\nStarting Serve on port ${port}...`));
15
+ execSync(`npx serve -l ${port}`, { stdio: "inherit" });
16
+ };
@@ -0,0 +1,20 @@
1
+ const inquirer = require("inquirer").default;
2
+ const chalk = require("chalk");
3
+ const { execSync } = require("child_process");
4
+
5
+ module.exports = async function tunnel() {
6
+ try {
7
+ const { port } = await inquirer.prompt([
8
+ {
9
+ type: "input",
10
+ name: "port",
11
+ message: chalk.cyan("Which port do you want to expose?"),
12
+ default: "3000",
13
+ },
14
+ ]);
15
+ console.log(chalk.green(`\nStarting LocalTunnel on port ${port}...`));
16
+ execSync(`npx localtunnel --port ${port}`, { stdio: "inherit" });
17
+ } catch (error) {
18
+ console.error(chalk.red(`\nFailed to start LocalTunnel.`));
19
+ }
20
+ };
@@ -0,0 +1,68 @@
1
+ const inquirer = require("inquirer").default;
2
+ const { execSync } = require("child_process");
3
+
4
+ module.exports = async function tools() {
5
+ const { selectedTool } = await inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "selectedTool",
9
+ message: "Which tool do you want to run?",
10
+ choices: [
11
+ {
12
+ name: "LocalTunnel (Expose localhost to the internet)",
13
+ value: "localtunnel",
14
+ },
15
+ {
16
+ name: "Live Server (Development static server with live reload)",
17
+ value: "live-server",
18
+ },
19
+ { name: "Serve (Simple static file server)", value: "serve" },
20
+ {
21
+ name: "JSON Server (Mock a complete REST API from a JSON file)",
22
+ value: "json-server",
23
+ },
24
+ ],
25
+ },
26
+ ]);
27
+
28
+ let port = "3000";
29
+
30
+ if (["localtunnel", "serve", "json-server"].includes(selectedTool)) {
31
+ const answer = await inquirer.prompt([
32
+ {
33
+ type: "input",
34
+ name: "port",
35
+ message: "Which port do you want to use/target?",
36
+ default: "3000",
37
+ },
38
+ ]);
39
+ port = answer.port;
40
+ }
41
+
42
+ try {
43
+ switch (selectedTool) {
44
+ case "localtunnel":
45
+ console.log(`Starting LocalTunnel on port ${port}...`);
46
+ execSync(`npx localtunnel --port ${port}`, { stdio: "inherit" });
47
+ break;
48
+ case "live-server":
49
+ console.log("Starting Live Server...");
50
+ execSync("npx live-server", { stdio: "inherit" });
51
+ break;
52
+ case "serve":
53
+ console.log(`Starting Serve on port ${port}...`);
54
+ execSync(`npx serve -l ${port}`, { stdio: "inherit" });
55
+ break;
56
+ case "json-server":
57
+ console.log(
58
+ `Starting JSON Server on port ${port}... (Make sure db.json exists)`,
59
+ );
60
+ execSync(`npx json-server --watch db.json --port ${port}`, {
61
+ stdio: "inherit",
62
+ });
63
+ break;
64
+ }
65
+ } catch (error) {
66
+ console.error(`\\nError running ${selectedTool}.`);
67
+ }
68
+ };
package/hello/hello.js ADDED
@@ -0,0 +1,50 @@
1
+ const chalk = require("chalk");
2
+ const packageJson = require("../package.json");
3
+
4
+ module.exports = function hello() {
5
+ // Witty title & separator
6
+ const title = `${chalk.hex("#fcd12a").bold("kitsui")}@${chalk.hex("#FA709A").bold("cli")}`;
7
+ const separator = chalk.gray("-".repeat(9));
8
+
9
+ // Cute Fox ASCII Art (Senko-san style coloring)
10
+ const foxArt = [
11
+ ` ⠀⠀⢰⠢⣄⠀⠀⠀⠀⠀ ⣀⣀ `,
12
+ `⠀⠀⠀⠀⠀⠀⠈⡄⢀⠙⢦⣀⠀⠀⠀⢀⢎⢀⠦⢹ `,
13
+ `⠀⠀⠀⠀⠀⠀⠀⢡⠨⣄⠈⠿⣕⣄⢀⡾⠊⠨⣸⡀⢧ `,
14
+ `⠀⠀⠀⠀⠀⠀⠀⠈⢞⠻⡗⢆⢷⢇⠛⢀⡀⢴⣶⡇⣸⣦ `,
15
+ `⠀⠀⠀⠀⠀⠀⠀⠀⠸⠢⠕⠈⠀⠈⠀⠞⢱⠿⠛⢠⢿⡙ `,
16
+ `⠀⠀⠀⠀⠀⠀⠀⠀⢐⠆⠀⠀⠀⠀⠀⠀⠁⣄⣄⡼⢎⡀⢣ `,
17
+ `⠀⠀⠀⠀⠀⠀⠀⠀⠙⢢⠀⠀⢰⣧⣤⠠⣆⡀⠫⡱⡢⡀⢹ `,
18
+ `⠀⠀⠀⠀⠀⠀⠀⠀⠀⡟⠀⡤⡏⠈⠀⠐⠊⠙⠢⡸⣞⡌⠘ `,
19
+ `⠀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠀⣴⡷⡤⢂⠁⠀⠀⢠⠈⠟⡞⢆ `,
20
+ `⠀⠀⠀⠀⠀⠀⠀⢿⣿⠞⠉⢙⣥⠮⠍⠒⠒⠠⠼⡀⠀⠇⡼ `,
21
+ `⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠑⠞⠁⠀⠀⠀⠀⠀⠀⠀ `,
22
+ ];
23
+
24
+ const labelColor = chalk.hex("#fcd12a").bold;
25
+ const foxColor = chalk.hex("#f9a42d");
26
+ const valueColor = chalk.white;
27
+
28
+ const info = [
29
+ ``,
30
+ title,
31
+ separator,
32
+ `${labelColor("Version")}: ${valueColor(packageJson.version)}`,
33
+ `${labelColor("Author")}: ${valueColor("VanSchwarz")}`,
34
+ `${labelColor("Description")}: ${valueColor("🦊 A magical CLI to boost your workflow")}`,
35
+ `${labelColor("Key Features")}: ${valueColor("Scaffold Frontend/Backend, Automate Git & Deploy")}`,
36
+ `${labelColor("Theme")}: ${valueColor("Senko-san Pastel (Yellow-Orange)")}`,
37
+ `${labelColor("Commands")}: ${valueColor(Object.keys(packageJson.dependencies).length + " internal modules")}`,
38
+ ];
39
+
40
+ const maxLines = Math.max(foxArt.length, info.length);
41
+
42
+ console.log();
43
+ for (let i = 0; i < maxLines; i++) {
44
+ const leftText = foxArt[i] ? foxArt[i].padEnd(16) : " ".repeat(16);
45
+ const left = foxColor(leftText);
46
+ const right = info[i] || "";
47
+ console.log(`${left} ${right}`);
48
+ }
49
+ console.log();
50
+ };
Binary file
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "kitsui-cli",
3
+ "version": "1.0.0",
4
+ "description": "command line assistant to start a new project",
5
+ "keywords": [
6
+ "cli"
7
+ ],
8
+ "bin": {
9
+ "kitsui": "bin/index.js"
10
+ },
11
+ "license": "ISC",
12
+ "author": "revananda",
13
+ "type": "commonjs",
14
+ "main": "index.js",
15
+ "scripts": {
16
+ "test": "echo \"Error: no test specified\" && exit 1"
17
+ },
18
+ "dependencies": {
19
+ "chalk": "^4.1.2",
20
+ "commander": "^11.0.0",
21
+ "cross-spawn": "^7.0.6",
22
+ "fs-extra": "^11.0.0",
23
+ "inquirer": "^9.0.0"
24
+ }
25
+ }