@hazeljs/cli 0.2.0-beta.54 → 0.2.0-beta.55

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 (61) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/add.test.d.ts +1 -0
  3. package/dist/commands/add.test.js +51 -0
  4. package/dist/commands/generate-agent.test.d.ts +1 -0
  5. package/dist/commands/generate-agent.test.js +36 -0
  6. package/dist/commands/generate-ai-service.js +2 -2
  7. package/dist/commands/generate-ai-service.test.d.ts +1 -0
  8. package/dist/commands/generate-ai-service.test.js +41 -0
  9. package/dist/commands/generate-app.js +1 -1
  10. package/dist/commands/generate-auth.js +2 -2
  11. package/dist/commands/generate-auth.test.d.ts +1 -0
  12. package/dist/commands/generate-auth.test.js +48 -0
  13. package/dist/commands/generate-cache.js +2 -2
  14. package/dist/commands/generate-cache.test.d.ts +1 -0
  15. package/dist/commands/generate-cache.test.js +36 -0
  16. package/dist/commands/generate-config.test.d.ts +1 -0
  17. package/dist/commands/generate-config.test.js +35 -0
  18. package/dist/commands/generate-controller.test.d.ts +1 -0
  19. package/dist/commands/generate-controller.test.js +48 -0
  20. package/dist/commands/generate-cron.js +2 -2
  21. package/dist/commands/generate-cron.test.d.ts +1 -0
  22. package/dist/commands/generate-cron.test.js +42 -0
  23. package/dist/commands/generate-crud.js +2 -2
  24. package/dist/commands/generate-crud.test.d.ts +1 -0
  25. package/dist/commands/generate-crud.test.js +52 -0
  26. package/dist/commands/generate-discovery.js +2 -2
  27. package/dist/commands/generate-discovery.test.d.ts +1 -0
  28. package/dist/commands/generate-discovery.test.js +36 -0
  29. package/dist/commands/generate-dto.test.d.ts +1 -0
  30. package/dist/commands/generate-dto.test.js +44 -0
  31. package/dist/commands/generate-exception-filter.test.d.ts +1 -0
  32. package/dist/commands/generate-exception-filter.test.js +43 -0
  33. package/dist/commands/generate-guard.test.d.ts +1 -0
  34. package/dist/commands/generate-guard.test.js +41 -0
  35. package/dist/commands/generate-interceptor.test.d.ts +1 -0
  36. package/dist/commands/generate-interceptor.test.js +41 -0
  37. package/dist/commands/generate-middleware.test.d.ts +1 -0
  38. package/dist/commands/generate-middleware.test.js +41 -0
  39. package/dist/commands/generate-module.js +2 -2
  40. package/dist/commands/generate-module.test.d.ts +1 -0
  41. package/dist/commands/generate-module.test.js +54 -0
  42. package/dist/commands/generate-pipe.test.d.ts +1 -0
  43. package/dist/commands/generate-pipe.test.js +35 -0
  44. package/dist/commands/generate-rag.js +2 -2
  45. package/dist/commands/generate-rag.test.d.ts +1 -0
  46. package/dist/commands/generate-rag.test.js +35 -0
  47. package/dist/commands/generate-repository.js +4 -5
  48. package/dist/commands/generate-repository.test.d.ts +1 -0
  49. package/dist/commands/generate-repository.test.js +41 -0
  50. package/dist/commands/generate-serverless-handler.test.d.ts +1 -0
  51. package/dist/commands/generate-serverless-handler.test.js +42 -0
  52. package/dist/commands/generate-service.js +2 -2
  53. package/dist/commands/generate-service.test.d.ts +1 -0
  54. package/dist/commands/generate-service.test.js +41 -0
  55. package/dist/commands/generate-websocket-gateway.test.d.ts +1 -0
  56. package/dist/commands/generate-websocket-gateway.test.js +41 -0
  57. package/dist/index.test.d.ts +1 -0
  58. package/dist/index.test.js +93 -0
  59. package/dist/utils/generator.test.d.ts +1 -0
  60. package/dist/utils/generator.test.js +137 -0
  61. package/package.json +2 -2
