neatnode 3.0.3 → 3.1.3

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 (56) hide show
  1. package/package.json +3 -1
  2. package/src/actions/createProject.js +15 -12
  3. package/src/cli.js +45 -30
  4. package/src/config/templates.js +12 -19
  5. package/src/utils/downloadRepoTemplate.js +47 -0
  6. package/templates/express-basic/.env.example +0 -3
  7. package/templates/express-basic/package-lock.json +0 -1505
  8. package/templates/express-basic/package.json +0 -21
  9. package/templates/express-basic/server.js +0 -11
  10. package/templates/express-basic/src/app.js +0 -45
  11. package/templates/express-basic/src/config/db.config.js +0 -12
  12. package/templates/express-basic/src/config/env.config.js +0 -11
  13. package/templates/express-basic/src/controllers/todo.controller.js +0 -90
  14. package/templates/express-basic/src/middleware/notFound.middleware.js +0 -5
  15. package/templates/express-basic/src/models/todo.model.js +0 -21
  16. package/templates/express-basic/src/routes/index.route.js +0 -10
  17. package/templates/express-basic/src/routes/todo.route.js +0 -15
  18. package/templates/express-basic/src/utils/responseHandler.js +0 -7
  19. package/templates/express-rest-api/.env.example +0 -7
  20. package/templates/express-rest-api/package-lock.json +0 -1977
  21. package/templates/express-rest-api/package.json +0 -30
  22. package/templates/express-rest-api/server.js +0 -14
  23. package/templates/express-rest-api/src/app.js +0 -55
  24. package/templates/express-rest-api/src/config/db.config.js +0 -14
  25. package/templates/express-rest-api/src/config/env.config.js +0 -13
  26. package/templates/express-rest-api/src/config/logger.config.js +0 -20
  27. package/templates/express-rest-api/src/controllers/user.controller.js +0 -35
  28. package/templates/express-rest-api/src/middleware/auth.middleware.js +0 -36
  29. package/templates/express-rest-api/src/middleware/error.middleware.js +0 -32
  30. package/templates/express-rest-api/src/middleware/rateLimiter.js +0 -13
  31. package/templates/express-rest-api/src/middleware/validateRequest.middleware.js +0 -15
  32. package/templates/express-rest-api/src/models/user.model.js +0 -31
  33. package/templates/express-rest-api/src/routes/user.route.js +0 -14
  34. package/templates/express-rest-api/src/schemas/user.schema.js +0 -43
  35. package/templates/express-rest-api/src/services/user.service.js +0 -54
  36. package/templates/express-rest-api/src/utils/ApiError.js +0 -17
  37. package/templates/express-rest-api/src/utils/ApiResponse.js +0 -9
  38. package/templates/express-rest-api/src/utils/CatchAsync.js +0 -5
  39. package/templates/express-rest-api/src/utils/Token.js +0 -16
  40. package/templates/express-socket/.env.example +0 -5
  41. package/templates/express-socket/package-lock.json +0 -2262
  42. package/templates/express-socket/package.json +0 -31
  43. package/templates/express-socket/server.js +0 -19
  44. package/templates/express-socket/src/app.js +0 -33
  45. package/templates/express-socket/src/config/db.config.js +0 -14
  46. package/templates/express-socket/src/config/env.config.js +0 -10
  47. package/templates/express-socket/src/config/logger.js +0 -20
  48. package/templates/express-socket/src/config/socket.js +0 -23
  49. package/templates/express-socket/src/middleware/auth.middleware.js +0 -36
  50. package/templates/express-socket/src/middleware/error.middleware.js +0 -31
  51. package/templates/express-socket/src/middleware/rateLimiter.js +0 -14
  52. package/templates/express-socket/src/middleware/validateRequest.middleware.js +0 -15
  53. package/templates/express-socket/src/utils/ApiError.js +0 -17
  54. package/templates/express-socket/src/utils/ApiResponse.js +0 -9
  55. package/templates/express-socket/src/utils/CatchAsync.js +0 -5
  56. package/templates/express-socket/src/utils/Token.js +0 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neatnode",
3
- "version": "3.0.3",
3
+ "version": "3.1.3",
4
4
  "description": "Plug & Play Node.js backend starter templates — build REST APIs, socket servers, and more in seconds.",
