@flink-app/flink 0.14.3 → 2.0.0-alpha.100

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 (280) hide show
  1. package/CHANGELOG.md +1051 -0
  2. package/SCHEMA_EXTRACTION_ANALYSIS.md +494 -0
  3. package/SIMPLE_AST_FEASIBILITY.md +570 -0
  4. package/bin/flink.ts +13 -2
  5. package/cli/build.ts +24 -44
  6. package/cli/clean.ts +13 -25
  7. package/cli/cli-utils.ts +190 -17
  8. package/cli/dev.ts +252 -0
  9. package/cli/loadEnvFiles.ts +116 -0
  10. package/cli/run.ts +45 -62
  11. package/dist/bin/flink.js +61 -2
  12. package/dist/cli/build.js +20 -25
  13. package/dist/cli/clean.js +12 -10
  14. package/dist/cli/cli-utils.d.ts +34 -3
  15. package/dist/cli/cli-utils.js +193 -12
  16. package/dist/cli/dev.d.ts +2 -0
  17. package/dist/cli/dev.js +279 -0
  18. package/dist/cli/loadEnvFiles.d.ts +30 -0
  19. package/dist/cli/loadEnvFiles.js +113 -0
  20. package/dist/cli/run.js +47 -46
  21. package/dist/src/DependencyTracker.d.ts +44 -0
  22. package/dist/src/DependencyTracker.js +239 -0
  23. package/dist/src/FlinkApp.d.ts +163 -10
  24. package/dist/src/FlinkApp.js +847 -184
  25. package/dist/src/FlinkContext.d.ts +41 -0
  26. package/dist/src/FlinkErrors.d.ts +19 -6
  27. package/dist/src/FlinkErrors.js +36 -42
  28. package/dist/src/FlinkHttpHandler.d.ts +219 -26
  29. package/dist/src/FlinkHttpHandler.js +37 -1
  30. package/dist/src/FlinkJob.d.ts +10 -0
  31. package/dist/src/FlinkLog.d.ts +82 -18
  32. package/dist/src/FlinkLog.js +165 -13
  33. package/dist/src/FlinkLogFactory.d.ts +288 -0
  34. package/dist/src/FlinkLogFactory.js +619 -0
  35. package/dist/src/FlinkRepo.d.ts +10 -2
  36. package/dist/src/FlinkRepo.js +11 -1
  37. package/dist/src/FlinkRequestContext.d.ts +63 -0
  38. package/dist/src/FlinkRequestContext.js +74 -0
  39. package/dist/src/FlinkResponse.d.ts +6 -0
  40. package/dist/src/FlinkService.d.ts +38 -0
  41. package/dist/src/FlinkService.js +46 -0
  42. package/dist/src/LeaderElection.d.ts +45 -0
  43. package/dist/src/LeaderElection.js +269 -0
  44. package/dist/src/SchemaCache.d.ts +84 -0
  45. package/dist/src/SchemaCache.js +289 -0
  46. package/dist/src/TypeScriptCompiler.d.ts +161 -51
  47. package/dist/src/TypeScriptCompiler.js +1253 -617
  48. package/dist/src/TypeScriptUtils.js +4 -0
  49. package/dist/src/ai/AgentRunner.d.ts +39 -0
  50. package/dist/src/ai/AgentRunner.js +760 -0
  51. package/dist/src/ai/ConversationAgent.d.ts +279 -0
  52. package/dist/src/ai/ConversationAgent.js +404 -0
  53. package/dist/src/ai/ConversationFlinkAgent.d.ts +278 -0
  54. package/dist/src/ai/ConversationFlinkAgent.js +404 -0
  55. package/dist/src/ai/FlinkAgent.d.ts +690 -0
  56. package/dist/src/ai/FlinkAgent.js +729 -0
  57. package/dist/src/ai/FlinkTool.d.ts +135 -0
  58. package/dist/src/ai/FlinkTool.js +2 -0
  59. package/dist/src/ai/InMemoryConversationAgent.d.ts +121 -0
  60. package/dist/src/ai/InMemoryConversationAgent.js +209 -0
  61. package/dist/src/ai/LLMAdapter.d.ts +148 -0
  62. package/dist/src/ai/LLMAdapter.js +2 -0
  63. package/dist/src/ai/PersistentFlinkAgent.d.ts +278 -0
  64. package/dist/src/ai/PersistentFlinkAgent.js +403 -0
  65. package/dist/src/ai/SubAgentExecutor.d.ts +38 -0
  66. package/dist/src/ai/SubAgentExecutor.js +223 -0
  67. package/dist/src/ai/ToolExecutor.d.ts +64 -0
  68. package/dist/src/ai/ToolExecutor.js +497 -0
  69. package/dist/src/ai/agentInstructions.d.ts +68 -0
  70. package/dist/src/ai/agentInstructions.js +286 -0
  71. package/dist/src/ai/index.d.ts +8 -0
  72. package/dist/src/ai/index.js +26 -0
  73. package/dist/src/ai/instructionFileLoader.d.ts +44 -0
  74. package/dist/src/ai/instructionFileLoader.js +179 -0
  75. package/dist/src/auth/FlinkAuthPlugin.d.ts +1 -1
  76. package/dist/src/handlers/StreamWriterFactory.d.ts +20 -0
  77. package/dist/src/handlers/StreamWriterFactory.js +83 -0
  78. package/dist/src/index.d.ts +14 -0
  79. package/dist/src/index.js +17 -0
  80. package/dist/src/loadPluginSchemas.d.ts +45 -0
  81. package/dist/src/loadPluginSchemas.js +143 -0
  82. package/dist/src/schema-extraction/ComplexTypeDetection.d.ts +40 -0
  83. package/dist/src/schema-extraction/ComplexTypeDetection.js +75 -0
  84. package/dist/src/schema-extraction/TypeScriptSourceParser.d.ts +321 -0
  85. package/dist/src/schema-extraction/TypeScriptSourceParser.js +925 -0
  86. package/dist/src/schema-extraction/TypeScriptSourceParser.spec.d.ts +1 -0
  87. package/dist/src/schema-extraction/TypeScriptSourceParser.spec.js +233 -0
  88. package/dist/src/schema-extraction/TypeScriptTokenizer.d.ts +57 -0
  89. package/dist/src/schema-extraction/TypeScriptTokenizer.js +177 -0
  90. package/dist/src/schema-extraction/index.d.ts +2 -0
  91. package/dist/src/schema-extraction/index.js +20 -0
  92. package/dist/src/schema-extraction/types.d.ts +31 -0
  93. package/dist/src/schema-extraction/types.js +2 -0
  94. package/dist/src/utils/loadFlinkConfig.d.ts +53 -0
  95. package/dist/src/utils/loadFlinkConfig.js +77 -0
  96. package/dist/src/utils.d.ts +30 -0
  97. package/dist/src/utils.js +52 -0
  98. package/dist/src/workers/SchemaGeneratorWorker.d.ts +1 -0
  99. package/dist/src/workers/SchemaGeneratorWorker.js +49 -0
  100. package/dist/src/workers/WorkerPool.d.ts +60 -0
  101. package/dist/src/workers/WorkerPool.js +306 -0
  102. package/examples/logging-hierarchical-example.ts +125 -0
  103. package/package.json +29 -4
  104. package/readme.md +499 -0
  105. package/spec/AgentDescendantDetection.spec.ts +335 -0
  106. package/spec/AgentDuplicateDetection.spec.ts +112 -0
  107. package/spec/AgentObserver.spec.ts +266 -0
  108. package/spec/AgentRunner.spec.ts +1062 -0
  109. package/spec/AsyncLocalStorageContext.spec.ts +223 -0
  110. package/spec/ConversationHooks.spec.ts +257 -0
  111. package/spec/FlinkAgent.spec.ts +681 -0
  112. package/spec/FlinkApp.htmlResponse.spec.ts +260 -0
  113. package/spec/FlinkApp.onError.invocation.spec.ts +151 -0
  114. package/spec/FlinkApp.onError.spec.ts +1 -2
  115. package/spec/FlinkApp.query.spec.ts +107 -0
  116. package/spec/FlinkApp.routeOrdering.spec.ts +61 -0
  117. package/spec/FlinkApp.undefinedResponse.spec.ts +123 -0
  118. package/spec/FlinkApp.validationMode.spec.ts +155 -0
  119. package/spec/FlinkJob.spec.ts +171 -0
  120. package/spec/FlinkLogFactory.spec.ts +337 -0
  121. package/spec/FlinkRepo.spec.ts +1 -1
  122. package/spec/LeaderElection.spec.ts +174 -0
  123. package/spec/StreamingIntegration.spec.ts +139 -0
  124. package/spec/ToolExecutor.spec.ts +465 -0
  125. package/spec/TypeScriptCompiler.spec.ts +1 -1
  126. package/spec/TypeScriptSourceParser.spec.ts +1215 -0
  127. package/spec/TypeScriptTokenizer.spec.ts +366 -0
  128. package/spec/ai/ContextCompaction.spec.ts +405 -0
  129. package/spec/ai/ConversationAgent.spec.ts +520 -0
  130. package/spec/ai/InMemoryConversationAgent.spec.ts +144 -0
  131. package/spec/ai/agentInstructions.spec.ts +358 -0
  132. package/spec/fixtures/agent-instructions/TestAgent.ts +24 -0
  133. package/spec/fixtures/agent-instructions/simple.md +3 -0
  134. package/spec/fixtures/agent-instructions/template.md +18 -0
  135. package/spec/fixtures/agent-instructions/yaml-format.yaml +9 -0
  136. package/spec/mock-project/dist/.tsbuildinfo +1 -0
  137. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar.js +56 -0
  138. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCar2.js +58 -0
  139. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema.js +52 -0
  140. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema2.js +52 -0
  141. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithArraySchema3.js +52 -0
  142. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema.js +54 -0
  143. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithLiteralSchema2.js +54 -0
  144. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile.js +57 -0
  145. package/spec/mock-project/dist/spec/mock-project/src/handlers/GetCarWithSchemaInFile2.js +57 -0
  146. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler.js +53 -0
  147. package/spec/mock-project/dist/spec/mock-project/src/handlers/ManuallyAddedHandler2.js +55 -0
  148. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchCar.js +57 -0
  149. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOnboardingSession.js +75 -0
  150. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchOrderWithComplexTypes.js +57 -0
  151. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchProductWithIntersection.js +58 -0
  152. package/spec/mock-project/dist/spec/mock-project/src/handlers/PatchUserWithUnion.js +58 -0
  153. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostCar.js +54 -0
  154. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogin.js +55 -0
  155. package/spec/mock-project/dist/spec/mock-project/src/handlers/PostLogout.js +54 -0
  156. package/spec/mock-project/dist/spec/mock-project/src/handlers/PutCar.js +54 -0
  157. package/spec/mock-project/dist/spec/mock-project/src/index.js +83 -0
  158. package/spec/mock-project/dist/spec/mock-project/src/repos/CarRepo.js +26 -0
  159. package/spec/mock-project/dist/spec/mock-project/src/schemas/Car.js +2 -0
  160. package/spec/mock-project/dist/spec/mock-project/src/schemas/DefaultExportSchema.js +2 -0
  161. package/spec/mock-project/dist/spec/mock-project/src/schemas/FileWithTwoSchemas.js +2 -0
  162. package/spec/mock-project/dist/src/FlinkApp.js +1000 -0
  163. package/spec/mock-project/dist/src/FlinkContext.js +2 -0
  164. package/spec/mock-project/dist/src/FlinkErrors.js +143 -0
  165. package/spec/mock-project/dist/src/FlinkHttpHandler.js +47 -0
  166. package/spec/mock-project/dist/src/FlinkJob.js +2 -0
  167. package/spec/mock-project/dist/src/FlinkLog.js +119 -0
  168. package/spec/mock-project/dist/src/FlinkLogFactory.js +617 -0
  169. package/spec/mock-project/dist/src/FlinkPlugin.js +2 -0
  170. package/spec/mock-project/dist/src/FlinkRepo.js +224 -0
  171. package/spec/mock-project/dist/src/FlinkRequestContext.js +74 -0
  172. package/spec/mock-project/dist/src/FlinkResponse.js +2 -0
  173. package/spec/mock-project/dist/src/ai/AgentExecutor.js +279 -0
  174. package/spec/mock-project/dist/src/ai/AgentRunner.js +632 -0
  175. package/spec/mock-project/dist/src/ai/ConversationAgent.js +402 -0
  176. package/spec/mock-project/dist/src/ai/ConversationFlinkAgent.js +422 -0
  177. package/spec/mock-project/dist/src/ai/FlinkAgent.js +699 -0
  178. package/spec/mock-project/dist/src/ai/FlinkTool.js +2 -0
  179. package/spec/mock-project/dist/src/ai/InMemoryConversationAgent.js +209 -0
  180. package/spec/mock-project/dist/src/ai/LLMAdapter.js +2 -0
  181. package/spec/mock-project/dist/src/ai/SubAgentExecutor.js +223 -0
  182. package/spec/mock-project/dist/src/ai/ToolExecutor.js +412 -0
  183. package/spec/mock-project/dist/src/ai/agentInstructions.js +246 -0
  184. package/spec/mock-project/dist/src/auth/FlinkAuthPlugin.js +2 -0
  185. package/spec/mock-project/dist/src/auth/FlinkAuthUser.js +2 -0
  186. package/spec/mock-project/dist/src/handlers/GetCar.js +26 -52
  187. package/spec/mock-project/dist/src/handlers/GetCar.js.map +1 -0
  188. package/spec/mock-project/dist/src/handlers/GetCar2.js +32 -54
  189. package/spec/mock-project/dist/src/handlers/GetCar2.js.map +1 -0
  190. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js +26 -48
  191. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema.js.map +1 -0
  192. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js +28 -48
  193. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema2.js.map +1 -0
  194. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js +29 -48
  195. package/spec/mock-project/dist/src/handlers/GetCarWithArraySchema3.js.map +1 -0
  196. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js +26 -50
  197. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema.js.map +1 -0
  198. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js +28 -50
  199. package/spec/mock-project/dist/src/handlers/GetCarWithLiteralSchema2.js.map +1 -0
  200. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js +27 -53
  201. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile.js.map +1 -0
  202. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js +29 -53
  203. package/spec/mock-project/dist/src/handlers/GetCarWithSchemaInFile2.js.map +1 -0
  204. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js +16 -49
  205. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler.js.map +1 -0
  206. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js +25 -50
  207. package/spec/mock-project/dist/src/handlers/ManuallyAddedHandler2.js.map +1 -0
  208. package/spec/mock-project/dist/src/handlers/PatchCar.js +27 -53
  209. package/spec/mock-project/dist/src/handlers/PatchCar.js.map +1 -0
  210. package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js +44 -70
  211. package/spec/mock-project/dist/src/handlers/PatchOnboardingSession.js.map +1 -0
  212. package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js +27 -53
  213. package/spec/mock-project/dist/src/handlers/PatchOrderWithComplexTypes.js.map +1 -0
  214. package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js +28 -54
  215. package/spec/mock-project/dist/src/handlers/PatchProductWithIntersection.js.map +1 -0
  216. package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js +28 -54
  217. package/spec/mock-project/dist/src/handlers/PatchUserWithUnion.js.map +1 -0
  218. package/spec/mock-project/dist/src/handlers/PostCar.js +24 -50
  219. package/spec/mock-project/dist/src/handlers/PostCar.js.map +1 -0
  220. package/spec/mock-project/dist/src/handlers/PostLogin.js +25 -51
  221. package/spec/mock-project/dist/src/handlers/PostLogin.js.map +1 -0
  222. package/spec/mock-project/dist/src/handlers/PostLogout.js +24 -50
  223. package/spec/mock-project/dist/src/handlers/PostLogout.js.map +1 -0
  224. package/spec/mock-project/dist/src/handlers/PutCar.js +24 -50
  225. package/spec/mock-project/dist/src/handlers/PutCar.js.map +1 -0
  226. package/spec/mock-project/dist/src/handlers/StreamWriterFactory.js +83 -0
  227. package/spec/mock-project/dist/src/index.js +52 -76
  228. package/spec/mock-project/dist/src/index.js.map +1 -0
  229. package/spec/mock-project/dist/src/mock-data-generator.js +9 -0
  230. package/spec/mock-project/dist/src/repos/CarRepo.js +12 -24
  231. package/spec/mock-project/dist/src/repos/CarRepo.js.map +1 -0
  232. package/spec/mock-project/dist/src/schemas/Car.js +3 -1
  233. package/spec/mock-project/dist/src/schemas/Car.js.map +1 -0
  234. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js +3 -1
  235. package/spec/mock-project/dist/src/schemas/DefaultExportSchema.js.map +1 -0
  236. package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js +3 -1
  237. package/spec/mock-project/dist/src/schemas/FileWithTwoSchemas.js.map +1 -0
  238. package/spec/mock-project/dist/src/utils.js +290 -0
  239. package/spec/mock-project/tsconfig.json +6 -1
  240. package/spec/schema-generation-nested-objects.spec.ts +97 -0
  241. package/spec/testHelpers.ts +49 -0
  242. package/spec/utils.caseConversion.spec.ts +78 -0
  243. package/spec/utils.spec.ts +13 -13
  244. package/src/DependencyTracker.ts +166 -0
  245. package/src/FlinkApp.ts +919 -155
  246. package/src/FlinkContext.ts +43 -0
  247. package/src/FlinkErrors.ts +32 -12
  248. package/src/FlinkHttpHandler.ts +246 -28
  249. package/src/FlinkJob.ts +11 -0
  250. package/src/FlinkLog.ts +119 -12
  251. package/src/FlinkLogFactory.ts +699 -0
  252. package/src/FlinkRepo.ts +10 -3
  253. package/src/FlinkRequestContext.ts +95 -0
  254. package/src/FlinkResponse.ts +6 -0
  255. package/src/FlinkService.ts +49 -0
  256. package/src/LeaderElection.ts +203 -0
  257. package/src/SchemaCache.ts +232 -0
  258. package/src/TypeScriptCompiler.ts +1347 -610
  259. package/src/TypeScriptUtils.ts +5 -0
  260. package/src/ai/AgentRunner.ts +646 -0
  261. package/src/ai/ConversationAgent.ts +413 -0
  262. package/src/ai/FlinkAgent.ts +1069 -0
  263. package/src/ai/FlinkTool.ts +165 -0
  264. package/src/ai/InMemoryConversationAgent.ts +149 -0
  265. package/src/ai/LLMAdapter.ts +126 -0
  266. package/src/ai/ToolExecutor.ts +485 -0
  267. package/src/ai/agentInstructions.ts +245 -0
  268. package/src/ai/index.ts +8 -0
  269. package/src/ai/instructionFileLoader.ts +156 -0
  270. package/src/auth/FlinkAuthPlugin.ts +2 -1
  271. package/src/handlers/StreamWriterFactory.ts +84 -0
  272. package/src/index.ts +14 -0
  273. package/src/loadPluginSchemas.ts +141 -0
  274. package/src/schema-extraction/TypeScriptSourceParser.ts +1058 -0
  275. package/src/schema-extraction/TypeScriptTokenizer.ts +205 -0
  276. package/src/schema-extraction/index.ts +2 -0
  277. package/src/schema-extraction/types.ts +34 -0
  278. package/src/utils/loadFlinkConfig.ts +89 -0
  279. package/src/utils.ts +52 -0
  280. package/tsconfig.json +6 -1