package/README.md CHANGED
@@ -675,4 +675,4 @@ Apache 2.0 © [HazelJS](https://hazeljs.com)
675
675
  - [Documentation](https://hazeljs.com/docs/packages/cli)
676
676
  - [GitHub](https://github.com/hazel-js/hazeljs)
677
677
  - [Issues](https://github.com/hazel-js/hazeljs/issues)
678
- - [Discord](https://discord.gg/hazeljs)
678
+ - [Discord](https://discord.com/channels/1448263814238965833/1448263814859456575)
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const child_process_1 = require("child_process");
4
+ const commander_1 = require("commander");
5
+ const add_1 = require("./add");
6
+ jest.mock('child_process');
7
+ jest.mock('inquirer');
8
+ describe('addCommand', () => {
9
+ const mockExecSync = child_process_1.execSync;
10
+ let program;
11
+ beforeEach(() => {
12
+ jest.clearAllMocks();
13
+ mockExecSync.mockImplementation(() => Buffer.from(''));
14
+ jest.spyOn(console, 'log').mockImplementation();
15
+ program = new commander_1.Command();
16
+ });
17
+ afterEach(() => {
18
+ jest.restoreAllMocks();
19
+ });
20
+ it('should register the add command', () => {
21
+ (0, add_1.addCommand)(program);
22
+ const cmd = program.commands.find(c => c.name() === 'add');
23
+ expect(cmd).toBeDefined();
24
+ });
25
+ it('should install a known package', async () => {
26
+ (0, add_1.addCommand)(program);
27
+ await program.parseAsync(['node', 'test', 'add', 'auth']);
28
+ expect(mockExecSync).toHaveBeenCalledWith(expect.stringContaining('@hazeljs/auth'), expect.objectContaining({ stdio: 'inherit' }));
29
+ });
30
+ it('should handle unknown packages gracefully', async () => {
31
+ const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
32
+ (0, add_1.addCommand)(program);
33
+ await program.parseAsync(['node', 'test', 'add', 'unknown-package']);
34
+ expect(mockExecSync).not.toHaveBeenCalled();
35
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Unknown package'));
36
+ consoleSpy.mockRestore();
37
+ });
38
+ it('should include all hazeljs packages', async () => {
39
+ (0, add_1.addCommand)(program);
40
+ // Test that all documented packages are available
41
+ const expectedPackages = [
42
+ 'ai', 'agent', 'auth', 'cache', 'config', 'cron',
43
+ 'discovery', 'prisma', 'typeorm', 'rag', 'serverless', 'swagger', 'websocket'
44
+ ];
45
+ for (const pkg of expectedPackages) {
46
+ mockExecSync.mockClear();
47
+ await program.parseAsync(['node', 'test', 'add', pkg]);
48
+ expect(mockExecSync).toHaveBeenCalledWith(expect.stringContaining(`@hazeljs/${pkg}`), expect.any(Object));
49
+ }
50
+ });
51
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_agent_1 = require("./generate-agent");
9
+ jest.mock('fs');
10
+ describe('generateAgent', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should generate an agent file with correct suffix', async () => {
24
+ (0, generate_agent_1.generateAgent)(program);
25
+ await program.parseAsync(['node', 'test', 'agent', 'research']);
26
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('research.agent.ts'), expect.stringContaining('ResearchAgent'));
27
+ });
28
+ it('should import from @hazeljs/agent', async () => {
29
+ (0, generate_agent_1.generateAgent)(program);
30
+ await program.parseAsync(['node', 'test', 'agent', 'research']);
31
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
32
+ expect(writtenContent).toContain("from '@hazeljs/agent'");
33
+ expect(writtenContent).toContain('@Agent');
34
+ expect(writtenContent).toContain('@Tool');
35
+ });
36
+ });
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateAIService = generateAIService;
4
4
  const generator_1 = require("../utils/generator");
5
- const AI_SERVICE_TEMPLATE = `import { Injectable } from '@hazeljs/core';
5
+ const AI_SERVICE_TEMPLATE = `import { Service } from '@hazeljs/core';
6
6
  import { AIService, AIFunction, AIPrompt } from '@hazeljs/ai';
7
7
 
8
- @Injectable()
8
+ @Service()
9
9
  export class {{className}}AIService {
10
10
  constructor(private readonly aiService: AIService) {}
11
11
 
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_ai_service_1 = require("./generate-ai-service");
9
+ jest.mock('fs');
10
+ describe('generateAIService', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should register the ai-service command with alias', () => {
24
+ (0, generate_ai_service_1.generateAIService)(program);
25
+ const cmd = program.commands.find(c => c.name() === 'ai-service');
26
+ expect(cmd).toBeDefined();
27
+ expect(cmd?.alias()).toBe('ai');
28
+ });
29
+ it('should generate an AI service file with correct suffix', async () => {
30
+ (0, generate_ai_service_1.generateAIService)(program);
31
+ await program.parseAsync(['node', 'test', 'ai-service', 'chat']);
32
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('chat.ai-service.ts'), expect.stringContaining('ChatAIService'));
33
+ });
34
+ it('should import from @hazeljs/ai', async () => {
35
+ (0, generate_ai_service_1.generateAIService)(program);
36
+ await program.parseAsync(['node', 'test', 'ai-service', 'chat']);
37
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
38
+ expect(writtenContent).toContain("from '@hazeljs/ai'");
39
+ expect(writtenContent).toContain('AIFunction');
40
+ });
41
+ });
@@ -430,7 +430,7 @@ coverage/
430
430
  }