5
5
  "bin": {
6
6
  "neatnode": "./bin/index.js"
@@ -39,6 +39,8 @@
39
39
  "license": "ISC",
40
40
  "type": "module",
41
41
  "dependencies": {
42
+ "axios": "^1.13.2",
43
+ "extract-zip": "^2.0.1",
42
44
  "fs-extra": "^11.3.2",
43
45
  "inquirer": "^12.10.0"
44
46
  }
@@ -4,14 +4,16 @@ import os from "os";
4
4
  import { fileURLToPath } from "url";
5
5
  import { copyTemplate } from "../utils/copyTemplate.js";
6
6
  import { removeCrud, removeCrudReferences } from "./removeCRUD.js";
7
+ import { downloadTemplate } from "../utils/downloadRepoTemplate.js";
7
8
 
8
9
  const __filename = fileURLToPath(import.meta.url);
9
10
  const __dirname = path.dirname(__filename);
10
11
 
11
- export async function createProject({ projectName, templatePath, includeCrud, crudName }) {
12
+ export async function createProject({ projectName, repoPath, includeCrud, crudName }) {
12
13
  try {
13
- // If user wants to create in current dir (.)
14
- const targetPath = projectName === "." ? process.cwd() : path.join(process.cwd(), projectName);
14
+ const targetPath = projectName === "."
15
+ ? process.cwd()
16
+ : path.join(process.cwd(), projectName);
15
17
 
16
18
  if (fs.existsSync(targetPath) && projectName !== ".") {
17
19
  console.error(`❌ Folder "${projectName}" already exists.`);
@@ -19,29 +21,30 @@ export async function createProject({ projectName, templatePath, includeCrud, cr
19
21
  }
20
22
 
21
23
  if (projectName !== ".") {
22
- console.log("Creating project folder...");
24
+ console.log("📁 Creating project folder...");
23
25
  fs.mkdirSync(targetPath);
24
26
  }
25
27
 
26
- await copyTemplate(templatePath, targetPath, {
28
+ console.log("⬇️ Downloading template...");
29
+ const localTemplatePath = await downloadTemplate(repoPath);
30
+
31
+ await copyTemplate(localTemplatePath, targetPath, {
27
32
  "project-name": projectName === "." ? path.basename(process.cwd()) : projectName,
28
33
  "author": os.userInfo().username || "author",
29
34
  });
30
35
 
31
- if (!includeCrud) {
32
- console.log("🗑️ Removing CRUD files...");
36
+ if (includeCrud && crudName ) {
37
+ console.log("🗑 Removing CRUD files...");
33
38
  removeCrud(targetPath, crudName);
34
39
  removeCrudReferences(path.join(targetPath, "src", "app.js"));
35
40
  }
36
41
 
37
- console.log(`✅ Project "${projectName}" created successfully!`);
38
- console.log(`\ncd ${projectName === "." ? "" : projectName}`);
39
- console.log("npm install");
40
- console.log("npm run dev (or npm start)\n");
42
+ console.log(`\n✅ Project "${projectName}" created successfully!\n`);
41
43
 
42
44
  } catch (err) {
43
- console.error("Failed to create project:", err);
45
+ console.error("Failed to create project:", err);
44
46
  process.exit(1);
45
47
  }
46
48
  }
47
49
 
50
+
package/src/cli.js CHANGED
@@ -1,74 +1,89 @@
1
1
  #!/usr/bin/env node
2
2
  import inquirer from "inquirer";
3
- import { createProject } from "./actions/createProject.js";
4
3
  import templates from "./config/templates.js";
4
+ import { createProject } from "./actions/createProject.js";
5
5
 
6
6
  async function main() {
7
- console.log("\n🚀 Welcome to NodeNeat CLI!\n");
7
+ console.log("\n🚀 Welcome to NeatNode CLI!\n");
8
8
 
9
- // Step 1: Ask for project name
9
+ // STEP 1 Project Name
10
10
  const { projectName } = await inquirer.prompt([
11
11
  {
12
- name: "projectName",
13
12
  type: "input",
14
- message: "Enter your project folder name:",
13
+ name: "projectName",
14
+ message: "Enter project folder name:",
15
15
  default: "my-app",
16
- validate: (input) => input.trim() !== "" || "Project name cannot be empty."
17
- }
16
+ validate: (v) => v.trim() !== "" || "Project name cannot be empty.",
17
+ },
18
+ ]);
19
+
20
+ // STEP 2 — Choose Language
21
+ const { language } = await inquirer.prompt([
22
+ {
23
+ type: "list",
24
+ name: "language",
25
+ message: "Select language:",
26
+ choices: ["JavaScript", "TypeScript"],
27
+ },
18
28
  ]);
19
29
 
20
- // Step 2: Choose template
30
+ const langKey = language === "JavaScript" ? "js" : "ts";
31
+ const templateList = templates[langKey];
32
+
33
+ // STEP 3 — Choose Template
21
34
  const { template } = await inquirer.prompt([
22
35
  {
23
- name: "template",
24
36
  type: "list",
37
+ name: "template",
25
38
  message: "Choose a template:",
26
- choices: templates.map((t) => t.name)
27
- }
39
+ choices: templateList.map((t) => t.name),
40
+ },
28
41
  ]);
29
42
 
30
- const chosen = templates.find((t) => t.name === template);
43
+ const chosen = templateList.find((t) => t.name === template);
31
44
 
32
- // Step 3: Optional prompt if REST API
45
+ // STEP 4 — CRUD Optional (only for some templates)
33
46
  let includeCrud = false;
34
47
  let crudName = "";
48
+
35
49
  if (chosen.name === "Basic Express") {
36
- const answer = await inquirer.prompt([
50
+ const { includeCrud: answer } = await inquirer.prompt([
37
51
  {
38
- name: "includeCrud",
39
52
  type: "confirm",
40
- message: "Include example Todo CRUD setup?",
41
- default: true
42
- }
53
+ name: "includeCrud",
54
+ message: "Include example Todo CRUD?",
55
+ default: true,
56
+ },
43
57
  ]);
44
- includeCrud = answer.includeCrud;
58
+ includeCrud = answer;
45
59
  crudName = "todo";
46
60
  }
47
61
 
48
62
  if (chosen.name === "REST API") {
49
- const answer = await inquirer.prompt([
63
+ const { includeCrud: answer } = await inquirer.prompt([
50
64
  {
51
- name: "includeCrud",
52
65
  type: "confirm",
53
- message: "Include example User CRUD setup?",
54
- default: true
55
- }
66
+ name: "includeCrud",
67
+ message: "Include example User CRUD?",
68
+ default: true,
69
+ },
56
70
  ]);
57
- includeCrud = answer.includeCrud;
71
+ includeCrud = answer;
58
72
  crudName = "user";
59
73
  }
60
74
 
61
- // Step 4: Create the project
75
+ // STEP 5 Create Project (Remote download logic inside)
62
76
  await createProject({
63
77
  projectName,
64
- templatePath: chosen.path,
78
+ repoPath: chosen.repoPath,
65
79
  includeCrud,
66
- crudName
80
+ crudName,
81
+ language: langKey,
67
82
  });
68
83
 
69
- console.log(`\n✅ Project "${projectName}" created successfully using "${chosen.name}" template.\n`);
84
+ console.log(`\n✅ Project "${projectName}" created successfully using "${chosen.name}".\n`);
70
85
  }
71
86
 
72
87
  main().catch((err) => {
73
- console.error("❌ Error:", err.message);
88
+ console.error("❌ Error:", err.message || err);
74
89
  });
@@ -1,20 +1,13 @@
1
- import path from "path";
2
- import { fileURLToPath } from "url";
1
+ export default {
2
+ js: [
3
+ { name: "Basic Express", repoPath: "templates/js/express-basic" },
4
+ { name: "REST API", repoPath: "templates/js/express-rest-api" },
5
+ { name: "Socket.IO", repoPath: "templates/js/express-socket" },
6
+ ],
3
7
 
4
- const __filename = fileURLToPath(import.meta.url);
5
- const __dirname = path.dirname(__filename);
6
-
7
- export default [
8
- {
9
- name: "Basic Express",
10
- path: path.join(__dirname, "../../templates/express-basic")
11
- },
12
- {
13
- name: "REST API",
14
- path: path.join(__dirname, "../../templates/express-rest-api")
15
- },
16
- {
17
- name: "Socket.IO Setup",
18
- path: path.join(__dirname, "../../templates/express-socket")
19
- }
20
- ];
8
+ ts: [
9
+ { name: "Basic Express (TS)", repoPath: "templates/ts/basic-express" },
10
+ // { name: "REST API (TS)", repoPath: "templates/ts/express-rest-api" },
11
+ // { name: "Socket.IO (TS)", repoPath: "templates/ts/express-socket" },
12
+ ],
13
+ };
@@ -0,0 +1,47 @@
1
+ import axios from "axios";
2
+ import extract from "extract-zip";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ // your repo
11
+ const owner = "aakash-gupta02";
12
+ const repo = "NeatNode";
13
+
14
+ // GitHub codeload URL
15
+ const zipUrl = `https://codeload.github.com/${owner}/${repo}/zip/refs/heads/main`;
16
+
17
+ export async function downloadTemplate(repoPath) {
18
+ const tempZip = path.join(__dirname, "repo.zip");
19
+ const tempExtractDir = path.join(__dirname, "repo-extract");
20
+ const tempFinalDir = path.join(__dirname, "template-final");
21
+
22
+ const response = await axios({
23
+ url: zipUrl,
24
+ responseType: "arraybuffer",
25
+ });
26
+
27
+ fs.writeFileSync(tempZip, response.data);
28
+
29
+ await extract(tempZip, { dir: tempExtractDir });
30
+
31
+ const extractedRoot = path.join(tempExtractDir, `${repo}-main`);
32
+ const srcTemplatePath = path.join(extractedRoot, repoPath);
33
+
34
+ // ensure final directory exists
35
+ fs.rmSync(tempFinalDir, { recursive: true, force: true });
36
+ fs.mkdirSync(tempFinalDir, { recursive: true });
37
+
38
+ fs.cpSync(srcTemplatePath, tempFinalDir, { recursive: true });
39
+
40
+ // cleanup zip + extract folder
41
+ fs.rmSync(tempZip);
42
+ fs.rmSync(tempExtractDir, { recursive: true, force: true });
43
+
44
+ console.log("✔ Template downloaded & extracted");
45
+ return tempFinalDir;
46
+ }
47
+
@@ -1,3 +0,0 @@
1
- PORT=3000
2
- MONGODB_URI=mongodb://localhost:27017/mydatabase
3
- CLIENT_URL=http://localhost:5137 # Frontend URL