go-gin-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.
@@ -0,0 +1,410 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require("path");
4
+ const prompts = require("prompts");
5
+ const fs = require("fs");
6
+
7
+ const { displayVersion } = require("../lib/utils/display");
8
+
9
+ // Colors for output
10
+ const COLORS = {
11
+ GREEN: "\x1b[32m",
12
+ YELLOW: "\x1b[33m",
13
+ RED: "\x1b[31m",
14
+ CYAN: "\x1b[36m",
15
+ MAGENTA: "\x1b[35m",
16
+ NC: "\x1b[0m",
17
+ };
18
+
19
+ // Command-line arguments
20
+ const args = process.argv.slice(2);
21
+
22
+ // Script paths
23
+ const scriptDir = path.join(__dirname);
24
+ const scripts = {
25
+ help: path.join(scriptDir, "./../lib/utils/help.js"),
26
+ createResource: path.join(scriptDir, "./../lib/utils/create-resource.js"),
27
+ createService: path.join(scriptDir, "./../lib/utils/create-service.js"),
28
+ createAuth: path.join(scriptDir, "./../lib/utils/create-auth.js"),
29
+ addAuthToResource: path.join(
30
+ scriptDir,
31
+ "./../lib/utils/add-auth-to-resource.js",
32
+ ),
33
+ removeModule: path.join(scriptDir, "./../lib/utils/remove-module.js"),
34
+ setup: path.join(scriptDir, "./../lib/utils/setup.js"),
35
+ };
36
+
37
+ // Utility functions
38
+ const utils = {
39
+ validateName: (name) => {
40
+ const isValid = /^[a-z][a-z-]*$/.test(name);
41
+ if (!isValid) {
42
+ console.error(
43
+ `${COLORS.RED}❌ Invalid name format: Use lowercase with hyphens (e.g., user-profile)${COLORS.NC}`
44
+ );
45
+ }
46
+ return isValid;
47
+ },
48
+
49
+ processName: (name) => ({
50
+ lower: name,
51
+ pascal: name
52
+ .split("-")
53
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
54
+ .join(""),
55
+ camel: name
56
+ .split("-")
57
+ .map((part, i) => i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1))
58
+ .join(""),
59
+ snake: name.replace(/-/g, "_"),
60
+ }),
61
+
62
+ showStructure: () => {
63
+ try {
64
+ console.log(`${COLORS.GREEN}✅ Operation completed!${COLORS.NC}`);
65
+ console.log(`${COLORS.YELLOW}📂 Project structure:${COLORS.NC}`);
66
+ const cmd =
67
+ process.platform === "win32"
68
+ ? "dir /ad"
69
+ : "tree -d -L 3 || find . -type d -maxdepth 3";
70
+ require("child_process").execSync(cmd, { stdio: "inherit", shell: true });
71
+ } catch (error) {
72
+ console.error(
73
+ `${COLORS.RED}❌ Structure display failed:${COLORS.NC} ${error.message}`
74
+ );
75
+ }
76
+ },
77
+
78
+ checkProjectExists: (name) => {
79
+ return fs.existsSync(path.join(process.cwd(), name));
80
+ },
81
+ };
82
+
83
+ async function setupProject() {
84
+ try {
85
+ while (true) {
86
+ const { project } = await prompts({
87
+ type: "text",
88
+ name: "project",
89
+ message: "Enter your project name:",
90
+ validate: utils.validateName,
91
+ hint: "Use lowercase with hyphens (e.g., my-project)",
92
+ onState: (state) => {
93
+ if (state.aborted) {
94
+ console.log(`${COLORS.CYAN}Exiting setup process${COLORS.NC}`);
95
+ console.clear();
96
+ process.exit(0);
97
+ }
98
+ },
99
+ });
100
+
101
+ if (!project) continue;
102
+
103
+ if (utils.checkProjectExists(project)) {
104
+ console.error(
105
+ `${COLORS.RED}❌ Project '${project}' already exists${COLORS.NC}`
106
+ );
107
+ continue;
108
+ }
109
+
110
+ // Get module name for go.mod
111
+ const { moduleName } = await prompts({
112
+ type: "text",
113
+ name: "moduleName",
114
+ message: "Enter Go module name (e.g., github.com/username/project):",
115
+ initial: `github.com/example/${project}`,
116
+ onState: (state) => {
117
+ if (state.aborted) {
118
+ console.log(`${COLORS.CYAN}Exiting setup process${COLORS.NC}`);
119
+ console.clear();
120
+ process.exit(0);
121
+ }
122
+ },
123
+ });
124
+
125
+ if (!moduleName) continue;
126
+
127
+ console.log(`
128
+ ${COLORS.CYAN}✨ Project Details ✨${COLORS.NC}
129
+ ├─ 📋 ${COLORS.YELLOW}Name:${COLORS.NC} ${project}
130
+ ├─ 📦 ${COLORS.YELLOW}Module:${COLORS.NC} ${moduleName}
131
+ ├─ 🚀 ${COLORS.YELLOW}Framework:${COLORS.NC} Gin-Gonic
132
+ └─ 💾 ${COLORS.YELLOW}Database:${COLORS.NC} PostgreSQL (GORM)
133
+ `);
134
+
135
+ const ProjectSetup = require(scripts.setup);
136
+ const setup = new ProjectSetup(project, moduleName);
137
+ await setup.execute();
138
+
139
+ console.log(`\n🎉 Project setup complete!`);
140
+ console.log(`\n🚀 To get started:`);
141
+ console.log(` ${COLORS.CYAN}cd ${project}${COLORS.NC}`);
142
+ console.log(` ${COLORS.CYAN}go mod tidy${COLORS.NC}`);
143
+ console.log(` ${COLORS.CYAN}go run src/main.go${COLORS.NC}`);
144
+ process.exit(0);
145
+ }
146
+ } catch (error) {
147
+ console.error(`${COLORS.RED}❌ Setup failed:${COLORS.NC} ${error.message}`);
148
+ }
149
+ }
150
+
151
+ async function generateResource() {
152
+ try {
153
+ const { name } = await prompts({
154
+ type: "text",
155
+ name: "name",
156
+ message: `Enter resource name:`,
157
+ validate: utils.validateName,
158
+ hint: "Use lowercase with hyphens (e.g., user-profile)",
159
+ });
160
+
161
+ if (!name) return;
162
+ const folders = getRepositoryFolders();
163
+ const findmodule = folders.find((folder) => folder === name);
164
+ if (findmodule) {
165
+ console.error(
166
+ `${COLORS.RED}❌ Resource '${name}' already exists${COLORS.NC}`
167
+ );
168
+ return;
169
+ }
170
+
171
+ const names = utils.processName(name);
172
+ const ModuleGenerator = require(scripts.createResource);
173
+ const generator = new ModuleGenerator(
174
+ names.lower,
175
+ names.pascal,
176
+ names.camel,
177
+ names.snake
178
+ );
179
+ await generator.execute();
180
+ return;
181
+ } catch (error) {
182
+ console.error(
183
+ `${COLORS.RED}❌ Resource setup failed:${COLORS.NC} ${error.message}`
184
+ );
185
+ }
186
+ }
187
+
188
+ async function generateService() {
189
+ try {
190
+ const ServiceGenerator = require(scripts.createService);
191
+ const generator = new ServiceGenerator();
192
+ await generator.execute();
193
+ return;
194
+ } catch (error) {
195
+ console.error(
196
+ `${COLORS.RED}❌ Service setup failed:${COLORS.NC} ${error.message}`
197
+ );
198
+ }
199
+ }
200
+
201
+ async function generateAuth() {
202
+ try {
203
+ const AuthGenerator = require(scripts.createAuth);
204
+ const generator = new AuthGenerator();
205
+ await generator.execute();
206
+ return;
207
+ } catch (error) {
208
+ console.error(
209
+ `${COLORS.RED}❌ Auth setup failed:${COLORS.NC} ${error.message}`,
210
+ );
211
+ }
212
+ }
213
+
214
+ async function addAuthToResource() {
215
+ try {
216
+ const folders = getRepositoryFolders();
217
+ if (folders[0].startsWith("No") || folders[0].startsWith("Error")) {
218
+ console.log(`${COLORS.YELLOW}${folders[0]}${COLORS.NC}`);
219
+ return;
220
+ }
221
+
222
+ // Filter out 'auth' folder since it's not a resource
223
+ const resourceFolders = folders.filter((f) => f !== "auth");
224
+ if (resourceFolders.length === 0) {
225
+ console.log(
226
+ `${COLORS.YELLOW}No resources found to add authentication${COLORS.NC}`,
227
+ );
228
+ return;
229
+ }
230
+
231
+ const { selectedResource } = await prompts({
232
+ type: "select",
233
+ name: "selectedResource",
234
+ message: "Select a resource to add authentication:",
235
+ choices: resourceFolders.map((folder) => ({
236
+ title: folder,
237
+ value: folder,
238
+ })),
239
+ initial: 0,
240
+ onState: (state) => {
241
+ if (state.aborted) {
242
+ console.log(`${COLORS.CYAN}Exiting...${COLORS.NC}`);
243
+ console.clear();
244
+ process.exit(0);
245
+ }
246
+ },
247
+ });
248
+
249
+ if (!selectedResource) {
250
+ console.log(`${COLORS.CYAN}Selection cancelled${COLORS.NC}`);
251
+ return;
252
+ }
253
+
254
+ const names = utils.processName(selectedResource);
255
+ const AddAuthToResource = require(scripts.addAuthToResource);
256
+ const generator = new AddAuthToResource(
257
+ names.lower,
258
+ names.pascal,
259
+ names.camel,
260
+ );
261
+ await generator.execute();
262
+ } catch (error) {
263
+ console.error(
264
+ `${COLORS.RED}❌ Add auth failed:${COLORS.NC} ${error.message}`,
265
+ );
266
+ }
267
+ }
268
+
269
+ // Function to List All Modules from Folder (matching NestJS structure)
270
+ const getRepositoryFolders = () => {
271
+ try {
272
+ const repoPath = "src/infrastructure/repositories";
273
+
274
+ if (!fs.existsSync(repoPath)) {
275
+ return ["No resource found"];
276
+ }
277
+
278
+ const folders = fs.readdirSync(repoPath, { withFileTypes: true })
279
+ .filter(dirent => dirent.isDirectory())
280
+ .map(dirent => dirent.name)
281
+ .filter(folder => folder !== "base");
282
+
283
+ return folders.length > 0 ? folders : ["No resource found"];
284
+ } catch (error) {
285
+ console.error(
286
+ `${COLORS.RED}❌ Error listing resource:${COLORS.NC} ${error.message}`
287
+ );
288
+ return ["Error listing resource"];
289
+ }
290
+ };
291
+
292
+ const listModules = async () => {
293
+ const folders = getRepositoryFolders();
294
+ if (folders[0].startsWith("No") || folders[0].startsWith("Error")) {
295
+ console.log(`${COLORS.YELLOW}${folders[0]}${COLORS.NC}`);
296
+ return null;
297
+ }
298
+
299
+ const { selectedRepo } = await prompts({
300
+ type: "select",
301
+ name: "selectedRepo",
302
+ message: "Select a resource to remove:",
303
+ choices: folders.map((folder) => ({
304
+ title: folder,
305
+ value: folder,
306
+ })),
307
+ initial: 0,
308
+ onState: (state) => {
309
+ if (state.aborted) {
310
+ console.log(`${COLORS.CYAN}Exiting setup process${COLORS.NC}`);
311
+ console.clear();
312
+ process.exit(0);
313
+ }
314
+ },
315
+ });
316
+ if (!selectedRepo) {
317
+ console.log(`${COLORS.CYAN}Selection cancelled${COLORS.NC}`);
318
+ return null;
319
+ }
320
+
321
+ return selectedRepo;
322
+ };
323
+
324
+ // Command-line mode
325
+ async function commandLineMode() {
326
+ if (args[0] === "-v" || args[0] === "--version") {
327
+ displayVersion();
328
+ return;
329
+ }
330
+
331
+ if (args[0] === "-h" || args[0] === "--help") {
332
+ require(scripts.help);
333
+ return;
334
+ }
335
+
336
+ try {
337
+ switch (args[0]) {
338
+ case "g":
339
+ if (!args[1])
340
+ throw new Error("Usage: gcg g [res|resource|s|service|au|auth]");
341
+ if (args[1] === "res" || args[1] === "resource") {
342
+ await generateResource();
343
+ } else if (args[1] === "s" || args[1] === "service") {
344
+ await generateService();
345
+ } else if (args[1] === "au" || args[1] === "auth") {
346
+ await generateAuth();
347
+ } else {
348
+ throw new Error("Usage: gcg g [res|resource|s|service|au|auth]");
349
+ }
350
+ break;
351
+
352
+ case "rm":
353
+ if (!args[1]) throw new Error("Usage: gcg rm res");
354
+ if (args[1] === "res" || args[1] === "resource") {
355
+ const moduleName = await listModules();
356
+ if (moduleName) {
357
+ const rmNames = utils.processName(moduleName);
358
+ await require(scripts.removeModule)(
359
+ rmNames.lower,
360
+ rmNames.pascal,
361
+ rmNames.camel,
362
+ rmNames.snake,
363
+ );
364
+ }
365
+ } else {
366
+ throw new Error("Usage: gcg rm res");
367
+ }
368
+ break;
369
+
370
+ case "list":
371
+ case "ls":
372
+ const selected = await listModules();
373
+ if (selected) {
374
+ console.log(`${COLORS.GREEN}Selected resource: ${selected}`);
375
+ }
376
+ break;
377
+
378
+ case "new":
379
+ case "n":
380
+ if (args[1]) throw new Error("'new' takes no arguments");
381
+ await setupProject();
382
+ break;
383
+
384
+ case "add":
385
+ if (!args[1]) throw new Error("Usage: gcg add [au|auth]");
386
+ if (args[1] === "au" || args[1] === "auth") {
387
+ await addAuthToResource();
388
+ } else {
389
+ throw new Error("Usage: gcg add [au|auth]");
390
+ }
391
+ break;
392
+
393
+ default:
394
+ throw new Error(`Unknown command: ${args[0]}`);
395
+ }
396
+ } catch (error) {
397
+ console.error(`${COLORS.RED}❌ Error: ${error.message}${COLORS.NC}`);
398
+ console.log(`${COLORS.CYAN}Use --help for command info${COLORS.NC}`);
399
+ process.exit(1);
400
+ }
401
+ }
402
+
403
+ // Run with error handling
404
+ if (require.main === module) {
405
+ commandLineMode().catch((error) => {
406
+ console.error(`${COLORS.RED}❌ Fatal error:${COLORS.NC} ${error.message}`);
407
+ process.stdout.write("\x1B[?25h");
408
+ process.exit(1);
409
+ });
410
+ }
@@ -0,0 +1,24 @@
1
+ const path = require("path");
2
+
3
+ const COLORS = {
4
+ GREEN: "\x1b[32m",
5
+ YELLOW: "\x1b[33m",
6
+ RED: "\x1b[31m",
7
+ CYAN: "\x1b[36m",
8
+ MAGENTA: "\x1b[35m",
9
+ NC: "\x1b[0m",
10
+ };
11
+
12
+ const CONFIG = {
13
+ MODULE_NAME: "",
14
+ MODULE_NAME_PASCAL: "",
15
+ MODULE_NAME_CAMEL: "",
16
+ MODULE_NAME_SNAKE: "",
17
+ ROOT_DIR: "",
18
+ GO_MODULE: "",
19
+ };
20
+
21
+ module.exports = {
22
+ COLORS,
23
+ CONFIG,
24
+ };
@@ -0,0 +1,22 @@
1
+ const fs = require("fs").promises;
2
+
3
+ const COLORS = {
4
+ GREEN: "\x1b[32m",
5
+ YELLOW: "\x1b[33m",
6
+ RED: "\x1b[31m",
7
+ NC: "\x1b[0m",
8
+ };
9
+
10
+ async function createDir(dirPath) {
11
+ try {
12
+ await fs.mkdir(dirPath, { recursive: true });
13
+ console.log(`${COLORS.GREEN}✔ Created directory ${dirPath}${COLORS.NC}`);
14
+ } catch (error) {
15
+ if (error.code !== "EEXIST") {
16
+ console.error(`${COLORS.RED}❌ Failed to create directory ${dirPath}: ${error.message}${COLORS.NC}`);
17
+ throw error;
18
+ }
19
+ }
20
+ }
21
+
22
+ module.exports = createDir;
@@ -0,0 +1,23 @@
1
+ const fs = require("fs").promises;
2
+ const path = require("path");
3
+
4
+ const COLORS = {
5
+ GREEN: "\x1b[32m",
6
+ YELLOW: "\x1b[33m",
7
+ RED: "\x1b[31m",
8
+ NC: "\x1b[0m",
9
+ };
10
+
11
+ async function createFile(filePath, content) {
12
+ try {
13
+ const dir = path.dirname(filePath);
14
+ await fs.mkdir(dir, { recursive: true });
15
+ await fs.writeFile(filePath, content, "utf8");
16
+ console.log(`${COLORS.GREEN}✔ Created ${filePath}${COLORS.NC}`);
17
+ } catch (error) {
18
+ console.error(`${COLORS.RED}❌ Failed to create ${filePath}: ${error.message}${COLORS.NC}`);
19
+ throw error;
20
+ }
21
+ }
22
+
23
+ module.exports = createFile;
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs").promises;
4
+ const path = require("path");
5
+ const { COLORS } = require("../constants/index");
6
+
7
+ /**
8
+ * AddAuthToResource - Adds JWT authentication guard to an existing Gin controller
9
+ */
10
+ class AddAuthToResource {
11
+ constructor(moduleNameLower, moduleNamePascal, moduleNameCamel) {
12
+ this.moduleNameLower = moduleNameLower;
13
+ this.moduleNamePascal = moduleNamePascal;
14
+ this.moduleNameCamel = moduleNameCamel;
15
+
16
+ this.srcDir = "src";
17
+ this.infrastructureDir = path.join(this.srcDir, "infrastructure");
18
+
19
+ // Get go module name from go.mod
20
+ this.goModule = this.getGoModuleName();
21
+ }
22
+
23
+ getGoModuleName() {
24
+ try {
25
+ const goModPath = path.join(process.cwd(), "go.mod");
26
+ const content = require("fs").readFileSync(goModPath, "utf8");
27
+ const match = content.match(/module\s+(.+)/);
28
+ return match ? match[1].trim() : "github.com/example/project";
29
+ } catch {
30
+ return "github.com/example/project";
31
+ }
32
+ }
33
+
34
+ async execute() {
35
+ try {
36
+ console.log(
37
+ `${COLORS.YELLOW}Adding authentication to ${this.moduleNamePascal} resource...${COLORS.NC}`,
38
+ );
39
+
40
+ // Check if auth module exists
41
+ const authDir = path.join(this.infrastructureDir, "common", "auth");
42
+ try {
43
+ await fs.access(authDir);
44
+ } catch {
45
+ console.log(
46
+ `${COLORS.RED}❌ Authentication module not found. Run 'gcg g au' first.${COLORS.NC}`,
47
+ );
48
+ return;
49
+ }
50
+
51
+ await this.updateController();
52
+ await this.updateRouter();
53
+
54
+ console.log(
55
+ `${COLORS.GREEN}✔ Authentication added to ${this.moduleNamePascal} resource!${COLORS.NC}`,
56
+ );
57
+ this.printSummary();
58
+ } catch (error) {
59
+ console.error(`${COLORS.RED}Error:${COLORS.NC} ${error.message}`);
60
+ throw error;
61
+ }
62
+ }
63
+
64
+ async updateController() {
65
+ const controllerPath = path.join(
66
+ this.infrastructureDir,
67
+ "controllers",
68
+ this.moduleNameLower,
69
+ `${this.moduleNameLower}.controller.go`,
70
+ );
71
+
72
+ try {
73
+ let content = await fs.readFile(controllerPath, "utf8");
74
+
75
+ // Check if already has auth middleware import
76
+ if (
77
+ content.includes("middleware.GetAuthUser") ||
78
+ content.includes("middleware.AuthMiddleware")
79
+ ) {
80
+ console.log(
81
+ `${COLORS.YELLOW}⚠ ${this.moduleNamePascal} controller already has authentication${COLORS.NC}`,
82
+ );
83
+ return;
84
+ }
85
+
86
+ // Add middleware import if not present
87
+ if (
88
+ !content.includes(
89
+ `"${this.goModule}/src/infrastructure/common/middleware"`,
90
+ )
91
+ ) {
92
+ content = content.replace(
93
+ /import \(\n/,
94
+ `import (\n\t"${this.goModule}/src/infrastructure/common/middleware"\n`,
95
+ );
96
+ }
97
+
98
+ // Add helper methods for auth
99
+ const authHelperFunc = `
100
+ // getAuthUser retrieves the authenticated user from Gin context
101
+ func (c *Controller) getAuthUser(ctx *gin.Context) (*models.AuthUser, bool) {
102
+ return middleware.GetAuthUser(ctx)
103
+ }
104
+ `;
105
+
106
+ // Add before the Converters section or at the end of the file
107
+ if (
108
+ content.includes(
109
+ "// ============================================================================\n// Converters",
110
+ )
111
+ ) {
112
+ content = content.replace(
113
+ "// ============================================================================\n// Converters",
114
+ authHelperFunc +
115
+ "\n// ============================================================================\n// Converters",
116
+ );
117
+ }
118
+
119
+ await fs.writeFile(controllerPath, content, "utf8");
120
+ console.log(`${COLORS.GREEN}✔ Updated ${controllerPath}${COLORS.NC}`);
121
+ } catch (error) {
122
+ console.error(
123
+ `${COLORS.YELLOW}⚠ Could not update controller: ${error.message}${COLORS.NC}`,
124
+ );
125
+ }
126
+ }
127
+
128
+ async updateRouter() {
129
+ const routerPath = path.join(
130
+ this.infrastructureDir,
131
+ "controllers",
132
+ "router.go",
133
+ );
134
+
135
+ try {
136
+ let content = await fs.readFile(routerPath, "utf8");
137
+
138
+ // Check if auth middleware import exists
139
+ if (
140
+ !content.includes(
141
+ `"${this.goModule}/src/infrastructure/common/middleware"`,
142
+ )
143
+ ) {
144
+ content = content.replace(
145
+ /import \(\n/,
146
+ `import (\n\t"${this.goModule}/src/infrastructure/common/middleware"\n`,
147
+ );
148
+ }
149
+
150
+ // Check if auth import exists
151
+ if (
152
+ !content.includes(`"${this.goModule}/src/infrastructure/common/auth"`)
153
+ ) {
154
+ content = content.replace(
155
+ /import \(\n/,
156
+ `import (\n\t"${this.goModule}/src/infrastructure/common/auth"\n`,
157
+ );
158
+ }
159
+
160
+ // Check if this module's routes already use auth middleware
161
+ const authMiddlewarePattern = new RegExp(
162
+ `${this.moduleNameLower}s?\\.Use\\(middleware\\.AuthMiddleware`,
163
+ "m",
164
+ );
165
+
166
+ if (authMiddlewarePattern.test(content)) {
167
+ console.log(
168
+ `${COLORS.YELLOW}⚠ Router already has auth middleware for ${this.moduleNamePascal}${COLORS.NC}`,
169
+ );
170
+ return;
171
+ }
172
+
173
+ // Find the module's route group and add auth middleware
174
+ // Pattern: moduleName := v1.Group("/moduleNames")
175
+ const groupPattern = new RegExp(
176
+ `(${this.moduleNameLower}s?\\s*:=\\s*v1\\.Group\\(["\']\/${this.moduleNameLower}s?["\']\\))`,
177
+ "m",
178
+ );
179
+
180
+ const match = content.match(groupPattern);
181
+ if (match) {
182
+ // Add auth middleware after the group declaration
183
+ const authMiddleware = `$1\n\t${this.moduleNameLower}s.Use(middleware.AuthMiddleware(auth.NewJWTService()))`;
184
+ content = content.replace(groupPattern, authMiddleware);
185
+
186
+ await fs.writeFile(routerPath, content, "utf8");
187
+ console.log(
188
+ `${COLORS.GREEN}✔ Updated ${routerPath} with auth middleware${COLORS.NC}`,
189
+ );
190
+ } else {
191
+ console.log(
192
+ `${COLORS.YELLOW}⚠ Could not find ${this.moduleNameLower} route group in router.go. Please add auth middleware manually.${COLORS.NC}`,
193
+ );
194
+ }
195
+ } catch (error) {
196
+ console.error(
197
+ `${COLORS.YELLOW}⚠ Could not update router: ${error.message}${COLORS.NC}`,
198
+ );
199
+ }
200
+ }
201
+
202
+ printSummary() {
203
+ console.log(`
204
+ ${COLORS.CYAN}╔════════════════════════════════════════════════════════════╗
205
+ ║ Authentication Added to Resource ║
206
+ ╠════════════════════════════════════════════════════════════╣
207
+ ║ 📁 Updated: ║
208
+ ║ • infrastructure/controllers/${this.moduleNameLower}/${this.moduleNameLower}.controller.go
209
+ ║ • infrastructure/controllers/router.go ║
210
+ ║ ║
211
+ ║ 🔧 New helper methods available: ║
212
+ ║ • c.getAuthUser(ctx) - Get authenticated user ║
213
+ ║ ║
214
+ ║ 📝 Usage in your controller methods: ║
215
+ ║ user, ok := c.getAuthUser(ctx) ║
216
+ ║ if !ok { response.Error(ctx, 401, "Unauthorized") } ║
217
+ ║ // Use user.ID, user.Email, user.Role ║
218
+ ║ ║
219
+ ║ 🔒 Auth middleware automatically added to ${this.moduleNameLower} routes ║
220
+ ╚════════════════════════════════════════════════════════════╝${COLORS.NC}
221
+ `);
222
+ }
223
+ }
224
+
225
+ module.exports = AddAuthToResource;