fragment-ts 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) 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 +131 -10
  15. package/dist/cli/commands/build.command.js.map +1 -0
  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 +201 -128
  23. package/dist/cli/commands/generate.command.js.map +1 -0
  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 +268 -305
  27. package/dist/cli/commands/init.command.js.map +1 -0
  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 +212 -83
  31. package/dist/cli/commands/migrate.command.js.map +1 -0
  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 +179 -21
  35. package/dist/cli/commands/serve.command.js.map +1 -0
  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 +76 -25
  43. package/dist/core/container/di-container.js.map +1 -0
  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 +13 -9
  59. package/dist/core/decorators/controller.decorator.js.map +1 -0
  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 +12 -8
  67. package/dist/core/decorators/injectable.decorator.js.map +1 -0
  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 +13 -1
  75. package/dist/core/decorators/repository.decorator.js.map +1 -0
  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 +13 -1
  79. package/dist/core/decorators/service.decorator.js.map +1 -0
  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 -23
  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 -0
  127. package/dist/web/interfaces.js.map +1 -0
  128. package/examples/ai-assistant/fragment.json +18 -0
  129. package/examples/ai-assistant/package-lock.json +2921 -0
  130. package/examples/ai-assistant/package.json +20 -0
  131. package/examples/ai-assistant/src/controllers/app.controller.ts +9 -0
  132. package/examples/ai-assistant/src/controllers/chat.controller.ts +69 -0
  133. package/examples/ai-assistant/src/controllers/conversation.controller.ts +29 -0
  134. package/examples/ai-assistant/src/controllers/message.controller.ts +29 -0
  135. package/examples/ai-assistant/src/controllers/search.controller.ts +16 -0
  136. package/examples/ai-assistant/src/dto/create-conversation.dto.ts +6 -0
  137. package/examples/ai-assistant/src/dto/create-message.dto.ts +6 -0
  138. package/examples/ai-assistant/src/entities/conversation.entity.ts +23 -0
  139. package/examples/ai-assistant/src/entities/message.entity.ts +27 -0
  140. package/examples/ai-assistant/src/entities/user.entity.ts +16 -0
  141. package/examples/ai-assistant/src/main.ts +15 -0
  142. package/examples/ai-assistant/src/migrations/1767738396740-CreateConversationTables.ts +37 -0
  143. package/examples/ai-assistant/src/repositories/conversation.repository.ts +32 -0
  144. package/examples/ai-assistant/src/repositories/message.repository.ts +30 -0
  145. package/examples/ai-assistant/src/services/ai.service.ts +41 -0
  146. package/examples/ai-assistant/src/services/app.service.ts +8 -0
  147. package/examples/ai-assistant/src/services/conversation.service.ts +75 -0
  148. package/examples/ai-assistant/src/services/message.service.ts +27 -0
  149. package/examples/ai-assistant/tsconfig.json +23 -0
  150. package/examples/blog-api/fragment.json +18 -0
  151. package/examples/blog-api/package.json +19 -0
  152. package/examples/blog-api/src/controllers/app.controller.ts +9 -0
  153. package/examples/blog-api/src/controllers/auth.controller.ts +17 -0
  154. package/examples/blog-api/src/controllers/category.controller.ts +29 -0
  155. package/examples/blog-api/src/controllers/comment.controller.ts +27 -0
  156. package/examples/blog-api/src/controllers/post.controller.ts +46 -0
  157. package/examples/blog-api/src/dto/create-category.dto.ts +6 -0
  158. package/examples/blog-api/src/dto/create-comment.dto.ts +6 -0
  159. package/examples/blog-api/src/dto/create-post.dto.ts +6 -0
  160. package/examples/blog-api/src/entities/category.entity.ts +16 -0
  161. package/examples/blog-api/src/entities/comment.entity.ts +29 -0
  162. package/examples/blog-api/src/entities/post.entity.ts +42 -0
  163. package/examples/blog-api/src/entities/user.entity.ts +25 -0
  164. package/examples/blog-api/src/main.ts +16 -0
  165. package/examples/blog-api/src/migrations/1767737463842-InitialSchema.ts +60 -0
  166. package/examples/blog-api/src/repositories/category.repository.ts +25 -0
  167. package/examples/blog-api/src/repositories/comment.repository.ts +25 -0
  168. package/examples/blog-api/src/repositories/post.repository.ts +29 -0
  169. package/examples/blog-api/src/seeds/SampleData.seed.ts +41 -0
  170. package/examples/blog-api/src/services/app.service.ts +8 -0
  171. package/examples/blog-api/src/services/auth.service.ts +15 -0
  172. package/examples/blog-api/src/services/category.service.ts +27 -0
  173. package/examples/blog-api/src/services/comment.service.ts +31 -0
  174. package/examples/blog-api/src/services/post.service.ts +35 -0
  175. package/examples/blog-api/tsconfig.json +23 -0
  176. package/package.json +56 -33
  177. package/src/ai/ai.module.ts +110 -0
  178. package/src/auth/auth.module.ts +77 -0
  179. package/src/cli/commands/build.command.ts +123 -13
  180. package/src/cli/commands/diagnostics.command.ts +438 -0
  181. package/src/cli/commands/generate.command.ts +206 -137
  182. package/src/cli/commands/init.command.ts +337 -349
  183. package/src/cli/commands/migrate.command.ts +203 -88
  184. package/src/cli/commands/serve.command.ts +176 -24
  185. package/src/cli/index.ts +23 -0
  186. package/src/core/container/di-container.ts +83 -26
  187. package/src/core/decorators/application.decorator.ts +26 -0
  188. package/src/core/decorators/auto-configuration.decorator.ts +17 -0
  189. package/src/core/decorators/conditional.decorators.ts +19 -0
  190. package/src/core/decorators/controller.decorator.ts +14 -11
  191. package/src/core/decorators/http.decorators.ts +71 -0
  192. package/src/core/decorators/injectable.decorator.ts +14 -9
  193. package/src/core/decorators/injection.decorators.ts +26 -0
  194. package/src/core/decorators/repository.decorator.ts +13 -2
  195. package/src/core/decorators/service.decorator.ts +13 -2
  196. package/src/core/index.ts +13 -0
  197. package/src/core/loader/file-loader.ts +55 -0
  198. package/src/core/metadata/metadata-keys.ts +19 -0
  199. package/src/core/metadata/metadata-storage.ts +91 -0
  200. package/src/core/scanner/component-scanner.ts +129 -0
  201. package/src/index.ts +45 -0
  202. package/src/plugins/plugin-manager.ts +52 -0
  203. package/src/shared/errors.ts +34 -0
  204. package/src/testing/runner.ts +143 -0
  205. package/src/typeorm/typeorm-module.ts +216 -0
  206. package/src/web/application.ts +348 -0
  207. package/src/web/interfaces.ts +17 -0
  208. package/tsconfig.json +8 -5
  209. package/.env.example +0 -0
  210. package/base.ts +0 -1810
  211. package/base2.ts +0 -968
  212. package/bin/frg.ts +0 -5
  213. package/config/fragment.lock.yaml +0 -0
  214. package/config/fragment.yaml +0 -0
  215. package/dist/app.d.ts +0 -15
  216. package/dist/app.js +0 -90
  217. package/dist/auth/auth.controller.d.ts +0 -10
  218. package/dist/auth/auth.controller.js +0 -87
  219. package/dist/auth/auth.middleware.d.ts +0 -2
  220. package/dist/auth/auth.middleware.js +0 -24
  221. package/dist/auth/auth.service.d.ts +0 -20
  222. package/dist/auth/auth.service.js +0 -143
  223. package/dist/auth/dto/login.dto.d.ts +0 -9
  224. package/dist/cli/cli.d.ts +0 -12
  225. package/dist/cli/cli.js +0 -186
  226. package/dist/cli/commands/config.command.d.ts +0 -6
  227. package/dist/cli/commands/config.command.js +0 -284
  228. package/dist/cli/templates/controller.template.d.ts +0 -1
  229. package/dist/cli/templates/controller.template.js +0 -52
  230. package/dist/cli/templates/entity.template.d.ts +0 -1
  231. package/dist/cli/templates/entity.template.js +0 -23
  232. package/dist/cli/templates/repository.template.d.ts +0 -1
  233. package/dist/cli/templates/repository.template.js +0 -43
  234. package/dist/cli/templates/service.template.d.ts +0 -1
  235. package/dist/cli/templates/service.template.js +0 -43
  236. package/dist/cli/utils/file-generator.d.ts +0 -9
  237. package/dist/cli/utils/logger.d.ts +0 -14
  238. package/dist/cli/utils/logger.js +0 -49
  239. package/dist/controllers/health.controller.d.ts +0 -13
  240. package/dist/controllers/health.controller.js +0 -50
  241. package/dist/core/config/config-loader.d.ts +0 -31
  242. package/dist/core/config/config-loader.js +0 -98
  243. package/dist/core/decorators/auth-guard.decorator.d.ts +0 -3
  244. package/dist/core/decorators/auth-guard.decorator.js +0 -18
  245. package/dist/core/decorators/autowire.decorator.d.ts +0 -3
  246. package/dist/core/decorators/autowire.decorator.js +0 -17
  247. package/dist/core/decorators/middleware.decorator.d.ts +0 -3
  248. package/dist/core/decorators/middleware.decorator.js +0 -20
  249. package/dist/core/decorators/route.decorator.d.ts +0 -14
  250. package/dist/core/decorators/route.decorator.js +0 -32
  251. package/dist/core/openai/openai-client.d.ts +0 -12
  252. package/dist/core/openai/openai-client.js +0 -93
  253. package/dist/database/data-source.d.ts +0 -4
  254. package/dist/database/data-source.js +0 -26
  255. package/dist/entities/session.entity.d.ts +0 -9
  256. package/dist/entities/session.entity.js +0 -45
  257. package/dist/entities/user.entity.d.ts +0 -10
  258. package/dist/entities/user.entity.js +0 -48
  259. package/dist/middlewares/logging.middleware.d.ts +0 -2
  260. package/dist/middlewares/logging.middleware.js +0 -28
  261. package/dist/repositories/session.repository.d.ts +0 -9
  262. package/dist/repositories/session.repository.js +0 -50
  263. package/dist/repositories/user.repository.d.ts +0 -10
  264. package/dist/repositories/user.repository.js +0 -43
  265. package/dist/server.d.ts +0 -1
  266. package/dist/server.js +0 -30
  267. package/dist/services/health.service.d.ts +0 -13
  268. package/dist/services/health.service.js +0 -44
  269. package/readme.md +0 -120
  270. package/src/app.ts +0 -121
  271. package/src/auth/auth.controller.ts +0 -52
  272. package/src/auth/auth.middleware.ts +0 -27
  273. package/src/auth/auth.service.ts +0 -110
  274. package/src/auth/dto/login.dto.ts +0 -11
  275. package/src/cli/cli.ts +0 -212
  276. package/src/cli/commands/config.command.ts +0 -280
  277. package/src/cli/templates/controller.template.ts +0 -51
  278. package/src/cli/templates/entity.template.ts +0 -22
  279. package/src/cli/templates/repository.template.ts +0 -42
  280. package/src/cli/templates/service.template.ts +0 -42
  281. package/src/cli/utils/file-generator.ts +0 -37
  282. package/src/cli/utils/logger.ts +0 -52
  283. package/src/controllers/health.controller.ts +0 -24
  284. package/src/core/config/config-loader.ts +0 -98
  285. package/src/core/decorators/auth-guard.decorator.ts +0 -15
  286. package/src/core/decorators/autowire.decorator.ts +0 -18
  287. package/src/core/decorators/middleware.decorator.ts +0 -18
  288. package/src/core/decorators/route.decorator.ts +0 -33
  289. package/src/core/openai/openai-client.ts +0 -99
  290. package/src/database/data-source.ts +0 -29
  291. package/src/entities/session.entity.ts +0 -25
  292. package/src/entities/user.entity.ts +0 -27
  293. package/src/middlewares/logging.middleware.ts +0 -28
  294. package/src/repositories/session.repository.ts +0 -42
  295. package/src/repositories/user.repository.ts +0 -37
  296. package/src/server.ts +0 -32
  297. package/src/services/health.service.ts +0 -29
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "ai-assistant",
3
+ "version": "1.0.0",
4
+ "main": "dist/main.js",
5
+ "scripts": {
6
+ "start": "node dist/main.js",
7
+ "dev": "fragment serve",
8
+ "build": "fragment build",
9
+ "test": "fragment test"
10
+ },
11
+ "dependencies": {
12
+ "fragment": "^1.0.0",
13
+ "reflect-metadata": "^0.1.13"
14
+ },
15
+ "devDependencies": {
16
+ "@types/node": "^20.10.5",
17
+ "ts-node": "^10.9.2",
18
+ "typescript": "^5.3.3"
19
+ }
20
+ }
@@ -0,0 +1,9 @@
1
+ import { Controller, Get } from 'fragment';
2
+
3
+ @Controller('/api')
4
+ export class AppController {
5
+ @Get('/health')
6
+ health() {
7
+ return { status: 'who dey help', timestamp: new Date().toISOString() };
8
+ }
9
+ }
@@ -0,0 +1,69 @@
1
+ import { Controller, Get, Post, Body, Param, Res } from "fragment";
2
+ import { ConversationService } from "../services/conversation.service";
3
+ import { Response } from "express";
4
+
5
+ @Controller("/api/chat")
6
+ export class ChatController {
7
+ constructor(private conversationService: ConversationService) {}
8
+
9
+ @Post("/conversations")
10
+ async createConversation(@Body() body: any) {
11
+ return this.conversationService.create(body.userId || 1, body.title);
12
+ }
13
+
14
+ @Get("/conversations/:userId")
15
+ async getConversations(@Param("userId") userId: string) {
16
+ return this.conversationService.findByUser(parseInt(userId));
17
+ }
18
+
19
+ @Get("/conversations/:id/messages")
20
+ async getMessages(@Param("id") id: string) {
21
+ return this.conversationService.getMessages(parseInt(id));
22
+ }
23
+
24
+ @Post("/conversations/:id/message")
25
+ async sendMessage(@Param("id") id: string, @Body() body: any) {
26
+ return this.conversationService.chat(parseInt(id), body.message);
27
+ }
28
+
29
+ @Post("/conversations/:id/stream")
30
+ async streamMessage(
31
+ @Param("id") id: string,
32
+ @Body() body: any,
33
+ @Res() res: Response,
34
+ ) {
35
+ res.setHeader("Content-Type", "text/event-stream");
36
+ res.setHeader("Cache-Control", "no-cache");
37
+ res.setHeader("Connection", "keep-alive");
38
+
39
+ let fullResponse = "";
40
+
41
+ await this.conversationService.addMessage(
42
+ parseInt(id),
43
+ "user",
44
+ body.message,
45
+ );
46
+
47
+ const messages = await this.conversationService.getMessages(parseInt(id));
48
+ const aiMessages = messages.map((m: any) => ({
49
+ role: m.role as any,
50
+ content: m.content,
51
+ }));
52
+
53
+ const aiService = (this.conversationService as any).aiService;
54
+
55
+ await aiService.streamChat(aiMessages, (chunk: string) => {
56
+ fullResponse += chunk;
57
+ res.write(`data: ${JSON.stringify({ chunk })}\n\n`);
58
+ });
59
+
60
+ await this.conversationService.addMessage(
61
+ parseInt(id),
62
+ "assistant",
63
+ fullResponse,
64
+ );
65
+
66
+ res.write("data: [DONE]\n\n");
67
+ res.end();
68
+ }
69
+ }
@@ -0,0 +1,29 @@
1
+ import { Controller, Get, Post, Put, Delete, Body, Param } from 'fragment';
2
+
3
+ @Controller('/conversation')
4
+ export class ConversationController {
5
+ @Get()
6
+ findAll() {
7
+ return [];
8
+ }
9
+
10
+ @Get('/:id')
11
+ findOne(@Param('id') id: string) {
12
+ return { id };
13
+ }
14
+
15
+ @Post()
16
+ create(@Body() body: any) {
17
+ return body;
18
+ }
19
+
20
+ @Put('/:id')
21
+ update(@Param('id') id: string, @Body() body: any) {
22
+ return { id, ...body };
23
+ }
24
+
25
+ @Delete('/:id')
26
+ delete(@Param('id') id: string) {
27
+ return { deleted: true, id };
28
+ }
29
+ }
@@ -0,0 +1,29 @@
1
+ import { Controller, Get, Post, Put, Delete, Body, Param } from 'fragment';
2
+
3
+ @Controller('/message')
4
+ export class MessageController {
5
+ @Get()
6
+ findAll() {
7
+ return [];
8
+ }
9
+
10
+ @Get('/:id')
11
+ findOne(@Param('id') id: string) {
12
+ return { id };
13
+ }
14
+
15
+ @Post()
16
+ create(@Body() body: any) {
17
+ return body;
18
+ }
19
+
20
+ @Put('/:id')
21
+ update(@Param('id') id: string, @Body() body: any) {
22
+ return { id, ...body };
23
+ }
24
+
25
+ @Delete('/:id')
26
+ delete(@Param('id') id: string) {
27
+ return { deleted: true, id };
28
+ }
29
+ }
@@ -0,0 +1,16 @@
1
+ import { Controller, Post, Body, Query } from "fragment";
2
+ import { ConversationService } from "../services/conversation.service";
3
+
4
+ @Controller("/api/search")
5
+ export class SearchController {
6
+ constructor(private conversationService: ConversationService) {}
7
+
8
+ @Post("/semantic")
9
+ async semanticSearch(
10
+ @Body() body: any,
11
+ @Query("conversationId") conversationId?: string,
12
+ ) {
13
+ const convId = conversationId ? parseInt(conversationId) : undefined;
14
+ return this.conversationService.semanticSearch(body.query, convId);
15
+ }
16
+ }
@@ -0,0 +1,6 @@
1
+ import { IsString } from 'class-validator';
2
+
3
+ export class CreateConversationDto {
4
+ @IsString()
5
+ name!: string;
6
+ }
@@ -0,0 +1,6 @@
1
+ import { IsString } from 'class-validator';
2
+
3
+ export class CreateMessageDto {
4
+ @IsString()
5
+ name!: string;
6
+ }
@@ -0,0 +1,23 @@
1
+ import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
2
+ import { Message } from './message.entity';
3
+
4
+ @Entity()
5
+ export class Conversation {
6
+ @PrimaryGeneratedColumn()
7
+ id!: number;
8
+
9
+ @Column()
10
+ title!: string;
11
+
12
+ @Column()
13
+ userId!: number;
14
+
15
+ @OneToMany(() => Message, message => message.conversation)
16
+ messages!: Message[];
17
+
18
+ @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
19
+ createdAt!: Date;
20
+
21
+ @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
22
+ updatedAt!: Date;
23
+ }
@@ -0,0 +1,27 @@
1
+ import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';
2
+ import { Conversation } from './conversation.entity';
3
+
4
+ @Entity()
5
+ export class Message {
6
+ @PrimaryGeneratedColumn()
7
+ id!: number;
8
+
9
+ @Column()
10
+ conversationId!: number;
11
+
12
+ @ManyToOne(() => Conversation, conversation => conversation.messages)
13
+ @JoinColumn({ name: 'conversationId' })
14
+ conversation!: Conversation;
15
+
16
+ @Column()
17
+ role!: string;
18
+
19
+ @Column('text')
20
+ content!: string;
21
+
22
+ @Column('simple-json', { nullable: true })
23
+ embedding!: number[];
24
+
25
+ @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
26
+ createdAt?: Date;
27
+ }
@@ -0,0 +1,16 @@
1
+ import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
2
+
3
+ @Entity()
4
+ export class User {
5
+ @PrimaryGeneratedColumn()
6
+ id!: number;
7
+
8
+ @Column()
9
+ email!: string;
10
+
11
+ @Column()
12
+ name!: string;
13
+
14
+ @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
15
+ createdAt?: Date;
16
+ }
@@ -0,0 +1,15 @@
1
+ import 'reflect-metadata';
2
+ import { FragmentApplication } from 'fragment';
3
+ import { FragmentWebApplication } from 'fragment';
4
+
5
+ @FragmentApplication({
6
+ port: 3000,
7
+ })
8
+ class Application {}
9
+
10
+ async function bootstrap() {
11
+ const app = new FragmentWebApplication();
12
+ await app.bootstrap(Application);
13
+ }
14
+
15
+ bootstrap();
@@ -0,0 +1,37 @@
1
+ import { MigrationInterface, QueryRunner, Table } from "typeorm";
2
+
3
+ export class CreateConversationTables1234567890 implements MigrationInterface {
4
+ async up(queryRunner: QueryRunner): Promise<void> {
5
+ await queryRunner.createTable(
6
+ new Table({
7
+ name: "conversation",
8
+ columns: [
9
+ { name: "id", type: "integer", isPrimary: true, isGenerated: true },
10
+ { name: "title", type: "varchar" },
11
+ { name: "userId", type: "integer" },
12
+ { name: "createdAt", type: "datetime", default: "CURRENT_TIMESTAMP" },
13
+ { name: "updatedAt", type: "datetime", default: "CURRENT_TIMESTAMP" },
14
+ ],
15
+ }),
16
+ );
17
+
18
+ await queryRunner.createTable(
19
+ new Table({
20
+ name: "message",
21
+ columns: [
22
+ { name: "id", type: "integer", isPrimary: true, isGenerated: true },
23
+ { name: "conversationId", type: "integer" },
24
+ { name: "role", type: "varchar" },
25
+ { name: "content", type: "text" },
26
+ { name: "embedding", type: "text", isNullable: true },
27
+ { name: "createdAt", type: "datetime", default: "CURRENT_TIMESTAMP" },
28
+ ],
29
+ }),
30
+ );
31
+ }
32
+
33
+ async down(queryRunner: QueryRunner): Promise<void> {
34
+ await queryRunner.dropTable("message");
35
+ await queryRunner.dropTable("conversation");
36
+ }
37
+ }
@@ -0,0 +1,32 @@
1
+ import { Repository } from "fragment";
2
+ import { Conversation } from "../entities/conversation.entity";
3
+
4
+ @Repository()
5
+ export class ConversationRepository {
6
+ async findAll(): Promise<Conversation[]> {
7
+ return [];
8
+ }
9
+
10
+ async findById(id: number): Promise<Conversation | null> {
11
+ return null;
12
+ }
13
+
14
+ async create(data: Partial<Conversation>): Promise<Conversation> {
15
+ return data as Conversation;
16
+ }
17
+
18
+ async update(
19
+ id: number,
20
+ data: Partial<Conversation>,
21
+ ): Promise<Conversation | null> {
22
+ return null;
23
+ }
24
+
25
+ async delete(id: number): Promise<boolean> {
26
+ return true;
27
+ }
28
+
29
+ async findByUser(userId: number): Promise<Conversation[]> {
30
+ return [];
31
+ }
32
+ }
@@ -0,0 +1,30 @@
1
+ import { Repository } from "fragment";
2
+ import { Message } from "../entities/message.entity";
3
+ import { Conversation } from "../entities/conversation.entity";
4
+
5
+ @Repository()
6
+ export class MessageRepository {
7
+ async findAll(): Promise<Message[]> {
8
+ return [];
9
+ }
10
+
11
+ async findById(id: number): Promise<Message | null> {
12
+ return null;
13
+ }
14
+
15
+ async create(data: Partial<Message>): Promise<Message> {
16
+ return data as Message;
17
+ }
18
+
19
+ async update(id: number, data: Partial<Message>): Promise<Message | null> {
20
+ return null;
21
+ }
22
+
23
+ async delete(id: number): Promise<boolean> {
24
+ return true;
25
+ }
26
+
27
+ async findByConversation(conversationId: number): Promise<Conversation[]> {
28
+ return [];
29
+ }
30
+ }
@@ -0,0 +1,41 @@
1
+ import { Service } from 'fragment';
2
+ import { AIModule } from 'fragment';
3
+
4
+ @Service()
5
+ export class AIService {
6
+ private aiModule: AIModule;
7
+
8
+ constructor() {
9
+ this.aiModule = new AIModule({
10
+ openaiKey: process.env.OPENAI_API_KEY,
11
+ ollamaUrl: process.env.OLLAMA_URL
12
+ });
13
+ }
14
+
15
+ async chat(messages: any[]) {
16
+ return this.aiModule.complete(messages, {
17
+ model: 'gpt-3.5-turbo',
18
+ temperature: 0.7,
19
+ maxTokens: 1000
20
+ });
21
+ }
22
+
23
+ async streamChat(messages: any[], onChunk: (chunk: string) => void) {
24
+ await this.aiModule.streamComplete(messages, {
25
+ model: 'gpt-3.5-turbo',
26
+ temperature: 0.7
27
+ }, onChunk);
28
+ }
29
+
30
+ async generateEmbedding(text: string): Promise<number[]> {
31
+ const embeddings = await this.aiModule.embeddings([text]);
32
+ return embeddings[0];
33
+ }
34
+
35
+ cosineSimilarity(a: number[], b: number[]): number {
36
+ const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
37
+ const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
38
+ const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
39
+ return dotProduct / (magnitudeA * magnitudeB);
40
+ }
41
+ }
@@ -0,0 +1,8 @@
1
+ import { Service } from 'fragment';
2
+
3
+ @Service()
4
+ export class AppService {
5
+ getMessage(): string {
6
+ return 'Welcome to Fragment Framework!';
7
+ }
8
+ }
@@ -0,0 +1,75 @@
1
+ import { Service } from "fragment";
2
+ import { ConversationRepository } from "../repositories/conversation.repository";
3
+ import { MessageRepository } from "../repositories/message.repository";
4
+ import { AIService } from "./ai.service";
5
+
6
+ @Service()
7
+ export class ConversationService {
8
+ constructor(
9
+ private conversationRepository: ConversationRepository,
10
+ private messageRepository: MessageRepository,
11
+ private aiService: AIService,
12
+ ) {}
13
+
14
+ async create(userId: number, title: string) {
15
+ return this.conversationRepository.create({ userId, title });
16
+ }
17
+
18
+ async findByUser(userId: number) {
19
+ return this.conversationRepository.findByUser(userId);
20
+ }
21
+
22
+ async addMessage(conversationId: number, role: string, content: string) {
23
+ const embedding = await this.aiService.generateEmbedding(content);
24
+
25
+ return this.messageRepository.create({
26
+ conversationId,
27
+ role,
28
+ content,
29
+ embedding,
30
+ });
31
+ }
32
+
33
+ async getMessages(conversationId: number) {
34
+ return this.messageRepository.findByConversation(conversationId);
35
+ }
36
+
37
+ async chat(conversationId: number, userMessage: string) {
38
+ await this.addMessage(conversationId, "user", userMessage);
39
+
40
+ const messages = await this.getMessages(conversationId);
41
+ const aiMessages = messages.map((m:any) => ({
42
+ role: m.role as any,
43
+ content: m.content,
44
+ }));
45
+
46
+ const response = await this.aiService.chat(aiMessages);
47
+
48
+ await this.addMessage(conversationId, "assistant", response);
49
+
50
+ return { response };
51
+ }
52
+
53
+ async semanticSearch(query: string, conversationId?: number) {
54
+ const queryEmbedding = await this.aiService.generateEmbedding(query);
55
+
56
+ let messages = await this.messageRepository.findAll();
57
+
58
+ if (conversationId) {
59
+ messages = messages.filter((m) => m.conversationId === conversationId);
60
+ }
61
+
62
+ const results = messages
63
+ .map((message) => ({
64
+ message,
65
+ similarity: this.aiService.cosineSimilarity(
66
+ queryEmbedding,
67
+ message.embedding || [],
68
+ ),
69
+ }))
70
+ .sort((a, b) => b.similarity - a.similarity)
71
+ .slice(0, 5);
72
+
73
+ return results;
74
+ }
75
+ }
@@ -0,0 +1,27 @@
1
+ import { Service } from 'fragment';
2
+ import { MessageRepository } from '../repositories/message.repository';
3
+
4
+ @Service()
5
+ export class MessageService {
6
+ constructor(private messageRepository: MessageRepository) {}
7
+
8
+ async findAll() {
9
+ return [];
10
+ }
11
+
12
+ async findOne(id: string) {
13
+ return { id };
14
+ }
15
+
16
+ async create(data: any) {
17
+ return data;
18
+ }
19
+
20
+ async update(id: string, data: any) {
21
+ return { id, ...data };
22
+ }
23
+
24
+ async delete(id: string) {
25
+ return { deleted: true, id };
26
+ }
27
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": [
6
+ "ES2020"
7
+ ],
8
+ "outDir": "./dist",
9
+ "rootDir": "./src",
10
+ "strict": true,
11
+ "esModuleInterop": true,
12
+ "experimentalDecorators": true,
13
+ "emitDecoratorMetadata": true,
14
+ "skipLibCheck": true
15
+ },
16
+ "include": [
17
+ "src/**/*"
18
+ ],
19
+ "exclude": [
20
+ "node_modules",
21
+ "dist"
22
+ ]
23
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "server": {
3
+ "port": 3000,
4
+ "host": "0.0.0.0"
5
+ },
6
+ "database": {
7
+ "type": "sqlite",
8
+ "database": "database.sqlite",
9
+ "synchronize": true,
10
+ "logging": false,
11
+ "entities": [
12
+ "dist/**/*.entity.js"
13
+ ],
14
+ "migrations": [
15
+ "dist/migrations/**/*.js"
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "blog-api",
3
+ "version": "1.0.0",
4
+ "main": "dist/main.js",
5
+ "scripts": {
6
+ "start": "node dist/main.js",
7
+ "dev": "fragment serve",
8
+ "build": "fragment build",
9
+ "test": "fragment test"
10
+ },
11
+ "dependencies": {
12
+ "fragment": "^1.0.0",
13
+ "reflect-metadata": "^0.1.13"
14
+ },
15
+ "devDependencies": {
16
+ "typescript": "^5.3.3",
17
+ "@types/node": "^20.10.5"
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ import { Controller, Get } from 'fragment';
2
+
3
+ @Controller('/api')
4
+ export class AppController {
5
+ @Get('/health')
6
+ health() {
7
+ return { status: 'ok', timestamp: new Date().toISOString() };
8
+ }
9
+ }
@@ -0,0 +1,17 @@
1
+ import { Controller, Post, Body } from 'fragment';
2
+ import { AuthService } from '../services/auth.service';
3
+
4
+ @Controller('/auth')
5
+ export class AuthController {
6
+ constructor(private authService: AuthService) {}
7
+
8
+ @Post('/login')
9
+ async login(@Body() body: any) {
10
+ return this.authService.login(body.email, body.password);
11
+ }
12
+
13
+ @Post('/register')
14
+ async register(@Body() body: any) {
15
+ return this.authService.register(body);
16
+ }
17
+ }
@@ -0,0 +1,29 @@
1
+ import { Controller, Get, Post, Put, Delete, Body, Param } from 'fragment';
2
+
3
+ @Controller('/category')
4
+ export class CategoryController {
5
+ @Get()
6
+ findAll() {
7
+ return [];
8
+ }
9
+
10
+ @Get('/:id')
11
+ findOne(@Param('id') id: string) {
12
+ return { id };
13
+ }
14
+
15
+ @Post()
16
+ create(@Body() body: any) {
17
+ return body;
18
+ }
19
+
20
+ @Put('/:id')
21
+ update(@Param('id') id: string, @Body() body: any) {
22
+ return { id, ...body };
23
+ }
24
+
25
+ @Delete('/:id')
26
+ delete(@Param('id') id: string) {
27
+ return { deleted: true, id };
28
+ }
29
+ }