create-charcole 2.1.0 → 2.2.1

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 (79) hide show
  1. package/.github/workflows/release.yml +26 -26
  2. package/CHANGELOG.md +301 -211
  3. package/LICENSE +21 -21
  4. package/README.md +354 -213
  5. package/bin/index.js +444 -288
  6. package/bin/lib/pkgManager.js +49 -49
  7. package/bin/lib/templateHandler.js +33 -33
  8. package/create-charcole-2.1.0.tgz +0 -0
  9. package/package.json +42 -27
  10. package/packages/swagger/BACKWARD_COMPATIBILITY.md +145 -0
  11. package/packages/swagger/CHANGELOG.md +404 -0
  12. package/packages/swagger/README.md +578 -0
  13. package/packages/swagger/charcole-swagger-1.0.0.tgz +0 -0
  14. package/packages/swagger/package-lock.json +1715 -0
  15. package/packages/swagger/package.json +57 -0
  16. package/packages/swagger/src/helpers.js +427 -0
  17. package/packages/swagger/src/index.d.ts +126 -0
  18. package/packages/swagger/src/index.js +12 -0
  19. package/packages/swagger/src/setup.js +100 -0
  20. package/template/js/.env.example +15 -15
  21. package/template/js/README.md +978 -855
  22. package/template/js/basePackage.json +26 -26
  23. package/template/js/src/app.js +81 -78
  24. package/template/js/src/config/constants.js +20 -20
  25. package/template/js/src/config/env.js +26 -26
  26. package/template/js/src/config/swagger.config.js +15 -0
  27. package/template/js/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
  28. package/template/js/src/middlewares/errorHandler.js +180 -180
  29. package/template/js/src/middlewares/requestLogger.js +33 -33
  30. package/template/js/src/middlewares/validateRequest.js +42 -42
  31. package/template/js/src/modules/auth/auth.constants.js +3 -3
  32. package/template/js/src/modules/auth/auth.controller.js +29 -29
  33. package/template/js/src/modules/auth/auth.middlewares.js +19 -19
  34. package/template/js/src/modules/auth/auth.routes.js +131 -9
  35. package/template/js/src/modules/auth/auth.schemas.js +60 -60
  36. package/template/js/src/modules/auth/auth.service.js +67 -67
  37. package/template/js/src/modules/auth/package.json +6 -6
  38. package/template/js/src/modules/health/controller.js +151 -50
  39. package/template/js/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
  40. package/template/js/src/modules/swagger/package.json +5 -0
  41. package/template/js/src/repositories/user.repo.js +19 -19
  42. package/template/js/src/routes/index.js +25 -25
  43. package/template/js/src/routes/protected.js +57 -13
  44. package/template/js/src/server.js +38 -38
  45. package/template/js/src/utils/AppError.js +182 -182
  46. package/template/js/src/utils/logger.js +73 -73
  47. package/template/js/src/utils/response.js +51 -51
  48. package/template/ts/.env.example +15 -15
  49. package/template/ts/README.md +978 -855
  50. package/template/ts/basePackage.json +36 -36
  51. package/template/ts/build.js +46 -46
  52. package/template/ts/src/app.ts +71 -67
  53. package/template/ts/src/config/constants.ts +27 -27
  54. package/template/ts/src/config/env.ts +40 -40
  55. package/template/ts/src/config/swagger.config.ts +30 -0
  56. package/template/ts/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
  57. package/template/ts/src/middlewares/errorHandler.ts +201 -201
  58. package/template/ts/src/middlewares/requestLogger.ts +38 -38
  59. package/template/ts/src/middlewares/validateRequest.ts +46 -46
  60. package/template/ts/src/modules/auth/auth.constants.ts +6 -6
  61. package/template/ts/src/modules/auth/auth.controller.ts +32 -32
  62. package/template/ts/src/modules/auth/auth.middlewares.ts +46 -46
  63. package/template/ts/src/modules/auth/auth.routes.ts +52 -9
  64. package/template/ts/src/modules/auth/auth.schemas.ts +73 -73
  65. package/template/ts/src/modules/auth/auth.service.ts +106 -106
  66. package/template/ts/src/modules/auth/package.json +10 -10
  67. package/template/ts/src/modules/health/controller.ts +80 -64
  68. package/template/ts/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
  69. package/template/ts/src/modules/swagger/package.json +5 -0
  70. package/template/ts/src/repositories/user.repo.ts +33 -33
  71. package/template/ts/src/routes/index.ts +24 -24
  72. package/template/ts/src/routes/protected.ts +46 -13
  73. package/template/ts/src/server.ts +41 -41
  74. package/template/ts/src/types/express.d.ts +9 -9
  75. package/template/ts/src/utils/AppError.ts +220 -220
  76. package/template/ts/src/utils/logger.ts +55 -55
  77. package/template/ts/src/utils/response.ts +100 -100
  78. package/template/ts/tsconfig.json +26 -26
  79. package/plans/V2_1_PLAN.md +0 -20