431
431
  console.log(chalk_1.default.gray(' npm run dev'));
432
432
  console.log(chalk_1.default.gray('\nDocumentation: https://hazeljs.com/docs'));
433
- console.log(chalk_1.default.gray('Discord: https://discord.gg/hazeljs\n'));
433
+ console.log(chalk_1.default.gray('Discord: https://discord.com/channels/1448263814238965833/1448263814859456575\n'));
434
434
  }
435
435
  catch (error) {
436
436
  console.error(chalk_1.default.red('\n✗ Failed to create project:'), error);
@@ -20,12 +20,12 @@ import { JwtAuthGuard } from './jwt-auth.guard';
20
20
  })
21
21
  export class AuthModule {}
22
22
  `;
23
- const AUTH_SERVICE_TEMPLATE = `import { Injectable, BadRequestError, UnauthorizedError } from '@hazeljs/core';
23
+ const AUTH_SERVICE_TEMPLATE = `import { Service, BadRequestError, UnauthorizedError } from '@hazeljs/core';
24
24
  import { JwtService } from '@hazeljs/auth';
25
25
  import { RegisterDto } from './dto/register.dto';
26
26
  import { LoginDto } from './dto/login.dto';
27
27
 
28
- @Injectable()
28
+ @Service()
29
29
  export class AuthService {
30
30
  constructor(
31
31
  private readonly jwtService: JwtService,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_auth_1 = require("./generate-auth");
9
+ jest.mock('fs');
10
+ describe('generateAuth', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(false);
16
+ mockFs.mkdirSync.mockImplementation(() => undefined);
17
+ mockFs.writeFileSync.mockImplementation(() => { });
18
+ jest.spyOn(console, 'log').mockImplementation();
19
+ program = new commander_1.Command();
20
+ });
21
+ afterEach(() => {
22
+ jest.restoreAllMocks();
23
+ });
24
+ it('should generate all auth files', async () => {
25
+ (0, generate_auth_1.generateAuth)(program);
26
+ await program.parseAsync(['node', 'test', 'auth']);
27
+ const writtenFiles = mockFs.writeFileSync.mock.calls.map(call => call[0]);
28
+ expect(writtenFiles.some(f => f.includes('auth.module.ts'))).toBe(true);
29
+ expect(writtenFiles.some(f => f.includes('auth.service.ts'))).toBe(true);
30
+ expect(writtenFiles.some(f => f.includes('auth.controller.ts'))).toBe(true);
31
+ expect(writtenFiles.some(f => f.includes('jwt-auth.guard.ts'))).toBe(true);
32
+ expect(writtenFiles.some(f => f.includes('register.dto.ts'))).toBe(true);
33
+ expect(writtenFiles.some(f => f.includes('login.dto.ts'))).toBe(true);
34
+ });
35
+ it('should use @hazeljs/auth imports in guard', async () => {
36
+ (0, generate_auth_1.generateAuth)(program);
37
+ await program.parseAsync(['node', 'test', 'auth']);
38
+ const guardContent = mockFs.writeFileSync.mock.calls
39
+ .find(call => call[0].includes('jwt-auth.guard'))?.[1];
40
+ expect(guardContent).toContain("from '@hazeljs/auth'");
41
+ expect(guardContent).toContain('JwtService');
42
+ });
43
+ it('should support --dry-run flag', async () => {
44
+ (0, generate_auth_1.generateAuth)(program);
45
+ await program.parseAsync(['node', 'test', 'auth', '--dry-run']);
46
+ expect(mockFs.writeFileSync).not.toHaveBeenCalled();
47
+ });
48
+ });
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateCache = generateCache;
7
7
  const generator_1 = require("../utils/generator");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const CACHE_SERVICE_TEMPLATE = `import { Injectable } from '@hazeljs/core';
