@hazeljs/cli 0.5.4 → 0.6.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.
Files changed (101) hide show
  1. package/@template-ai-native/package.json +1 -1
  2. package/README.md +122 -591
  3. package/dist/commands/add.js +26 -126
  4. package/dist/commands/generate-app.js +17 -230
  5. package/dist/commands/generate-simple.d.ts +27 -0
  6. package/dist/commands/generate-simple.js +448 -0
  7. package/dist/commands/generate-simple.test.js +100 -0
  8. package/dist/index.js +5 -47
  9. package/dist/index.list.test.js +8 -22
  10. package/dist/index.test.js +19 -56
  11. package/dist/utils/generator-registry.js +29 -65
  12. package/dist/utils/generator.d.ts +0 -1
  13. package/dist/utils/generator.js +0 -22
  14. package/dist/utils/generator.test.js +0 -28
  15. package/dist/utils/packages-registry.d.ts +25 -0
  16. package/dist/utils/packages-registry.js +371 -0
  17. package/package.json +3 -5
  18. package/dist/commands/build.d.ts +0 -2
  19. package/dist/commands/build.js +0 -52
  20. package/dist/commands/generate-agent.d.ts +0 -4
  21. package/dist/commands/generate-agent.js +0 -64
  22. package/dist/commands/generate-agent.test.js +0 -36
  23. package/dist/commands/generate-ai-service.d.ts +0 -4
  24. package/dist/commands/generate-ai-service.js +0 -54
  25. package/dist/commands/generate-ai-service.test.d.ts +0 -1
  26. package/dist/commands/generate-ai-service.test.js +0 -41
  27. package/dist/commands/generate-cache.d.ts +0 -4
  28. package/dist/commands/generate-cache.js +0 -66
  29. package/dist/commands/generate-cache.test.d.ts +0 -1
  30. package/dist/commands/generate-cache.test.js +0 -36
  31. package/dist/commands/generate-config.d.ts +0 -4
  32. package/dist/commands/generate-config.js +0 -59
  33. package/dist/commands/generate-config.test.d.ts +0 -1
  34. package/dist/commands/generate-config.test.js +0 -35
  35. package/dist/commands/generate-controller.d.ts +0 -4
  36. package/dist/commands/generate-controller.js +0 -66
  37. package/dist/commands/generate-controller.test.d.ts +0 -1
  38. package/dist/commands/generate-controller.test.js +0 -48
  39. package/dist/commands/generate-cron.d.ts +0 -4
  40. package/dist/commands/generate-cron.js +0 -61
  41. package/dist/commands/generate-cron.test.d.ts +0 -1
  42. package/dist/commands/generate-cron.test.js +0 -42
  43. package/dist/commands/generate-discovery.d.ts +0 -4
  44. package/dist/commands/generate-discovery.js +0 -63
  45. package/dist/commands/generate-discovery.test.d.ts +0 -1
  46. package/dist/commands/generate-discovery.test.js +0 -36
  47. package/dist/commands/generate-exception-filter.d.ts +0 -4
  48. package/dist/commands/generate-exception-filter.js +0 -54
  49. package/dist/commands/generate-exception-filter.test.d.ts +0 -1
  50. package/dist/commands/generate-exception-filter.test.js +0 -43
  51. package/dist/commands/generate-guard.d.ts +0 -4
  52. package/dist/commands/generate-guard.js +0 -42
  53. package/dist/commands/generate-guard.test.d.ts +0 -1
  54. package/dist/commands/generate-guard.test.js +0 -41
  55. package/dist/commands/generate-interceptor.d.ts +0 -4
  56. package/dist/commands/generate-interceptor.js +0 -43
  57. package/dist/commands/generate-interceptor.test.d.ts +0 -1
  58. package/dist/commands/generate-interceptor.test.js +0 -41
  59. package/dist/commands/generate-middleware.d.ts +0 -4
  60. package/dist/commands/generate-middleware.js +0 -47
  61. package/dist/commands/generate-middleware.test.d.ts +0 -1
  62. package/dist/commands/generate-middleware.test.js +0 -41
  63. package/dist/commands/generate-pipe.d.ts +0 -4
  64. package/dist/commands/generate-pipe.js +0 -39
  65. package/dist/commands/generate-pipe.test.d.ts +0 -1
  66. package/dist/commands/generate-pipe.test.js +0 -35
  67. package/dist/commands/generate-rag.d.ts +0 -4
  68. package/dist/commands/generate-rag.js +0 -68
  69. package/dist/commands/generate-rag.test.d.ts +0 -1
  70. package/dist/commands/generate-rag.test.js +0 -35
  71. package/dist/commands/generate-repository.d.ts +0 -4
  72. package/dist/commands/generate-repository.js +0 -46
  73. package/dist/commands/generate-repository.test.d.ts +0 -1
  74. package/dist/commands/generate-repository.test.js +0 -41
  75. package/dist/commands/generate-serverless-handler.d.ts +0 -4
  76. package/dist/commands/generate-serverless-handler.js +0 -57
  77. package/dist/commands/generate-serverless-handler.test.d.ts +0 -1
  78. package/dist/commands/generate-serverless-handler.test.js +0 -42
  79. package/dist/commands/generate-service.d.ts +0 -4
  80. package/dist/commands/generate-service.js +0 -58
  81. package/dist/commands/generate-service.test.d.ts +0 -1
  82. package/dist/commands/generate-service.test.js +0 -41
  83. package/dist/commands/generate-setup.d.ts +0 -4
  84. package/dist/commands/generate-setup.js +0 -187
  85. package/dist/commands/generate-setup.test.d.ts +0 -1
  86. package/dist/commands/generate-setup.test.js +0 -50
  87. package/dist/commands/generate-websocket-gateway.d.ts +0 -4
  88. package/dist/commands/generate-websocket-gateway.js +0 -53
  89. package/dist/commands/generate-websocket-gateway.test.d.ts +0 -1
  90. package/dist/commands/generate-websocket-gateway.test.js +0 -41
  91. package/dist/commands/pdf-to-audio.d.ts +0 -2
  92. package/dist/commands/pdf-to-audio.js +0 -170
  93. package/dist/commands/pdf-to-audio.test.d.ts +0 -1
  94. package/dist/commands/pdf-to-audio.test.js +0 -92
  95. package/dist/commands/start.d.ts +0 -2
  96. package/dist/commands/start.js +0 -61
  97. package/dist/commands/test.d.ts +0 -2
  98. package/dist/commands/test.js +0 -63
  99. package/dist/commands/utility-commands.test.d.ts +0 -1
  100. package/dist/commands/utility-commands.test.js +0 -95
  101. /package/dist/commands/{generate-agent.test.d.ts → generate-simple.test.d.ts} +0 -0
