fragment-ts 1.0.2 → 1.0.3

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 (304) hide show
  1. package/README.md +401 -0
  2. package/USAGE.md +1439 -0
  3. package/bin/fragment.js +2 -0
  4. package/dist/ai/ai.module.d.ts +27 -0
  5. package/dist/ai/ai.module.d.ts.map +1 -0
  6. package/dist/ai/ai.module.js +77 -0
  7. package/dist/ai/ai.module.js.map +1 -0
  8. package/dist/auth/auth.module.d.ts +18 -0
  9. package/dist/auth/auth.module.d.ts.map +1 -0
  10. package/dist/auth/auth.module.js +89 -0
  11. package/dist/auth/auth.module.js.map +1 -0
  12. package/dist/cli/commands/build.command.d.ts +6 -1
  13. package/dist/cli/commands/build.command.d.ts.map +1 -0
  14. package/dist/cli/commands/build.command.js +130 -10
  15. package/dist/cli/commands/build.command.js.map +1 -1
  16. package/dist/cli/commands/diagnostics.command.d.ts +16 -0
  17. package/dist/cli/commands/diagnostics.command.d.ts.map +1 -0
  18. package/dist/cli/commands/diagnostics.command.js +419 -0
  19. package/dist/cli/commands/diagnostics.command.js.map +1 -0
  20. package/dist/cli/commands/generate.command.d.ts +13 -6
  21. package/dist/cli/commands/generate.command.d.ts.map +1 -0
  22. package/dist/cli/commands/generate.command.js +200 -128
  23. package/dist/cli/commands/generate.command.js.map +1 -1
  24. package/dist/cli/commands/init.command.d.ts +11 -5
  25. package/dist/cli/commands/init.command.d.ts.map +1 -0
  26. package/dist/cli/commands/init.command.js +267 -305
  27. package/dist/cli/commands/init.command.js.map +1 -1
  28. package/dist/cli/commands/migrate.command.d.ts +12 -5
  29. package/dist/cli/commands/migrate.command.d.ts.map +1 -0
  30. package/dist/cli/commands/migrate.command.js +211 -83
  31. package/dist/cli/commands/migrate.command.js.map +1 -1
  32. package/dist/cli/commands/serve.command.d.ts +5 -4
  33. package/dist/cli/commands/serve.command.d.ts.map +1 -0
  34. package/dist/cli/commands/serve.command.js +178 -21
  35. package/dist/cli/commands/serve.command.js.map +1 -1
  36. package/dist/cli/index.d.ts +2 -0
  37. package/dist/cli/index.d.ts.map +1 -0
  38. package/dist/cli/index.js +22 -0
  39. package/dist/cli/index.js.map +1 -0
  40. package/dist/core/container/di-container.d.ts +13 -7
  41. package/dist/core/container/di-container.d.ts.map +1 -0
  42. package/dist/core/container/di-container.js +75 -25
  43. package/dist/core/container/di-container.js.map +1 -1
  44. package/dist/core/decorators/application.decorator.d.ts +8 -0
  45. package/dist/core/decorators/application.decorator.d.ts.map +1 -0
  46. package/dist/core/decorators/application.decorator.js +16 -0
  47. package/dist/core/decorators/application.decorator.js.map +1 -0
  48. package/dist/core/decorators/auto-configuration.decorator.d.ts +2 -0
  49. package/dist/core/decorators/auto-configuration.decorator.d.ts.map +1 -0
  50. package/dist/core/decorators/auto-configuration.decorator.js +19 -0
  51. package/dist/core/decorators/auto-configuration.decorator.js.map +1 -0
  52. package/dist/core/decorators/conditional.decorators.d.ts +4 -0
  53. package/dist/core/decorators/conditional.decorators.d.ts.map +1 -0
  54. package/dist/core/decorators/conditional.decorators.js +22 -0
  55. package/dist/core/decorators/conditional.decorators.js.map +1 -0
  56. package/dist/core/decorators/controller.decorator.d.ts +1 -3
  57. package/dist/core/decorators/controller.decorator.d.ts.map +1 -0
  58. package/dist/core/decorators/controller.decorator.js +12 -9
  59. package/dist/core/decorators/controller.decorator.js.map +1 -1
  60. package/dist/core/decorators/http.decorators.d.ts +12 -0
  61. package/dist/core/decorators/http.decorators.d.ts.map +1 -0
  62. package/dist/core/decorators/http.decorators.js +52 -0
  63. package/dist/core/decorators/http.decorators.js.map +1 -0
  64. package/dist/core/decorators/injectable.decorator.d.ts +3 -3
  65. package/dist/core/decorators/injectable.decorator.d.ts.map +1 -0
  66. package/dist/core/decorators/injectable.decorator.js +11 -8
  67. package/dist/core/decorators/injectable.decorator.js.map +1 -1
  68. package/dist/core/decorators/injection.decorators.d.ts +5 -0
  69. package/dist/core/decorators/injection.decorators.d.ts.map +1 -0
  70. package/dist/core/decorators/injection.decorators.js +29 -0
  71. package/dist/core/decorators/injection.decorators.js.map +1 -0
  72. package/dist/core/decorators/repository.decorator.d.ts +1 -0
  73. package/dist/core/decorators/repository.decorator.d.ts.map +1 -0
  74. package/dist/core/decorators/repository.decorator.js +12 -1
  75. package/dist/core/decorators/repository.decorator.js.map +1 -1
  76. package/dist/core/decorators/service.decorator.d.ts +1 -0
  77. package/dist/core/decorators/service.decorator.d.ts.map +1 -0
  78. package/dist/core/decorators/service.decorator.js +12 -1
  79. package/dist/core/decorators/service.decorator.js.map +1 -1
  80. package/dist/core/index.d.ts +13 -0
  81. package/dist/core/index.d.ts.map +1 -0
  82. package/dist/core/index.js +29 -0
  83. package/dist/core/index.js.map +1 -0
  84. package/dist/core/loader/file-loader.d.ts +5 -0
  85. package/dist/core/loader/file-loader.d.ts.map +1 -0
  86. package/dist/core/loader/file-loader.js +85 -0
  87. package/dist/core/loader/file-loader.js.map +1 -0
  88. package/dist/core/metadata/metadata-keys.d.ts +20 -0
  89. package/dist/core/metadata/metadata-keys.d.ts.map +1 -0
  90. package/dist/core/metadata/metadata-keys.js +23 -0
  91. package/dist/core/metadata/metadata-keys.js.map +1 -0
  92. package/dist/core/metadata/metadata-storage.d.ts +36 -0
  93. package/dist/core/metadata/metadata-storage.d.ts.map +1 -0
  94. package/dist/core/metadata/metadata-storage.js +53 -0
  95. package/dist/core/metadata/metadata-storage.js.map +1 -0
  96. package/dist/core/scanner/component-scanner.d.ts +16 -0
  97. package/dist/core/scanner/component-scanner.d.ts.map +1 -0
  98. package/dist/core/scanner/component-scanner.js +147 -0
  99. package/dist/core/scanner/component-scanner.js.map +1 -0
  100. package/dist/index.d.ts +22 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +60 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/plugins/plugin-manager.d.ts +14 -0
  105. package/dist/plugins/plugin-manager.d.ts.map +1 -0
  106. package/dist/{cli/utils/file-generator.js → plugins/plugin-manager.js} +32 -24
  107. package/dist/plugins/plugin-manager.js.map +1 -0
  108. package/dist/shared/errors.d.ts +18 -0
  109. package/dist/shared/errors.d.ts.map +1 -0
  110. package/dist/shared/errors.js +41 -0
  111. package/dist/shared/errors.js.map +1 -0
  112. package/dist/testing/runner.d.ts +26 -0
  113. package/dist/testing/runner.d.ts.map +1 -0
  114. package/dist/testing/runner.js +143 -0
  115. package/dist/testing/runner.js.map +1 -0
  116. package/dist/typeorm/typeorm-module.d.ts +36 -0
  117. package/dist/typeorm/typeorm-module.d.ts.map +1 -0
  118. package/dist/typeorm/typeorm-module.js +150 -0
  119. package/dist/typeorm/typeorm-module.js.map +1 -0
  120. package/dist/web/application.d.ts +29 -0
  121. package/dist/web/application.d.ts.map +1 -0
  122. package/dist/web/application.js +301 -0
  123. package/dist/web/application.js.map +1 -0
  124. package/dist/web/interfaces.d.ts +14 -0
  125. package/dist/web/interfaces.d.ts.map +1 -0
  126. package/dist/{auth/dto/login.dto.js → web/interfaces.js} +1 -1
  127. package/dist/web/interfaces.js.map +1 -0
  128. package/examples/blog-api/fragment.json +14 -0
  129. package/examples/blog-api/package-lock.json +3405 -0
  130. package/examples/blog-api/package.json +19 -0
  131. package/examples/blog-api/src/controllers/app.controller.ts +9 -0
  132. package/examples/blog-api/src/controllers/auth.controller.ts +17 -0
  133. package/examples/blog-api/src/controllers/category.controller.ts +29 -0
  134. package/examples/blog-api/src/controllers/comment.controller.ts +31 -0
  135. package/examples/blog-api/src/controllers/post.controller.ts +46 -0
  136. package/examples/blog-api/src/dto/create-category.dto.ts +6 -0
  137. package/examples/blog-api/src/dto/create-comment.dto.ts +6 -0
  138. package/examples/blog-api/src/dto/create-post.dto.ts +6 -0
  139. package/examples/blog-api/src/entities/category.entity.ts +16 -0
  140. package/examples/blog-api/src/entities/comment.entity.ts +29 -0
  141. package/examples/blog-api/src/entities/post.entity.ts +42 -0
  142. package/examples/blog-api/src/entities/user.entity.ts +25 -0
  143. package/examples/blog-api/src/main.ts +16 -0
  144. package/examples/blog-api/src/migrations/1767737463842-InitialSchema.ts +60 -0
  145. package/examples/blog-api/src/repositories/category.repository.ts +25 -0
  146. package/examples/blog-api/src/repositories/comment.repository.ts +25 -0
  147. package/examples/blog-api/src/repositories/post.repository.ts +29 -0
  148. package/examples/blog-api/src/seeds/SampleData.seed.ts +41 -0
  149. package/examples/blog-api/src/services/app.service.ts +8 -0
  150. package/examples/blog-api/src/services/auth.service.ts +15 -0
  151. package/examples/blog-api/src/services/category.service.ts +27 -0
  152. package/examples/blog-api/src/services/comment.service.ts +31 -0
  153. package/examples/blog-api/src/services/post.service.ts +35 -0
  154. package/examples/blog-api/tsconfig.json +23 -0
  155. package/package.json +55 -33
  156. package/src/ai/ai.module.ts +110 -0
  157. package/src/auth/auth.module.ts +77 -0
  158. package/src/cli/commands/build.command.ts +123 -13
  159. package/src/cli/commands/diagnostics.command.ts +438 -0
  160. package/src/cli/commands/generate.command.ts +206 -137
  161. package/src/cli/commands/init.command.ts +337 -349
  162. package/src/cli/commands/migrate.command.ts +203 -88
  163. package/src/cli/commands/serve.command.ts +176 -24
  164. package/src/cli/index.ts +23 -0
  165. package/src/core/container/di-container.ts +83 -26
  166. package/src/core/decorators/application.decorator.ts +26 -0
  167. package/src/core/decorators/auto-configuration.decorator.ts +17 -0
  168. package/src/core/decorators/conditional.decorators.ts +19 -0
  169. package/src/core/decorators/controller.decorator.ts +14 -11
  170. package/src/core/decorators/http.decorators.ts +71 -0
  171. package/src/core/decorators/injectable.decorator.ts +14 -9
  172. package/src/core/decorators/injection.decorators.ts +26 -0
  173. package/src/core/decorators/repository.decorator.ts +13 -2
  174. package/src/core/decorators/service.decorator.ts +13 -2
  175. package/src/core/index.ts +13 -0
  176. package/src/core/loader/file-loader.ts +55 -0
  177. package/src/core/metadata/metadata-keys.ts +19 -0
  178. package/src/core/metadata/metadata-storage.ts +91 -0
  179. package/src/core/scanner/component-scanner.ts +129 -0
  180. package/src/index.ts +45 -0
  181. package/src/plugins/plugin-manager.ts +52 -0
  182. package/src/shared/errors.ts +34 -0
  183. package/src/testing/runner.ts +143 -0
  184. package/src/typeorm/typeorm-module.ts +216 -0
  185. package/src/web/application.ts +348 -0
  186. package/src/web/interfaces.ts +17 -0
  187. package/tsconfig.json +8 -6
  188. package/.env.example +0 -0
  189. package/base.ts +0 -1810
  190. package/base2.ts +0 -968
  191. package/bin/frg.ts +0 -5
  192. package/config/fragment.lock.yaml +0 -0
  193. package/config/fragment.yaml +0 -0
  194. package/dist/app.d.ts +0 -15
  195. package/dist/app.js +0 -91
  196. package/dist/app.js.map +0 -1
  197. package/dist/auth/auth.controller.d.ts +0 -10
  198. package/dist/auth/auth.controller.js +0 -88
  199. package/dist/auth/auth.controller.js.map +0 -1
  200. package/dist/auth/auth.middleware.d.ts +0 -2
  201. package/dist/auth/auth.middleware.js +0 -25
  202. package/dist/auth/auth.middleware.js.map +0 -1
  203. package/dist/auth/auth.service.d.ts +0 -20
  204. package/dist/auth/auth.service.js +0 -144
  205. package/dist/auth/auth.service.js.map +0 -1
  206. package/dist/auth/dto/login.dto.d.ts +0 -9
  207. package/dist/auth/dto/login.dto.js.map +0 -1
  208. package/dist/cli/cli.d.ts +0 -12
  209. package/dist/cli/cli.js +0 -187
  210. package/dist/cli/cli.js.map +0 -1
  211. package/dist/cli/commands/config.command.d.ts +0 -6
  212. package/dist/cli/commands/config.command.js +0 -285
  213. package/dist/cli/commands/config.command.js.map +0 -1
  214. package/dist/cli/templates/controller.template.d.ts +0 -1
  215. package/dist/cli/templates/controller.template.js +0 -53
  216. package/dist/cli/templates/controller.template.js.map +0 -1
  217. package/dist/cli/templates/entity.template.d.ts +0 -1
  218. package/dist/cli/templates/entity.template.js +0 -24
  219. package/dist/cli/templates/entity.template.js.map +0 -1
  220. package/dist/cli/templates/repository.template.d.ts +0 -1
  221. package/dist/cli/templates/repository.template.js +0 -44
  222. package/dist/cli/templates/repository.template.js.map +0 -1
  223. package/dist/cli/templates/service.template.d.ts +0 -1
  224. package/dist/cli/templates/service.template.js +0 -44
  225. package/dist/cli/templates/service.template.js.map +0 -1
  226. package/dist/cli/utils/file-generator.d.ts +0 -9
  227. package/dist/cli/utils/file-generator.js.map +0 -1
  228. package/dist/cli/utils/logger.d.ts +0 -14
  229. package/dist/cli/utils/logger.js +0 -50
  230. package/dist/cli/utils/logger.js.map +0 -1
  231. package/dist/controllers/health.controller.d.ts +0 -13
  232. package/dist/controllers/health.controller.js +0 -51
  233. package/dist/controllers/health.controller.js.map +0 -1
  234. package/dist/core/config/config-loader.d.ts +0 -31
  235. package/dist/core/config/config-loader.js +0 -99
  236. package/dist/core/config/config-loader.js.map +0 -1
  237. package/dist/core/decorators/auth-guard.decorator.d.ts +0 -3
  238. package/dist/core/decorators/auth-guard.decorator.js +0 -19
  239. package/dist/core/decorators/auth-guard.decorator.js.map +0 -1
  240. package/dist/core/decorators/autowire.decorator.d.ts +0 -3
  241. package/dist/core/decorators/autowire.decorator.js +0 -18
  242. package/dist/core/decorators/autowire.decorator.js.map +0 -1
  243. package/dist/core/decorators/middleware.decorator.d.ts +0 -3
  244. package/dist/core/decorators/middleware.decorator.js +0 -21
  245. package/dist/core/decorators/middleware.decorator.js.map +0 -1
  246. package/dist/core/decorators/route.decorator.d.ts +0 -14
  247. package/dist/core/decorators/route.decorator.js +0 -33
  248. package/dist/core/decorators/route.decorator.js.map +0 -1
  249. package/dist/core/openai/openai-client.d.ts +0 -12
  250. package/dist/core/openai/openai-client.js +0 -94
  251. package/dist/core/openai/openai-client.js.map +0 -1
  252. package/dist/database/data-source.d.ts +0 -4
  253. package/dist/database/data-source.js +0 -27
  254. package/dist/database/data-source.js.map +0 -1
  255. package/dist/entities/session.entity.d.ts +0 -9
  256. package/dist/entities/session.entity.js +0 -46
  257. package/dist/entities/session.entity.js.map +0 -1
  258. package/dist/entities/user.entity.d.ts +0 -10
  259. package/dist/entities/user.entity.js +0 -49
  260. package/dist/entities/user.entity.js.map +0 -1
  261. package/dist/middlewares/logging.middleware.d.ts +0 -2
  262. package/dist/middlewares/logging.middleware.js +0 -29
  263. package/dist/middlewares/logging.middleware.js.map +0 -1
  264. package/dist/repositories/session.repository.d.ts +0 -9
  265. package/dist/repositories/session.repository.js +0 -51
  266. package/dist/repositories/session.repository.js.map +0 -1
  267. package/dist/repositories/user.repository.d.ts +0 -10
  268. package/dist/repositories/user.repository.js +0 -44
  269. package/dist/repositories/user.repository.js.map +0 -1
  270. package/dist/server.d.ts +0 -1
  271. package/dist/server.js +0 -31
  272. package/dist/server.js.map +0 -1
  273. package/dist/services/health.service.d.ts +0 -13
  274. package/dist/services/health.service.js +0 -45
  275. package/dist/services/health.service.js.map +0 -1
  276. package/readme.md +0 -120
  277. package/src/app.ts +0 -121
  278. package/src/auth/auth.controller.ts +0 -52
  279. package/src/auth/auth.middleware.ts +0 -27
  280. package/src/auth/auth.service.ts +0 -110
  281. package/src/auth/dto/login.dto.ts +0 -11
  282. package/src/cli/cli.ts +0 -212
  283. package/src/cli/commands/config.command.ts +0 -280
  284. package/src/cli/templates/controller.template.ts +0 -51
  285. package/src/cli/templates/entity.template.ts +0 -22
  286. package/src/cli/templates/repository.template.ts +0 -42
  287. package/src/cli/templates/service.template.ts +0 -42
  288. package/src/cli/utils/file-generator.ts +0 -37
  289. package/src/cli/utils/logger.ts +0 -52
  290. package/src/controllers/health.controller.ts +0 -24
  291. package/src/core/config/config-loader.ts +0 -98
  292. package/src/core/decorators/auth-guard.decorator.ts +0 -15
  293. package/src/core/decorators/autowire.decorator.ts +0 -18
  294. package/src/core/decorators/middleware.decorator.ts +0 -18
  295. package/src/core/decorators/route.decorator.ts +0 -33
  296. package/src/core/openai/openai-client.ts +0 -99
  297. package/src/database/data-source.ts +0 -29
  298. package/src/entities/session.entity.ts +0 -25
  299. package/src/entities/user.entity.ts +0 -27
  300. package/src/middlewares/logging.middleware.ts +0 -28
  301. package/src/repositories/session.repository.ts +0 -42
  302. package/src/repositories/user.repository.ts +0 -37
  303. package/src/server.ts +0 -32
  304. package/src/services/health.service.ts +0 -29