9
+ const CACHE_SERVICE_TEMPLATE = `import { Service } from '@hazeljs/core';
10
10
  import { CacheService, Cacheable, CacheEvict } from '@hazeljs/cache';
11
11
 
12
- @Injectable()
12
+ @Service()
13
13
  export class {{className}}CacheService {
14
14
  constructor(private readonly cacheService: CacheService) {}
15
15
 
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_cache_1 = require("./generate-cache");
9
+ jest.mock('fs');
10
+ describe('generateCache', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should generate a cache service file', async () => {
24
+ (0, generate_cache_1.generateCache)(program);
25
+ await program.parseAsync(['node', 'test', 'cache', 'product']);
26
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('product.cache.ts'), expect.stringContaining('ProductCacheService'));
27
+ });
28
+ it('should import from @hazeljs/cache', async () => {
29
+ (0, generate_cache_1.generateCache)(program);
30
+ await program.parseAsync(['node', 'test', 'cache', 'product']);
31
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
32
+ expect(writtenContent).toContain("from '@hazeljs/cache'");
33
+ expect(writtenContent).toContain('@Cacheable');
34
+ expect(writtenContent).toContain('@CacheEvict');
35
+ });
36
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_config_1 = require("./generate-config");
9
+ jest.mock('fs');
10
+ describe('generateConfig', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should generate a config module file', async () => {
24
+ (0, generate_config_1.generateConfig)(program);
25
+ await program.parseAsync(['node', 'test', 'config']);
26
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('app.config.ts'), expect.stringContaining('ConfigModule'));
27
+ });
28
+ it('should import from @hazeljs/config', async () => {
29
+ (0, generate_config_1.generateConfig)(program);
30
+ await program.parseAsync(['node', 'test', 'config']);
31
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
32
+ expect(writtenContent).toContain("from '@hazeljs/config'");
33
+ expect(writtenContent).toContain('ConfigService');
34
+ });
35
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_controller_1 = require("./generate-controller");
9
+ jest.mock('fs');
10
+ describe('generateController', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should register the controller command with alias', () => {
24
+ (0, generate_controller_1.generateController)(program);
25
+ const cmd = program.commands.find(c => c.name() === 'controller');
26
+ expect(cmd).toBeDefined();
27
+ expect(cmd?.alias()).toBe('c');
28
+ });
29
+ it('should generate a controller file with correct suffix', async () => {
30
+ (0, generate_controller_1.generateController)(program);
31
+ await program.parseAsync(['node', 'test', 'controller', 'user']);
32
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('user.controller.ts'), expect.stringContaining('UserController'));
33
+ });
34
+ it('should include proper imports from @hazeljs/core', async () => {
35
+ (0, generate_controller_1.generateController)(program);
36
+ await program.parseAsync(['node', 'test', 'controller', 'user']);
37
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
38
+ expect(writtenContent).toContain("from '@hazeljs/core'");
39
+ expect(writtenContent).toContain('Controller');
40
+ expect(writtenContent).toContain('Get');
41
+ expect(writtenContent).toContain('Post');
42
+ });
43
+ it('should support --dry-run flag', async () => {
44
+ (0, generate_controller_1.generateController)(program);
45
+ await program.parseAsync(['node', 'test', 'controller', 'user', '--dry-run']);
46
+ expect(mockFs.writeFileSync).not.toHaveBeenCalled();
47
+ });
48
+ });
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateCron = generateCron;
7
7
  const generator_1 = require("../utils/generator");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const CRON_SERVICE_TEMPLATE = `import { Injectable } from '@hazeljs/core';