@@ -6,130 +6,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.addCommand = addCommand;
7
7
  const child_process_1 = require("child_process");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
9
11
  const inquirer_1 = __importDefault(require("inquirer"));
10
- const HAZEL_PACKAGES = {
11
- ai: {
12
- npm: '@hazeljs/ai',
13
- hint: 'import { AIModule } from "@hazeljs/ai";',
14
- },
15
- agent: {
16
- npm: '@hazeljs/agent',
17
- hint: 'import { AgentModule } from "@hazeljs/agent";',
18
- },
19
- audit: {
20
- npm: '@hazeljs/audit',
21
- hint: 'import { AuditModule, ConsoleAuditTransport } from "@hazeljs/audit";\n // AuditModule.forRoot({ transports: [new ConsoleAuditTransport()] })',
22
- },
23
- auth: {
24
- npm: '@hazeljs/auth',
25
- hint: 'import { JwtModule } from "@hazeljs/auth";\n // JwtModule.forRoot({ secret: "your-secret", expiresIn: "1d" })',
26
- },
27
- oauth: {
28
- npm: '@hazeljs/oauth',
29
- hint: 'import { OAuthModule } from "@hazeljs/oauth";\n // OAuthModule.forRoot({ providers: { google: {...}, microsoft: {...}, github: {...} } })',
30
- },
31
- cache: {
32
- npm: '@hazeljs/cache',
33
- hint: 'import { CacheModule } from "@hazeljs/cache";',
34
- },
35
- config: {
36
- npm: '@hazeljs/config',
37
- hint: 'import { ConfigModule } from "@hazeljs/config";\n // ConfigModule.forRoot({ envFilePath: ".env" })',
38
- },
39
- cron: {
40
- npm: '@hazeljs/cron',
41
- hint: 'import { CronModule } from "@hazeljs/cron";',
42
- },
43
- data: {
44
- npm: '@hazeljs/data',
45
- hint: 'import { DataModule } from "@hazeljs/data";',
46
- },
47
- discovery: {
48
- npm: '@hazeljs/discovery',
49
- hint: 'import { ServiceRegistry, DiscoveryClient } from "@hazeljs/discovery";',
50
- },
51
- 'event-emitter': {
52
- npm: '@hazeljs/event-emitter',
53
- hint: 'import { EventEmitterModule } from "@hazeljs/event-emitter";',
54
- },
55
- gateway: {
56
- npm: '@hazeljs/gateway',
57
- hint: 'import { GatewayModule } from "@hazeljs/gateway";',
58
- },
59
- guardrails: {
60
- npm: '@hazeljs/guardrails',
61
- hint: 'import { GuardrailsModule } from "@hazeljs/guardrails";\n // GuardrailsModule.forRoot({ redactPIIByDefault: true })',
62
- },
63
- graphql: {
64
- npm: '@hazeljs/graphql',
65
- hint: 'import { GraphQLModule } from "@hazeljs/graphql";',
66
- },
67
- grpc: {
68
- npm: '@hazeljs/grpc',
69
- hint: 'import { GrpcModule } from "@hazeljs/grpc";',
70
- },
71
- kafka: {
72
- npm: '@hazeljs/kafka',
73
- hint: 'import { KafkaModule } from "@hazeljs/kafka";',
74
- },
75
- messaging: {
76
- npm: '@hazeljs/messaging',
77
- hint: 'import { MessagingModule } from "@hazeljs/messaging";',
78
- },
79
- mcp: {
80
- npm: '@hazeljs/mcp',
81
- hint: 'import { createMcpServer } from "@hazeljs/mcp";\n // createMcpServer({ name, version, toolRegistry }).listenStdio();',
82
- },
83
- ml: {
84
- npm: '@hazeljs/ml',
85
- hint: 'import { MLModule } from "@hazeljs/ml";',
86
- },
87
- prompts: {
88
- npm: '@hazeljs/prompts',
89
- hint: 'import { PromptTemplate, PromptRegistry } from "@hazeljs/prompts";',
90
- },
91
- prisma: {
92
- npm: '@hazeljs/prisma',
93
- hint: 'import { PrismaModule } from "@hazeljs/prisma";',
94
- },
95
- typeorm: {
96
- npm: '@hazeljs/typeorm',
97
- hint: 'import { TypeOrmModule } from "@hazeljs/typeorm";',
98
- },
99
- queue: {
100
- npm: '@hazeljs/queue',
101
- hint: 'import { QueueModule } from "@hazeljs/queue";',
102
- },
103
- rag: {
104
- npm: '@hazeljs/rag',
105
- hint: 'import { RAGPipeline } from "@hazeljs/rag";',
106
- },
107
- resilience: {
108
- npm: '@hazeljs/resilience',
109
- hint: 'import { CircuitBreaker, WithRetry, WithTimeout } from "@hazeljs/resilience";',
110
- },
111
- 'pdf-to-audio': {
112
- npm: '@hazeljs/pdf-to-audio',
113
- hint: 'import { PdfToAudioModule } from "@hazeljs/pdf-to-audio";\n // PdfToAudioModule converts PDFs to audio via TTS',
114
- },
115
- serverless: {
116
- npm: '@hazeljs/serverless',
117
- hint: 'import { createLambdaHandler } from "@hazeljs/serverless";',
118
- },
119
- swagger: {
120
- npm: '@hazeljs/swagger',
121
- hint: 'import { SwaggerModule } from "@hazeljs/swagger";',
122
- },
123
- websocket: {
124
- npm: '@hazeljs/websocket',
125
- hint: 'import { WebSocketModule } from "@hazeljs/websocket";',
126
- },
127
- };
12
+ const packages_registry_1 = require("../utils/packages-registry");
13
+ const generator_1 = require("../utils/generator");
128
14
  function addCommand(program) {
129
15
  program
130
16
  .command('add [package]')
131
- .description('Add a HazelJS package to your project')
17
+ .description('Add a HazelJS package to your project (optionally generate a setup file with --setup)')
132
18
  .option('--dev', 'Install as dev dependency')
19
+ .option('--setup', 'Also generate a minimal setup/starter file in src/')
20
+ .option('--setup-path <path>', 'Path for the setup file', 'src')
133
21
  .action(async (packageName, options) => {
134
22
  try {
135
23
  let selectedPackage = packageName;
@@ -140,21 +28,21 @@ function addCommand(program) {
140
28
  type: 'list',
141
29
  name: 'package',
142
30
  message: 'Which HazelJS package would you like to add?',
143
- choices: Object.keys(HAZEL_PACKAGES).map((key) => ({
144
- name: `${key} - ${HAZEL_PACKAGES[key].npm}`,
145
- value: key,
31
+ choices: packages_registry_1.HAZEL_PACKAGES.map((p) => ({
32
+ name: `${p.shortName} - ${p.npm}`,
33
+ value: p.shortName,
146
34
  })),
147
35
  },
148
36
  ]);
149
37
  selectedPackage = pkg;
150
38
  }
151
39
  // Get the package info
152
- const pkgInfo = HAZEL_PACKAGES[selectedPackage];
40
+ const pkgInfo = (0, packages_registry_1.findPackage)(selectedPackage);
153
41
  if (!pkgInfo) {
154
42
  console.log(chalk_1.default.yellow(`Unknown package: ${selectedPackage}`));
155
43
  console.log(chalk_1.default.gray('\nAvailable packages:'));
156
- Object.keys(HAZEL_PACKAGES).forEach((key) => {
157
- console.log(chalk_1.default.gray(` - ${key}: ${HAZEL_PACKAGES[key].npm}`));
44
+ packages_registry_1.HAZEL_PACKAGES.forEach((p) => {
45
+ console.log(chalk_1.default.gray(` - ${p.shortName}: ${p.npm}`));
158
46
  });
159
47
  return;
160
48
  }
@@ -163,10 +51,22 @@ function addCommand(program) {
163
51
  const command = `npm install ${pkgInfo.npm} ${devFlag}`.trim();
164
52
  (0, child_process_1.execSync)(command, { stdio: 'inherit' });
165
53
  console.log(chalk_1.default.green(`\n\u2713 Successfully installed ${pkgInfo.npm}`));
54
+ // Generate setup file if requested
55
+ if (options?.setup && pkgInfo.setupTemplate) {
56
+ const setupDir = path_1.default.join(process.cwd(), options.setupPath || 'src');
57
+ const setupFile = path_1.default.join(setupDir, `${(0, generator_1.toKebabCase)(pkgInfo.shortName)}.setup.ts`);
58
+ if (!fs_1.default.existsSync(setupDir))
59
+ fs_1.default.mkdirSync(setupDir, { recursive: true });
60
+ fs_1.default.writeFileSync(setupFile, pkgInfo.setupTemplate);
61
+ console.log(chalk_1.default.green(`\u2713 Generated setup file: ${setupFile}`));
62
+ }
63
+ else if (options?.setup && !pkgInfo.setupTemplate) {
64
+ console.log(chalk_1.default.gray('\nNo setup template available for this package.'));
65
+ }
166
66
  // Show usage hints
167
67
  console.log(chalk_1.default.gray('\nUsage:'));
168
68
  console.log(chalk_1.default.gray(` ${pkgInfo.hint}`));
169
- console.log(chalk_1.default.gray(`\nDocumentation: https://hazeljs.ai/docs/packages/${selectedPackage}`));
69
+ console.log(chalk_1.default.gray(`\nDocumentation: https://hazeljs.ai/docs/packages/${pkgInfo.shortName}`));
170
70
  }
171
71
  catch (error) {
172
72
  console.error(chalk_1.default.red('Error installing package:'), error);
@@ -12,6 +12,7 @@ const child_process_1 = require("child_process");
12
12
  const chalk_1 = __importDefault(require("chalk"));
13
13
  const inquirer_1 = __importDefault(require("inquirer"));
14
14
  const generator_1 = require("../utils/generator");
15
+ const packages_registry_1 = require("../utils/packages-registry");
15
16
  function copyRecursiveSync(src, dest) {
16
17
  if (fs_1.default.existsSync(src)) {
17
18
  fs_1.default.mkdirSync(dest, { recursive: true });
@@ -61,7 +62,7 @@ function createSkeletonAtDest(destPath, appName, description) {
61
62
  'lint:fix': 'eslint "src/**/*.ts" --fix',
62
63
  format: 'prettier --write "src/**/*.ts"',
63
64
  },
64
- dependencies: { '@hazeljs/core': '^0.2.0', 'reflect-metadata': '^0.2.2' },
65
+ dependencies: { '@hazeljs/core': '^0.2.0' },
65
66
  devDependencies: {
66
67
  '@types/jest': '^29.5.12',
67
68
  '@types/node': '^20.0.0',
@@ -78,8 +79,7 @@ function createSkeletonAtDest(destPath, appName, description) {
78
79
  },
79
80
  };
80
81
  fs_1.default.writeFileSync(path_1.default.join(destPath, 'package.json'), JSON.stringify(packageJson, null, 2));
81
- const indexContent = `import 'reflect-metadata';
82
- import { HazelApp, HazelModule, Controller, Get } from '@hazeljs/core';
82
+ const indexContent = `import { HazelApp, HazelModule, Controller, Get } from '@hazeljs/core';
83
83
 
84
84
  @Controller('/')
85
85
  export class AppController {
@@ -134,114 +134,21 @@ function scaffoldPackageBoilerplate(destPath, packages) {
134
134
  // Always include the default HelloController
135
135
  imports.push("import { HelloController } from './hello.controller';");
136
136
  controllers.push('HelloController');
137
+ // Special handling for config: create .env files
137
138
  if (packages.includes('@hazeljs/config')) {
138
- imports.push("import { ConfigModule } from '@hazeljs/config';");
139
- moduleImports.push("ConfigModule.forRoot({ envFilePath: '.env' })");
140
- // Create .env file
141
139
  fs_1.default.writeFileSync(path_1.default.join(destPath, '.env'), 'PORT=3000\nNODE_ENV=development\n');
142
140
  fs_1.default.writeFileSync(path_1.default.join(destPath, '.env.example'), 'PORT=3000\nNODE_ENV=development\n');
143
141
  console.log(chalk_1.default.green(' ✓ Created .env and .env.example'));
144
142
  }
145
- if (packages.includes('@hazeljs/swagger')) {
146
- imports.push("import { SwaggerModule } from '@hazeljs/swagger';");
147
- moduleImports.push('SwaggerModule');
148
- }
149
- if (packages.includes('@hazeljs/prisma')) {
150
- imports.push("import { PrismaModule } from '@hazeljs/prisma';");
151
- moduleImports.push('PrismaModule');
152
- }
153
- if (packages.includes('@hazeljs/typeorm')) {
154
- imports.push("import { TypeOrmModule } from '@hazeljs/typeorm';");
155
- moduleImports.push('TypeOrmModule');
156
- }
157
- if (packages.includes('@hazeljs/audit')) {
158
- imports.push("import { AuditModule, ConsoleAuditTransport } from '@hazeljs/audit';");
159
- moduleImports.push("AuditModule.forRoot({ transports: [new ConsoleAuditTransport()] })");
160
- }
161
- if (packages.includes('@hazeljs/auth')) {
162
- imports.push("import { JwtModule } from '@hazeljs/auth';");
163
- moduleImports.push("JwtModule.forRoot({ secret: process.env.JWT_SECRET || 'change-me', expiresIn: '1d' })");
164
- }
165
- if (packages.includes('@hazeljs/oauth')) {
166
- imports.push("import { OAuthModule } from '@hazeljs/oauth';");
167
- moduleImports.push("OAuthModule.forRoot({ providers: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, redirectUri: process.env.OAUTH_REDIRECT_URI! } } })");
168
- }
169
- if (packages.includes('@hazeljs/cache')) {
170
- imports.push("import { CacheModule } from '@hazeljs/cache';");
171
- moduleImports.push('CacheModule');
172
- }
173
- if (packages.includes('@hazeljs/cron')) {
174
- imports.push("import { CronModule } from '@hazeljs/cron';");
175
- moduleImports.push('CronModule');
176
- }
177
- if (packages.includes('@hazeljs/websocket')) {
178
- imports.push("import { WebSocketModule } from '@hazeljs/websocket';");
179
- moduleImports.push('WebSocketModule');
180
- }
181
- if (packages.includes('@hazeljs/ai')) {
182
- imports.push("import { AIModule } from '@hazeljs/ai';");
183
- moduleImports.push('AIModule');
184
- }
185
- if (packages.includes('@hazeljs/agent')) {
186
- imports.push("import { AgentModule } from '@hazeljs/agent';");
187
- moduleImports.push('AgentModule');
188
- }
189
- if (packages.includes('@hazeljs/rag')) {
190
- imports.push("import { RAGModule } from '@hazeljs/rag';");
191
- moduleImports.push('RAGModule');
192
- }
193
- if (packages.includes('@hazeljs/discovery')) {
194
- // Discovery uses ServiceRegistry/DiscoveryClient programmatically - no module import
195
- }
196
- if (packages.includes('@hazeljs/prompts')) {
197
- // Prompts is a library (PromptTemplate, PromptRegistry) - no module import
198
- }
199
- if (packages.includes('@hazeljs/mcp')) {
200
- // MCP uses createMcpServer() programmatically - no module import
201
- }
202
- if (packages.includes('@hazeljs/pdf-to-audio')) {
203
- imports.push("import { PdfToAudioModule } from '@hazeljs/pdf-to-audio';");
204
- moduleImports.push('PdfToAudioModule');
205
- }
206
- if (packages.includes('@hazeljs/data')) {
207
- imports.push("import { DataModule } from '@hazeljs/data';");
208
- moduleImports.push('DataModule.forRoot()');
209
- }
210
- if (packages.includes('@hazeljs/event-emitter')) {
211
- imports.push("import { EventEmitterModule } from '@hazeljs/event-emitter';");
212
- moduleImports.push('EventEmitterModule.forRoot()');
213
- }
214
- if (packages.includes('@hazeljs/gateway')) {
215
- imports.push("import { GatewayModule } from '@hazeljs/gateway';");
216
- moduleImports.push('GatewayModule');
217
- }
218
- if (packages.includes('@hazeljs/graphql')) {
219
- imports.push("import { GraphQLModule } from '@hazeljs/graphql';");
220
- moduleImports.push('GraphQLModule');
221
- }
222
- if (packages.includes('@hazeljs/grpc')) {
223
- imports.push("import { GrpcModule } from '@hazeljs/grpc';");
224
- moduleImports.push('GrpcModule');
225
- }
226
- if (packages.includes('@hazeljs/kafka')) {
227
- imports.push("import { KafkaModule } from '@hazeljs/kafka';");
228
- moduleImports.push('KafkaModule');
229
- }
230
- if (packages.includes('@hazeljs/messaging')) {
231
- imports.push("import { MessagingModule } from '@hazeljs/messaging';");
232
- moduleImports.push('MessagingModule');
233
- }
234
- if (packages.includes('@hazeljs/ml')) {
235
- imports.push("import { MLModule } from '@hazeljs/ml';");
236
- moduleImports.push('MLModule.forRoot()');
237
- }
238
- if (packages.includes('@hazeljs/queue')) {
239
- imports.push("import { QueueModule } from '@hazeljs/queue';");
240
- moduleImports.push('QueueModule');
241
- }
242
- if (packages.includes('@hazeljs/resilience')) {
243
- // Resilience is a library of decorators, not a module - no import needed in app.module
244
- // User can import { CircuitBreaker, WithRetry } in their services
143
+ // Data-driven: derive imports from centralized registry
144
+ for (const npmName of packages) {
145
+ const meta = (0, packages_registry_1.findPackage)(npmName);
146
+ if (!meta)
147
+ continue;
148
+ if (meta.moduleImport)
149
+ imports.push(meta.moduleImport);
150
+ if (meta.moduleExpression)
151
+ moduleImports.push(meta.moduleExpression);
245
152
  }
246
153
  // Generate the enhanced app.module.ts
247
154
  const importsSection = moduleImports.length > 0
@@ -258,8 +165,7 @@ export class AppModule {}
258
165
  console.log(chalk_1.default.green(' ✓ Updated app.module.ts with package imports'));
259
166
  // Update index.ts / main.ts if swagger is selected
260
167
  if (packages.includes('@hazeljs/swagger')) {
261
- const mainContent = `import 'reflect-metadata';
262
- import { HazelApp } from '@hazeljs/core';
168
+ const mainContent = `import { HazelApp } from '@hazeljs/core';
263
169
  import { SwaggerModule } from '@hazeljs/swagger';
264
170
  import { AppModule } from './app.module';
265
171
 
@@ -329,36 +235,7 @@ function generateApp(program) {
329
235
  type: 'checkbox',
330
236
  name: 'packages',
331
237
  message: 'Select additional HazelJS packages to install:',
332
- choices: [
333
- { name: 'AI Integration (@hazeljs/ai)', value: '@hazeljs/ai' },
334
- { name: 'AI Agents (@hazeljs/agent)', value: '@hazeljs/agent' },
335
- { name: 'Audit Logging (@hazeljs/audit)', value: '@hazeljs/audit' },
336
- { name: 'Authentication (@hazeljs/auth)', value: '@hazeljs/auth' },
337
- { name: 'OAuth - Google/Microsoft/GitHub (@hazeljs/oauth)', value: '@hazeljs/oauth' },
338
- { name: 'Caching (@hazeljs/cache)', value: '@hazeljs/cache' },
339
- { name: 'Configuration (@hazeljs/config)', value: '@hazeljs/config' },
340
- { name: 'Cron Jobs (@hazeljs/cron)', value: '@hazeljs/cron' },
341
- { name: 'Data/ETL (@hazeljs/data)', value: '@hazeljs/data' },
342
- { name: 'Service Discovery (@hazeljs/discovery)', value: '@hazeljs/discovery' },
343
- { name: 'Event Emitter (@hazeljs/event-emitter)', value: '@hazeljs/event-emitter' },
344
- { name: 'API Gateway (@hazeljs/gateway)', value: '@hazeljs/gateway' },
345
- { name: 'GraphQL (@hazeljs/graphql)', value: '@hazeljs/graphql' },
346
- { name: 'gRPC (@hazeljs/grpc)', value: '@hazeljs/grpc' },
347
- { name: 'Kafka (@hazeljs/kafka)', value: '@hazeljs/kafka' },
348
- { name: 'Messaging - WhatsApp/Telegram (@hazeljs/messaging)', value: '@hazeljs/messaging' },
349
- { name: 'Machine Learning (@hazeljs/ml)', value: '@hazeljs/ml' },
350
- { name: 'MCP - Model Context Protocol (@hazeljs/mcp)', value: '@hazeljs/mcp' },
351
- { name: 'PDF to Audio (@hazeljs/pdf-to-audio)', value: '@hazeljs/pdf-to-audio' },
352
- { name: 'Prompts - typed templates (@hazeljs/prompts)', value: '@hazeljs/prompts' },
353
- { name: 'Prisma ORM (@hazeljs/prisma)', value: '@hazeljs/prisma' },
354
- { name: 'TypeORM (@hazeljs/typeorm)', value: '@hazeljs/typeorm' },
355
- { name: 'Queue/BullMQ (@hazeljs/queue)', value: '@hazeljs/queue' },
356
- { name: 'RAG/Vector Search (@hazeljs/rag)', value: '@hazeljs/rag' },
357
- { name: 'Resilience - Circuit Breaker (@hazeljs/resilience)', value: '@hazeljs/resilience' },
358
- { name: 'Serverless (@hazeljs/serverless)', value: '@hazeljs/serverless' },
359
- { name: 'Swagger/OpenAPI (@hazeljs/swagger)', value: '@hazeljs/swagger' },
360
- { name: 'WebSocket (@hazeljs/websocket)', value: '@hazeljs/websocket' },
361
- ],
238
+ choices: packages_registry_1.HAZEL_PACKAGES.map((p) => ({ name: p.label, value: p.npm })),
362
239
  },
363
240
  ]);
364
241
  projectConfig = { ...projectConfig, ...answers };
@@ -384,97 +261,7 @@ function generateApp(program) {
384
261
  }
385
262
  else {
386
263
  console.log(chalk_1.default.yellow(`⚠ ${options.template} template not found, creating basic structure...`));
387
- // Create basic structure
388
- fs_1.default.mkdirSync(destPath, { recursive: true });
389
- fs_1.default.mkdirSync(path_1.default.join(destPath, 'src'), { recursive: true });
390
- // Create package.json
391
- const packageJson = {
392
- name: projectConfig.name,
393
- version: '0.1.0',
394
- description: projectConfig.description,
395
- main: 'dist/index.js',
396
- scripts: {
397
- build: 'tsc',
398
- start: 'node dist/index.js',
399
- dev: 'ts-node-dev --respawn --transpile-only src/index.ts',
400
- test: 'jest',
401
- lint: 'eslint "src/**/*.ts"',
402
- 'lint:fix': 'eslint "src/**/*.ts" --fix',
403
- format: 'prettier --write "src/**/*.ts"',
404
- },
405
- dependencies: {
406
- '@hazeljs/core': '^0.2.0',
407
- 'reflect-metadata': '^0.2.2',
408
- },
409
- devDependencies: {
410
- '@types/jest': '^29.5.12',
411
- '@types/node': '^20.0.0',
412
- '@typescript-eslint/eslint-plugin': '^8.18.2',
413
- '@typescript-eslint/parser': '^8.18.2',
414
- 'eslint': '^8.56.0',
415
- 'eslint-config-prettier': '^9.1.0',
416
- 'eslint-plugin-prettier': '^5.1.3',
417
- 'jest': '^29.7.0',
418
- 'prettier': '^3.2.5',
419
- 'ts-jest': '^29.1.2',
420
- 'ts-node-dev': '^2.0.0',
421
- 'typescript': '^5.3.3',
422
- },
423
- author: projectConfig.author,
424
- license: projectConfig.license,
425
- };
426
- fs_1.default.writeFileSync(path_1.default.join(destPath, 'package.json'), JSON.stringify(packageJson, null, 2));
427
- // Create basic index.ts
428
- const indexContent = `import 'reflect-metadata';
429
- import { HazelApp, HazelModule, Controller, Get } from '@hazeljs/core';
430
-
431
- @Controller('/')
432
- export class AppController {
433
- @Get()
434
- hello() {
435
- return { message: 'Hello from HazelJS!' };
436
- }
437
- }
438
-
439
- @HazelModule({
440
- controllers: [AppController],
441
- })
442
- export class AppModule {}
443
-
444
- async function bootstrap() {
445
- const app = new HazelApp(AppModule);
446
-
447
- app.enableCors({
448
- origin: '*',
449
- methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
450
- });
451
-
452
- const port = parseInt(process.env.PORT || '3000', 10);
453
- await app.listen(port);
454
- }
455
-
456
- bootstrap();
457
- `;
458
- fs_1.default.writeFileSync(path_1.default.join(destPath, 'src', 'index.ts'), indexContent);
459
- // Create tsconfig.json
460
- const tsConfig = {
461
- compilerOptions: {
462
- target: 'ES2020',
463
- module: 'commonjs',
464
- lib: ['ES2020'],
465
- outDir: './dist',
466
- rootDir: './src',
467
- strict: true,
468
- esModuleInterop: true,
469
- skipLibCheck: true,
470
- forceConsistentCasingInFileNames: true,
471
- experimentalDecorators: true,
472
- emitDecoratorMetadata: true,
473
- },
474
- include: ['src/**/*'],
475
- exclude: ['node_modules', 'dist'],
476
- };
477
- fs_1.default.writeFileSync(path_1.default.join(destPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
264
+ createSkeletonAtDest(destPath, projectConfig.name, projectConfig.description);
478
265
  console.log(chalk_1.default.green('✓ Basic structure created'));
479
266
  }
480
267
  // Initialize git
@@ -531,7 +318,7 @@ coverage/
531
318
  }
532
319
  console.log(chalk_1.default.gray(' npm run dev'));
533
320
  console.log(chalk_1.default.gray('\nDocumentation: https://hazeljs.ai/docs'));
534
- console.log(chalk_1.default.gray('Discord: https://discord.gg/xe495BvE\n'));
321
+ console.log(chalk_1.default.gray('Discord: https://discord.com/channels/1448263814238965833/1448263814859456575\n'));
535
322
  }
536
323
  catch (error) {
537
324
  console.error(chalk_1.default.red('\n✗ Failed to create project:'), error);
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Config-driven generator factory for simple single-file generators.
3
+ * Replaces 12+ individual generator files with one data-driven approach.
4
+ */
5
+ import { Command } from 'commander';
6
+ import { GenerateResult, GenerateCLIOptions } from '../utils/generator';
7
+ export interface SimpleGeneratorConfig {
8
+ type: string;
9
+ description: string;
10
+ suffix: string;
11
+ template: string;
12
+ alias?: string;
13
+ defaultPath?: string;
14
+ nameRequired: boolean;
15
+ /** Extra template data injected at generation time */
16
+ extraData?: (name: string) => Record<string, string>;
17
+ /** Next steps shown after generation */
18
+ nextSteps?: string[];
19
+ /** Extra CLI options beyond --path, --dry-run, --json */
20
+ extraOptions?: string[];
21
+ }
22
+ export declare const SIMPLE_GENERATORS: SimpleGeneratorConfig[];
23
+ export declare function runSimpleGenerator(config: SimpleGeneratorConfig, name: string, options: GenerateCLIOptions): Promise<GenerateResult>;
24
+ /** Register all simple generators as sub-commands of the generate command */
25
+ export declare function registerSimpleGenerators(generateCommand: Command): void;
26
+ /** Lookup a simple generator config by type */
27
+ export declare function findSimpleGenerator(type: string): SimpleGeneratorConfig | undefined;