@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.
- package/@template-ai-native/package.json +1 -1
- package/README.md +122 -591
- package/dist/commands/add.js +26 -126
- package/dist/commands/generate-app.js +17 -230
- package/dist/commands/generate-simple.d.ts +27 -0
- package/dist/commands/generate-simple.js +448 -0
- package/dist/commands/generate-simple.test.js +100 -0
- package/dist/index.js +5 -47
- package/dist/index.list.test.js +8 -22
- package/dist/index.test.js +19 -56
- package/dist/utils/generator-registry.js +29 -65
- package/dist/utils/generator.d.ts +0 -1
- package/dist/utils/generator.js +0 -22
- package/dist/utils/generator.test.js +0 -28
- package/dist/utils/packages-registry.d.ts +25 -0
- package/dist/utils/packages-registry.js +371 -0
- package/package.json +3 -5
- package/dist/commands/build.d.ts +0 -2
- package/dist/commands/build.js +0 -52
- package/dist/commands/generate-agent.d.ts +0 -4
- package/dist/commands/generate-agent.js +0 -64
- package/dist/commands/generate-agent.test.js +0 -36
- package/dist/commands/generate-ai-service.d.ts +0 -4
- package/dist/commands/generate-ai-service.js +0 -54
- package/dist/commands/generate-ai-service.test.d.ts +0 -1
- package/dist/commands/generate-ai-service.test.js +0 -41
- package/dist/commands/generate-cache.d.ts +0 -4
- package/dist/commands/generate-cache.js +0 -66
- package/dist/commands/generate-cache.test.d.ts +0 -1
- package/dist/commands/generate-cache.test.js +0 -36
- package/dist/commands/generate-config.d.ts +0 -4
- package/dist/commands/generate-config.js +0 -59
- package/dist/commands/generate-config.test.d.ts +0 -1
- package/dist/commands/generate-config.test.js +0 -35
- package/dist/commands/generate-controller.d.ts +0 -4
- package/dist/commands/generate-controller.js +0 -66
- package/dist/commands/generate-controller.test.d.ts +0 -1
- package/dist/commands/generate-controller.test.js +0 -48
- package/dist/commands/generate-cron.d.ts +0 -4
- package/dist/commands/generate-cron.js +0 -61
- package/dist/commands/generate-cron.test.d.ts +0 -1
- package/dist/commands/generate-cron.test.js +0 -42
- package/dist/commands/generate-discovery.d.ts +0 -4
- package/dist/commands/generate-discovery.js +0 -63
- package/dist/commands/generate-discovery.test.d.ts +0 -1
- package/dist/commands/generate-discovery.test.js +0 -36
- package/dist/commands/generate-exception-filter.d.ts +0 -4
- package/dist/commands/generate-exception-filter.js +0 -54
- package/dist/commands/generate-exception-filter.test.d.ts +0 -1
- package/dist/commands/generate-exception-filter.test.js +0 -43
- package/dist/commands/generate-guard.d.ts +0 -4
- package/dist/commands/generate-guard.js +0 -42
- package/dist/commands/generate-guard.test.d.ts +0 -1
- package/dist/commands/generate-guard.test.js +0 -41
- package/dist/commands/generate-interceptor.d.ts +0 -4
- package/dist/commands/generate-interceptor.js +0 -43
- package/dist/commands/generate-interceptor.test.d.ts +0 -1
- package/dist/commands/generate-interceptor.test.js +0 -41
- package/dist/commands/generate-middleware.d.ts +0 -4
- package/dist/commands/generate-middleware.js +0 -47
- package/dist/commands/generate-middleware.test.d.ts +0 -1
- package/dist/commands/generate-middleware.test.js +0 -41
- package/dist/commands/generate-pipe.d.ts +0 -4
- package/dist/commands/generate-pipe.js +0 -39
- package/dist/commands/generate-pipe.test.d.ts +0 -1
- package/dist/commands/generate-pipe.test.js +0 -35
- package/dist/commands/generate-rag.d.ts +0 -4
- package/dist/commands/generate-rag.js +0 -68
- package/dist/commands/generate-rag.test.d.ts +0 -1
- package/dist/commands/generate-rag.test.js +0 -35
- package/dist/commands/generate-repository.d.ts +0 -4
- package/dist/commands/generate-repository.js +0 -46
- package/dist/commands/generate-repository.test.d.ts +0 -1
- package/dist/commands/generate-repository.test.js +0 -41
- package/dist/commands/generate-serverless-handler.d.ts +0 -4
- package/dist/commands/generate-serverless-handler.js +0 -57
- package/dist/commands/generate-serverless-handler.test.d.ts +0 -1
- package/dist/commands/generate-serverless-handler.test.js +0 -42
- package/dist/commands/generate-service.d.ts +0 -4
- package/dist/commands/generate-service.js +0 -58
- package/dist/commands/generate-service.test.d.ts +0 -1
- package/dist/commands/generate-service.test.js +0 -41
- package/dist/commands/generate-setup.d.ts +0 -4
- package/dist/commands/generate-setup.js +0 -187
- package/dist/commands/generate-setup.test.d.ts +0 -1
- package/dist/commands/generate-setup.test.js +0 -50
- package/dist/commands/generate-websocket-gateway.d.ts +0 -4
- package/dist/commands/generate-websocket-gateway.js +0 -53
- package/dist/commands/generate-websocket-gateway.test.d.ts +0 -1
- package/dist/commands/generate-websocket-gateway.test.js +0 -41
- package/dist/commands/pdf-to-audio.d.ts +0 -2
- package/dist/commands/pdf-to-audio.js +0 -170
- package/dist/commands/pdf-to-audio.test.d.ts +0 -1
- package/dist/commands/pdf-to-audio.test.js +0 -92
- package/dist/commands/start.d.ts +0 -2
- package/dist/commands/start.js +0 -61
- package/dist/commands/test.d.ts +0 -2
- package/dist/commands/test.js +0 -63
- package/dist/commands/utility-commands.test.d.ts +0 -1
- package/dist/commands/utility-commands.test.js +0 -95
- /package/dist/commands/{generate-agent.test.d.ts → generate-simple.test.d.ts} +0 -0
package/dist/commands/add.js
CHANGED
|
@@ -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
|
|
11
|
-
|
|
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:
|
|
144
|
-
name: `${
|
|
145
|
-
value:
|
|
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 =
|
|
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
|
-
|
|
157
|
-
console.log(chalk_1.default.gray(` - ${
|
|
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/${
|
|
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'
|
|
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 '
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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 '
|
|
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
|
-
|
|
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.
|
|
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;
|