@@ -1,49 +1,49 @@
1
- const { execSync } = require("child_process");
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- /**
6
- * Detect which package manager the user is using
7
- * Priority: pnpm > yarn > npm
8
- */
9
- function detectPackageManager() {
10
- const userAgent = process.env.npm_config_user_agent;
11
-
12
- if (userAgent) {
13
- if (userAgent.includes("pnpm")) return "pnpm";
14
- if (userAgent.includes("yarn")) return "yarn";
15
- if (userAgent.includes("npm")) return "npm";
16
- }
17
-
18
- const lockFiles = {
19
- "pnpm-lock.yaml": "pnpm",
20
- "yarn.lock": "yarn",
21
- "package-lock.json": "npm",
22
- };
23
-
24
- for (const [lockFile, manager] of Object.entries(lockFiles)) {
25
- if (fs.existsSync(path.join(process.cwd(), lockFile))) {
26
- return manager;
27
- }
28
- }
29
-
30
- return "npm";
31
- }
32
-
33
- /**
34
- * Install dependencies
35
- */
36
- function installDependencies(targetDir, pkgManager) {
37
- const installCmd =
38
- pkgManager === "yarn" ? "yarn install" : `${pkgManager} install`;
39
-
40
- execSync(installCmd, {
41
- cwd: targetDir,
42
- stdio: "inherit",
43
- });
44
- }
45
-
46
- module.exports = {
47
- detectPackageManager,
48
- installDependencies,
49
- };
1
+ const { execSync } = require("child_process");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ /**
6
+ * Detect which package manager the user is using
7
+ * Priority: pnpm > yarn > npm
8
+ */
9
+ function detectPackageManager() {
10
+ const userAgent = process.env.npm_config_user_agent;
11
+
12
+ if (userAgent) {
13
+ if (userAgent.includes("pnpm")) return "pnpm";
14
+ if (userAgent.includes("yarn")) return "yarn";
15
+ if (userAgent.includes("npm")) return "npm";
16
+ }
17
+
18
+ const lockFiles = {
19
+ "pnpm-lock.yaml": "pnpm",
20
+ "yarn.lock": "yarn",
21
+ "package-lock.json": "npm",
22
+ };
23
+
24
+ for (const [lockFile, manager] of Object.entries(lockFiles)) {
25
+ if (fs.existsSync(path.join(process.cwd(), lockFile))) {
26
+ return manager;
27
+ }
28
+ }
29
+
30
+ return "npm";
31
+ }
32
+
33
+ /**
34
+ * Install dependencies
35
+ */
36
+ function installDependencies(targetDir, pkgManager) {
37
+ const installCmd =
38
+ pkgManager === "yarn" ? "yarn install" : `${pkgManager} install`;
39
+
40
+ execSync(installCmd, {
41
+ cwd: targetDir,
42
+ stdio: "inherit",
43
+ });
44
+ }
45
+
46
+ module.exports = {
47
+ detectPackageManager,
48
+ installDependencies,
49
+ };
@@ -1,33 +1,33 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
-
4
- /**
5
- * Recursively copy directory contents, excluding specific files
6
- */
7
- function copyDir(src, dest, excludeFiles = []) {
8
- if (!fs.existsSync(dest)) {
9
- fs.mkdirSync(dest, { recursive: true });
10
- }
11
-
12
- const entries = fs.readdirSync(src, { withFileTypes: true });
13
-
14
- for (const entry of entries) {
15
- const srcPath = path.join(src, entry.name);
16
- const destPath = path.join(dest, entry.name);
17
-
18
- // Skip excluded files
19
- if (excludeFiles.includes(entry.name)) {
20
- continue;
21
- }
22
-
23
- if (entry.isDirectory()) {
24
- copyDir(srcPath, destPath, excludeFiles);
25
- } else {
26
- fs.copyFileSync(srcPath, destPath);
27
- }
28
- }
29
- }
30
-
31
- module.exports = {
32
- copyDir,
33
- };
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ /**
5
+ * Recursively copy directory contents, excluding specific files
6
+ */
7
+ function copyDir(src, dest, excludeFiles = []) {
8
+ if (!fs.existsSync(dest)) {
9
+ fs.mkdirSync(dest, { recursive: true });
10
+ }
11
+
12
+ const entries = fs.readdirSync(src, { withFileTypes: true });
13
+
14
+ for (const entry of entries) {
15
+ const srcPath = path.join(src, entry.name);
16
+ const destPath = path.join(dest, entry.name);
17
+
18
+ // Skip excluded files
19
+ if (excludeFiles.includes(entry.name)) {
20
+ continue;
21
+ }
22
+
23
+ if (entry.isDirectory()) {
24
+ copyDir(srcPath, destPath, excludeFiles);
25
+ } else {
26
+ fs.copyFileSync(srcPath, destPath);
27
+ }
28
+ }
29
+ }
30
+
31
+ module.exports = {
32
+ copyDir,
33
+ };
Binary file
package/package.json CHANGED
@@ -1,27 +1,42 @@
1
- {
2
- "name": "create-charcole",
3
- "version": "2.1.0",
4
- "description": "CLI to create production-ready Node.js Express APIs with TypeScript/JavaScript, JWT auth, and repository pattern",
5
- "license": "MIT",
6
- "author": {
7
- "name": "Sheraz Manzoor",
8
- "email": "sheraz.dev121@gmail.com"
9
- },
10
- "bin": {
11
- "create-charcole": "bin/index.js"
12
- },
13
- "keywords": [
14
- "express",
15
- "backend",
16
- "starter",
17
- "boilerplate",
18
- "production",
19
- "charcole"
20
- ],
21
- "engines": {
22
- "node": ">=16"
23
- },
24
- "dependencies": {
25
- "prompts": "^2.4.2"
26
- }
27
- }
1
+ {
2
+ "name": "create-charcole",
3
+ "version": "2.2.1",
4
+ "description": "CLI to create production-ready Node.js Express APIs with TypeScript/JavaScript, JWT auth, auto-generated Swagger docs, and repository pattern",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Sheraz Manzoor",
8
+ "email": "sheraz.dev121@gmail.com"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/sheraz4196/create-charcole.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/sheraz4196/create-charcole/issues"
16
+ },
17
+ "homepage": "https://www.charcole.site/",
18
+ "bin": {
19
+ "create-charcole": "bin/index.js"
20
+ },
21
+ "keywords": [
22
+ "express",
23
+ "backend",
24
+ "starter",
25
+ "boilerplate",
26
+ "production",
27
+ "charcole",
28
+ "nodejs starter",
29
+ "express starter",
30
+ "typescript backend",
31
+ "swagger",
32
+ "backend template",
33
+ "api-boilerplate",
34
+ "zod validation"
35
+ ],
36
+ "engines": {
37
+ "node": ">=16"
38
+ },
39
+ "dependencies": {
40
+ "prompts": "^2.4.2"
41
+ }
42
+ }
@@ -0,0 +1,145 @@
1
+ # @charcoles/swagger v2.0.0 - Backward Compatibility Test
2
+
3
+ ## Test Cases
4
+
5
+ ### ✅ Old JSDoc Approach (Still Works)
6
+
7
+ The traditional manual schema approach still works without any changes:
8
+
9
+ ```typescript
10
+ /**
11
+ * @swagger
12
+ * /api/old-endpoint:
13
+ * post:
14
+ * summary: Old style endpoint
15
+ * requestBody:
16
+ * content:
17
+ * application/json:
18
+ * schema:
19
+ * type: object
20
+ * required:
21
+ * - name
22
+ * properties:
23
+ * name:
24
+ * type: string
25
+ * responses:
26
+ * 200:
27
+ * description: Success
28
+ */
29
+ ```
30
+
31
+ **Status:** ✅ Fully compatible
32
+
33
+ ### ✅ Minimal Setup (Still Works)
34
+
35
+ Old setup without new options:
36
+
37
+ ```typescript
38
+ setupSwagger(app, {
39
+ title: "My API",
40
+ version: "1.0.0",
41
+ });
42
+ ```
43
+
44
+ **Status:** ✅ Fully compatible (new options are optional)
45
+
46
+ ### ✅ Mixed Approach (Old + New)
47
+
48
+ You can mix manual schemas and auto-generated ones:
49
+
50
+ ```typescript
51
+ setupSwagger(app, {
52
+ schemas: {
53
+ createUserSchema, // New: auto-generated from Zod
54
+ },
55
+ });
56
+
57
+ // Old manual approach
58
+ /**
59
+ * @swagger
60
+ * /api/manual:
61
+ * get:
62
+ * responses:
63
+ * 200:
64
+ * description: Success
65
+ */
66
+
67
+ // New reference approach
68
+ /**
69
+ * @swagger
70
+ * /api/auto:
71
+ * post:
72
+ * requestBody:
73
+ * content:
74
+ * application/json:
75
+ * schema:
76
+ * $ref: '#/components/schemas/createUserSchema'
77
+ */
78
+ ```
79
+
80
+ **Status:** ✅ Fully compatible
81
+
82
+ ### ✅ No Zod (Non-Charcole Projects)
83
+
84
+ Works fine without Zod schemas:
85
+
86
+ ```typescript
87
+ import { setupSwagger } from "@charcoles/swagger";
88
+
89
+ setupSwagger(app, {
90
+ title: "My API",
91
+ // No schemas - just use manual JSDoc approach
92
+ });
93
+ ```
94
+
95
+ **Status:** ✅ Fully compatible
96
+
97
+ ### ✅ Disable Common Responses
98
+
99
+ Can disable built-in responses if not wanted:
100
+
101
+ ```typescript
102
+ setupSwagger(app, {
103
+ includeCommonResponses: false, // Opt-out
104
+ });
105
+ ```
106
+
107
+ **Status:** ✅ Fully compatible
108
+
109
+ ## Migration Path
110
+
111
+ ### No Breaking Changes
112
+
113
+ All existing code continues to work:
114
+
115
+ 1. **Don't want to use new features?**
116
+ - No changes needed
117
+ - Everything works as before
118
+
119
+ 2. **Want to gradually adopt?**
120
+ - Start using schema references one endpoint at a time
121
+ - Mix old and new approaches
122
+
123
+ 3. **Want full benefits?**
124
+ - Register schemas in config
125
+ - Update JSDoc to use `$ref`
126
+ - Enjoy 60-80% less code
127
+
128
+ ## Compatibility Matrix
129
+
130
+ | Feature | v1.0.0 | v2.0.0 | Notes |
131
+ | ------------------------ | ------ | ------ | ------------------------------ |
132
+ | Manual JSDoc | ✅ | ✅ | No changes needed |
133
+ | Basic setup | ✅ | ✅ | All old options work |
134
+ | Security schemes | ✅ | ✅ | bearerAuth still auto-included |
135
+ | File scanning | ✅ | ✅ | Same directories scanned |
136
+ | TypeScript detection | ✅ | ✅ | Same auto-detection |
137
+ | Zod schemas (new) | ❌ | ✅ | Optional new feature |
138
+ | Response templates (new) | ❌ | ✅ | Optional new feature |
139
+ | Helper functions (new) | ❌ | ✅ | Optional new feature |
140
+
141
+ ## Conclusion
142
+
143
+ **100% backward compatible** ✅
144
+
145
+ No breaking changes. All new features are additive and optional.