@@ -0,0 +1,925 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TypeScriptSourceParser = void 0;
4
+ var TypeScriptTokenizer_1 = require("./TypeScriptTokenizer");
5
+ /**
6
+ * Pure utility class for parsing TypeScript source code as text.
7
+ * All methods are static and side-effect free for easy testing.
8
+ *
9
+ * This class provides fast, regex-based parsing without using ts-morph
10
+ * or the TypeScript compiler, making it suitable for performance-critical
11
+ * schema extraction.
12
+ */
13
+ var TypeScriptSourceParser = /** @class */ (function () {
14
+ function TypeScriptSourceParser() {
15
+ }
16
+ /**
17
+ * Remove comments from source code to avoid false positives in schema detection.
18
+ * Handles both single-line (//) and multi-line (/* *\/) comments.
19
+ */
20
+ TypeScriptSourceParser.removeComments = function (sourceText) {
21
+ // Remove multi-line comments: /* ... */
22
+ var text = sourceText.replace(/\/\*[\s\S]*?\*\//g, '');
23
+ // Remove single-line comments: // ...
24
+ text = text.replace(/\/\/.*$/gm, '');
25
+ return text;
26
+ };
27
+ /**
28
+ * Detect if a tool source file uses Zod or JSON schemas.
29
+ * If true, TypeScript schema extraction should be skipped.
30
+ *
31
+ * Note: Strips comments first to avoid false positives from commented-out schemas.
32
+ */
33
+ TypeScriptSourceParser.detectSchemaType = function (sourceText) {
34
+ // Strip comments to avoid matching commented-out schema definitions
35
+ var textWithoutComments = this.removeComments(sourceText);
36
+ var hasZodSchemas = textWithoutComments.includes('inputSchema:') || textWithoutComments.includes('outputSchema:');
37
+ var hasJsonSchemas = textWithoutComments.includes('inputJsonSchema:') || textWithoutComments.includes('outputJsonSchema:');
38
+ return {
39
+ hasZodSchemas: hasZodSchemas,
40
+ hasJsonSchemas: hasJsonSchemas,
41
+ shouldSkipTypeScriptExtraction: hasZodSchemas || hasJsonSchemas,
42
+ };
43
+ };
44
+ /**
45
+ * Extract type arguments from Handler<Ctx, Req, Res, Params, Query> declaration.
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * parseHandlerTypeArgs('const handler: Handler<AppCtx, LoginReq, LoginRes>')
50
+ * // Returns: { contextType: 'AppCtx', reqType: 'LoginReq', resType: 'LoginRes' }
51
+ * ```
52
+ */
53
+ TypeScriptSourceParser.parseHandlerTypeArgs = function (sourceText) {
54
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
55
+ // Try to find Handler< or GetHandler< or PostHandler< etc.
56
+ var handlerMatch = sourceText.match(/\b(Get|Post|Put|Patch|Delete)?Handler\s*</);
57
+ if (!handlerMatch) {
58
+ return null;
59
+ }
60
+ var handlerType = handlerMatch[0].replace(/\s*<$/, '');
61
+ var startIdx = sourceText.indexOf(handlerMatch[0]);
62
+ if (startIdx === -1) {
63
+ return null;
64
+ }
65
+ // Find the matching closing > by counting bracket depth
66
+ var depth = 0;
67
+ var endIdx = -1;
68
+ for (var i = startIdx + handlerMatch[0].length; i < sourceText.length; i++) {
69
+ if (sourceText[i] === '<') {
70
+ depth++;
71
+ }
72
+ else if (sourceText[i] === '>') {
73
+ if (depth === 0) {
74
+ endIdx = i;
75
+ break;
76
+ }
77
+ depth--;
78
+ }
79
+ }
80
+ if (endIdx === -1) {
81
+ return null;
82
+ }
83
+ var typeArgsText = sourceText.slice(startIdx + handlerMatch[0].length, endIdx);
84
+ var typeArgs = this.splitTopLevelCommas(typeArgsText);
85
+ if (typeArgs.length === 0) {
86
+ return null;
87
+ }
88
+ // Handler<Ctx, Req, Res, Params, Query>
89
+ // GetHandler<Ctx, Res, Params, Query> (no Req)
90
+ // PostHandler<Ctx, Req, Res, Params, Query>
91
+ // etc.
92
+ var isGetHandler = handlerType === 'GetHandler';
93
+ if (isGetHandler) {
94
+ // GetHandler<Ctx, Res, Params, Query>
95
+ return {
96
+ contextType: (_a = typeArgs[0]) === null || _a === void 0 ? void 0 : _a.trim(),
97
+ resType: (_b = typeArgs[1]) === null || _b === void 0 ? void 0 : _b.trim(),
98
+ paramsType: (_c = typeArgs[2]) === null || _c === void 0 ? void 0 : _c.trim(),
99
+ queryType: (_d = typeArgs[3]) === null || _d === void 0 ? void 0 : _d.trim(),
100
+ };
101
+ }
102
+ else {
103
+ // Handler<Ctx, Req, Res, Params, Query>
104
+ return {
105
+ contextType: (_e = typeArgs[0]) === null || _e === void 0 ? void 0 : _e.trim(),
106
+ reqType: (_f = typeArgs[1]) === null || _f === void 0 ? void 0 : _f.trim(),
107
+ resType: (_g = typeArgs[2]) === null || _g === void 0 ? void 0 : _g.trim(),
108
+ paramsType: (_h = typeArgs[3]) === null || _h === void 0 ? void 0 : _h.trim(),
109
+ queryType: (_j = typeArgs[4]) === null || _j === void 0 ? void 0 : _j.trim(),
110
+ };
111
+ }
112
+ };
113
+ /**
114
+ * Extract type arguments from FlinkTool<Ctx, Input, Output> declaration.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * parseFlinkToolTypeArgs('const handler: FlinkTool<Ctx, CreateDocInput, ToolResult<DocOutput>>')
119
+ * // Returns: { contextType: 'Ctx', inputType: 'CreateDocInput', outputType: 'ToolResult<DocOutput>' }
120
+ * ```
121
+ */
122
+ TypeScriptSourceParser.parseFlinkToolTypeArgs = function (sourceText) {
123
+ // Find FlinkTool< and then manually parse to find the matching closing >
124
+ var startIdx = sourceText.indexOf('FlinkTool<');
125
+ if (startIdx === -1) {
126
+ return null;
127
+ }
128
+ // Find the matching closing > by counting bracket depth
129
+ var depth = 0;
130
+ var endIdx = -1;
131
+ for (var i = startIdx + 'FlinkTool<'.length; i < sourceText.length; i++) {
132
+ if (sourceText[i] === '<') {
133
+ depth++;
134
+ }
135
+ else if (sourceText[i] === '>') {
136
+ if (depth === 0) {
137
+ endIdx = i;
138
+ break;
139
+ }
140
+ depth--;
141
+ }
142
+ }
143
+ if (endIdx === -1) {
144
+ return null;
145
+ }
146
+ // Extract the content between the brackets
147
+ var typeArgsStr = sourceText.substring(startIdx + 'FlinkTool<'.length, endIdx);
148
+ // Parse the type arguments by splitting on commas at the top level (not inside angle brackets)
149
+ var typeArgs = this.splitTopLevelCommas(typeArgsStr);
150
+ if (typeArgs.length < 3) {
151
+ return null;
152
+ }
153
+ return {
154
+ contextType: typeArgs[0].trim(),
155
+ inputType: typeArgs[1].trim(),
156
+ outputType: typeArgs[2].trim(),
157
+ };
158
+ };
159
+ /**
160
+ * Split a string by commas, but only at the top level (not inside angle brackets).
161
+ * Helper for parsing generic type arguments like "Ctx, Input, ToolResult<Output>"
162
+ */
163
+ TypeScriptSourceParser.splitTopLevelCommas = function (str) {
164
+ var result = [];
165
+ var current = '';
166
+ var depth = 0;
167
+ for (var _i = 0, str_1 = str; _i < str_1.length; _i++) {
168
+ var char = str_1[_i];
169
+ if (char === '<') {
170
+ depth++;
171
+ current += char;
172
+ }
173
+ else if (char === '>') {
174
+ depth--;
175
+ current += char;
176
+ }
177
+ else if (char === ',' && depth === 0) {
178
+ result.push(current);
179
+ current = '';
180
+ }
181
+ else {
182
+ current += char;
183
+ }
184
+ }
185
+ if (current) {
186
+ result.push(current);
187
+ }
188
+ return result;
189
+ };
190
+ /**
191
+ * Check if a type should generate a schema.
192
+ * Returns false for primitives and special types, true for named types and inline objects.
193
+ */
194
+ TypeScriptSourceParser.shouldGenerateSchema = function (typeName) {
195
+ // Skip 'any' and 'unknown'
196
+ if (typeName === 'any' || typeName === 'unknown') {
197
+ return false;
198
+ }
199
+ // Generate schemas for inline object types like {} or { foo: string }
200
+ if (typeName.startsWith('{')) {
201
+ return true;
202
+ }
203
+ // Skip primitive types
204
+ var primitives = ['string', 'number', 'boolean', 'void', 'undefined', 'null'];
205
+ if (primitives.includes(typeName.toLowerCase())) {
206
+ return false;
207
+ }
208
+ // Skip binary/non-serializable built-in types that can never have JSON schemas
209
+ var nonSerializableTypes = ['Buffer', 'ArrayBuffer', 'SharedArrayBuffer', 'Blob', 'ReadableStream', 'WritableStream', 'DataView', 'Uint8Array'];
210
+ if (nonSerializableTypes.includes(typeName)) {
211
+ return false;
212
+ }
213
+ // Must be a named type (starts with uppercase letter)
214
+ return /^[A-Z]/.test(typeName);
215
+ };
216
+ /**
217
+ * Check if a type is a built-in TypeScript type.
218
+ */
219
+ TypeScriptSourceParser.isBuiltInType = function (typeName) {
220
+ var builtIns = [
221
+ 'String', 'Number', 'Boolean', 'Date', 'Array', 'Object', 'Record',
222
+ 'Promise', 'Set', 'Map', 'Partial', 'Required', 'Pick', 'Omit',
223
+ 'Readonly', 'ReadonlyArray'
224
+ ];
225
+ return builtIns.includes(typeName);
226
+ };
227
+ /**
228
+ * Extract T from ToolResult<T> type name.
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * unwrapToolResultType('ToolResult<DocOutput>') // Returns: 'DocOutput'
233
+ * unwrapToolResultType('DocOutput') // Returns: 'DocOutput'
234
+ * ```
235
+ */
236
+ TypeScriptSourceParser.unwrapToolResultType = function (typeName) {
237
+ var match = typeName.match(/ToolResult<(.+)>/);
238
+ if (match) {
239
+ return match[1].trim();
240
+ }
241
+ return typeName;
242
+ };
243
+ /**
244
+ * Convert inline object type to interface definition.
245
+ *
246
+ * @example
247
+ * ```typescript
248
+ * convertInlineObjectToInterface('{}', 'MyInput')
249
+ * // Returns: 'export interface MyInput {}'
250
+ *
251
+ * convertInlineObjectToInterface('{ foo: string }', 'MyInput')
252
+ * // Returns: 'export interface MyInput {\n foo: string;\n}'
253
+ * ```
254
+ */
255
+ TypeScriptSourceParser.convertInlineObjectToInterface = function (inlineType, interfaceName) {
256
+ // For empty object, create empty interface
257
+ if (inlineType.trim() === '{}') {
258
+ return "export interface ".concat(interfaceName, " {}");
259
+ }
260
+ // For non-empty inline object, convert to interface
261
+ // Remove outer braces and clean up
262
+ var body = inlineType.trim().slice(1, -1).trim();
263
+ // Ensure properties end with semicolons (convert commas to semicolons if needed)
264
+ body = body.replace(/,\s*$/g, ';').replace(/([^;])\s*$/g, '$1;');
265
+ return "export interface ".concat(interfaceName, " {\n ").concat(body, "\n}");
266
+ };
267
+ /**
268
+ * Find an interface or type definition in source text.
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * const source = `
273
+ * interface User {
274
+ * name: string;
275
+ * }
276
+ * `;
277
+ * findTypeDefinition(source, 'User')
278
+ * // Returns: { name: 'User', definition: 'interface User { ... }', kind: 'interface' }
279
+ * ```
280
+ */
281
+ TypeScriptSourceParser.findTypeDefinition = function (sourceText, typeName) {
282
+ // Skip if it's an inline type
283
+ if (typeName.startsWith('{')) {
284
+ return null;
285
+ }
286
+ // Try to find interface definition first
287
+ // Pattern: (optional JSDoc) interface Name (optional generics) (optional extends) { ... }
288
+ var interfacePattern = new RegExp("((?:\\/\\*\\*[\\s\\S]*?\\*\\/\\s*)?)interface\\s+".concat(typeName, "\\s*"), 'gm');
289
+ var interfaceMatch = interfacePattern.exec(sourceText);
290
+ if (interfaceMatch) {
291
+ var startIndex = interfaceMatch.index;
292
+ var jsDocAndInterface = interfaceMatch[0];
293
+ // Find the opening brace
294
+ var afterInterface = sourceText.slice(interfaceMatch.index + interfaceMatch[0].length);
295
+ var braceMatch = afterInterface.match(/^[^{]*\{/);
296
+ if (braceMatch) {
297
+ var braceStart = interfaceMatch.index + interfaceMatch[0].length + braceMatch[0].length - 1;
298
+ // Use tokenizer for robust bracket matching (handles strings and comments)
299
+ var tokenizer = new TypeScriptTokenizer_1.TypeScriptTokenizer(sourceText);
300
+ var braceEnd = tokenizer.findMatchingBracketAt(braceStart, '{');
301
+ if (braceEnd !== -1) {
302
+ var definition = sourceText.slice(startIndex, braceEnd + 1).trim();
303
+ return {
304
+ name: typeName,
305
+ definition: definition,
306
+ kind: 'interface',
307
+ };
308
+ }
309
+ }
310
+ }
311
+ // Match type alias: type Name = ...;
312
+ var typePattern = new RegExp("((?:\\/\\*\\*[\\s\\S]*?\\*\\/\\s*)?)type\\s+".concat(typeName, "\\s*=\\s*"), 'gm');
313
+ var typeMatch = typePattern.exec(sourceText);
314
+ if (typeMatch) {
315
+ var startIndex = typeMatch.index;
316
+ var afterEquals = typeMatch.index + typeMatch[0].length;
317
+ // Use tokenizer to find semicolon, properly handling strings and comments
318
+ var tokenizer = new TypeScriptTokenizer_1.TypeScriptTokenizer(sourceText);
319
+ var depth = 0;
320
+ var i = afterEquals;
321
+ while (i < sourceText.length) {
322
+ var token = tokenizer.getNextToken(i);
323
+ // Only process non-string, non-comment tokens
324
+ if (token.type !== 'string' && token.type !== 'comment') {
325
+ var char = token.value;
326
+ // Track depth
327
+ if (char === '{' || char === '[' || char === '(' || char === '<') {
328
+ depth++;
329
+ }
330
+ else if (char === '}' || char === ']' || char === ')' || char === '>') {
331
+ depth--;
332
+ // Closing a bracket back to top level may terminate a
333
+ // semicolon-free type alias (e.g. `type Params = { ... }`
334
+ // with no trailing `;`). Only stop if the type does not
335
+ // continue with an operator such as `|` or `&`.
336
+ if (depth === 0 && !this.typeContinuesAfter(sourceText, token.endPos)) {
337
+ var definition = sourceText.slice(startIndex, token.endPos).trim();
338
+ return {
339
+ name: typeName,
340
+ definition: definition,
341
+ kind: 'type',
342
+ };
343
+ }
344
+ }
345
+ // End of type at semicolon (at depth 0)
346
+ if (char === ';' && depth === 0) {
347
+ var definition = sourceText.slice(startIndex, i + 1).trim();
348
+ return {
349
+ name: typeName,
350
+ definition: definition,
351
+ kind: 'type',
352
+ };
353
+ }
354
+ }
355
+ i = token.endPos;
356
+ }
357
+ }
358
+ return null;
359
+ };
360
+ /**
361
+ * Peek at the next non-whitespace, non-comment character starting at `fromPos`.
362
+ * Returns the character, or undefined if only whitespace/comments remain.
363
+ */
364
+ TypeScriptSourceParser.peekNextSignificantChar = function (sourceText, fromPos) {
365
+ var tokenizer = new TypeScriptTokenizer_1.TypeScriptTokenizer(sourceText);
366
+ var i = fromPos;
367
+ while (i < sourceText.length) {
368
+ var token = tokenizer.getNextToken(i);
369
+ if (token.type === 'comment') {
370
+ i = token.endPos;
371
+ continue;
372
+ }
373
+ if (token.type === 'string') {
374
+ return token.value[0];
375
+ }
376
+ if (!/\s/.test(token.value)) {
377
+ return token.value;
378
+ }
379
+ i = token.endPos;
380
+ }
381
+ return undefined;
382
+ };
383
+ /**
384
+ * Determine whether a type expression continues after `fromPos`, i.e. whether
385
+ * the character that follows is a type-combinator/continuation operator
386
+ * (`|`, `&`, `[`, `.`, etc.) rather than the start of an unrelated statement.
387
+ *
388
+ * Used to decide if a top-level closing bracket terminates a semicolon-free
389
+ * type alias or whether the alias keeps going (e.g. a union of object types).
390
+ */
391
+ TypeScriptSourceParser.typeContinuesAfter = function (sourceText, fromPos) {
392
+ var next = this.peekNextSignificantChar(sourceText, fromPos);
393
+ if (next === undefined) {
394
+ return false;
395
+ }
396
+ // Operators that mean the type expression continues across the boundary.
397
+ return '|&[.<'.includes(next);
398
+ };
399
+ /**
400
+ * Rename an interface or type definition.
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * renameTypeDefinition('interface User { name: string }', 'User', 'Person')
405
+ * // Returns: 'export interface Person { name: string }'
406
+ * ```
407
+ */
408
+ TypeScriptSourceParser.renameTypeDefinition = function (definition, oldName, newName, exportIt) {
409
+ if (exportIt === void 0) { exportIt = true; }
410
+ var exportPrefix = exportIt ? 'export ' : '';
411
+ // Try interface rename
412
+ if (definition.includes('interface')) {
413
+ return definition.replace(new RegExp("interface\\s+".concat(oldName, "\\b")), "".concat(exportPrefix, "interface ").concat(newName));
414
+ }
415
+ // Try type alias rename
416
+ if (definition.includes('type')) {
417
+ return definition.replace(new RegExp("type\\s+".concat(oldName, "\\b")), "".concat(exportPrefix, "type ").concat(newName));
418
+ }
419
+ return definition;
420
+ };
421
+ /**
422
+ * Extract all type names referenced in a type definition.
423
+ * Excludes JSDoc comments and string literals.
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * extractReferencedTypes('interface Doc { author: User; tags: Tag[] }')
428
+ * // Returns: ['User', 'Tag']
429
+ * extractReferencedTypes('PaginatedResponse<Car>')
430
+ * // Returns: ['PaginatedResponse', 'Car']
431
+ * ```
432
+ */
433
+ TypeScriptSourceParser.extractReferencedTypes = function (typeDefinition) {
434
+ var types = [];
435
+ // Remove JSDoc comments to avoid extracting type names from documentation
436
+ var withoutJsDoc = typeDefinition.replace(/\/\*\*[\s\S]*?\*\//g, '');
437
+ // Match type references in actual code
438
+ // Types appear after: : < Array< extends implements | &
439
+ // Also match standalone types (e.g., PaginatedResponse in "PaginatedResponse<Car>")
440
+ // But exclude types after "interface" or "type" keywords (those are definitions, not references)
441
+ var typeContextRegex = /(?<!interface\s)(?<!type\s)(?::\s*|<|Array<|extends\s+|implements\s+|\|\s*|&\s*)?([A-Z][a-zA-Z0-9_]*)/g;
442
+ var match;
443
+ while ((match = typeContextRegex.exec(withoutJsDoc)) !== null) {
444
+ var typeName = match[1];
445
+ // Skip if this looks like it's part of "interface Name" or "type Name"
446
+ var beforeMatch = withoutJsDoc.substring(Math.max(0, match.index - 15), match.index);
447
+ if (/\b(interface|type)\s*$/.test(beforeMatch)) {
448
+ continue;
449
+ }
450
+ // Filter out built-in types and duplicates
451
+ if (!this.isBuiltInType(typeName) && !types.includes(typeName)) {
452
+ types.push(typeName);
453
+ }
454
+ }
455
+ return types;
456
+ };
457
+ /**
458
+ * Check if a type name is an inline object type.
459
+ */
460
+ TypeScriptSourceParser.isInlineObjectType = function (typeName) {
461
+ return typeName.trim().startsWith('{');
462
+ };
463
+ /**
464
+ * Parse JSDoc comment text to extract description.
465
+ * Strips JSDoc comment markers and leading asterisks.
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * parseJsDocDescription('/** Max cars to retrieve *\/')
470
+ * // Returns: "Max cars to retrieve"
471
+ *
472
+ * parseJsDocDescription('/**\n * Max cars to retrieve\n * from the database\n *\/')
473
+ * // Returns: "Max cars to retrieve from the database"
474
+ *
475
+ * parseJsDocDescription('')
476
+ * // Returns: ""
477
+ * ```
478
+ */
479
+ TypeScriptSourceParser.parseJsDocDescription = function (jsDocText) {
480
+ if (!jsDocText) {
481
+ return '';
482
+ }
483
+ // Remove /** and */ markers
484
+ var cleaned = jsDocText.replace(/^\/\*\*/, '').replace(/\*\/$/, '');
485
+ // Remove leading * from each line
486
+ cleaned = cleaned
487
+ .split('\n')
488
+ .map(function (line) { return line.trim().replace(/^\*\s?/, ''); })
489
+ .filter(function (line) { return line.length > 0; })
490
+ .join(' ');
491
+ // Collapse multiple spaces into single space
492
+ cleaned = cleaned.replace(/\s+/g, ' ');
493
+ return cleaned.trim();
494
+ };
495
+ /**
496
+ * Extract property metadata from an object type body.
497
+ * Parses properties with optional JSDoc comments.
498
+ * Only extracts top-level properties (not nested object properties).
499
+ *
500
+ * @param objectBody The content between { and } in an object type
501
+ * @returns Array of property metadata (name + description)
502
+ *
503
+ * @example
504
+ * ```typescript
505
+ * const body = `
506
+ * /** Max cars to retrieve *\/
507
+ * limit: string;
508
+ * page?: number;
509
+ * `;
510
+ * extractPropertiesFromObjectType(body)
511
+ * // Returns: [
512
+ * // { name: "limit", description: "Max cars to retrieve" },
513
+ * // { name: "page", description: "" }
514
+ * // ]
515
+ * ```
516
+ */
517
+ TypeScriptSourceParser.extractPropertiesFromObjectType = function (objectBody) {
518
+ var properties = [];
519
+ var i = 0;
520
+ while (i < objectBody.length) {
521
+ // Skip whitespace
522
+ while (i < objectBody.length && /\s/.test(objectBody[i])) {
523
+ i++;
524
+ }
525
+ if (i >= objectBody.length)
526
+ break;
527
+ // Check for JSDoc comment
528
+ var jsDoc = '';
529
+ if (objectBody[i] === '/' && i + 1 < objectBody.length && objectBody[i + 1] === '*' && i + 2 < objectBody.length && objectBody[i + 2] === '*') {
530
+ var endIndex = objectBody.indexOf('*/', i + 3);
531
+ if (endIndex !== -1) {
532
+ jsDoc = objectBody.slice(i, endIndex + 2);
533
+ i = endIndex + 2;
534
+ }
535
+ else {
536
+ break;
537
+ }
538
+ }
539
+ // Skip whitespace after JSDoc
540
+ while (i < objectBody.length && /\s/.test(objectBody[i])) {
541
+ i++;
542
+ }
543
+ if (i >= objectBody.length)
544
+ break;
545
+ // Extract property name
546
+ var propertyNameMatch = objectBody.slice(i).match(/^(\w+)\??:/);
547
+ if (!propertyNameMatch) {
548
+ i++;
549
+ continue;
550
+ }
551
+ var propertyName = propertyNameMatch[1];
552
+ i += propertyNameMatch[0].length;
553
+ // Skip the type until we hit a delimiter at top level (;, ,, or closing })
554
+ // Use tokenizer to properly handle strings and comments
555
+ var tokenizer = new TypeScriptTokenizer_1.TypeScriptTokenizer(objectBody);
556
+ var depth = 0;
557
+ while (i < objectBody.length) {
558
+ var token = tokenizer.getNextToken(i);
559
+ // Only process non-string, non-comment tokens
560
+ if (token.type !== 'string' && token.type !== 'comment') {
561
+ var char = token.value;
562
+ // Track depth for nested objects/arrays
563
+ if (char === '{' || char === '[' || char === '(') {
564
+ depth++;
565
+ }
566
+ else if (char === '}' || char === ']' || char === ')') {
567
+ depth--;
568
+ }
569
+ // End of property at top level
570
+ if (depth === 0 && (char === ';' || char === ',')) {
571
+ i = token.endPos; // Move past delimiter
572
+ break;
573
+ }
574
+ // End of property at a top-level newline when no `;`/`,`
575
+ // delimiter is used (semicolon-free style, issue #77). Only
576
+ // terminate when the next line starts a new member (an
577
+ // identifier, quoted key, or JSDoc) - not a continuation of
578
+ // the current type such as a leading `|` union arm.
579
+ if (depth === 0 && (char === '\n' || char === '\r')) {
580
+ var next = this.peekNextSignificantChar(objectBody, token.endPos);
581
+ if (next === undefined || /[A-Za-z_$"'/]/.test(next)) {
582
+ break; // Leave i at the newline; outer loop skips whitespace
583
+ }
584
+ }
585
+ }
586
+ i = token.endPos;
587
+ }
588
+ // Add property
589
+ var description = this.parseJsDocDescription(jsDoc);
590
+ properties.push({
591
+ name: propertyName,
592
+ description: description,
593
+ });
594
+ }
595
+ return properties;
596
+ };
597
+ /**
598
+ * Copy a type definition and recursively find all its dependencies.
599
+ * Returns structured data without side effects.
600
+ *
601
+ * @param sourceText Full source file text to search for types
602
+ * @param typeName Name of the type to copy
603
+ * @param newName New name for the type (use same name for dependencies)
604
+ * @param copiedTypes Set of already-copied type names to avoid duplication
605
+ * @returns Object containing the main definition, dependency definitions, and import statements
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * const source = `
610
+ * import { Address } from './Address';
611
+ * interface User {
612
+ * profile: Profile;
613
+ * address: Address;
614
+ * }
615
+ * interface Profile {
616
+ * name: string;
617
+ * }
618
+ * `;
619
+ * const result = copyTypeWithDependencies(source, 'User', 'UserSchema', new Set());
620
+ * // Returns: {
621
+ * // mainDefinition: 'export interface UserSchema { profile: Profile; address: Address; }',
622
+ * // dependencies: ['export interface Profile { name: string; }'],
623
+ * // imports: ['import { Address } from "./Address"'],
624
+ * // copiedTypes: Set(['User', 'Profile'])
625
+ * // }
626
+ * ```
627
+ */
628
+ TypeScriptSourceParser.copyTypeWithDependencies = function (sourceText, typeName, newName, copiedTypes) {
629
+ var dependencies = [];
630
+ var imports = [];
631
+ // Handle inline object types specially
632
+ var mainDefinition = null;
633
+ if (this.isInlineObjectType(typeName)) {
634
+ mainDefinition = this.convertInlineObjectToInterface(typeName, newName);
635
+ }
636
+ else {
637
+ // Find and copy the main type from file
638
+ var found = this.findTypeDefinition(sourceText, typeName);
639
+ if (found) {
640
+ mainDefinition = this.renameTypeDefinition(found.definition, typeName, newName);
641
+ }
642
+ }
643
+ if (!mainDefinition) {
644
+ return { mainDefinition: null, dependencies: [], imports: [], copiedTypes: copiedTypes };
645
+ }
646
+ // Mark this type as copied
647
+ copiedTypes.add(typeName);
648
+ // Find all referenced types in the definition
649
+ var referencedTypes = this.extractReferencedTypes(mainDefinition);
650
+ // Recursively copy each referenced type (if not already copied)
651
+ for (var _i = 0, referencedTypes_1 = referencedTypes; _i < referencedTypes_1.length; _i++) {
652
+ var refType = referencedTypes_1[_i];
653
+ if (!copiedTypes.has(refType) && !this.isBuiltInType(refType)) {
654
+ // Check if this type is defined in the current file
655
+ var typeDef = this.findTypeDefinition(sourceText, refType);
656
+ if (typeDef) {
657
+ // Type is defined in same file - recursively copy it
658
+ var result = this.copyTypeWithDependencies(sourceText, refType, refType, copiedTypes);
659
+ if (result.mainDefinition) {
660
+ dependencies.push(result.mainDefinition);
661
+ }
662
+ dependencies.push.apply(dependencies, result.dependencies);
663
+ imports.push.apply(imports, result.imports);
664
+ }
665
+ else {
666
+ // Type is not in current file - must be imported
667
+ // Extract the import statement for it
668
+ var importStmt = this.extractImportForType(sourceText, refType);
669
+ if (importStmt && !imports.includes(importStmt)) {
670
+ imports.push(importStmt);
671
+ }
672
+ // Mark as copied to avoid trying to find it again
673
+ copiedTypes.add(refType);
674
+ }
675
+ }
676
+ }
677
+ return { mainDefinition: mainDefinition, dependencies: dependencies, imports: imports, copiedTypes: copiedTypes };
678
+ };
679
+ /**
680
+ * Extract import statement for a specific type from source text.
681
+ *
682
+ * @param sourceText Full source file text
683
+ * @param typeName Name of the type to find import for
684
+ * @returns Import statement or null if not found
685
+ *
686
+ * @example
687
+ * ```typescript
688
+ * const source = `
689
+ * import { User } from '../schemas/User';
690
+ * import type { Profile } from '../schemas/Profile';
691
+ * import Foo from '../schemas/Foo';
692
+ * `;
693
+ * extractImportForType(source, 'User')
694
+ * // Returns: "import { User } from '../schemas/User'"
695
+ *
696
+ * extractImportForType(source, 'Profile')
697
+ * // Returns: "import type { Profile } from '../schemas/Profile'"
698
+ *
699
+ * extractImportForType(source, 'Foo')
700
+ * // Returns: "import Foo from '../schemas/Foo'"
701
+ * ```
702
+ */
703
+ TypeScriptSourceParser.extractImportForType = function (sourceText, typeName) {
704
+ // Supports: import Foo from '...' OR import { Foo } from '...'
705
+ // Also supports: import type Foo from '...' OR import type { Foo } from '...'
706
+ var importRegex = new RegExp("import\\s+(?:type\\s+)?(?:{[^}]*\\b".concat(typeName, "\\b[^}]*}|").concat(typeName, ")\\s+from\\s+(['\"][^'\"]+['\"])"), 'gm');
707
+ var match = importRegex.exec(sourceText);
708
+ if (match) {
709
+ return match[0];
710
+ }
711
+ return null;
712
+ };
713
+ /**
714
+ * Extract all imports from a source file.
715
+ * Used to get transitive dependencies when importing a type.
716
+ *
717
+ * @param sourceText Source code to extract imports from
718
+ * @returns Array of import statements
719
+ */
720
+ TypeScriptSourceParser.extractAllImports = function (sourceText) {
721
+ var imports = [];
722
+ // Match all import statements (including type imports, named imports, default imports, namespace imports)
723
+ var importRegex = /import\s+(?:type\s+)?(?:{[^}]+}|\w+|(?:\*\s+as\s+\w+))\s+from\s+['"][^'"]+['"]/gm;
724
+ var match;
725
+ while ((match = importRegex.exec(sourceText)) !== null) {
726
+ imports.push(match[0]);
727
+ }
728
+ return imports;
729
+ };
730
+ /**
731
+ * Adjust import path to be relative to .flink/schemas/ directory.
732
+ *
733
+ * @param importStatement Original import statement
734
+ * @returns Adjusted import statement with corrected path
735
+ *
736
+ * @example
737
+ * ```typescript
738
+ * adjustImportPathForSchemas('import { User } from "../schemas/User"')
739
+ * // Returns: 'import { User } from "../../src/schemas/User"'
740
+ *
741
+ * adjustImportPathForSchemas('import Profile from "../../schemas/Profile"')
742
+ * // Returns: 'import Profile from "../../src/schemas/Profile"'
743
+ *
744
+ * adjustImportPathForSchemas('import { Req } from "../clients/SupermetricsClient"')
745
+ * // Returns: 'import { Req } from "../../src/clients/SupermetricsClient"'
746
+ *
747
+ * adjustImportPathForSchemas('import { Foo } from "@company/shared"')
748
+ * // Returns: 'import { Foo } from "@company/shared"' (unchanged - not relative)
749
+ * ```
750
+ */
751
+ TypeScriptSourceParser.adjustImportPathForSchemas = function (importStatement) {
752
+ // schemas.ts is at: .flink/schemas/schemas.ts
753
+ // Handler imports can be from anywhere in src/ (handlers, schemas, clients, etc.)
754
+ // We need to adjust ALL relative imports to work from .flink/schemas/
755
+ // Extract the path from import statement
756
+ var pathMatch = importStatement.match(/from\s+(['"])([^'"]+)['"]/);
757
+ if (!pathMatch) {
758
+ return importStatement;
759
+ }
760
+ var quote = pathMatch[1];
761
+ var importPath = pathMatch[2];
762
+ // Skip non-relative imports (package imports like "@company/shared", "lodash")
763
+ if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
764
+ return importStatement;
765
+ }
766
+ // For relative imports, we need to adjust the path to work from .flink/schemas/
767
+ // Original: from handler at src/handlers/foo/Bar.ts importing "../clients/Client"
768
+ // Resolves to: src/clients/Client
769
+ // From schemas.ts at .flink/schemas/schemas.ts, we need: "../../src/clients/Client"
770
+ // Extract the path after src/ directory
771
+ // Patterns we handle:
772
+ // - "../schemas/User" → "../../src/schemas/User"
773
+ // - "../../schemas/User" → "../../src/schemas/User"
774
+ // - "../clients/Client" → "../../src/clients/Client"
775
+ // - "../../types/Foo" → "../../src/types/Foo"
776
+ // Find the src directory marker in the path
777
+ var adjustedPath;
778
+ if (importPath.includes('/schemas/')) {
779
+ // Special case for schemas - extract everything after '/schemas/'
780
+ var schemasIndex = importPath.indexOf('/schemas/');
781
+ var pathAfterSchemas = importPath.substring(schemasIndex + '/schemas/'.length);
782
+ adjustedPath = "../../src/schemas/".concat(pathAfterSchemas);
783
+ }
784
+ else {
785
+ // General case: assume the import resolves to src/<something>
786
+ // Count the number of "../" to understand directory depth, then reconstruct
787
+ // For simplicity, we'll assume all imports from handlers resolve to src/*
788
+ // Pattern: any number of "../" optionally followed by "./" followed by a directory path
789
+ // Strip both "../" and "./" prefixes
790
+ var pathWithoutLeadingDots = importPath.replace(/^(\.\.\/)*/, '').replace(/^\.\//, '');
791
+ adjustedPath = "../../src/".concat(pathWithoutLeadingDots);
792
+ }
793
+ return importStatement.replace("from ".concat(quote).concat(importPath).concat(quote), "from ".concat(quote).concat(adjustedPath).concat(quote));
794
+ };
795
+ /**
796
+ * Extract property metadata from a named type definition.
797
+ * Searches for the type definition and parses its properties.
798
+ *
799
+ * @param sourceText Full source file text
800
+ * @param typeName Name of the type to extract properties from
801
+ * @returns Array of property metadata, or null if type not found
802
+ *
803
+ * @example
804
+ * ```typescript
805
+ * const source = `
806
+ * interface Query {
807
+ * /** Max items *\/
808
+ * limit: string;
809
+ * page?: number;
810
+ * }
811
+ * `;
812
+ * extractPropertyMetadata(source, 'Query')
813
+ * // Returns: [
814
+ * // { name: "limit", description: "Max items" },
815
+ * // { name: "page", description: "" }
816
+ * // ]
817
+ * ```
818
+ */
819
+ TypeScriptSourceParser.extractPropertyMetadata = function (sourceText, typeName) {
820
+ // Find the type definition
821
+ var typeDef = this.findTypeDefinition(sourceText, typeName);
822
+ if (!typeDef) {
823
+ return null;
824
+ }
825
+ // Extract the object body (content between { and })
826
+ var definition = typeDef.definition;
827
+ // Find the opening brace
828
+ var openBraceIndex = definition.indexOf('{');
829
+ if (openBraceIndex === -1) {
830
+ return null;
831
+ }
832
+ // Use tokenizer to find the matching closing brace (handles strings and comments)
833
+ var tokenizer = new TypeScriptTokenizer_1.TypeScriptTokenizer(definition);
834
+ var closeBraceIndex = tokenizer.findMatchingBracketAt(openBraceIndex, '{');
835
+ if (closeBraceIndex === -1) {
836
+ return null;
837
+ }
838
+ // Extract the object body (excluding the outer braces)
839
+ var objectBody = definition.slice(openBraceIndex + 1, closeBraceIndex);
840
+ return this.extractPropertiesFromObjectType(objectBody);
841
+ };
842
+ /**
843
+ * Consolidates duplicate imports from the same module.
844
+ * Merges named imports and preserves default imports.
845
+ *
846
+ * @param imports Array of import statements
847
+ * @returns Consolidated import statements with duplicates merged
848
+ *
849
+ * @example
850
+ * ```typescript
851
+ * const imports = [
852
+ * 'import { Ad } from "../../src/schemas/Ad"',
853
+ * 'import { AdStatus } from "../../src/schemas/Ad"',
854
+ * 'import { User } from "../../src/schemas/User"'
855
+ * ];
856
+ * consolidateImports(imports)
857
+ * // Returns: [
858
+ * // 'import { Ad, AdStatus } from "../../src/schemas/Ad"',
859
+ * // 'import { User } from "../../src/schemas/User"'
860
+ * // ]
861
+ * ```
862
+ */
863
+ TypeScriptSourceParser.consolidateImports = function (imports) {
864
+ // Map: module path -> { namedImports: Set<string>, defaultImport?: string }
865
+ var importMap = new Map();
866
+ var _loop_1 = function (importStmt) {
867
+ // Parse import statement to extract module path and imports
868
+ // Patterns:
869
+ // - import { Foo, Bar } from "path"
870
+ // - import type { Foo, Bar } from "path"
871
+ // - import Foo from "path"
872
+ // - import type Foo from "path"
873
+ var namedMatch = importStmt.match(/import\s+(?:type\s+)?\{([^}]+)\}\s+from\s+(['"])([^'"]+)['"]/);
874
+ var defaultMatch = importStmt.match(/import\s+(?:type\s+)?(\w+)\s+from\s+(['"])([^'"]+)['"]/);
875
+ if (namedMatch) {
876
+ var namedImports = namedMatch[1]
877
+ .split(',')
878
+ .map(function (s) { return s.trim(); })
879
+ .filter(function (s) { return s.length > 0; });
880
+ var modulePath = namedMatch[3];
881
+ if (!importMap.has(modulePath)) {
882
+ importMap.set(modulePath, { namedImports: new Set() });
883
+ }
884
+ var entry_1 = importMap.get(modulePath);
885
+ namedImports.forEach(function (name) { return entry_1.namedImports.add(name); });
886
+ }
887
+ else if (defaultMatch) {
888
+ var defaultImport = defaultMatch[1];
889
+ var modulePath = defaultMatch[3];
890
+ if (!importMap.has(modulePath)) {
891
+ importMap.set(modulePath, { namedImports: new Set() });
892
+ }
893
+ var entry = importMap.get(modulePath);
894
+ entry.defaultImport = defaultImport;
895
+ }
896
+ };
897
+ for (var _i = 0, imports_1 = imports; _i < imports_1.length; _i++) {
898
+ var importStmt = imports_1[_i];
899
+ _loop_1(importStmt);
900
+ }
901
+ // Generate consolidated import statements
902
+ var consolidated = [];
903
+ var entries = Array.from(importMap.entries());
904
+ for (var _a = 0, entries_1 = entries; _a < entries_1.length; _a++) {
905
+ var _b = entries_1[_a], modulePath = _b[0], _c = _b[1], namedImports = _c.namedImports, defaultImport = _c.defaultImport;
906
+ if (defaultImport && namedImports.size > 0) {
907
+ // Both default and named imports
908
+ var named = Array.from(namedImports).sort().join(', ');
909
+ consolidated.push("import ".concat(defaultImport, ", { ").concat(named, " } from \"").concat(modulePath, "\""));
910
+ }
911
+ else if (defaultImport) {
912
+ // Default import only
913
+ consolidated.push("import ".concat(defaultImport, " from \"").concat(modulePath, "\""));
914
+ }
915
+ else if (namedImports.size > 0) {
916
+ // Named imports only
917
+ var named = Array.from(namedImports).sort().join(', ');
918
+ consolidated.push("import { ".concat(named, " } from \"").concat(modulePath, "\""));
919
+ }
920
+ }
921
+ return consolidated;
922
+ };
923
+ return TypeScriptSourceParser;
924
+ }());
925
+ exports.TypeScriptSourceParser = TypeScriptSourceParser;