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,42 +0,0 @@
1
-
2
- export function repositoryTemplate(name: string, entityName: string): string {
3
- const className = name.endsWith('Repository') ? name : `${name}Repository`;
4
-
5
- return `import { Repository as TypeORMRepository } from 'typeorm';
6
- import { Repository } from '../core/decorators/repository.decorator';
7
- import { ${entityName} } from '../entities/${entityName.toLowerCase()}.entity';
8
- import { AppDataSource } from '../database/data-source';
9
-
10
- @Repository()
11
- export class ${className} {
12
- private repository: TypeORMRepository<${entityName}>;
13
-
14
- constructor() {
15
- this.repository = AppDataSource.getRepository(${entityName});
16
- }
17
-
18
- async findAll(): Promise<${entityName}[]> {
19
- return await this.repository.find();
20
- }
21
-
22
- async findById(id: number): Promise<${entityName} | null> {
23
- return await this.repository.findOne({ where: { id } });
24
- }
25
-
26
- async create(data: Partial<${entityName}>): Promise<${entityName}> {
27
- const entity = this.repository.create(data);
28
- return await this.repository.save(entity);
29
- }
30
-
31
- async update(id: number, data: Partial<${entityName}>): Promise<${entityName} | null> {
32
- await this.repository.update(id, data);
33
- return await this.findById(id);
34
- }
35
-
36
- async delete(id: number): Promise<boolean> {
37
- const result = await this.repository.delete(id);
38
- return result.affected ? result.affected > 0 : false;
39
- }
40
- }
41
- `;
42
- }
@@ -1,42 +0,0 @@
1
-
2
- export function serviceTemplate(name: string): string {
3
- const className = name.endsWith('Service') ? name : `${name}Service`;
4
- const repoName = name.replace('Service', '') + 'Repository';
5
-
6
- return `import { Service } from '../core/decorators/service.decorator';
7
- import { Autowire } from '../core/decorators/autowire.decorator';
8
- import { ${repoName} } from '../repositories/${name.toLowerCase()}.repository';
9
-
10
- @Service()
11
- export class ${className} {
12
- constructor(
13
- @Autowire() private ${repoName.charAt(0).toLowerCase() + repoName.slice(1)}: ${repoName}
14
- ) {}
15
-
16
- async findAll() {
17
- // Implement business logic
18
- return [];
19
- }
20
-
21
- async findById(id: number) {
22
- // Implement business logic
23
- return null;
24
- }
25
-
26
- async create(data: any) {
27
- // Implement business logic
28
- return data;
29
- }
30
-
31
- async update(id: number, data: any) {
32
- // Implement business logic
33
- return data;
34
- }
35
-
36
- async delete(id: number) {
37
- // Implement business logic
38
- return true;
39
- }
40
- }
41
- `;
42
- }
@@ -1,37 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
-
4
- export class FileGenerator {
5
- static createDirectory(dirPath: string): void {
6
- if (!fs.existsSync(dirPath)) {
7
- fs.mkdirSync(dirPath, { recursive: true });
8
- }
9
- }
10
-
11
- static writeFile(filePath: string, content: string): void {
12
- const dir = path.dirname(filePath);
13
- this.createDirectory(dir);
14
- fs.writeFileSync(filePath, content, 'utf-8');
15
- }
16
-
17
- static fileExists(filePath: string): boolean {
18
- return fs.existsSync(filePath);
19
- }
20
-
21
- static readFile(filePath: string): string {
22
- return fs.readFileSync(filePath, 'utf-8');
23
- }
24
-
25
- static toCamelCase(str: string): string {
26
- return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
27
- }
28
-
29
- static toPascalCase(str: string): string {
30
- const camel = this.toCamelCase(str);
31
- return camel.charAt(0).toUpperCase() + camel.slice(1);
32
- }
33
-
34
- static toKebabCase(str: string): string {
35
- return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
36
- }
37
- }
@@ -1,52 +0,0 @@
1
- import chalk from 'chalk';
2
- import ora, { Ora } from 'ora';
3
-
4
- export class CLILogger {
5
- static success(message: string): void {
6
- console.log(chalk.green('✓'), message);
7
- }
8
-
9
- static error(message: string): void {
10
- console.log(chalk.red('✗'), message);
11
- }
12
-
13
- static info(message: string): void {
14
- console.log(chalk.blue('ℹ'), message);
15
- }
16
-
17
- static warning(message: string): void {
18
- console.log(chalk.yellow('⚠'), message);
19
- }
20
-
21
- static title(message: string): void {
22
- console.log(chalk.bold.cyan(`\n${message}\n`));
23
- }
24
-
25
- static section(message: string): void {
26
- console.log(chalk.bold(`\n${message}`));
27
- }
28
-
29
- static spinner(text: string): Ora {
30
- return ora(text).start();
31
- }
32
-
33
- static box(title: string, content: string[]): void {
34
- const maxLength = Math.max(title.length, ...content.map(c => c.length)) + 4;
35
- const border = '═'.repeat(maxLength);
36
-
37
- console.log(chalk.cyan(`╔${border}╗`));
38
- console.log(chalk.cyan('║') + chalk.bold(` ${title.padEnd(maxLength)} `) + chalk.cyan('║'));
39
- console.log(chalk.cyan(`╠${border}╣`));
40
- content.forEach(line => {
41
- console.log(chalk.cyan('║') + ` ${line.padEnd(maxLength)} ` + chalk.cyan('║'));
42
- });
43
- console.log(chalk.cyan(`╚${border}╝`));
44
- }
45
-
46
- static table(data: { [key: string]: string }): void {
47
- const maxKeyLength = Math.max(...Object.keys(data).map(k => k.length));
48
- Object.entries(data).forEach(([key, value]) => {
49
- console.log(` ${chalk.cyan(key.padEnd(maxKeyLength))} : ${value}`);
50
- });
51
- }
52
- }
@@ -1,24 +0,0 @@
1
-
2
- import { Controller } from '../core/decorators/controller.decorator';
3
- import { Get } from '../core/decorators/route.decorator';
4
- import { Injectable } from '../core/decorators/injectable.decorator';
5
- import { Autowire } from '../core/decorators/autowire.decorator';
6
- import { HealthService } from '../services/health.service';
7
-
8
- @Controller('/api/health')
9
- @Injectable()
10
- export class HealthController {
11
- constructor(
12
- @Autowire() private healthService: HealthService
13
- ) {}
14
-
15
- @Get('/')
16
- async getStatus() {
17
- return await this.healthService.getStatus();
18
- }
19
-
20
- @Get('/tip')
21
- async getHealthTip() {
22
- return await this.healthService.generateHealthTip();
23
- }
24
- }
@@ -1,98 +0,0 @@
1
-
2
- import * as fs from 'fs';
3
- import * as path from 'path';
4
- import * as yaml from 'js-yaml';
5
-
6
- export interface AppConfig {
7
- app: {
8
- name: string;
9
- port: number;
10
- env: string;
11
- };
12
- database: {
13
- type: string;
14
- host: string;
15
- port: number;
16
- username: string;
17
- password: string;
18
- database: string;
19
- synchronize: boolean;
20
- logging: boolean;
21
- };
22
- openai: {
23
- apiKey: string;
24
- model: string;
25
- };
26
- auth: {
27
- tokenExpiry: string;
28
- sessionExpiry: string;
29
- };
30
- }
31
-
32
- export class ConfigLoader {
33
- private static config: AppConfig | null = null;
34
-
35
- static load(useYaml: boolean = true): AppConfig {
36
- if (this.config) {
37
- return this.config;
38
- }
39
-
40
- const configDir = path.join(process.cwd(), 'config');
41
- let configPath: string;
42
-
43
- if (useYaml) {
44
- // Try .lock.yaml first, then .yaml
45
- const lockPath = path.join(configDir, 'app.lock.yaml');
46
- const yamlPath = path.join(configDir, 'app.yaml');
47
-
48
- configPath = fs.existsSync(lockPath) ? lockPath : yamlPath;
49
-
50
- if (!fs.existsSync(configPath)) {
51
- throw new Error('Configuration file not found');
52
- }
53
-
54
- const fileContent = fs.readFileSync(configPath, 'utf8');
55
- this.config = yaml.load(fileContent) as AppConfig;
56
- } else {
57
- // JSON fallback
58
- configPath = path.join(configDir, 'app.json');
59
- const fileContent = fs.readFileSync(configPath, 'utf8');
60
- this.config = JSON.parse(fileContent);
61
- }
62
-
63
- // Override with environment variables
64
- this.config = this.mergeEnvVariables(this.config!);
65
-
66
- return this.config;
67
- }
68
-
69
- private static mergeEnvVariables(config: AppConfig): AppConfig {
70
- return {
71
- ...config,
72
- app: {
73
- ...config.app,
74
- port: process.env.PORT ? parseInt(process.env.PORT) : config.app.port,
75
- env: process.env.NODE_ENV || config.app.env
76
- },
77
- database: {
78
- ...config.database,
79
- host: process.env.DB_HOST || config.database.host,
80
- port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : config.database.port,
81
- username: process.env.DB_USERNAME || config.database.username,
82
- password: process.env.DB_PASSWORD || config.database.password,
83
- database: process.env.DB_DATABASE || config.database.database
84
- },
85
- openai: {
86
- ...config.openai,
87
- apiKey: process.env.OPENAI_API_KEY || config.openai.apiKey
88
- }
89
- };
90
- }
91
-
92
- static get(): AppConfig {
93
- if (!this.config) {
94
- throw new Error('Config not loaded. Call ConfigLoader.load() first.');
95
- }
96
- return this.config;
97
- }
98
- }
@@ -1,15 +0,0 @@
1
- import 'reflect-metadata';
2
-
3
- export const AUTH_GUARD_METADATA = 'auth:guard';
4
-
5
- export function AuthGuard(): MethodDecorator & ClassDecorator {
6
- return (target: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor) => {
7
- if (propertyKey) {
8
- // method decorator
9
- Reflect.defineMetadata(AUTH_GUARD_METADATA, true, target.constructor, propertyKey);
10
- } else {
11
- // class decorator
12
- Reflect.defineMetadata(AUTH_GUARD_METADATA, true, target);
13
- }
14
- };
15
- }
@@ -1,18 +0,0 @@
1
-
2
- import 'reflect-metadata';
3
-
4
- export const AUTOWIRE_METADATA = 'autowire:metadata';
5
-
6
- export function Autowire(): ParameterDecorator {
7
- return (target: any, propertyKey: string | symbol | undefined, parameterIndex: number) => {
8
- const existingParams = Reflect.getOwnMetadata(AUTOWIRE_METADATA, target) || [];
9
- const types = Reflect.getMetadata('design:paramtypes', target) || [];
10
-
11
- existingParams.push({
12
- index: parameterIndex,
13
- type: types[parameterIndex]
14
- });
15
-
16
- Reflect.defineMetadata(AUTOWIRE_METADATA, existingParams, target);
17
- };
18
- }
@@ -1,18 +0,0 @@
1
-
2
- import 'reflect-metadata';
3
-
4
- export const MIDDLEWARE_METADATA = 'middleware:metadata';
5
-
6
- export function Middleware(...middlewares: Function[]): ClassDecorator | MethodDecorator {
7
- return (target: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor) => {
8
- if (propertyKey) {
9
- // Method-level middleware
10
- const existing = Reflect.getOwnMetadata(MIDDLEWARE_METADATA, target.constructor, propertyKey) || [];
11
- Reflect.defineMetadata(MIDDLEWARE_METADATA, [...existing, ...middlewares], target.constructor, propertyKey);
12
- } else {
13
- // Class-level middleware
14
- const existing = Reflect.getOwnMetadata(MIDDLEWARE_METADATA, target) || [];
15
- Reflect.defineMetadata(MIDDLEWARE_METADATA, [...existing, ...middlewares], target);
16
- }
17
- };
18
- }
@@ -1,33 +0,0 @@
1
-
2
- import 'reflect-metadata';
3
-
4
- export const ROUTE_METADATA = 'route:metadata';
5
-
6
- export enum HttpMethod {
7
- GET = 'get',
8
- POST = 'post',
9
- PUT = 'put',
10
- DELETE = 'delete',
11
- PATCH = 'patch'
12
- }
13
-
14
- function createRouteDecorator(method: HttpMethod) {
15
- return (path: string = ''): MethodDecorator => {
16
- return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
17
- const routes = Reflect.getOwnMetadata(ROUTE_METADATA, target.constructor) || [];
18
- routes.push({
19
- method,
20
- path,
21
- handlerName: propertyKey
22
- });
23
- Reflect.defineMetadata(ROUTE_METADATA, routes, target.constructor);
24
- return descriptor;
25
- };
26
- };
27
- }
28
-
29
- export const Get = createRouteDecorator(HttpMethod.GET);
30
- export const Post = createRouteDecorator(HttpMethod.POST);
31
- export const Put = createRouteDecorator(HttpMethod.PUT);
32
- export const Delete = createRouteDecorator(HttpMethod.DELETE);
33
- export const Patch = createRouteDecorator(HttpMethod.PATCH);
@@ -1,99 +0,0 @@
1
- import { Injectable } from "../decorators/injectable.decorator";
2
- import { ConfigLoader } from "../config/config-loader";
3
-
4
- @Injectable()
5
- export class OpenAIClient {
6
- private apiKey: string;
7
- private model: string;
8
- private baseURL: string = "https://api.openai.com/v1";
9
-
10
- constructor() {
11
- const config = ConfigLoader.get();
12
- this.apiKey = config.openai.apiKey;
13
- this.model = config.openai.model;
14
- }
15
-
16
- async complete(
17
- prompt: string,
18
- options?: {
19
- model?: string;
20
- maxTokens?: number;
21
- temperature?: number;
22
- }
23
- ): Promise<string> {
24
- const response = await fetch(`${this.baseURL}/chat/completions`, {
25
- method: "POST",
26
- headers: {
27
- "Content-Type": "application/json",
28
- Authorization: `Bearer ${this.apiKey}`,
29
- },
30
- body: JSON.stringify({
31
- model: options?.model || this.model,
32
- messages: [{ role: "user", content: prompt }],
33
- max_tokens: options?.maxTokens || 1000,
34
- temperature: options?.temperature || 0.7,
35
- }),
36
- });
37
-
38
- if (!response.ok) {
39
- throw new Error(`OpenAI API error: ${response.statusText}`);
40
- }
41
-
42
- const data = (await response.json()) as any;
43
- return data.choices[0].message.content;
44
- }
45
-
46
- async streamComplete(
47
- prompt: string,
48
- onChunk: (chunk: string) => void
49
- ): Promise<void> {
50
- const response = await fetch(`${this.baseURL}/chat/completions`, {
51
- method: "POST",
52
- headers: {
53
- "Content-Type": "application/json",
54
- Authorization: `Bearer ${this.apiKey}`,
55
- },
56
- body: JSON.stringify({
57
- model: this.model,
58
- messages: [{ role: "user", content: prompt }],
59
- stream: true,
60
- }),
61
- });
62
-
63
- if (!response.ok) {
64
- throw new Error(`OpenAI API error: ${response.statusText}`);
65
- }
66
-
67
- const reader = response.body?.getReader();
68
- const decoder = new TextDecoder();
69
-
70
- if (!reader) {
71
- throw new Error("No response body");
72
- }
73
-
74
- while (true) {
75
- const { done, value } = await reader.read();
76
- if (done) break;
77
-
78
- const chunk = decoder.decode(value);
79
- const lines = chunk.split("\n").filter((line) => line.trim() !== "");
80
-
81
- for (const line of lines) {
82
- if (line.startsWith("data: ")) {
83
- const data = line.slice(6);
84
- if (data === "[DONE]") continue;
85
-
86
- try {
87
- const parsed = JSON.parse(data);
88
- const content = parsed.choices[0]?.delta?.content;
89
- if (content) {
90
- onChunk(content);
91
- }
92
- } catch (e) {
93
- // Skip invalid JSON
94
- }
95
- }
96
- }
97
- }
98
- }
99
- }
@@ -1,29 +0,0 @@
1
-
2
- import { DataSource } from 'typeorm';
3
- import { ConfigLoader } from '../core/config/config-loader';
4
- import { User } from '../entities/user.entity';
5
- import { Session } from '../entities/session.entity';
6
-
7
- let AppDataSource: DataSource;
8
-
9
- export function initializeDataSource(): DataSource {
10
- const config = ConfigLoader.get();
11
-
12
- AppDataSource = new DataSource({
13
- type: config.database.type as any,
14
- host: config.database.host,
15
- port: config.database.port,
16
- username: config.database.username,
17
- password: config.database.password,
18
- database: config.database.database,
19
- synchronize: config.database.synchronize,
20
- logging: config.database.logging,
21
- entities: [User, Session],
22
- migrations: [],
23
- subscribers: []
24
- });
25
-
26
- return AppDataSource;
27
- }
28
-
29
- export { AppDataSource };
@@ -1,25 +0,0 @@
1
-
2
- import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn, CreateDateColumn } from 'typeorm';
3
- import { User } from './user.entity';
4
-
5
- @Entity('sessions')
6
- export class Session {
7
- @PrimaryGeneratedColumn()
8
- id!: number;
9
-
10
- @Column({ unique: true, length: 255 })
11
- token!: string;
12
-
13
- @Column()
14
- userId!: number;
15
-
16
- @ManyToOne(() => User, (user) => user.sessions, { onDelete: 'CASCADE' })
17
- @JoinColumn({ name: 'userId' })
18
- user!: User;
19
-
20
- @Column()
21
- expiresAt!: Date;
22
-
23
- @CreateDateColumn()
24
- createdAt!: Date;
25
- }
@@ -1,27 +0,0 @@
1
-
2
- import { Entity, PrimaryGeneratedColumn, Column, OneToMany, CreateDateColumn, UpdateDateColumn } from 'typeorm';
3
- import { Session } from './session.entity';
4
-
5
- @Entity('users')
6
- export class User {
7
- @PrimaryGeneratedColumn()
8
- id!: number;
9
-
10
- @Column({ length: 100 })
11
- name!: string;
12
-
13
- @Column({ unique: true, length: 255 })
14
- email!: string;
15
-
16
- @Column({ length: 255 })
17
- passwordHash!: string;
18
-
19
- @OneToMany(() => Session, (session) => session.user)
20
- sessions!: Session[];
21
-
22
- @CreateDateColumn()
23
- createdAt!: Date;
24
-
25
- @UpdateDateColumn()
26
- updatedAt!: Date;
27
- }
@@ -1,28 +0,0 @@
1
-
2
- import { Request, Response, NextFunction } from 'express';
3
- import pino from 'pino';
4
-
5
- const logger = pino({
6
- transport: {
7
- target: 'pino-pretty',
8
- options: {
9
- colorize: true
10
- }
11
- }
12
- });
13
-
14
- export function loggingMiddleware(req: Request, res: Response, next: NextFunction) {
15
- const start = Date.now();
16
-
17
- res.on('finish', () => {
18
- const duration = Date.now() - start;
19
- logger.info({
20
- method: req.method,
21
- url: req.url,
22
- status: res.statusCode,
23
- duration: `${duration}ms`
24
- });
25
- });
26
-
27
- next();
28
- }
@@ -1,42 +0,0 @@
1
-
2
- import { Repository as TypeORMRepository, MoreThan } from 'typeorm';
3
- import { Repository } from '../core/decorators/repository.decorator';
4
- import { Session } from '../entities/session.entity';
5
- import { AppDataSource } from '../database/data-source';
6
-
7
- @Repository()
8
- export class SessionRepository {
9
- private repository: TypeORMRepository<Session>;
10
-
11
- constructor() {
12
- this.repository = AppDataSource.getRepository(Session);
13
- }
14
-
15
- async findByToken(token: string): Promise<Session | null> {
16
- return await this.repository.findOne({
17
- where: {
18
- token,
19
- expiresAt: MoreThan(new Date())
20
- },
21
- relations: ['user']
22
- });
23
- }
24
-
25
- async create(sessionData: Partial<Session>): Promise<Session> {
26
- const session = this.repository.create(sessionData);
27
- return await this.repository.save(session);
28
- }
29
-
30
- async deleteByToken(token: string): Promise<boolean> {
31
- const result = await this.repository.delete({ token });
32
- return result.affected ? result.affected > 0 : false;
33
- }
34
-
35
- async deleteExpired(): Promise<void> {
36
- await this.repository
37
- .createQueryBuilder()
38
- .delete()
39
- .where('expiresAt < :now', { now: new Date() })
40
- .execute();
41
- }
42
- }
@@ -1,37 +0,0 @@
1
-
2
- import { Repository as TypeORMRepository } from 'typeorm';
3
- import { Repository } from '../core/decorators/repository.decorator';
4
- import { User } from '../entities/user.entity';
5
- import { AppDataSource } from '../database/data-source';
6
-
7
- @Repository()
8
- export class UserRepository {
9
- private repository: TypeORMRepository<User>;
10
-
11
- constructor() {
12
- this.repository = AppDataSource.getRepository(User);
13
- }
14
-
15
- async findById(id: number): Promise<User | null> {
16
- return await this.repository.findOne({ where: { id } });
17
- }
18
-
19
- async findByEmail(email: string): Promise<User | null> {
20
- return await this.repository.findOne({ where: { email } });
21
- }
22
-
23
- async create(userData: Partial<User>): Promise<User> {
24
- const user = this.repository.create(userData);
25
- return await this.repository.save(user);
26
- }
27
-
28
- async update(id: number, userData: Partial<User>): Promise<User | null> {
29
- await this.repository.update(id, userData);
30
- return await this.findById(id);
31
- }
32
-
33
- async delete(id: number): Promise<boolean> {
34
- const result = await this.repository.delete(id);
35
- return result.affected ? result.affected > 0 : false;
36
- }
37
- }