@@ -1,170 +1,239 @@
1
-
1
+ import { Command } from 'commander';
2
+ import * as fs from 'fs-extra';
2
3
  import * as path from 'path';
3
- import { CLILogger } from '../utils/logger';
4
- import { FileGenerator } from '../utils/file-generator';
5
- import inquirer from 'inquirer';
6
- import { controllerTemplate } from '../templates/controller.template';
7
- import { entityTemplate } from '../templates/entity.template';
8
- import { repositoryTemplate } from '../templates/repository.template';
9
- import { serviceTemplate } from '../templates/service.template';
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
10
6
 
11
7
  export class GenerateCommand {
12
- async execute(type: string, name?: string): Promise<void> {
13
- if (!name) {
14
- const answer = await inquirer.prompt([
15
- {
16
- type: 'input',
17
- name: 'name',
18
- message: `Enter ${type} name:`,
19
- validate: (input: string) => {
20
- if (!input) return 'Name is required';
21
- return true;
22
- }
23
- }
24
- ]);
25
- name = answer.name;
26
- }
8
+ static register(program: Command): void {
9
+ program
10
+ .command('generate <type> <name>')
11
+ .alias('g')
12
+ .description('Generate a new resource')
13
+ .option('--with-repository', 'Generate repository for service')
14
+ .action(async (type, name, options) => {
15
+ await GenerateCommand.execute(type, name, options);
16
+ });
17
+ }
27
18
 
28
- const pascalName = FileGenerator.toPascalCase(name!);
29
- const kebabName = FileGenerator.toKebabCase(name!);
30
-
31
- switch (type) {
32
- case 'controller':
33
- await this.generateController(pascalName, kebabName);
34
- break;
35
- case 'service':
36
- await this.generateService(pascalName, kebabName);
37
- break;
38
- case 'repository':
39
- await this.generateRepository(pascalName, kebabName);
40
- break;
41
- case 'entity':
42
- await this.generateEntity(pascalName, kebabName);
43
- break;
44
- case 'resource':
45
- await this.generateResource(pascalName, kebabName);
46
- break;
47
- default:
48
- CLILogger.error(`Unknown type: ${type}`);
49
- CLILogger.info('Available types: controller, service, repository, entity, resource');
19
+ static async execute(type: string, name: string, options: any): Promise<void> {
20
+ const spinner = ora();
21
+
22
+ try {
23
+ spinner.start(`Generating ${type}...`);
24
+
25
+ switch (type) {
26
+ case 'controller':
27
+ await this.generateController(name);
28
+ break;
29
+ case 'service':
30
+ await this.generateService(name, options.withRepository);
31
+ break;
32
+ case 'resource':
33
+ await this.generateResource(name);
34
+ break;
35
+ case 'entity':
36
+ await this.generateEntity(name);
37
+ break;
38
+ case 'dto':
39
+ await this.generateDto(name);
40
+ break;
41
+ case 'repository':
42
+ await this.generateRepository(name);
43
+ break;
44
+ default:
45
+ spinner.fail(`Unknown type: ${type}`);
46
+ return;
47
+ }
48
+
49
+ spinner.succeed(`${type} generated successfully!`);
50
+ } catch (error) {
51
+ spinner.fail(`Failed to generate ${type}`);
52
+ console.error(chalk.red(error));
50
53
  }
51
54
  }
52
55
 
53
- private async generateController(name: string, fileName: string): Promise<void> {
54
- const answers = await inquirer.prompt([
55
- {
56
- type: 'input',
57
- name: 'route',
58
- message: 'Route path:',
59
- default: `/api/${fileName}s`
60
- }
61
- ]);
56
+ private static async generateController(name: string): Promise<void> {
57
+ const className = this.capitalize(name) + 'Controller';
58
+ const fileName = this.kebabCase(name) + '.controller.ts';
59
+ const filePath = path.join(process.cwd(), 'src', 'controllers', fileName);
62
60
 
63
- const filePath = path.join(process.cwd(), 'src/controllers', `${fileName}.controller.ts`);
64
-
65
- if (FileGenerator.fileExists(filePath)) {
66
- CLILogger.error(`Controller ${name} already exists`);
67
- return;
68
- }
61
+ const content = `import { Controller, Get, Post, Put, Delete, Body, Param } from 'fragment-ts';
69
62
 
70
- const content = controllerTemplate(name, answers.route);
71
- FileGenerator.writeFile(filePath, content);
63
+ @Controller('/${this.kebabCase(name)}')
64
+ export class ${className} {
65
+ @Get()
66
+ findAll() {
67
+ return [];
68
+ }
72
69
 
73
- CLILogger.success(`Controller created: src/controllers/${fileName}.controller.ts`);
74
- CLILogger.info(`Route: ${answers.route}`);
70
+ @Get('/:id')
71
+ findOne(@Param('id') id: string) {
72
+ return { id };
75
73
  }
76
74
 
77
- private async generateService(name: string, fileName: string): Promise<void> {
78
- const filePath = path.join(process.cwd(), 'src/services', `${fileName}.service.ts`);
79
-
80
- if (FileGenerator.fileExists(filePath)) {
81
- CLILogger.error(`Service ${name} already exists`);
82
- return;
83
- }
75
+ @Post()
76
+ create(@Body() body: any) {
77
+ return body;
78
+ }
84
79
 
85
- const content = serviceTemplate(name);
86
- FileGenerator.writeFile(filePath, content);
80
+ @Put('/:id')
81
+ update(@Param('id') id: string, @Body() body: any) {
82
+ return { id, ...body };
83
+ }
87
84
 
88
- CLILogger.success(`Service created: src/services/${fileName}.service.ts`);
85
+ @Delete('/:id')
86
+ delete(@Param('id') id: string) {
87
+ return { deleted: true, id };
89
88
  }
89
+ }
90
+ `;
90
91
 
91
- private async generateRepository(name: string, fileName: string): Promise<void> {
92
- const answers = await inquirer.prompt([
93
- {
94
- type: 'input',
95
- name: 'entity',
96
- message: 'Entity name:',
97
- default: name.replace('Repository', '')
98
- }
99
- ]);
92
+ await fs.ensureDir(path.dirname(filePath));
93
+ await fs.writeFile(filePath, content);
94
+ }
100
95
 
101
- const filePath = path.join(process.cwd(), 'src/repositories', `${fileName}.repository.ts`);
96
+ private static async generateService(name: string, withRepository: boolean): Promise<void> {
97
+ const className = this.capitalize(name) + 'Service';
98
+ const fileName = this.kebabCase(name) + '.service.ts';
99
+ const filePath = path.join(process.cwd(), 'src', 'services', fileName);
100
+
101
+ let imports = "import { Service } from 'fragment-ts';\n";
102
+ let repositoryProp = '';
102
103
 
103
- if (FileGenerator.fileExists(filePath)) {
104
- CLILogger.error(`Repository ${name} already exists`);
105
- return;
104
+ if (withRepository) {
105
+ const repoName = this.capitalize(name) + 'Repository';
106
+ imports += `import { ${repoName} } from '../repositories/${this.kebabCase(name)}.repository';\n`;
107
+ repositoryProp = `\n constructor(private ${this.camelCase(name)}Repository: ${repoName}) {}\n`;
106
108
  }
107
109
 
108
- const content = repositoryTemplate(name, answers.entity);
109
- FileGenerator.writeFile(filePath, content);
110
+ const content = `${imports}
111
+ @Service()
112
+ export class ${className} {${repositoryProp}
113
+ async findAll() {
114
+ return [];
115
+ }
110
116
 
111
- CLILogger.success(`Repository created: src/repositories/${fileName}.repository.ts`);
117
+ async findOne(id: string) {
118
+ return { id };
112
119
  }
113
120
 
114
- private async generateEntity(name: string, fileName: string): Promise<void> {
115
- const filePath = path.join(process.cwd(), 'src/entities', `${fileName}.entity.ts`);
121
+ async create(data: any) {
122
+ return data;
123
+ }
124
+
125
+ async update(id: string, data: any) {
126
+ return { id, ...data };
127
+ }
128
+
129
+ async delete(id: string) {
130
+ return { deleted: true, id };
131
+ }
132
+ }
133
+ `;
134
+
135
+ await fs.ensureDir(path.dirname(filePath));
136
+ await fs.writeFile(filePath, content);
116
137
 
117
- if (FileGenerator.fileExists(filePath)) {
118
- CLILogger.error(`Entity ${name} already exists`);
119
- return;
138
+ if (withRepository) {
139
+ await this.generateRepository(name);
120
140
  }
141
+ }
142
+
143
+ private static async generateResource(name: string): Promise<void> {
144
+ await this.generateController(name);
145
+ await this.generateService(name, true);
146
+ await this.generateEntity(name);
147
+ await this.generateDto(name);
148
+ }
121
149
 
122
- const content = entityTemplate(name);
123
- FileGenerator.writeFile(filePath, content);
150
+ private static async generateEntity(name: string): Promise<void> {
151
+ const className = this.capitalize(name);
152
+ const fileName = this.kebabCase(name) + '.entity.ts';
153
+ const filePath = path.join(process.cwd(), 'src', 'entities', fileName);
124
154
 
125
- CLILogger.success(`Entity created: src/entities/${fileName}.entity.ts`);
155
+ const content = `import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
156
+
157
+ @Entity()
158
+ export class ${className} {
159
+ @PrimaryGeneratedColumn()
160
+ id: number;
161
+
162
+ @Column()
163
+ name: string;
164
+
165
+ @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
166
+ createdAt: Date;
167
+
168
+ @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP' })
169
+ updatedAt: Date;
170
+ }
171
+ `;
172
+
173
+ await fs.ensureDir(path.dirname(filePath));
174
+ await fs.writeFile(filePath, content);
126
175
  }
127
176
 
128
- private async generateResource(name: string, fileName: string): Promise<void> {
129
- CLILogger.title(`🔷 Generating resource: ${name}`);
177
+ private static async generateDto(name: string): Promise<void> {
178
+ const className = 'Create' + this.capitalize(name) + 'Dto';
179
+ const fileName = 'create-' + this.kebabCase(name) + '.dto.ts';
180
+ const filePath = path.join(process.cwd(), 'src', 'dto', fileName);
130
181
 
131
- const spinner = CLILogger.spinner('Generating files...');
182
+ const content = `export class ${className} {
183
+ name: string;
184
+ }
185
+ `;
132
186
 
133
- try {
134
- // Generate entity
135
- const entityPath = path.join(process.cwd(), 'src/entities', `${fileName}.entity.ts`);
136
- FileGenerator.writeFile(entityPath, entityTemplate(name));
137
- spinner.text = 'Entity created...';
138
-
139
- // Generate repository
140
- const repoPath = path.join(process.cwd(), 'src/repositories', `${fileName}.repository.ts`);
141
- FileGenerator.writeFile(repoPath, repositoryTemplate(name + 'Repository', name));
142
- spinner.text = 'Repository created...';
143
-
144
- // Generate service
145
- const servicePath = path.join(process.cwd(), 'src/services', `${fileName}.service.ts`);
146
- FileGenerator.writeFile(servicePath, serviceTemplate(name + 'Service'));
147
- spinner.text = 'Service created...';
148
-
149
- // Generate controller
150
- const controllerPath = path.join(process.cwd(), 'src/controllers', `${fileName}.controller.ts`);
151
- FileGenerator.writeFile(controllerPath, controllerTemplate(name + 'Controller', `/api/${fileName}s`));
152
- spinner.text = 'Controller created...';
153
-
154
- spinner.succeed('Resource generated successfully');
155
-
156
- CLILogger.box('📦 Generated Files', [
157
- `Entity: src/entities/${fileName}.entity.ts`,
158
- `Repository: src/repositories/${fileName}.repository.ts`,
159
- `Service: src/services/${fileName}.service.ts`,
160
- `Controller: src/controllers/${fileName}.controller.ts`
161
- ]);
162
-
163
- CLILogger.info(`\nRoute available at: /api/${fileName}s`);
164
-
165
- } catch (error: any) {
166
- spinner.fail('Failed to generate resource');
167
- CLILogger.error(error.message);
168
- }
187
+ await fs.ensureDir(path.dirname(filePath));
188
+ await fs.writeFile(filePath, content);
189
+ }
190
+
191
+ private static async generateRepository(name: string): Promise<void> {
192
+ const className = this.capitalize(name) + 'Repository';
193
+ const entityName = this.capitalize(name);
194
+ const fileName = this.kebabCase(name) + '.repository.ts';
195
+ const filePath = path.join(process.cwd(), 'src', 'repositories', fileName);
196
+
197
+ const content = `import { Repository } from 'fragment-ts';
198
+ import { ${entityName} } from '../entities/${this.kebabCase(name)}.entity';
199
+
200
+ @Repository()
201
+ export class ${className} {
202
+ async findAll(): Promise<${entityName}[]> {
203
+ return [];
204
+ }
205
+
206
+ async findById(id: number): Promise<${entityName} | null> {
207
+ return null;
208
+ }
209
+
210
+ async create(data: Partial<${entityName}>): Promise<${entityName}> {
211
+ return data as ${entityName};
212
+ }
213
+
214
+ async update(id: number, data: Partial<${entityName}>): Promise<${entityName} | null> {
215
+ return null;
216
+ }
217
+
218
+ async delete(id: number): Promise<boolean> {
219
+ return true;
220
+ }
221
+ }
222
+ `;
223
+
224
+ await fs.ensureDir(path.dirname(filePath));
225
+ await fs.writeFile(filePath, content);
226
+ }
227
+
228
+ private static capitalize(str: string): string {
229
+ return str.charAt(0).toUpperCase() + str.slice(1);
230
+ }
231
+
232
+ private static kebabCase(str: string): string {
233
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
234
+ }
235
+
236
+ private static camelCase(str: string): string {
237
+ return str.charAt(0).toLowerCase() + str.slice(1);
169
238
  }
170
239
  }