9
+ const CRON_SERVICE_TEMPLATE = `import { Service } from '@hazeljs/core';
10
10
  import { Cron, CronExpression } from '@hazeljs/cron';
11
11
 
12
- @Injectable()
12
+ @Service()
13
13
  export class {{className}}CronService {
14
14
  @Cron(CronExpression.EVERY_MINUTE)
15
15
  handleEveryMinute() {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_cron_1 = require("./generate-cron");
9
+ jest.mock('fs');
10
+ describe('generateCron', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should register the cron command with alias', () => {
24
+ (0, generate_cron_1.generateCron)(program);
25
+ const cmd = program.commands.find(c => c.name() === 'cron');
26
+ expect(cmd).toBeDefined();
27
+ expect(cmd?.alias()).toBe('job');
28
+ });
29
+ it('should generate a cron service file', async () => {
30
+ (0, generate_cron_1.generateCron)(program);
31
+ await program.parseAsync(['node', 'test', 'cron', 'cleanup']);
32
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('cleanup.cron.ts'), expect.stringContaining('CleanupCronService'));
33
+ });
34
+ it('should import from @hazeljs/cron', async () => {
35
+ (0, generate_cron_1.generateCron)(program);
36
+ await program.parseAsync(['node', 'test', 'cron', 'cleanup']);
37
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
38
+ expect(writtenContent).toContain("from '@hazeljs/cron'");
39
+ expect(writtenContent).toContain('@Cron');
40
+ expect(writtenContent).toContain('CronExpression');
41
+ });
42
+ });
@@ -42,10 +42,10 @@ export class {{className}}Controller {
42
42
  }
43
43
  }
44
44
  `;
45
- const serviceTemplate = `import { Injectable } from '@hazeljs/core';
45
+ const serviceTemplate = `import { Service } from '@hazeljs/core';
46
46
  import { Create{{className}}Dto, Update{{className}}Dto } from './dto/{{fileName}}.dto';
47
47
 
48
- @Injectable()
48
+ @Service()
49
49
  export class {{className}}Service {
50
50
  private {{camelName}}s: any[] = [];
51
51
 
@@ -0,0 +1 @@
1
+ export {};
@@ -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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_crud_1 = require("./generate-crud");
9
+ jest.mock('fs');
10
+ describe('generateCrud', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(false);
16
+ mockFs.mkdirSync.mockImplementation(() => undefined);
17
+ mockFs.writeFileSync.mockImplementation(() => { });
18
+ jest.spyOn(console, 'log').mockImplementation();
19
+ program = new commander_1.Command();
20
+ });
21
+ afterEach(() => {
22
+ jest.restoreAllMocks();
23
+ });
24
+ it('should generate all CRUD files', async () => {
25
+ (0, generate_crud_1.generateCrud)(program);
26
+ await program.parseAsync(['node', 'test', 'crud', 'product']);
27
+ const writtenFiles = mockFs.writeFileSync.mock.calls.map(call => call[0]);
28
+ expect(writtenFiles.some(f => f.includes('product.controller.ts'))).toBe(true);
29
+ expect(writtenFiles.some(f => f.includes('product.service.ts'))).toBe(true);
30
+ expect(writtenFiles.some(f => f.includes('product.dto.ts'))).toBe(true);
31
+ expect(writtenFiles.some(f => f.includes('product.module.ts'))).toBe(true);
32
+ });
33
+ it('should use @hazeljs/core imports', async () => {
34
+ (0, generate_crud_1.generateCrud)(program);
35
+ await program.parseAsync(['node', 'test', 'crud', 'product']);
36
+ const controllerContent = mockFs.writeFileSync.mock.calls
37
+ .find(call => call[0].includes('controller'))?.[1];
38
+ expect(controllerContent).toContain("from '@hazeljs/core'");
39
+ });
40
+ it('should support --dry-run flag', async () => {
41
+ (0, generate_crud_1.generateCrud)(program);
42
+ await program.parseAsync(['node', 'test', 'crud', 'product', '--dry-run']);
43
+ expect(mockFs.writeFileSync).not.toHaveBeenCalled();
44
+ });
45
+ it('should support custom route path', async () => {
46
+ (0, generate_crud_1.generateCrud)(program);
47
+ await program.parseAsync(['node', 'test', 'crud', 'product', '-r', 'api/products']);
48
+ const controllerContent = mockFs.writeFileSync.mock.calls
49
+ .find(call => call[0].includes('controller'))?.[1];
50
+ expect(controllerContent).toContain('api/products');
51
+ });
52
+ });
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateDiscovery = generateDiscovery;
7
7
  const generator_1 = require("../utils/generator");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const DISCOVERY_TEMPLATE = `import { Injectable } from '@hazeljs/core';
9
+ const DISCOVERY_TEMPLATE = `import { Service } from '@hazeljs/core';
10
10
  import { ServiceRegistry, DiscoveryClient } from '@hazeljs/discovery';
