@hazeljs/cli 0.2.0-beta.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 (76) hide show
  1. package/@template/README.md +61 -0
  2. package/@template/package.json +48 -0
  3. package/@template/src/app.module.ts +7 -0
  4. package/@template/src/hello.controller.ts +9 -0
  5. package/@template/src/index.ts +10 -0
  6. package/README.md +675 -0
  7. package/dist/commands/add.d.ts +2 -0
  8. package/dist/commands/add.js +90 -0
  9. package/dist/commands/build.d.ts +2 -0
  10. package/dist/commands/build.js +52 -0
  11. package/dist/commands/generate-agent.d.ts +2 -0
  12. package/dist/commands/generate-agent.js +56 -0
  13. package/dist/commands/generate-ai-service.d.ts +2 -0
  14. package/dist/commands/generate-ai-service.js +49 -0
  15. package/dist/commands/generate-app.d.ts +2 -0
  16. package/dist/commands/generate-app.js +246 -0
  17. package/dist/commands/generate-controller.d.ts +2 -0
  18. package/dist/commands/generate-controller.js +59 -0
  19. package/dist/commands/generate-crud.d.ts +2 -0
  20. package/dist/commands/generate-crud.js +203 -0
  21. package/dist/commands/generate-dto.d.ts +2 -0
  22. package/dist/commands/generate-dto.js +56 -0
  23. package/dist/commands/generate-exception-filter.d.ts +2 -0
  24. package/dist/commands/generate-exception-filter.js +50 -0
  25. package/dist/commands/generate-guard.d.ts +2 -0
  26. package/dist/commands/generate-guard.js +35 -0
  27. package/dist/commands/generate-interceptor.d.ts +2 -0
  28. package/dist/commands/generate-interceptor.js +37 -0
  29. package/dist/commands/generate-middleware.d.ts +2 -0
  30. package/dist/commands/generate-middleware.js +79 -0
  31. package/dist/commands/generate-module.d.ts +2 -0
  32. package/dist/commands/generate-module.js +96 -0
  33. package/dist/commands/generate-pipe.d.ts +2 -0
  34. package/dist/commands/generate-pipe.js +33 -0
  35. package/dist/commands/generate-repository.d.ts +2 -0
  36. package/dist/commands/generate-repository.js +38 -0
  37. package/dist/commands/generate-serverless-handler.d.ts +2 -0
  38. package/dist/commands/generate-serverless-handler.js +46 -0
  39. package/dist/commands/generate-service.d.ts +2 -0
  40. package/dist/commands/generate-service.js +51 -0
  41. package/dist/commands/generate-websocket-gateway.d.ts +2 -0
  42. package/dist/commands/generate-websocket-gateway.js +47 -0
  43. package/dist/commands/info.d.ts +2 -0
  44. package/dist/commands/info.js +91 -0
  45. package/dist/commands/start.d.ts +2 -0
  46. package/dist/commands/start.js +61 -0
  47. package/dist/commands/test.d.ts +2 -0
  48. package/dist/commands/test.js +63 -0
  49. package/dist/index.d.ts +2 -0
  50. package/dist/index.js +61 -0
  51. package/dist/utils/generator.d.ts +14 -0
  52. package/dist/utils/generator.js +79 -0
  53. package/package.json +67 -0
  54. package/src/commands/add.ts +101 -0
  55. package/src/commands/build.ts +56 -0
  56. package/src/commands/generate-agent.ts +58 -0
  57. package/src/commands/generate-ai-service.ts +52 -0
  58. package/src/commands/generate-app.ts +270 -0
  59. package/src/commands/generate-controller.ts +61 -0
  60. package/src/commands/generate-crud.ts +214 -0
  61. package/src/commands/generate-dto.ts +61 -0
  62. package/src/commands/generate-exception-filter.ts +53 -0
  63. package/src/commands/generate-guard.ts +37 -0
  64. package/src/commands/generate-interceptor.ts +39 -0
  65. package/src/commands/generate-middleware.ts +86 -0
  66. package/src/commands/generate-module.ts +102 -0
  67. package/src/commands/generate-pipe.ts +36 -0
  68. package/src/commands/generate-repository.ts +41 -0
  69. package/src/commands/generate-serverless-handler.ts +53 -0
  70. package/src/commands/generate-service.ts +53 -0
  71. package/src/commands/generate-websocket-gateway.ts +50 -0
  72. package/src/commands/info.ts +106 -0
  73. package/src/commands/start.ts +61 -0
  74. package/src/commands/test.ts +70 -0
  75. package/src/index.ts +68 -0
  76. package/src/utils/generator.ts +93 -0
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addCommand = addCommand;
7
+ const child_process_1 = require("child_process");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const HAZEL_PACKAGES = {
11
+ ai: '@hazeljs/ai',
12
+ auth: '@hazeljs/auth',
13
+ cache: '@hazeljs/cache',
14
+ config: '@hazeljs/config',
15
+ cron: '@hazeljs/cron',
16
+ prisma: '@hazeljs/prisma',
17
+ rag: '@hazeljs/rag',
18
+ serverless: '@hazeljs/serverless',
19
+ swagger: '@hazeljs/swagger',
20
+ websocket: '@hazeljs/websocket',
21
+ discovery: '@hazeljs/discovery',
22
+ };
23
+ function addCommand(program) {
24
+ program
25
+ .command('add [package]')
26
+ .description('Add a HazelJS package to your project')
27
+ .option('--dev', 'Install as dev dependency')
28
+ .action(async (packageName, options) => {
29
+ try {
30
+ let selectedPackage = packageName;
31
+ // If no package specified, show interactive selection
32
+ if (!selectedPackage) {
33
+ const { package: pkg } = await inquirer_1.default.prompt([
34
+ {
35
+ type: 'list',
36
+ name: 'package',
37
+ message: 'Which HazelJS package would you like to add?',
38
+ choices: Object.keys(HAZEL_PACKAGES).map((key) => ({
39
+ name: `${key} - ${HAZEL_PACKAGES[key]}`,
40
+ value: key,
41
+ })),
42
+ },
43
+ ]);
44
+ selectedPackage = pkg;
45
+ }
46
+ // Get the full package name
47
+ const fullPackageName = HAZEL_PACKAGES[selectedPackage];
48
+ if (!fullPackageName) {
49
+ console.log(chalk_1.default.yellow(`Unknown package: ${selectedPackage}`));
50
+ console.log(chalk_1.default.gray('\nAvailable packages:'));
51
+ Object.keys(HAZEL_PACKAGES).forEach((key) => {
52
+ console.log(chalk_1.default.gray(` - ${key}: ${HAZEL_PACKAGES[key]}`));
53
+ });
54
+ return;
55
+ }
56
+ console.log(chalk_1.default.blue(`\n📦 Installing ${fullPackageName}...`));
57
+ const devFlag = options?.dev ? '--save-dev' : '';
58
+ const command = `npm install ${fullPackageName} ${devFlag}`.trim();
59
+ (0, child_process_1.execSync)(command, { stdio: 'inherit' });
60
+ console.log(chalk_1.default.green(`\n✓ Successfully installed ${fullPackageName}`));
61
+ // Show usage hints
62
+ console.log(chalk_1.default.gray('\nNext steps:'));
63
+ switch (selectedPackage) {
64
+ case 'ai':
65
+ console.log(chalk_1.default.gray(' import { AIModule } from "@hazeljs/ai";'));
66
+ break;
67
+ case 'auth':
68
+ console.log(chalk_1.default.gray(' import { AuthModule } from "@hazeljs/auth";'));
69
+ break;
70
+ case 'cache':
71
+ console.log(chalk_1.default.gray(' import { CacheModule } from "@hazeljs/cache";'));
72
+ break;
73
+ case 'prisma':
74
+ console.log(chalk_1.default.gray(' import { PrismaModule } from "@hazeljs/prisma";'));
75
+ break;
76
+ case 'swagger':
77
+ console.log(chalk_1.default.gray(' import { SwaggerModule } from "@hazeljs/swagger";'));
78
+ break;
79
+ case 'websocket':
80
+ console.log(chalk_1.default.gray(' import { WebSocketModule } from "@hazeljs/websocket";'));
81
+ break;
82
+ }
83
+ console.log(chalk_1.default.gray(`\nDocumentation: https://hazeljs.com/docs/packages/${selectedPackage}`));
84
+ }
85
+ catch (error) {
86
+ console.error(chalk_1.default.red('Error installing package:'), error);
87
+ process.exit(1);
88
+ }
89
+ });
90
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function buildCommand(program: Command): void;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildCommand = buildCommand;
7
+ const child_process_1 = require("child_process");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ function buildCommand(program) {
12
+ program
13
+ .command('build')
14
+ .description('Build the HazelJS project')
15
+ .option('-w, --watch', 'Watch mode')
16
+ .option('-p, --production', 'Production build')
17
+ .action((options) => {
18
+ try {
19
+ const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
20
+ if (!fs_1.default.existsSync(packageJsonPath)) {
21
+ console.log(chalk_1.default.red('✗ No package.json found'));
22
+ console.log(chalk_1.default.gray('Run this command from your project root'));
23
+ process.exit(1);
24
+ }
25
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
26
+ if (!packageJson.scripts?.build) {
27
+ console.log(chalk_1.default.yellow('⚠ No build script found in package.json'));
28
+ console.log(chalk_1.default.gray('\nAdd a build script to your package.json:'));
29
+ console.log(chalk_1.default.gray(' "scripts": {'));
30
+ console.log(chalk_1.default.gray(' "build": "tsc"'));
31
+ console.log(chalk_1.default.gray(' }'));
32
+ process.exit(1);
33
+ }
34
+ console.log(chalk_1.default.blue('🔨 Building project...\n'));
35
+ let command = 'npm run build';
36
+ if (options.watch) {
37
+ command = 'npm run build -- --watch';
38
+ }
39
+ if (options.production) {
40
+ process.env.NODE_ENV = 'production';
41
+ }
42
+ (0, child_process_1.execSync)(command, { stdio: 'inherit' });
43
+ if (!options.watch) {
44
+ console.log(chalk_1.default.green('\n✓ Build completed successfully'));
45
+ }
46
+ }
47
+ catch {
48
+ console.error(chalk_1.default.red('\n✗ Build failed'));
49
+ process.exit(1);
50
+ }
51
+ });
52
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function generateAgent(program: Command): void;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAgent = generateAgent;
4
+ const generator_1 = require("../utils/generator");
5
+ const AGENT_TEMPLATE = `import { Agent, Tool } from '@hazeljs/agent';
6
+
7
+ @Agent({
8
+ name: '{{fileName}}',
9
+ description: '{{description}}',
10
+ systemPrompt: 'You are a helpful {{className}} agent.',
11
+ enableMemory: true,
12
+ enableRAG: true,
13
+ })
14
+ export class {{className}}Agent {
15
+ @Tool({
16
+ description: 'Example tool for {{fileName}}',
17
+ parameters: [
18
+ {
19
+ name: 'input',
20
+ type: 'string',
21
+ description: 'Input parameter',
22
+ required: true,
23
+ },
24
+ ],
25
+ })
26
+ async exampleTool(input: { input: string }): Promise<{ result: string }> {
27
+ // Implement your tool logic here
28
+ return {
29
+ result: \`Processed: \${input.input}\`,
30
+ };
31
+ }
32
+ }
33
+ `;
34
+ class AgentGenerator extends generator_1.Generator {
35
+ getDefaultTemplate() {
36
+ return AGENT_TEMPLATE;
37
+ }
38
+ }
39
+ function generateAgent(program) {
40
+ program
41
+ .command('agent <name>')
42
+ .description('Generate a new AI agent with @Agent and @Tool decorators')
43
+ .option('-p, --path <path>', 'Path where the agent should be generated')
44
+ .action(async (name, options) => {
45
+ const generator = new AgentGenerator();
46
+ const generatorOptions = {
47
+ name,
48
+ path: options.path,
49
+ data: {
50
+ description: `A ${name} agent`,
51
+ },
52
+ };
53
+ const finalOptions = await generator.promptForOptions(generatorOptions);
54
+ await generator.generate(finalOptions);
55
+ });
56
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function generateAIService(program: Command): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAIService = generateAIService;
4
+ const generator_1 = require("../utils/generator");
5
+ const AI_SERVICE_TEMPLATE = `import { Injectable } from '@hazeljs/core';
6
+ import { AIService } from '@hazeljs/ai';
7
+ import { AIFunction, AIPrompt } from '@hazeljs/ai';
8
+
9
+ @Injectable()
10
+ export class {{className}}AIService {
11
+ constructor(private readonly aiService: AIService) {}
12
+
13
+ @AIFunction({
14
+ provider: 'openai',
15
+ model: 'gpt-4',
16
+ streaming: false,
17
+ })
18
+ async {{fileName}}Task(@AIPrompt() prompt: string): Promise<unknown> {
19
+ const result = await this.aiService.complete({
20
+ provider: 'openai',
21
+ model: 'gpt-4',
22
+ messages: [{ role: 'user', content: prompt }],
23
+ });
24
+
25
+ return result;
26
+ }
27
+ }
28
+ `;
29
+ class AIServiceGenerator extends generator_1.Generator {
30
+ getDefaultTemplate() {
31
+ return AI_SERVICE_TEMPLATE;
32
+ }
33
+ }
34
+ function generateAIService(program) {
35
+ program
36
+ .command('ai-service <name>')
37
+ .description('Generate a new AI service with decorators')
38
+ .alias('ai')
39
+ .option('-p, --path <path>', 'Path where the AI service should be generated')
40
+ .action(async (name, options) => {
41
+ const generator = new AIServiceGenerator();
42
+ const generatorOptions = {
43
+ name,
44
+ path: options.path,
45
+ };
46
+ const finalOptions = await generator.promptForOptions(generatorOptions);
47
+ await generator.generate(finalOptions);
48
+ });
49
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function generateApp(program: Command): void;
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateApp = generateApp;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const child_process_1 = require("child_process");
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const inquirer_1 = __importDefault(require("inquirer"));
12
+ function copyRecursiveSync(src, dest) {
13
+ if (fs_1.default.existsSync(src)) {
14
+ fs_1.default.mkdirSync(dest, { recursive: true });
15
+ for (const entry of fs_1.default.readdirSync(src)) {
16
+ const srcPath = path_1.default.join(src, entry);
17
+ const destPath = path_1.default.join(dest, entry);
18
+ if (fs_1.default.lstatSync(srcPath).isDirectory()) {
19
+ copyRecursiveSync(srcPath, destPath);
20
+ }
21
+ else {
22
+ fs_1.default.copyFileSync(srcPath, destPath);
23
+ }
24
+ }
25
+ }
26
+ }
27
+ function updatePackageJson(destPath, appName, description) {
28
+ const packageJsonPath = path_1.default.join(destPath, 'package.json');
29
+ if (fs_1.default.existsSync(packageJsonPath)) {
30
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
31
+ packageJson.name = appName;
32
+ packageJson.description = description;
33
+ packageJson.version = '0.1.0';
34
+ fs_1.default.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
35
+ }
36
+ }
37
+ function generateApp(program) {
38
+ program
39
+ .command('new <appName>')
40
+ .description('Create a new HazelJS application')
41
+ .option('-d, --dest <destPath>', 'Destination path', '.')
42
+ .option('--skip-install', 'Skip npm install')
43
+ .option('--skip-git', 'Skip git initialization')
44
+ .option('-i, --interactive', 'Interactive setup')
45
+ .action(async (appName, options) => {
46
+ try {
47
+ let projectConfig = {
48
+ name: appName,
49
+ description: `A HazelJS application`,
50
+ author: '',
51
+ license: 'MIT',
52
+ packages: [],
53
+ };
54
+ // Interactive setup
55
+ if (options.interactive) {
56
+ console.log(chalk_1.default.blue('\n🚀 Welcome to HazelJS project setup!\n'));
57
+ const answers = await inquirer_1.default.prompt([
58
+ {
59
+ type: 'input',
60
+ name: 'description',
61
+ message: 'Project description:',
62
+ default: projectConfig.description,
63
+ },
64
+ {
65
+ type: 'input',
66
+ name: 'author',
67
+ message: 'Author:',
68
+ },
69
+ {
70
+ type: 'list',
71
+ name: 'license',
72
+ message: 'License:',
73
+ choices: ['MIT', 'Apache-2.0', 'GPL-3.0', 'BSD-3-Clause', 'ISC'],
74
+ default: 'MIT',
75
+ },
76
+ {
77
+ type: 'checkbox',
78
+ name: 'packages',
79
+ message: 'Select additional HazelJS packages to install:',
80
+ choices: [
81
+ { name: 'AI Integration (@hazeljs/ai)', value: '@hazeljs/ai' },
82
+ { name: 'Authentication (@hazeljs/auth)', value: '@hazeljs/auth' },
83
+ { name: 'Caching (@hazeljs/cache)', value: '@hazeljs/cache' },
84
+ { name: 'Configuration (@hazeljs/config)', value: '@hazeljs/config' },
85
+ { name: 'Cron Jobs (@hazeljs/cron)', value: '@hazeljs/cron' },
86
+ { name: 'Prisma ORM (@hazeljs/prisma)', value: '@hazeljs/prisma' },
87
+ { name: 'RAG/Vector Search (@hazeljs/rag)', value: '@hazeljs/rag' },
88
+ { name: 'Serverless (@hazeljs/serverless)', value: '@hazeljs/serverless' },
89
+ { name: 'Swagger/OpenAPI (@hazeljs/swagger)', value: '@hazeljs/swagger' },
90
+ { name: 'WebSocket (@hazeljs/websocket)', value: '@hazeljs/websocket' },
91
+ ],
92
+ },
93
+ ]);
94
+ projectConfig = { ...projectConfig, ...answers };
95
+ }
96
+ const destPath = path_1.default.join(process.cwd(), options.dest || '.', appName);
97
+ console.log(chalk_1.default.blue('\n📦 Creating new HazelJS project...\n'));
98
+ console.log(chalk_1.default.gray(`Project: ${projectConfig.name}`));
99
+ console.log(chalk_1.default.gray(`Location: ${destPath}\n`));
100
+ // Check if destination exists
101
+ if (fs_1.default.existsSync(destPath)) {
102
+ console.error(chalk_1.default.red(`✗ Destination already exists: ${destPath}`));
103
+ process.exit(1);
104
+ }
105
+ // Use local template
106
+ const templatePath = path_1.default.join(__dirname, '../../@template');
107
+ if (fs_1.default.existsSync(templatePath)) {
108
+ console.log(chalk_1.default.blue('📋 Copying template files...'));
109
+ copyRecursiveSync(templatePath, destPath);
110
+ // Update package.json
111
+ updatePackageJson(destPath, projectConfig.name, projectConfig.description);
112
+ console.log(chalk_1.default.green('✓ Template files copied'));
113
+ }
114
+ else {
115
+ console.log(chalk_1.default.yellow('⚠ Local template not found, creating basic structure...'));
116
+ // Create basic structure
117
+ fs_1.default.mkdirSync(destPath, { recursive: true });
118
+ fs_1.default.mkdirSync(path_1.default.join(destPath, 'src'), { recursive: true });
119
+ // Create package.json
120
+ const packageJson = {
121
+ name: projectConfig.name,
122
+ version: '0.1.0',
123
+ description: projectConfig.description,
124
+ main: 'dist/index.js',
125
+ scripts: {
126
+ build: 'tsc',
127
+ start: 'node dist/index.js',
128
+ dev: 'ts-node-dev --respawn --transpile-only src/index.ts',
129
+ test: 'jest',
130
+ lint: 'eslint "src/**/*.ts"',
131
+ },
132
+ dependencies: {
133
+ '@hazeljs/core': '^0.2.0',
134
+ },
135
+ devDependencies: {
136
+ '@types/node': '^20.0.0',
137
+ 'typescript': '^5.0.0',
138
+ 'ts-node-dev': '^2.0.0',
139
+ },
140
+ author: projectConfig.author,
141
+ license: projectConfig.license,
142
+ };
143
+ fs_1.default.writeFileSync(path_1.default.join(destPath, 'package.json'), JSON.stringify(packageJson, null, 2));
144
+ // Create basic index.ts
145
+ const indexContent = `import { HazelApp, HazelModule, Controller, Get } from '@hazeljs/core';
146
+
147
+ @Controller('/')
148
+ export class AppController {
149
+ @Get()
150
+ hello() {
151
+ return { message: 'Hello from HazelJS!' };
152
+ }
153
+ }
154
+
155
+ @HazelModule({
156
+ controllers: [AppController],
157
+ })
158
+ export class AppModule {}
159
+
160
+ async function bootstrap() {
161
+ const app = await HazelApp.create(AppModule);
162
+ await app.listen(3000);
163
+ console.log('🚀 Server running on http://localhost:3000');
164
+ }
165
+
166
+ bootstrap();
167
+ `;
168
+ fs_1.default.writeFileSync(path_1.default.join(destPath, 'src', 'index.ts'), indexContent);
169
+ // Create tsconfig.json
170
+ const tsConfig = {
171
+ compilerOptions: {
172
+ target: 'ES2020',
173
+ module: 'commonjs',
174
+ lib: ['ES2020'],
175
+ outDir: './dist',
176
+ rootDir: './src',
177
+ strict: true,
178
+ esModuleInterop: true,
179
+ skipLibCheck: true,
180
+ forceConsistentCasingInFileNames: true,
181
+ experimentalDecorators: true,
182
+ emitDecoratorMetadata: true,
183
+ },
184
+ include: ['src/**/*'],
185
+ exclude: ['node_modules', 'dist'],
186
+ };
187
+ fs_1.default.writeFileSync(path_1.default.join(destPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
188
+ console.log(chalk_1.default.green('✓ Basic structure created'));
189
+ }
190
+ // Initialize git
191
+ if (!options.skipGit) {
192
+ try {
193
+ console.log(chalk_1.default.blue('\n📝 Initializing git repository...'));
194
+ (0, child_process_1.execSync)('git init', { cwd: destPath, stdio: 'ignore' });
195
+ // Create .gitignore
196
+ const gitignore = `node_modules/
197
+ dist/
198
+ .env
199
+ .DS_Store
200
+ coverage/
201
+ *.log
202
+ `;
203
+ fs_1.default.writeFileSync(path_1.default.join(destPath, '.gitignore'), gitignore);
204
+ console.log(chalk_1.default.green('✓ Git initialized'));
205
+ }
206
+ catch {
207
+ console.log(chalk_1.default.yellow('⚠ Git initialization skipped'));
208
+ }
209
+ }
210
+ // Install dependencies
211
+ if (!options.skipInstall) {
212
+ console.log(chalk_1.default.blue('\n📦 Installing dependencies...\n'));
213
+ try {
214
+ (0, child_process_1.execSync)('npm install', { cwd: destPath, stdio: 'inherit' });
215
+ // Install additional packages
216
+ if (projectConfig.packages.length > 0) {
217
+ console.log(chalk_1.default.blue('\n📦 Installing additional packages...\n'));
218
+ (0, child_process_1.execSync)(`npm install ${projectConfig.packages.join(' ')}`, {
219
+ cwd: destPath,
220
+ stdio: 'inherit',
221
+ });
222
+ }
223
+ console.log(chalk_1.default.green('\n✓ Dependencies installed'));
224
+ }
225
+ catch {
226
+ console.log(chalk_1.default.yellow('\n⚠ Dependency installation failed'));
227
+ console.log(chalk_1.default.gray('You can install them manually with: npm install'));
228
+ }
229
+ }
230
+ // Success message
231
+ console.log(chalk_1.default.green.bold('\n✨ Project created successfully!\n'));
232
+ console.log(chalk_1.default.gray('Next steps:'));
233
+ console.log(chalk_1.default.gray(` cd ${appName}`));
234
+ if (options.skipInstall) {
235
+ console.log(chalk_1.default.gray(' npm install'));
236
+ }
237
+ console.log(chalk_1.default.gray(' npm run dev'));
238
+ console.log(chalk_1.default.gray('\nDocumentation: https://hazeljs.com/docs'));
239
+ console.log(chalk_1.default.gray('Discord: https://discord.gg/hazeljs\n'));
240
+ }
241
+ catch (error) {
242
+ console.error(chalk_1.default.red('\n✗ Failed to create project:'), error);
243
+ process.exit(1);
244
+ }
245
+ });
246
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function generateController(program: Command): void;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateController = generateController;
4
+ const generator_1 = require("../utils/generator");
5
+ const CONTROLLER_TEMPLATE = `import { Controller, Get, Post, Body, Param, Delete, Put } from '@hazeljs/core';
6
+ import { {{className}}Service } from './{{fileName}}.service';
7
+ import { Create{{className}}Dto } from './dto/create-{{fileName}}.dto';
8
+ import { Update{{className}}Dto } from './dto/update-{{fileName}}.dto';
9
+
10
+ @Controller('{{fileName}}')
11
+ export class {{className}}Controller {
12
+ constructor(private readonly {{fileName}}Service: {{className}}Service) {}
13
+
14
+ @Get()
15
+ findAll() {
16
+ return this.{{fileName}}Service.findAll();
17
+ }
18
+
19
+ @Get(':id')
20
+ findOne(@Param('id') id: string) {
21
+ return this.{{fileName}}Service.findOne(id);
22
+ }
23
+
24
+ @Post()
25
+ create(@Body(Create{{className}}Dto) create{{className}}Dto: Create{{className}}Dto) {
26
+ return this.{{fileName}}Service.create(create{{className}}Dto);
27
+ }
28
+
29
+ @Put(':id')
30
+ update(@Param('id') id: string, @Body(Update{{className}}Dto) update{{className}}Dto: Update{{className}}Dto) {
31
+ return this.{{fileName}}Service.update(id, update{{className}}Dto);
32
+ }
33
+
34
+ @Delete(':id')
35
+ remove(@Param('id') id: string) {
36
+ return this.{{fileName}}Service.remove(id);
37
+ }
38
+ }
39
+ `;
40
+ class ControllerGenerator extends generator_1.Generator {
41
+ getDefaultTemplate() {
42
+ return CONTROLLER_TEMPLATE;
43
+ }
44
+ }
45
+ function generateController(program) {
46
+ program
47
+ .command('controller <name>')
48
+ .description('Generate a new controller')
49
+ .option('-p, --path <path>', 'Path where the controller should be generated')
50
+ .action(async (name, options) => {
51
+ const generator = new ControllerGenerator();
52
+ const generatorOptions = {
53
+ name,
54
+ path: options.path,
55
+ };
56
+ const finalOptions = await generator.promptForOptions(generatorOptions);
57
+ await generator.generate(finalOptions);
58
+ });
59
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function generateCrud(command: Command): void;