@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.
- package/@template/README.md +61 -0
- package/@template/package.json +48 -0
- package/@template/src/app.module.ts +7 -0
- package/@template/src/hello.controller.ts +9 -0
- package/@template/src/index.ts +10 -0
- package/README.md +675 -0
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +90 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.js +52 -0
- package/dist/commands/generate-agent.d.ts +2 -0
- package/dist/commands/generate-agent.js +56 -0
- package/dist/commands/generate-ai-service.d.ts +2 -0
- package/dist/commands/generate-ai-service.js +49 -0
- package/dist/commands/generate-app.d.ts +2 -0
- package/dist/commands/generate-app.js +246 -0
- package/dist/commands/generate-controller.d.ts +2 -0
- package/dist/commands/generate-controller.js +59 -0
- package/dist/commands/generate-crud.d.ts +2 -0
- package/dist/commands/generate-crud.js +203 -0
- package/dist/commands/generate-dto.d.ts +2 -0
- package/dist/commands/generate-dto.js +56 -0
- package/dist/commands/generate-exception-filter.d.ts +2 -0
- package/dist/commands/generate-exception-filter.js +50 -0
- package/dist/commands/generate-guard.d.ts +2 -0
- package/dist/commands/generate-guard.js +35 -0
- package/dist/commands/generate-interceptor.d.ts +2 -0
- package/dist/commands/generate-interceptor.js +37 -0
- package/dist/commands/generate-middleware.d.ts +2 -0
- package/dist/commands/generate-middleware.js +79 -0
- package/dist/commands/generate-module.d.ts +2 -0
- package/dist/commands/generate-module.js +96 -0
- package/dist/commands/generate-pipe.d.ts +2 -0
- package/dist/commands/generate-pipe.js +33 -0
- package/dist/commands/generate-repository.d.ts +2 -0
- package/dist/commands/generate-repository.js +38 -0
- package/dist/commands/generate-serverless-handler.d.ts +2 -0
- package/dist/commands/generate-serverless-handler.js +46 -0
- package/dist/commands/generate-service.d.ts +2 -0
- package/dist/commands/generate-service.js +51 -0
- package/dist/commands/generate-websocket-gateway.d.ts +2 -0
- package/dist/commands/generate-websocket-gateway.js +47 -0
- package/dist/commands/info.d.ts +2 -0
- package/dist/commands/info.js +91 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.js +61 -0
- package/dist/commands/test.d.ts +2 -0
- package/dist/commands/test.js +63 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +61 -0
- package/dist/utils/generator.d.ts +14 -0
- package/dist/utils/generator.js +79 -0
- package/package.json +67 -0
- package/src/commands/add.ts +101 -0
- package/src/commands/build.ts +56 -0
- package/src/commands/generate-agent.ts +58 -0
- package/src/commands/generate-ai-service.ts +52 -0
- package/src/commands/generate-app.ts +270 -0
- package/src/commands/generate-controller.ts +61 -0
- package/src/commands/generate-crud.ts +214 -0
- package/src/commands/generate-dto.ts +61 -0
- package/src/commands/generate-exception-filter.ts +53 -0
- package/src/commands/generate-guard.ts +37 -0
- package/src/commands/generate-interceptor.ts +39 -0
- package/src/commands/generate-middleware.ts +86 -0
- package/src/commands/generate-module.ts +102 -0
- package/src/commands/generate-pipe.ts +36 -0
- package/src/commands/generate-repository.ts +41 -0
- package/src/commands/generate-serverless-handler.ts +53 -0
- package/src/commands/generate-service.ts +53 -0
- package/src/commands/generate-websocket-gateway.ts +50 -0
- package/src/commands/info.ts +106 -0
- package/src/commands/start.ts +61 -0
- package/src/commands/test.ts +70 -0
- package/src/index.ts +68 -0
- package/src/utils/generator.ts +93 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateServerlessHandler = generateServerlessHandler;
|
|
4
|
+
const generator_1 = require("../utils/generator");
|
|
5
|
+
const SERVERLESS_HANDLER_TEMPLATE = `import { createLambdaHandler } from '@hazeljs/serverless';
|
|
6
|
+
import { AppModule } from './app.module';
|
|
7
|
+
|
|
8
|
+
export const handler = createLambdaHandler(AppModule);
|
|
9
|
+
`;
|
|
10
|
+
const SERVERLESS_CLOUD_FUNCTION_TEMPLATE = `import { createCloudFunctionHandler } from '@hazeljs/serverless';
|
|
11
|
+
import { AppModule } from './app.module';
|
|
12
|
+
|
|
13
|
+
export const handler = createCloudFunctionHandler(AppModule);
|
|
14
|
+
`;
|
|
15
|
+
class ServerlessHandlerGenerator extends generator_1.Generator {
|
|
16
|
+
getDefaultTemplate() {
|
|
17
|
+
return SERVERLESS_HANDLER_TEMPLATE;
|
|
18
|
+
}
|
|
19
|
+
async generate(options) {
|
|
20
|
+
const { platform = 'lambda', ...restOptions } = options;
|
|
21
|
+
const template = platform === 'lambda'
|
|
22
|
+
? SERVERLESS_HANDLER_TEMPLATE
|
|
23
|
+
: SERVERLESS_CLOUD_FUNCTION_TEMPLATE;
|
|
24
|
+
await super.generate({
|
|
25
|
+
...restOptions,
|
|
26
|
+
template,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function generateServerlessHandler(program) {
|
|
31
|
+
program
|
|
32
|
+
.command('serverless <name>')
|
|
33
|
+
.description('Generate a serverless handler (Lambda or Cloud Function)')
|
|
34
|
+
.alias('sls')
|
|
35
|
+
.option('-p, --path <path>', 'Path where the handler should be generated', 'src')
|
|
36
|
+
.option('--platform <platform>', 'Platform: lambda or cloud-function', 'lambda')
|
|
37
|
+
.action(async (name, options) => {
|
|
38
|
+
const generator = new ServerlessHandlerGenerator();
|
|
39
|
+
const generatorOptions = {
|
|
40
|
+
name,
|
|
41
|
+
path: options.path,
|
|
42
|
+
};
|
|
43
|
+
const finalOptions = await generator.promptForOptions(generatorOptions);
|
|
44
|
+
await generator.generate({ ...finalOptions, platform: options.platform });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateService = generateService;
|
|
4
|
+
const generator_1 = require("../utils/generator");
|
|
5
|
+
const SERVICE_TEMPLATE = `import { Injectable } from '@hazeljs/core';
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class {{className}}Service {
|
|
9
|
+
constructor() {}
|
|
10
|
+
|
|
11
|
+
async findAll() {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async findOne(id: string) {
|
|
16
|
+
return { id };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async create(create{{className}}Dto: any) {
|
|
20
|
+
return create{{className}}Dto;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async update(id: string, update{{className}}Dto: any) {
|
|
24
|
+
return { id, ...update{{className}}Dto };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async remove(id: string) {
|
|
28
|
+
return { id };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
class ServiceGenerator extends generator_1.Generator {
|
|
33
|
+
getDefaultTemplate() {
|
|
34
|
+
return SERVICE_TEMPLATE;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function generateService(program) {
|
|
38
|
+
program
|
|
39
|
+
.command('service <name>')
|
|
40
|
+
.description('Generate a new service')
|
|
41
|
+
.option('-p, --path <path>', 'Path where the service should be generated')
|
|
42
|
+
.action(async (name, options) => {
|
|
43
|
+
const generator = new ServiceGenerator();
|
|
44
|
+
const generatorOptions = {
|
|
45
|
+
name,
|
|
46
|
+
path: options.path,
|
|
47
|
+
};
|
|
48
|
+
const finalOptions = await generator.promptForOptions(generatorOptions);
|
|
49
|
+
await generator.generate(finalOptions);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateWebSocketGateway = generateWebSocketGateway;
|
|
4
|
+
const generator_1 = require("../utils/generator");
|
|
5
|
+
const WEBSOCKET_GATEWAY_TEMPLATE = `import { Realtime, OnConnect, OnDisconnect, OnMessage, Subscribe, Client, Data, WebSocketClient } from '@hazeljs/websocket';
|
|
6
|
+
|
|
7
|
+
@Realtime('/{{fileName}}')
|
|
8
|
+
export class {{className}}Gateway {
|
|
9
|
+
@OnConnect()
|
|
10
|
+
handleConnection(@Client() client: WebSocketClient) {
|
|
11
|
+
console.log('Client connected:', client.id);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@OnDisconnect()
|
|
15
|
+
handleDisconnect(@Client() client: WebSocketClient) {
|
|
16
|
+
console.log('Client disconnected:', client.id);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Subscribe('message')
|
|
20
|
+
@OnMessage('message')
|
|
21
|
+
handleMessage(@Client() client: WebSocketClient, @Data() data: unknown) {
|
|
22
|
+
console.log('Message received from', client.id, ':', data);
|
|
23
|
+
// Handle message logic here
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
class WebSocketGatewayGenerator extends generator_1.Generator {
|
|
28
|
+
getDefaultTemplate() {
|
|
29
|
+
return WEBSOCKET_GATEWAY_TEMPLATE;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function generateWebSocketGateway(program) {
|
|
33
|
+
program
|
|
34
|
+
.command('gateway <name>')
|
|
35
|
+
.description('Generate a new WebSocket gateway')
|
|
36
|
+
.alias('ws')
|
|
37
|
+
.option('-p, --path <path>', 'Path where the gateway should be generated')
|
|
38
|
+
.action(async (name, options) => {
|
|
39
|
+
const generator = new WebSocketGatewayGenerator();
|
|
40
|
+
const generatorOptions = {
|
|
41
|
+
name,
|
|
42
|
+
path: options.path,
|
|
43
|
+
};
|
|
44
|
+
const finalOptions = await generator.promptForOptions(generatorOptions);
|
|
45
|
+
await generator.generate(finalOptions);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
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.infoCommand = infoCommand;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
function infoCommand(program) {
|
|
11
|
+
program
|
|
12
|
+
.command('info')
|
|
13
|
+
.description('Display information about the current HazelJS project')
|
|
14
|
+
.action(() => {
|
|
15
|
+
try {
|
|
16
|
+
const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
|
|
17
|
+
if (!fs_1.default.existsSync(packageJsonPath)) {
|
|
18
|
+
console.log(chalk_1.default.yellow('⚠ No package.json found in current directory'));
|
|
19
|
+
console.log(chalk_1.default.gray('This does not appear to be a Node.js project'));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
|
|
23
|
+
console.log(chalk_1.default.bold.blue('\n📦 Project Information\n'));
|
|
24
|
+
// Basic info
|
|
25
|
+
console.log(chalk_1.default.bold('Name:'), packageJson.name || 'N/A');
|
|
26
|
+
console.log(chalk_1.default.bold('Version:'), packageJson.version || 'N/A');
|
|
27
|
+
console.log(chalk_1.default.bold('Description:'), packageJson.description || 'N/A');
|
|
28
|
+
// HazelJS packages
|
|
29
|
+
const hazelPackages = [];
|
|
30
|
+
const allDeps = {
|
|
31
|
+
...packageJson.dependencies,
|
|
32
|
+
...packageJson.devDependencies,
|
|
33
|
+
};
|
|
34
|
+
Object.keys(allDeps).forEach((dep) => {
|
|
35
|
+
if (dep.startsWith('@hazeljs/')) {
|
|
36
|
+
hazelPackages.push(`${dep}@${allDeps[dep]}`);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
if (hazelPackages.length > 0) {
|
|
40
|
+
console.log(chalk_1.default.bold('\n🔧 HazelJS Packages:\n'));
|
|
41
|
+
hazelPackages.forEach((pkg) => {
|
|
42
|
+
console.log(chalk_1.default.green(' ✓'), pkg);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.log(chalk_1.default.yellow('\n⚠ No HazelJS packages found'));
|
|
47
|
+
console.log(chalk_1.default.gray('Install HazelJS packages with: npm install @hazeljs/core'));
|
|
48
|
+
}
|
|
49
|
+
// Project structure
|
|
50
|
+
console.log(chalk_1.default.bold('\n📁 Project Structure:\n'));
|
|
51
|
+
const srcPath = path_1.default.join(process.cwd(), 'src');
|
|
52
|
+
if (fs_1.default.existsSync(srcPath)) {
|
|
53
|
+
const items = fs_1.default.readdirSync(srcPath);
|
|
54
|
+
items.forEach((item) => {
|
|
55
|
+
const itemPath = path_1.default.join(srcPath, item);
|
|
56
|
+
const stat = fs_1.default.statSync(itemPath);
|
|
57
|
+
const icon = stat.isDirectory() ? '📁' : '📄';
|
|
58
|
+
console.log(` ${icon} ${item}`);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.log(chalk_1.default.gray(' No src directory found'));
|
|
63
|
+
}
|
|
64
|
+
// Environment
|
|
65
|
+
console.log(chalk_1.default.bold('\n🌍 Environment:\n'));
|
|
66
|
+
console.log(chalk_1.default.bold('Node:'), process.version);
|
|
67
|
+
console.log(chalk_1.default.bold('Platform:'), process.platform);
|
|
68
|
+
console.log(chalk_1.default.bold('Architecture:'), process.arch);
|
|
69
|
+
// Config files
|
|
70
|
+
console.log(chalk_1.default.bold('\n⚙️ Configuration Files:\n'));
|
|
71
|
+
const configFiles = [
|
|
72
|
+
'tsconfig.json',
|
|
73
|
+
'.env',
|
|
74
|
+
'.env.example',
|
|
75
|
+
'.eslintrc.js',
|
|
76
|
+
'.prettierrc',
|
|
77
|
+
'jest.config.js',
|
|
78
|
+
];
|
|
79
|
+
configFiles.forEach((file) => {
|
|
80
|
+
const exists = fs_1.default.existsSync(path_1.default.join(process.cwd(), file));
|
|
81
|
+
const icon = exists ? chalk_1.default.green('✓') : chalk_1.default.gray('✗');
|
|
82
|
+
console.log(` ${icon} ${file}`);
|
|
83
|
+
});
|
|
84
|
+
console.log('');
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error(chalk_1.default.red('Error reading project information:'), error);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
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.startCommand = startCommand;
|
|
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 startCommand(program) {
|
|
12
|
+
program
|
|
13
|
+
.command('start')
|
|
14
|
+
.description('Start the HazelJS application')
|
|
15
|
+
.option('-d, --dev', 'Start in development mode')
|
|
16
|
+
.option('-p, --port <port>', 'Specify port')
|
|
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
|
+
let command;
|
|
27
|
+
if (options.dev) {
|
|
28
|
+
if (!packageJson.scripts?.dev) {
|
|
29
|
+
console.log(chalk_1.default.yellow('⚠ No dev script found in package.json'));
|
|
30
|
+
console.log(chalk_1.default.gray('\nAdd a dev script to your package.json:'));
|
|
31
|
+
console.log(chalk_1.default.gray(' "scripts": {'));
|
|
32
|
+
console.log(chalk_1.default.gray(' "dev": "ts-node-dev --respawn src/index.ts"'));
|
|
33
|
+
console.log(chalk_1.default.gray(' }'));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
command = 'npm run dev';
|
|
37
|
+
console.log(chalk_1.default.blue('🚀 Starting in development mode...\n'));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (!packageJson.scripts?.start) {
|
|
41
|
+
console.log(chalk_1.default.yellow('⚠ No start script found in package.json'));
|
|
42
|
+
console.log(chalk_1.default.gray('\nAdd a start script to your package.json:'));
|
|
43
|
+
console.log(chalk_1.default.gray(' "scripts": {'));
|
|
44
|
+
console.log(chalk_1.default.gray(' "start": "node dist/index.js"'));
|
|
45
|
+
console.log(chalk_1.default.gray(' }'));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
command = 'npm start';
|
|
49
|
+
console.log(chalk_1.default.blue('🚀 Starting application...\n'));
|
|
50
|
+
}
|
|
51
|
+
if (options.port) {
|
|
52
|
+
process.env.PORT = options.port;
|
|
53
|
+
}
|
|
54
|
+
(0, child_process_1.execSync)(command, { stdio: 'inherit' });
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
console.error(chalk_1.default.red('\n✗ Failed to start application'));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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.testCommand = testCommand;
|
|
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 testCommand(program) {
|
|
12
|
+
program
|
|
13
|
+
.command('test [pattern]')
|
|
14
|
+
.description('Run tests')
|
|
15
|
+
.option('-w, --watch', 'Watch mode')
|
|
16
|
+
.option('-c, --coverage', 'Generate coverage report')
|
|
17
|
+
.option('--ci', 'Run in CI mode')
|
|
18
|
+
.action((pattern, options) => {
|
|
19
|
+
try {
|
|
20
|
+
const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
|
|
21
|
+
if (!fs_1.default.existsSync(packageJsonPath)) {
|
|
22
|
+
console.log(chalk_1.default.red('✗ No package.json found'));
|
|
23
|
+
console.log(chalk_1.default.gray('Run this command from your project root'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
|
|
27
|
+
if (!packageJson.scripts?.test) {
|
|
28
|
+
console.log(chalk_1.default.yellow('⚠ No test script found in package.json'));
|
|
29
|
+
console.log(chalk_1.default.gray('\nAdd a test script to your package.json:'));
|
|
30
|
+
console.log(chalk_1.default.gray(' "scripts": {'));
|
|
31
|
+
console.log(chalk_1.default.gray(' "test": "jest"'));
|
|
32
|
+
console.log(chalk_1.default.gray(' }'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
console.log(chalk_1.default.blue('🧪 Running tests...\n'));
|
|
36
|
+
let command = 'npm test';
|
|
37
|
+
const args = [];
|
|
38
|
+
if (pattern) {
|
|
39
|
+
args.push(pattern);
|
|
40
|
+
}
|
|
41
|
+
if (options?.watch) {
|
|
42
|
+
args.push('--watch');
|
|
43
|
+
}
|
|
44
|
+
if (options?.coverage) {
|
|
45
|
+
args.push('--coverage');
|
|
46
|
+
}
|
|
47
|
+
if (options?.ci) {
|
|
48
|
+
command = packageJson.scripts['test:ci'] ? 'npm run test:ci' : 'npm test -- --ci';
|
|
49
|
+
}
|
|
50
|
+
if (args.length > 0 && !options?.ci) {
|
|
51
|
+
command += ' -- ' + args.join(' ');
|
|
52
|
+
}
|
|
53
|
+
(0, child_process_1.execSync)(command, { stdio: 'inherit' });
|
|
54
|
+
if (!options?.watch) {
|
|
55
|
+
console.log(chalk_1.default.green('\n✓ Tests completed'));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
console.error(chalk_1.default.red('\n✗ Tests failed'));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const generate_module_1 = require("./commands/generate-module");
|
|
6
|
+
const generate_app_1 = require("./commands/generate-app");
|
|
7
|
+
const generate_controller_1 = require("./commands/generate-controller");
|
|
8
|
+
const generate_service_1 = require("./commands/generate-service");
|
|
9
|
+
const generate_dto_1 = require("./commands/generate-dto");
|
|
10
|
+
const generate_guard_1 = require("./commands/generate-guard");
|
|
11
|
+
const generate_interceptor_1 = require("./commands/generate-interceptor");
|
|
12
|
+
const generate_websocket_gateway_1 = require("./commands/generate-websocket-gateway");
|
|
13
|
+
const generate_exception_filter_1 = require("./commands/generate-exception-filter");
|
|
14
|
+
const generate_pipe_1 = require("./commands/generate-pipe");
|
|
15
|
+
const generate_repository_1 = require("./commands/generate-repository");
|
|
16
|
+
const generate_ai_service_1 = require("./commands/generate-ai-service");
|
|
17
|
+
const generate_agent_1 = require("./commands/generate-agent");
|
|
18
|
+
const generate_serverless_handler_1 = require("./commands/generate-serverless-handler");
|
|
19
|
+
const generate_crud_1 = require("./commands/generate-crud");
|
|
20
|
+
const generate_middleware_1 = require("./commands/generate-middleware");
|
|
21
|
+
const info_1 = require("./commands/info");
|
|
22
|
+
const add_1 = require("./commands/add");
|
|
23
|
+
const build_1 = require("./commands/build");
|
|
24
|
+
const start_1 = require("./commands/start");
|
|
25
|
+
const test_1 = require("./commands/test");
|
|
26
|
+
const program = new commander_1.Command();
|
|
27
|
+
program
|
|
28
|
+
.name('hazel')
|
|
29
|
+
.description('CLI for generating HazelJS components and applications')
|
|
30
|
+
.version('0.2.0');
|
|
31
|
+
// New app command
|
|
32
|
+
(0, generate_app_1.generateApp)(program);
|
|
33
|
+
// Utility commands
|
|
34
|
+
(0, info_1.infoCommand)(program);
|
|
35
|
+
(0, add_1.addCommand)(program);
|
|
36
|
+
(0, build_1.buildCommand)(program);
|
|
37
|
+
(0, start_1.startCommand)(program);
|
|
38
|
+
(0, test_1.testCommand)(program);
|
|
39
|
+
// Generate command group
|
|
40
|
+
const generateCommand = program
|
|
41
|
+
.command('generate')
|
|
42
|
+
.description('Generate HazelJS components')
|
|
43
|
+
.alias('g');
|
|
44
|
+
// Core components
|
|
45
|
+
(0, generate_controller_1.generateController)(generateCommand);
|
|
46
|
+
(0, generate_service_1.generateService)(generateCommand);
|
|
47
|
+
(0, generate_module_1.generateModule)(generateCommand);
|
|
48
|
+
(0, generate_dto_1.generateDto)(generateCommand);
|
|
49
|
+
(0, generate_guard_1.generateGuard)(generateCommand);
|
|
50
|
+
(0, generate_interceptor_1.generateInterceptor)(generateCommand);
|
|
51
|
+
(0, generate_middleware_1.generateMiddleware)(generateCommand);
|
|
52
|
+
// Advanced generators
|
|
53
|
+
(0, generate_crud_1.generateCrud)(generateCommand);
|
|
54
|
+
(0, generate_websocket_gateway_1.generateWebSocketGateway)(generateCommand);
|
|
55
|
+
(0, generate_exception_filter_1.generateExceptionFilter)(generateCommand);
|
|
56
|
+
(0, generate_pipe_1.generatePipe)(generateCommand);
|
|
57
|
+
(0, generate_repository_1.generateRepository)(generateCommand);
|
|
58
|
+
(0, generate_ai_service_1.generateAIService)(generateCommand);
|
|
59
|
+
(0, generate_agent_1.generateAgent)(generateCommand);
|
|
60
|
+
(0, generate_serverless_handler_1.generateServerlessHandler)(generateCommand);
|
|
61
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface GeneratorOptions {
|
|
2
|
+
name: string;
|
|
3
|
+
path?: string;
|
|
4
|
+
template?: string;
|
|
5
|
+
data?: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export declare class Generator {
|
|
8
|
+
generate(options: GeneratorOptions): Promise<void>;
|
|
9
|
+
protected toPascalCase(str: string): string;
|
|
10
|
+
protected toKebabCase(str: string): string;
|
|
11
|
+
protected getFilePath(name: string, customPath?: string): string;
|
|
12
|
+
protected getDefaultTemplate(): string;
|
|
13
|
+
promptForOptions(options: Partial<GeneratorOptions>): Promise<GeneratorOptions>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
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.Generator = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
11
|
+
const mustache_1 = __importDefault(require("mustache"));
|
|
12
|
+
class Generator {
|
|
13
|
+
async generate(options) {
|
|
14
|
+
const { name, path: customPath, template, data = {} } = options;
|
|
15
|
+
// Get the template
|
|
16
|
+
const templateContent = template || this.getDefaultTemplate();
|
|
17
|
+
// Prepare the data
|
|
18
|
+
const templateData = {
|
|
19
|
+
name,
|
|
20
|
+
className: this.toPascalCase(name),
|
|
21
|
+
fileName: this.toKebabCase(name),
|
|
22
|
+
...data,
|
|
23
|
+
};
|
|
24
|
+
// Render the template
|
|
25
|
+
const content = mustache_1.default.render(templateContent, templateData);
|
|
26
|
+
// Determine the file path
|
|
27
|
+
const filePath = this.getFilePath(name, customPath);
|
|
28
|
+
// Create directory if it doesn't exist
|
|
29
|
+
const dir = path_1.default.dirname(filePath);
|
|
30
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
31
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
// Write the file
|
|
34
|
+
fs_1.default.writeFileSync(filePath, content);
|
|
35
|
+
console.log(chalk_1.default.green(`✓ Generated ${filePath}`));
|
|
36
|
+
}
|
|
37
|
+
toPascalCase(str) {
|
|
38
|
+
return str
|
|
39
|
+
.split(/[-_]/)
|
|
40
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
41
|
+
.join('');
|
|
42
|
+
}
|
|
43
|
+
toKebabCase(str) {
|
|
44
|
+
return str
|
|
45
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
46
|
+
.replace(/[\s_]+/g, '-')
|
|
47
|
+
.toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
getFilePath(name, customPath) {
|
|
50
|
+
const fileName = this.toKebabCase(name);
|
|
51
|
+
const basePath = customPath || 'src';
|
|
52
|
+
return path_1.default.join(process.cwd(), basePath, `${fileName}.ts`);
|
|
53
|
+
}
|
|
54
|
+
getDefaultTemplate() {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
async promptForOptions(options) {
|
|
58
|
+
const answers = await inquirer_1.default.prompt([
|
|
59
|
+
{
|
|
60
|
+
type: 'input',
|
|
61
|
+
name: 'name',
|
|
62
|
+
message: 'What is the name of the component?',
|
|
63
|
+
when: !options.name,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'input',
|
|
67
|
+
name: 'path',
|
|
68
|
+
message: 'Where should the component be generated?',
|
|
69
|
+
default: 'src',
|
|
70
|
+
when: !options.path,
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
73
|
+
return {
|
|
74
|
+
...options,
|
|
75
|
+
...answers,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.Generator = Generator;
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hazeljs/cli",
|
|
3
|
+
"version": "0.2.0-beta.1",
|
|
4
|
+
"description": "Command-line interface for scaffolding and generating HazelJS applications and components",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"hazel": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"lint": "eslint src --ext .ts",
|
|
14
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
15
|
+
"prepare": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"chalk": "^4.1.2",
|
|
19
|
+
"commander": "^11.1.0",
|
|
20
|
+
"inquirer": "^8.2.6",
|
|
21
|
+
"mustache": "^4.2.0",
|
|
22
|
+
"ora": "^5.4.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/inquirer": "^8.2.6",
|
|
26
|
+
"@types/jest": "^29.5.12",
|
|
27
|
+
"@types/mustache": "^4.2.4",
|
|
28
|
+
"@types/node": "^20.11.24",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
|
30
|
+
"@typescript-eslint/parser": "^8.18.2",
|
|
31
|
+
"eslint": "^8.57.0",
|
|
32
|
+
"jest": "^29.7.0",
|
|
33
|
+
"prettier": "^3.2.5",
|
|
34
|
+
"ts-jest": "^29.1.2",
|
|
35
|
+
"typescript": "^5.3.3"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=14.0.0"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"hazeljs",
|
|
45
|
+
"cli",
|
|
46
|
+
"generator",
|
|
47
|
+
"scaffolding",
|
|
48
|
+
"code-generator",
|
|
49
|
+
"typescript",
|
|
50
|
+
"framework"
|
|
51
|
+
],
|
|
52
|
+
"author": "Muhammad Arslan <marslan@hazeljs.com>",
|
|
53
|
+
"license": "MIT",
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+https://github.com/hazel-js/hazeljs.git",
|
|
57
|
+
"directory": "packages/cli"
|
|
58
|
+
},
|
|
59
|
+
"bugs": {
|
|
60
|
+
"url": "https://github.com/hazeljs/hazel-js/issues"
|
|
61
|
+
},
|
|
62
|
+
"homepage": "https://hazeljs.com",
|
|
63
|
+
"funding": {
|
|
64
|
+
"type": "opencollective",
|
|
65
|
+
"url": "https://opencollective.com/hazeljs"
|
|
66
|
+
}
|
|
67
|
+
}
|