11
11
 
12
- @Injectable()
12
+ @Service()
13
13
  export class {{className}}DiscoveryService {
14
14
  constructor(
15
15
  private readonly registry: ServiceRegistry,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_discovery_1 = require("./generate-discovery");
9
+ jest.mock('fs');
10
+ describe('generateDiscovery', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should generate a discovery service file', async () => {
24
+ (0, generate_discovery_1.generateDiscovery)(program);
25
+ await program.parseAsync(['node', 'test', 'discovery', 'app']);
26
+ expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('app.discovery.ts'), expect.stringContaining('AppDiscoveryService'));
27
+ });
28
+ it('should import from @hazeljs/discovery', async () => {
29
+ (0, generate_discovery_1.generateDiscovery)(program);
30
+ await program.parseAsync(['node', 'test', 'discovery', 'app']);
31
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
32
+ expect(writtenContent).toContain("from '@hazeljs/discovery'");
33
+ expect(writtenContent).toContain('ServiceRegistry');
34
+ expect(writtenContent).toContain('DiscoveryClient');
35
+ });
36
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const commander_1 = require("commander");
8
+ const generate_dto_1 = require("./generate-dto");
9
+ jest.mock('fs');
10
+ describe('generateDto', () => {
11
+ const mockFs = fs_1.default;
12
+ let program;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockFs.existsSync.mockReturnValue(true);
16
+ mockFs.writeFileSync.mockImplementation(() => { });
17
+ jest.spyOn(console, 'log').mockImplementation();
18
+ program = new commander_1.Command();
19
+ });
20
+ afterEach(() => {
21
+ jest.restoreAllMocks();
22
+ });
23
+ it('should register the dto command with alias', () => {
24
+ (0, generate_dto_1.generateDto)(program);
25
+ const cmd = program.commands.find(c => c.name() === 'dto');
26
+ expect(cmd).toBeDefined();
27
+ expect(cmd?.alias()).toBe('d');
28
+ });
29
+ it('should generate both create and update DTOs', async () => {
30
+ (0, generate_dto_1.generateDto)(program);
31
+ await program.parseAsync(['node', 'test', 'dto', 'user']);
32
+ expect(mockFs.writeFileSync).toHaveBeenCalledTimes(2);
33
+ const writtenFiles = mockFs.writeFileSync.mock.calls.map(call => call[0]);
34
+ expect(writtenFiles.some(f => f.includes('user.dto.ts'))).toBe(true);
35
+ expect(writtenFiles.some(f => f.includes('update-user.dto.ts'))).toBe(true);
36
+ });
37
+ it('should include class-validator decorators', async () => {
38
+ (0, generate_dto_1.generateDto)(program);
39
+ await program.parseAsync(['node', 'test', 'dto', 'user']);
40
+ const writtenContent = mockFs.writeFileSync.mock.calls[0][1];
41
+ expect(writtenContent).toContain('class-validator');
42
+ expect(writtenContent).toContain('IsString');
43
+ });
44
+ });
@@ -0,0 +1 @@
1
+ export {};