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,118 +1,233 @@
1
-
2
- import { execSync } from 'child_process';
3
- import { CLILogger } from '../utils/logger';
4
- import inquirer from 'inquirer';
1
+ import { Command } from 'commander';
2
+ import * as fs from 'fs-extra';
3
+ import * as path from 'path';
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { TypeORMModule } from '../../typeorm/typeorm-module';
5
7
 
6
8
  export class MigrateCommand {
7
- async execute(action?: string): Promise<void> {
8
- if (!action) {
9
- const answer = await inquirer.prompt([
10
- {
11
- type: 'list',
12
- name: 'action',
13
- message: 'Select migration action:',
14
- choices: [
15
- { name: 'Run pending migrations', value: 'run' },
16
- { name: 'Generate new migration', value: 'generate' },
17
- { name: 'Revert last migration', value: 'revert' },
18
- { name: 'Show migration status', value: 'show' }
19
- ]
20
- }
21
- ]);
22
- action = answer.action;
23
- }
9
+ static register(program: Command): void {
10
+ program
11
+ .command('migrate')
12
+ .description('Run all pending migrations')
13
+ .action(async () => {
14
+ await this.runMigrations();
15
+ });
24
16
 
25
- switch (action) {
26
- case 'run':
17
+ program
18
+ .command('migrate:create <name>')
19
+ .description('Create a new migration')
20
+ .action(async (name) => {
21
+ await this.createMigration(name);
22
+ });
23
+
24
+ program
25
+ .command('migrate:run')
26
+ .description('Run pending migrations')
27
+ .action(async () => {
27
28
  await this.runMigrations();
28
- break;
29
- case 'generate':
30
- await this.generateMigration();
31
- break;
32
- case 'revert':
29
+ });
30
+
31
+ program
32
+ .command('migrate:revert')
33
+ .description('Revert the last migration')
34
+ .action(async () => {
33
35
  await this.revertMigration();
34
- break;
35
- case 'show':
36
- await this.showMigrations();
37
- break;
38
- default:
39
- CLILogger.error(`Unknown action: ${action}`);
40
- }
36
+ });
37
+
38
+ program
39
+ .command('migrate:refresh')
40
+ .description('Rollback all migrations and re-run them')
41
+ .action(async () => {
42
+ await this.refreshMigrations();
43
+ });
44
+
45
+ program
46
+ .command('migrate:status')
47
+ .description('Show migration status')
48
+ .action(async () => {
49
+ await this.showStatus();
50
+ });
51
+
52
+ program
53
+ .command('schema:sync')
54
+ .description('Synchronize database schema')
55
+ .action(async () => {
56
+ await this.syncSchema();
57
+ });
58
+
59
+ program
60
+ .command('schema:drop')
61
+ .description('Drop database schema')
62
+ .action(async () => {
63
+ await this.dropSchema();
64
+ });
65
+
66
+ program
67
+ .command('seed')
68
+ .description('Run database seeds')
69
+ .action(async () => {
70
+ await this.runSeeds();
71
+ });
72
+
73
+ program
74
+ .command('seed:create <name>')
75
+ .description('Create a new seed file')
76
+ .action(async (name) => {
77
+ await this.createSeed(name);
78
+ });
41
79
  }
42
80
 
43
- private async runMigrations(): Promise<void> {
44
- CLILogger.title('šŸ“¦ Running Migrations');
45
- const spinner = CLILogger.spinner('Executing migrations...');
81
+ private static async createMigration(name: string): Promise<void> {
82
+ const spinner = ora('Creating migration...').start();
83
+
84
+ try {
85
+ const timestamp = Date.now();
86
+ const fileName = `${timestamp}-${name}.ts`;
87
+ const filePath = path.join(process.cwd(), 'src', 'migrations', fileName);
46
88
 
89
+ const content = `import { MigrationInterface, QueryRunner } from 'typeorm';
90
+
91
+ export class ${name}${timestamp} implements MigrationInterface {
92
+ async up(queryRunner: QueryRunner): Promise<void> {
93
+ // Add migration code here
94
+ }
95
+
96
+ async down(queryRunner: QueryRunner): Promise<void> {
97
+ // Add revert code here
98
+ }
99
+ }
100
+ `;
101
+
102
+ await fs.ensureDir(path.dirname(filePath));
103
+ await fs.writeFile(filePath, content);
104
+
105
+ spinner.succeed(`Migration created: ${fileName}`);
106
+ } catch (error) {
107
+ spinner.fail('Failed to create migration');
108
+ console.error(chalk.red(error));
109
+ }
110
+ }
111
+
112
+ private static async runMigrations(): Promise<void> {
113
+ const spinner = ora('Running migrations...').start();
114
+
47
115
  try {
48
- execSync('npm run typeorm migration:run', { stdio: 'pipe' });
49
- spinner.succeed('Migrations executed successfully');
50
- } catch (error: any) {
116
+ await TypeORMModule.initialize();
117
+ await TypeORMModule.runMigrations();
118
+ spinner.succeed('Migrations completed successfully');
119
+ } catch (error) {
51
120
  spinner.fail('Migration failed');
52
- CLILogger.error(error.message);
121
+ console.error(chalk.red(error));
53
122
  }
54
123
  }
55
124
 
56
- private async generateMigration(): Promise<void> {
57
- const answer = await inquirer.prompt([
58
- {
59
- type: 'input',
60
- name: 'name',
61
- message: 'Migration name:',
62
- validate: (input: string) => {
63
- if (!input) return 'Name is required';
64
- return true;
65
- }
66
- }
67
- ]);
68
-
69
- CLILogger.title(`šŸ“ Generating Migration: ${answer.name}`);
70
- const spinner = CLILogger.spinner('Creating migration file...');
125
+ private static async revertMigration(): Promise<void> {
126
+ const spinner = ora('Reverting migration...').start();
127
+
128
+ try {
129
+ await TypeORMModule.initialize();
130
+ await TypeORMModule.revertMigration();
131
+ spinner.succeed('Migration reverted successfully');
132
+ } catch (error) {
133
+ spinner.fail('Revert failed');
134
+ console.error(chalk.red(error));
135
+ }
136
+ }
71
137
 
138
+ private static async refreshMigrations(): Promise<void> {
139
+ const spinner = ora('Refreshing migrations...').start();
140
+
72
141
  try {
73
- execSync(`npm run typeorm migration:generate -- -n ${answer.name}`, { stdio: 'pipe' });
74
- spinner.succeed('Migration generated successfully');
75
- } catch (error: any) {
76
- spinner.fail('Failed to generate migration');
77
- CLILogger.error(error.message);
142
+ await TypeORMModule.initialize();
143
+ await TypeORMModule.dropSchema();
144
+ await TypeORMModule.runMigrations();
145
+ spinner.succeed('Migrations refreshed successfully');
146
+ } catch (error) {
147
+ spinner.fail('Refresh failed');
148
+ console.error(chalk.red(error));
78
149
  }
79
150
  }
80
151
 
81
- private async revertMigration(): Promise<void> {
82
- const confirm = await inquirer.prompt([
83
- {
84
- type: 'confirm',
85
- name: 'confirmed',
86
- message: 'Are you sure you want to revert the last migration?',
87
- default: false
88
- }
89
- ]);
152
+ private static async showStatus(): Promise<void> {
153
+ console.log(chalk.blue('Migration Status:'));
154
+ console.log(' Implement status checking using TypeORM QueryRunner');
155
+ }
90
156
 
91
- if (!confirm.confirmed) {
92
- CLILogger.info('Migration revert cancelled');
93
- return;
157
+ private static async syncSchema(): Promise<void> {
158
+ const spinner = ora('Synchronizing schema...').start();
159
+
160
+ try {
161
+ await TypeORMModule.initialize();
162
+ await TypeORMModule.syncSchema();
163
+ spinner.succeed('Schema synchronized');
164
+ } catch (error) {
165
+ spinner.fail('Sync failed');
166
+ console.error(chalk.red(error));
94
167
  }
168
+ }
95
169
 
96
- CLILogger.title('āŖ Reverting Migration');
97
- const spinner = CLILogger.spinner('Reverting last migration...');
98
-
170
+ private static async dropSchema(): Promise<void> {
171
+ const spinner = ora('Dropping schema...').start();
172
+
99
173
  try {
100
- execSync('npm run typeorm migration:revert', { stdio: 'pipe' });
101
- spinner.succeed('Migration reverted successfully');
102
- } catch (error: any) {
103
- spinner.fail('Failed to revert migration');
104
- CLILogger.error(error.message);
174
+ await TypeORMModule.initialize();
175
+ await TypeORMModule.dropSchema();
176
+ spinner.succeed('Schema dropped');
177
+ } catch (error) {
178
+ spinner.fail('Drop failed');
179
+ console.error(chalk.red(error));
105
180
  }
106
181
  }
107
182
 
108
- private async showMigrations(): Promise<void> {
109
- CLILogger.title('šŸ“‹ Migration Status');
183
+ private static async runSeeds(): Promise<void> {
184
+ const spinner = ora('Running seeds...').start();
110
185
 
111
186
  try {
112
- const output = execSync('npm run typeorm migration:show', { encoding: 'utf-8' });
113
- console.log(output);
114
- } catch (error: any) {
115
- CLILogger.error('Failed to show migrations');
187
+ const seedsDir = path.join(process.cwd(), 'dist', 'seeds');
188
+
189
+ if (fs.existsSync(seedsDir)) {
190
+ const files = fs.readdirSync(seedsDir);
191
+
192
+ for (const file of files) {
193
+ if (file.endsWith('.js')) {
194
+ const seedModule = require(path.join(seedsDir, file));
195
+ if (seedModule.default && typeof seedModule.default.run === 'function') {
196
+ await seedModule.default.run();
197
+ }
198
+ }
199
+ }
200
+ }
201
+
202
+ spinner.succeed('Seeds completed successfully');
203
+ } catch (error) {
204
+ spinner.fail('Seed failed');
205
+ console.error(chalk.red(error));
116
206
  }
117
207
  }
208
+
209
+ private static async createSeed(name: string): Promise<void> {
210
+ const spinner = ora('Creating seed...').start();
211
+
212
+ try {
213
+ const fileName = `${name}.seed.ts`;
214
+ const filePath = path.join(process.cwd(), 'src', 'seeds', fileName);
215
+
216
+ const content = `export default class ${name}Seed {
217
+ static async run() {
218
+ console.log('Running ${name} seed...');
219
+ // Add seed logic here
220
+ }
118
221
  }
222
+ `;
223
+
224
+ await fs.ensureDir(path.dirname(filePath));
225
+ await fs.writeFile(filePath, content);
226
+
227
+ spinner.succeed(`Seed created: ${fileName}`);
228
+ } catch (error) {
229
+ spinner.fail('Failed to create seed');
230
+ console.error(chalk.red(error));
231
+ }
232
+ }
233
+ }
@@ -1,37 +1,189 @@
1
-
2
- import { spawn } from 'child_process';
3
- import { CLILogger } from '../utils/logger';
1
+ import { Command } from "commander";
2
+ import { spawn, ChildProcess, execSync } from "child_process";
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ import chalk from "chalk";
4
6
 
5
7
  export class ServeCommand {
6
- async execute(options: { port?: number; watch?: boolean }): Promise<void> {
7
- CLILogger.title('šŸš€ Starting Fragment Application');
8
+ static register(program: Command): void {
9
+ program
10
+ .command("serve")
11
+ .description("Start the development server")
12
+ .option("-w, --watch", "Watch for changes", true)
13
+ .option("-p, --port <port>", "Port to run on", "3000")
14
+ .action(async (options) => {
15
+ await ServeCommand.execute(options);
16
+ });
17
+ }
18
+
19
+ static async execute(options: any): Promise<void> {
20
+ console.log(chalk.blue("šŸš€ Starting Fragment development server...\n"));
21
+
22
+ const mainFile = path.join(process.cwd(), "src", "main.ts");
8
23
 
9
- const port = options.port || process.env.PORT || 3000;
10
- const args = ['--respawn', '--transpile-only'];
24
+ if (!fs.existsSync(mainFile)) {
25
+ console.error(chalk.red("Main file not found at src/main.ts"));
26
+ process.exit(1);
27
+ }
11
28
 
12
- if (options.watch !== false) {
13
- args.push('--watch');
29
+ // Find ts-node
30
+ const tsNode = this.findTsNode();
31
+ if (!tsNode) {
32
+ console.error(chalk.red("ts-node not found. Install it:"));
33
+ console.log(chalk.cyan(" npm install --save-dev ts-node"));
34
+ process.exit(1);
14
35
  }
15
36
 
16
- args.push('src/server.ts');
37
+ let appProcess: ChildProcess | null = null;
38
+ let isRestarting = false;
39
+
40
+ const startServer = () => {
41
+ if (isRestarting) return;
42
+
43
+ // Use ts-node directly instead of node with -r flag
44
+ appProcess = spawn(tsNode, [mainFile], {
45
+ stdio: "inherit",
46
+ env: { ...process.env, PORT: options.port },
47
+ });
48
+
49
+ appProcess.on("error", (error) => {
50
+ console.error(chalk.red(`Failed to start server: ${error.message}`));
51
+ });
17
52
 
18
- const env = { ...process.env, PORT: port.toString() };
53
+ appProcess.on("exit", (code, signal) => {
54
+ if (!isRestarting && signal !== "SIGTERM" && signal !== "SIGINT") {
55
+ console.error(chalk.red(`Server exited with code ${code}`));
56
+ }
57
+ });
58
+ };
19
59
 
20
- CLILogger.info(`Starting server on port ${port}...`);
60
+ const killServer = (): Promise<void> => {
61
+ return new Promise((resolve) => {
62
+ if (!appProcess || appProcess.killed) {
63
+ resolve();
64
+ return;
65
+ }
21
66
 
22
- const child = spawn('ts-node-dev', args, {
23
- env,
24
- stdio: 'inherit'
25
- });
67
+ const timeout = setTimeout(() => {
68
+ if (appProcess && !appProcess.killed) {
69
+ console.log(chalk.yellow("Force killing server..."));
70
+ appProcess.kill("SIGKILL");
71
+ }
72
+ resolve();
73
+ }, 3000);
26
74
 
27
- child.on('error', (error) => {
28
- CLILogger.error(`Failed to start server: ${error.message}`);
29
- });
75
+ appProcess.once("exit", () => {
76
+ clearTimeout(timeout);
77
+ appProcess = null;
78
+ resolve();
79
+ });
30
80
 
31
- child.on('close', (code) => {
32
- if (code !== 0) {
33
- CLILogger.error(`Server exited with code ${code}`);
81
+ appProcess.kill("SIGTERM");
82
+ });
83
+ };
84
+
85
+ const restartServer = async (filePath?: string) => {
86
+ if (isRestarting) return;
87
+ isRestarting = true;
88
+
89
+ if (filePath) {
90
+ console.log(
91
+ chalk.yellow(
92
+ `\nšŸ”„ File changed: ${path.relative(process.cwd(), filePath)}`,
93
+ ),
94
+ );
34
95
  }
35
- });
96
+ console.log(chalk.blue("Restarting server...\n"));
97
+
98
+ await killServer();
99
+
100
+ // Wait a bit for port to be released
101
+ await new Promise((resolve) => setTimeout(resolve, 500));
102
+
103
+ isRestarting = false;
104
+ startServer();
105
+ };
106
+
107
+ // Start initial server
108
+ startServer();
109
+
110
+ // Watch for changes
111
+ if (options.watch) {
112
+ try {
113
+ const chokidar = await import("chokidar");
114
+
115
+ const watcher = chokidar.watch("src/**/*.ts", {
116
+ ignored: /(^|[/\\])\../,
117
+ persistent: true,
118
+ ignoreInitial: true,
119
+ });
120
+
121
+ let debounceTimer: NodeJS.Timeout | null = null;
122
+
123
+ watcher.on("change", (filePath) => {
124
+ // Debounce rapid changes
125
+ if (debounceTimer) {
126
+ clearTimeout(debounceTimer);
127
+ }
128
+
129
+ debounceTimer = setTimeout(() => {
130
+ restartServer(filePath);
131
+ }, 300);
132
+ });
133
+
134
+ watcher.on("error", (error) => {
135
+ console.error(chalk.red(`Watcher error: ${error}`));
136
+ });
137
+
138
+ // Cleanup on exit
139
+ const cleanup = async () => {
140
+ console.log(chalk.yellow("\n\nšŸ›‘ Shutting down..."));
141
+ watcher.close();
142
+ await killServer();
143
+ process.exit(0);
144
+ };
145
+
146
+ process.on("SIGINT", cleanup);
147
+ process.on("SIGTERM", cleanup);
148
+ } catch (error) {
149
+ console.error(
150
+ chalk.red(
151
+ "Failed to start file watcher. Install chokidar: npm install chokidar",
152
+ ),
153
+ );
154
+ process.exit(1);
155
+ }
156
+ } else {
157
+ // No watch mode - just handle cleanup
158
+ const cleanup = async () => {
159
+ await killServer();
160
+ process.exit(0);
161
+ };
162
+
163
+ process.on("SIGINT", cleanup);
164
+ process.on("SIGTERM", cleanup);
165
+ }
166
+ }
167
+
168
+ private static findTsNode(): string | null {
169
+ // Try local ts-node
170
+ const localTsNode = path.join(
171
+ process.cwd(),
172
+ "node_modules",
173
+ ".bin",
174
+ process.platform === "win32" ? "ts-node.cmd" : "ts-node",
175
+ );
176
+
177
+ if (fs.existsSync(localTsNode)) {
178
+ return localTsNode;
179
+ }
180
+
181
+ // Try global ts-node
182
+ try {
183
+ execSync("ts-node --version", { stdio: "ignore" });
184
+ return "ts-node";
185
+ } catch {
186
+ return null;
187
+ }
36
188
  }
37
- }
189
+ }
@@ -0,0 +1,23 @@
1
+ import { Command } from 'commander';
2
+ import { InitCommand } from './commands/init.command';
3
+ import { GenerateCommand } from './commands/generate.command';
4
+ import { ServeCommand } from './commands/serve.command';
5
+ import { BuildCommand } from './commands/build.command';
6
+ import { MigrateCommand } from './commands/migrate.command';
7
+ import { DiagnosticsCommand } from './commands/diagnostics.command';
8
+
9
+ const program = new Command();
10
+
11
+ program
12
+ .name('fragment')
13
+ .description('Fragment Framework CLI')
14
+ .version('1.0.0');
15
+
16
+ InitCommand.register(program);
17
+ GenerateCommand.register(program);
18
+ ServeCommand.register(program);
19
+ BuildCommand.register(program);
20
+ MigrateCommand.register(program);
21
+ DiagnosticsCommand.register(program);
22
+
23
+ program.parse();