codeguardian-mcp 1.0.0

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 (335) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +348 -0
  3. package/dist/agent/agentTools.d.ts +26 -0
  4. package/dist/agent/agentTools.d.ts.map +1 -0
  5. package/dist/agent/agentTools.js +699 -0
  6. package/dist/agent/agentTools.js.map +1 -0
  7. package/dist/agent/autoValidator.d.ts +110 -0
  8. package/dist/agent/autoValidator.d.ts.map +1 -0
  9. package/dist/agent/autoValidator.js +964 -0
  10. package/dist/agent/autoValidator.js.map +1 -0
  11. package/dist/agent/fileWatcher.d.ts +28 -0
  12. package/dist/agent/fileWatcher.d.ts.map +1 -0
  13. package/dist/agent/fileWatcher.js +88 -0
  14. package/dist/agent/fileWatcher.js.map +1 -0
  15. package/dist/agent/guardianPersistence.d.ts +98 -0
  16. package/dist/agent/guardianPersistence.d.ts.map +1 -0
  17. package/dist/agent/guardianPersistence.js +296 -0
  18. package/dist/agent/guardianPersistence.js.map +1 -0
  19. package/dist/agent/mcpNotifications.d.ts +38 -0
  20. package/dist/agent/mcpNotifications.d.ts.map +1 -0
  21. package/dist/agent/mcpNotifications.js +81 -0
  22. package/dist/agent/mcpNotifications.js.map +1 -0
  23. package/dist/analyzers/aiPatterns.d.ts +16 -0
  24. package/dist/analyzers/aiPatterns.d.ts.map +1 -0
  25. package/dist/analyzers/aiPatterns.js +103 -0
  26. package/dist/analyzers/aiPatterns.js.map +1 -0
  27. package/dist/analyzers/antiPatterns.d.ts +60 -0
  28. package/dist/analyzers/antiPatterns.d.ts.map +1 -0
  29. package/dist/analyzers/antiPatterns.js +198 -0
  30. package/dist/analyzers/antiPatterns.js.map +1 -0
  31. package/dist/analyzers/builtinTypes.d.ts +18 -0
  32. package/dist/analyzers/builtinTypes.d.ts.map +1 -0
  33. package/dist/analyzers/builtinTypes.js +1275 -0
  34. package/dist/analyzers/builtinTypes.js.map +1 -0
  35. package/dist/analyzers/complexity.d.ts +14 -0
  36. package/dist/analyzers/complexity.d.ts.map +1 -0
  37. package/dist/analyzers/complexity.js +610 -0
  38. package/dist/analyzers/complexity.js.map +1 -0
  39. package/dist/analyzers/findingVerifier.d.ts +59 -0
  40. package/dist/analyzers/findingVerifier.d.ts.map +1 -0
  41. package/dist/analyzers/findingVerifier.js +1169 -0
  42. package/dist/analyzers/findingVerifier.js.map +1 -0
  43. package/dist/analyzers/impactAnalyzer.d.ts +53 -0
  44. package/dist/analyzers/impactAnalyzer.d.ts.map +1 -0
  45. package/dist/analyzers/impactAnalyzer.js +152 -0
  46. package/dist/analyzers/impactAnalyzer.js.map +1 -0
  47. package/dist/analyzers/languageDetector.d.ts +48 -0
  48. package/dist/analyzers/languageDetector.d.ts.map +1 -0
  49. package/dist/analyzers/languageDetector.js +404 -0
  50. package/dist/analyzers/languageDetector.js.map +1 -0
  51. package/dist/analyzers/parsers/incrementalParser.d.ts +53 -0
  52. package/dist/analyzers/parsers/incrementalParser.d.ts.map +1 -0
  53. package/dist/analyzers/parsers/incrementalParser.js +193 -0
  54. package/dist/analyzers/parsers/incrementalParser.js.map +1 -0
  55. package/dist/analyzers/parsers/scopeResolver.d.ts +92 -0
  56. package/dist/analyzers/parsers/scopeResolver.d.ts.map +1 -0
  57. package/dist/analyzers/parsers/scopeResolver.js +324 -0
  58. package/dist/analyzers/parsers/scopeResolver.js.map +1 -0
  59. package/dist/analyzers/parsers/semanticIndex.d.ts +127 -0
  60. package/dist/analyzers/parsers/semanticIndex.d.ts.map +1 -0
  61. package/dist/analyzers/parsers/semanticIndex.js +429 -0
  62. package/dist/analyzers/parsers/semanticIndex.js.map +1 -0
  63. package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts +42 -0
  64. package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts.map +1 -0
  65. package/dist/analyzers/parsers/sessionDiffAnalyzer.js +233 -0
  66. package/dist/analyzers/parsers/sessionDiffAnalyzer.js.map +1 -0
  67. package/dist/analyzers/parsers/treeSitterParser.d.ts +76 -0
  68. package/dist/analyzers/parsers/treeSitterParser.d.ts.map +1 -0
  69. package/dist/analyzers/parsers/treeSitterParser.js +709 -0
  70. package/dist/analyzers/parsers/treeSitterParser.js.map +1 -0
  71. package/dist/analyzers/relevanceScorer.d.ts +43 -0
  72. package/dist/analyzers/relevanceScorer.d.ts.map +1 -0
  73. package/dist/analyzers/relevanceScorer.js +200 -0
  74. package/dist/analyzers/relevanceScorer.js.map +1 -0
  75. package/dist/analyzers/standardLibrary.d.ts +22 -0
  76. package/dist/analyzers/standardLibrary.d.ts.map +1 -0
  77. package/dist/analyzers/standardLibrary.js +211 -0
  78. package/dist/analyzers/standardLibrary.js.map +1 -0
  79. package/dist/analyzers/symbolGraph.d.ts +30 -0
  80. package/dist/analyzers/symbolGraph.d.ts.map +1 -0
  81. package/dist/analyzers/symbolGraph.js +380 -0
  82. package/dist/analyzers/symbolGraph.js.map +1 -0
  83. package/dist/analyzers/symbolTable.d.ts +18 -0
  84. package/dist/analyzers/symbolTable.d.ts.map +1 -0
  85. package/dist/analyzers/symbolTable.js +176 -0
  86. package/dist/analyzers/symbolTable.js.map +1 -0
  87. package/dist/analyzers/typeChecker.d.ts +13 -0
  88. package/dist/analyzers/typeChecker.d.ts.map +1 -0
  89. package/dist/analyzers/typeChecker.js +580 -0
  90. package/dist/analyzers/typeChecker.js.map +1 -0
  91. package/dist/analyzers/usagePatterns.d.ts +42 -0
  92. package/dist/analyzers/usagePatterns.d.ts.map +1 -0
  93. package/dist/analyzers/usagePatterns.js +75 -0
  94. package/dist/analyzers/usagePatterns.js.map +1 -0
  95. package/dist/api-contract/context/backend.d.ts +19 -0
  96. package/dist/api-contract/context/backend.d.ts.map +1 -0
  97. package/dist/api-contract/context/backend.js +64 -0
  98. package/dist/api-contract/context/backend.js.map +1 -0
  99. package/dist/api-contract/context/contract.d.ts +34 -0
  100. package/dist/api-contract/context/contract.d.ts.map +1 -0
  101. package/dist/api-contract/context/contract.js +306 -0
  102. package/dist/api-contract/context/contract.js.map +1 -0
  103. package/dist/api-contract/context/frontend.d.ts +19 -0
  104. package/dist/api-contract/context/frontend.d.ts.map +1 -0
  105. package/dist/api-contract/context/frontend.js +64 -0
  106. package/dist/api-contract/context/frontend.js.map +1 -0
  107. package/dist/api-contract/detector.d.ts +28 -0
  108. package/dist/api-contract/detector.d.ts.map +1 -0
  109. package/dist/api-contract/detector.js +393 -0
  110. package/dist/api-contract/detector.js.map +1 -0
  111. package/dist/api-contract/extractors/python.d.ts +32 -0
  112. package/dist/api-contract/extractors/python.d.ts.map +1 -0
  113. package/dist/api-contract/extractors/python.js +521 -0
  114. package/dist/api-contract/extractors/python.js.map +1 -0
  115. package/dist/api-contract/extractors/pythonAstUtils.d.ts +44 -0
  116. package/dist/api-contract/extractors/pythonAstUtils.d.ts.map +1 -0
  117. package/dist/api-contract/extractors/pythonAstUtils.js +489 -0
  118. package/dist/api-contract/extractors/pythonAstUtils.js.map +1 -0
  119. package/dist/api-contract/extractors/tsAstUtils.d.ts +47 -0
  120. package/dist/api-contract/extractors/tsAstUtils.d.ts.map +1 -0
  121. package/dist/api-contract/extractors/tsAstUtils.js +173 -0
  122. package/dist/api-contract/extractors/tsAstUtils.js.map +1 -0
  123. package/dist/api-contract/extractors/typescript.d.ts +32 -0
  124. package/dist/api-contract/extractors/typescript.d.ts.map +1 -0
  125. package/dist/api-contract/extractors/typescript.js +666 -0
  126. package/dist/api-contract/extractors/typescript.js.map +1 -0
  127. package/dist/api-contract/index.d.ts +104 -0
  128. package/dist/api-contract/index.d.ts.map +1 -0
  129. package/dist/api-contract/index.js +232 -0
  130. package/dist/api-contract/index.js.map +1 -0
  131. package/dist/api-contract/types.d.ts +151 -0
  132. package/dist/api-contract/types.d.ts.map +1 -0
  133. package/dist/api-contract/types.js +19 -0
  134. package/dist/api-contract/types.js.map +1 -0
  135. package/dist/api-contract/validators/endpoint.d.ts +21 -0
  136. package/dist/api-contract/validators/endpoint.d.ts.map +1 -0
  137. package/dist/api-contract/validators/endpoint.js +224 -0
  138. package/dist/api-contract/validators/endpoint.js.map +1 -0
  139. package/dist/api-contract/validators/index.d.ts +40 -0
  140. package/dist/api-contract/validators/index.d.ts.map +1 -0
  141. package/dist/api-contract/validators/index.js +875 -0
  142. package/dist/api-contract/validators/index.js.map +1 -0
  143. package/dist/api-contract/validators/parameter.d.ts +17 -0
  144. package/dist/api-contract/validators/parameter.d.ts.map +1 -0
  145. package/dist/api-contract/validators/parameter.js +250 -0
  146. package/dist/api-contract/validators/parameter.js.map +1 -0
  147. package/dist/api-contract/validators/type.d.ts +38 -0
  148. package/dist/api-contract/validators/type.d.ts.map +1 -0
  149. package/dist/api-contract/validators/type.js +244 -0
  150. package/dist/api-contract/validators/type.js.map +1 -0
  151. package/dist/context/apiContract/complexTypeSupport.d.ts +83 -0
  152. package/dist/context/apiContract/complexTypeSupport.d.ts.map +1 -0
  153. package/dist/context/apiContract/complexTypeSupport.js +665 -0
  154. package/dist/context/apiContract/complexTypeSupport.js.map +1 -0
  155. package/dist/context/apiContract/graphqlSupport.d.ts +105 -0
  156. package/dist/context/apiContract/graphqlSupport.d.ts.map +1 -0
  157. package/dist/context/apiContract/graphqlSupport.js +671 -0
  158. package/dist/context/apiContract/graphqlSupport.js.map +1 -0
  159. package/dist/context/apiContract/index.d.ts +14 -0
  160. package/dist/context/apiContract/index.d.ts.map +1 -0
  161. package/dist/context/apiContract/index.js +17 -0
  162. package/dist/context/apiContract/index.js.map +1 -0
  163. package/dist/context/apiContract/webSocketSupport.d.ts +104 -0
  164. package/dist/context/apiContract/webSocketSupport.d.ts.map +1 -0
  165. package/dist/context/apiContract/webSocketSupport.js +465 -0
  166. package/dist/context/apiContract/webSocketSupport.js.map +1 -0
  167. package/dist/context/apiContractContext.d.ts +15 -0
  168. package/dist/context/apiContractContext.d.ts.map +1 -0
  169. package/dist/context/apiContractContext.js +979 -0
  170. package/dist/context/apiContractContext.js.map +1 -0
  171. package/dist/context/apiContractExtraction.d.ts +52 -0
  172. package/dist/context/apiContractExtraction.d.ts.map +1 -0
  173. package/dist/context/apiContractExtraction.js +438 -0
  174. package/dist/context/apiContractExtraction.js.map +1 -0
  175. package/dist/context/contextLineage.d.ts +79 -0
  176. package/dist/context/contextLineage.d.ts.map +1 -0
  177. package/dist/context/contextLineage.js +259 -0
  178. package/dist/context/contextLineage.js.map +1 -0
  179. package/dist/context/contextOrchestrator.d.ts +57 -0
  180. package/dist/context/contextOrchestrator.d.ts.map +1 -0
  181. package/dist/context/contextOrchestrator.js +162 -0
  182. package/dist/context/contextOrchestrator.js.map +1 -0
  183. package/dist/context/intentTracker.d.ts +73 -0
  184. package/dist/context/intentTracker.d.ts.map +1 -0
  185. package/dist/context/intentTracker.js +168 -0
  186. package/dist/context/intentTracker.js.map +1 -0
  187. package/dist/context/projectContext.d.ts +219 -0
  188. package/dist/context/projectContext.d.ts.map +1 -0
  189. package/dist/context/projectContext.js +1984 -0
  190. package/dist/context/projectContext.js.map +1 -0
  191. package/dist/prompts/index.d.ts +17 -0
  192. package/dist/prompts/index.d.ts.map +1 -0
  193. package/dist/prompts/index.js +260 -0
  194. package/dist/prompts/index.js.map +1 -0
  195. package/dist/prompts/library.d.ts +51 -0
  196. package/dist/prompts/library.d.ts.map +1 -0
  197. package/dist/prompts/library.js +65 -0
  198. package/dist/prompts/library.js.map +1 -0
  199. package/dist/prompts/templates.d.ts +44 -0
  200. package/dist/prompts/templates.d.ts.map +1 -0
  201. package/dist/prompts/templates.js +97 -0
  202. package/dist/prompts/templates.js.map +1 -0
  203. package/dist/queue/jobPersistence.d.ts +46 -0
  204. package/dist/queue/jobPersistence.d.ts.map +1 -0
  205. package/dist/queue/jobPersistence.js +158 -0
  206. package/dist/queue/jobPersistence.js.map +1 -0
  207. package/dist/queue/jobQueue.d.ts +116 -0
  208. package/dist/queue/jobQueue.d.ts.map +1 -0
  209. package/dist/queue/jobQueue.js +275 -0
  210. package/dist/queue/jobQueue.js.map +1 -0
  211. package/dist/queue/validationJob.d.ts +69 -0
  212. package/dist/queue/validationJob.d.ts.map +1 -0
  213. package/dist/queue/validationJob.js +435 -0
  214. package/dist/queue/validationJob.js.map +1 -0
  215. package/dist/resources/index.d.ts +15 -0
  216. package/dist/resources/index.d.ts.map +1 -0
  217. package/dist/resources/index.js +328 -0
  218. package/dist/resources/index.js.map +1 -0
  219. package/dist/resources/validationReportStore.d.ts +170 -0
  220. package/dist/resources/validationReportStore.d.ts.map +1 -0
  221. package/dist/resources/validationReportStore.js +515 -0
  222. package/dist/resources/validationReportStore.js.map +1 -0
  223. package/dist/server.d.ts +12 -0
  224. package/dist/server.d.ts.map +1 -0
  225. package/dist/server.js +102 -0
  226. package/dist/server.js.map +1 -0
  227. package/dist/tools/asyncValidation.d.ts +19 -0
  228. package/dist/tools/asyncValidation.d.ts.map +1 -0
  229. package/dist/tools/asyncValidation.js +346 -0
  230. package/dist/tools/asyncValidation.js.map +1 -0
  231. package/dist/tools/buildContext.d.ts +17 -0
  232. package/dist/tools/buildContext.d.ts.map +1 -0
  233. package/dist/tools/buildContext.js +188 -0
  234. package/dist/tools/buildContext.js.map +1 -0
  235. package/dist/tools/getDependencyGraph.d.ts +16 -0
  236. package/dist/tools/getDependencyGraph.d.ts.map +1 -0
  237. package/dist/tools/getDependencyGraph.js +436 -0
  238. package/dist/tools/getDependencyGraph.js.map +1 -0
  239. package/dist/tools/incrementalValidation.d.ts +71 -0
  240. package/dist/tools/incrementalValidation.d.ts.map +1 -0
  241. package/dist/tools/incrementalValidation.js +203 -0
  242. package/dist/tools/incrementalValidation.js.map +1 -0
  243. package/dist/tools/index.d.ts +24 -0
  244. package/dist/tools/index.d.ts.map +1 -0
  245. package/dist/tools/index.js +106 -0
  246. package/dist/tools/index.js.map +1 -0
  247. package/dist/tools/validateCode.d.ts +17 -0
  248. package/dist/tools/validateCode.d.ts.map +1 -0
  249. package/dist/tools/validateCode.js +368 -0
  250. package/dist/tools/validateCode.js.map +1 -0
  251. package/dist/tools/validateCodeLite.d.ts +2 -0
  252. package/dist/tools/validateCodeLite.d.ts.map +1 -0
  253. package/dist/tools/validateCodeLite.js +2 -0
  254. package/dist/tools/validateCodeLite.js.map +1 -0
  255. package/dist/tools/validation/builtins.d.ts +92 -0
  256. package/dist/tools/validation/builtins.d.ts.map +1 -0
  257. package/dist/tools/validation/builtins.js +2184 -0
  258. package/dist/tools/validation/builtins.js.map +1 -0
  259. package/dist/tools/validation/contextualNaming.d.ts +99 -0
  260. package/dist/tools/validation/contextualNaming.d.ts.map +1 -0
  261. package/dist/tools/validation/contextualNaming.js +959 -0
  262. package/dist/tools/validation/contextualNaming.js.map +1 -0
  263. package/dist/tools/validation/deadCode.d.ts +115 -0
  264. package/dist/tools/validation/deadCode.d.ts.map +1 -0
  265. package/dist/tools/validation/deadCode.js +861 -0
  266. package/dist/tools/validation/deadCode.js.map +1 -0
  267. package/dist/tools/validation/extractors/index.d.ts +131 -0
  268. package/dist/tools/validation/extractors/index.d.ts.map +1 -0
  269. package/dist/tools/validation/extractors/index.js +233 -0
  270. package/dist/tools/validation/extractors/index.js.map +1 -0
  271. package/dist/tools/validation/extractors/javascript.d.ts +73 -0
  272. package/dist/tools/validation/extractors/javascript.d.ts.map +1 -0
  273. package/dist/tools/validation/extractors/javascript.js +1841 -0
  274. package/dist/tools/validation/extractors/javascript.js.map +1 -0
  275. package/dist/tools/validation/extractors/python.d.ts +93 -0
  276. package/dist/tools/validation/extractors/python.d.ts.map +1 -0
  277. package/dist/tools/validation/extractors/python.js +799 -0
  278. package/dist/tools/validation/extractors/python.js.map +1 -0
  279. package/dist/tools/validation/manifest.d.ts +45 -0
  280. package/dist/tools/validation/manifest.d.ts.map +1 -0
  281. package/dist/tools/validation/manifest.js +719 -0
  282. package/dist/tools/validation/manifest.js.map +1 -0
  283. package/dist/tools/validation/parser.d.ts +58 -0
  284. package/dist/tools/validation/parser.d.ts.map +1 -0
  285. package/dist/tools/validation/parser.js +232 -0
  286. package/dist/tools/validation/parser.js.map +1 -0
  287. package/dist/tools/validation/registry.d.ts +15 -0
  288. package/dist/tools/validation/registry.d.ts.map +1 -0
  289. package/dist/tools/validation/registry.js +169 -0
  290. package/dist/tools/validation/registry.js.map +1 -0
  291. package/dist/tools/validation/scoring.d.ts +54 -0
  292. package/dist/tools/validation/scoring.d.ts.map +1 -0
  293. package/dist/tools/validation/scoring.js +242 -0
  294. package/dist/tools/validation/scoring.js.map +1 -0
  295. package/dist/tools/validation/types.d.ts +120 -0
  296. package/dist/tools/validation/types.d.ts.map +1 -0
  297. package/dist/tools/validation/types.js +11 -0
  298. package/dist/tools/validation/types.js.map +1 -0
  299. package/dist/tools/validation/unusedLocals.d.ts +36 -0
  300. package/dist/tools/validation/unusedLocals.d.ts.map +1 -0
  301. package/dist/tools/validation/unusedLocals.js +333 -0
  302. package/dist/tools/validation/unusedLocals.js.map +1 -0
  303. package/dist/tools/validation/validation.d.ts +98 -0
  304. package/dist/tools/validation/validation.d.ts.map +1 -0
  305. package/dist/tools/validation/validation.js +1837 -0
  306. package/dist/tools/validation/validation.js.map +1 -0
  307. package/dist/types/codeGraph.d.ts +163 -0
  308. package/dist/types/codeGraph.d.ts.map +1 -0
  309. package/dist/types/codeGraph.js +9 -0
  310. package/dist/types/codeGraph.js.map +1 -0
  311. package/dist/types/symbolGraph.d.ts +68 -0
  312. package/dist/types/symbolGraph.d.ts.map +1 -0
  313. package/dist/types/symbolGraph.js +10 -0
  314. package/dist/types/symbolGraph.js.map +1 -0
  315. package/dist/types/tools.d.ts +43 -0
  316. package/dist/types/tools.d.ts.map +1 -0
  317. package/dist/types/tools.js +7 -0
  318. package/dist/types/tools.js.map +1 -0
  319. package/dist/utils/fileFilter.d.ts +37 -0
  320. package/dist/utils/fileFilter.d.ts.map +1 -0
  321. package/dist/utils/fileFilter.js +91 -0
  322. package/dist/utils/fileFilter.js.map +1 -0
  323. package/dist/utils/gitUtils.d.ts +28 -0
  324. package/dist/utils/gitUtils.d.ts.map +1 -0
  325. package/dist/utils/gitUtils.js +81 -0
  326. package/dist/utils/gitUtils.js.map +1 -0
  327. package/dist/utils/logger.d.ts +15 -0
  328. package/dist/utils/logger.d.ts.map +1 -0
  329. package/dist/utils/logger.js +38 -0
  330. package/dist/utils/logger.js.map +1 -0
  331. package/dist/utils/serialization.d.ts +25 -0
  332. package/dist/utils/serialization.d.ts.map +1 -0
  333. package/dist/utils/serialization.js +53 -0
  334. package/dist/utils/serialization.js.map +1 -0
  335. package/package.json +90 -0
@@ -0,0 +1,665 @@
1
+ /**
2
+ * API Contract Guardian - Complex TypeScript Type Handling
3
+ *
4
+ * Handles advanced TypeScript types including:
5
+ * - Union types (string | number)
6
+ * - Generic types (Array<T>, Promise<T>)
7
+ * - Intersection types (Type1 & Type2)
8
+ * - Mapped types (Partial<T>, Required<T>, etc.)
9
+ * - Conditional types
10
+ * - Type aliases
11
+ * - Cross-file type resolution
12
+ *
13
+ * @format
14
+ */
15
+ import * as fs from "fs/promises";
16
+ import * as path from "path";
17
+ import { logger } from "../../utils/logger.js";
18
+ import { getParser } from "../../tools/validation/parser.js";
19
+ // ============================================================================
20
+ // Type Parser
21
+ // ============================================================================
22
+ /**
23
+ * Parse a complex TypeScript type string into structured info
24
+ */
25
+ export function parseComplexType(typeString, file, line) {
26
+ const trimmed = typeString.trim();
27
+ // Check for union types: string | number | null
28
+ if (trimmed.includes("|")) {
29
+ return parseUnionType(trimmed, file, line);
30
+ }
31
+ // Check for intersection types: Type1 & Type2
32
+ if (trimmed.includes("&")) {
33
+ return parseIntersectionType(trimmed, file, line);
34
+ }
35
+ // Check for mapped types FIRST: Partial<T>, Required<T>, etc.
36
+ // These look like generics but are special TypeScript utility types
37
+ const mappedTypeMatch = trimmed.match(/^(Partial|Required|Readonly|Pick|Omit|Record|Exclude|Extract)<(.+)>$/);
38
+ if (mappedTypeMatch) {
39
+ return parseMappedType(mappedTypeMatch[1], mappedTypeMatch[2], file, line);
40
+ }
41
+ // Check for generic types: Array<T>, Promise<T>, Map<K, V>
42
+ if (trimmed.includes("<") && trimmed.includes(">")) {
43
+ return parseGenericType(trimmed, file, line);
44
+ }
45
+ // Check for conditional types: T extends U ? X : Y
46
+ if (trimmed.includes("extends") && trimmed.includes("?")) {
47
+ return parseConditionalType(trimmed, file, line);
48
+ }
49
+ // Primitive type
50
+ return {
51
+ name: trimmed,
52
+ kind: "primitive",
53
+ file,
54
+ line,
55
+ };
56
+ }
57
+ function parseUnionType(typeString, file, line) {
58
+ const parts = splitTypeString(typeString, "|");
59
+ const constituents = parts.map(p => parseComplexType(p.trim(), file, line));
60
+ // Check if it's a nullable type (includes null or undefined)
61
+ const isNullable = constituents.some(c => c.name === "null" || c.name === "undefined");
62
+ return {
63
+ name: typeString,
64
+ kind: "union",
65
+ constituents,
66
+ file,
67
+ line,
68
+ };
69
+ }
70
+ function parseIntersectionType(typeString, file, line) {
71
+ const parts = splitTypeString(typeString, "&");
72
+ const constituents = parts.map(p => parseComplexType(p.trim(), file, line));
73
+ return {
74
+ name: typeString,
75
+ kind: "intersection",
76
+ constituents,
77
+ file,
78
+ line,
79
+ };
80
+ }
81
+ function parseGenericType(typeString, file, line) {
82
+ // Match: TypeName<T1, T2, ...>
83
+ const match = typeString.match(/^(\w+)<(.+)>$/);
84
+ if (!match) {
85
+ return {
86
+ name: typeString,
87
+ kind: "primitive",
88
+ file,
89
+ line,
90
+ };
91
+ }
92
+ const baseType = match[1];
93
+ const paramsString = match[2];
94
+ // Split type parameters (handle nested generics)
95
+ const typeParameters = splitTypeParams(paramsString);
96
+ return {
97
+ name: typeString,
98
+ kind: "generic",
99
+ baseType,
100
+ typeParameters,
101
+ file,
102
+ line,
103
+ };
104
+ }
105
+ function parseMappedType(mappedType, typeArg, file, line) {
106
+ const mappedTypeMap = {
107
+ Partial: "partial",
108
+ Required: "required",
109
+ Readonly: "readonly",
110
+ Pick: "pick",
111
+ Omit: "omit",
112
+ Record: "record",
113
+ Exclude: "exclude",
114
+ Extract: "extract",
115
+ };
116
+ return {
117
+ name: `${mappedType}<${typeArg}>`,
118
+ kind: "mapped",
119
+ mappedType: mappedTypeMap[mappedType],
120
+ mappedTypeArgument: typeArg,
121
+ file,
122
+ line,
123
+ };
124
+ }
125
+ function parseConditionalType(typeString, file, line) {
126
+ // Match: T extends U ? X : Y
127
+ const match = typeString.match(/^(.+?)\s+extends\s+(.+?)\s*\?\s*(.+?)\s*:\s*(.+)$/);
128
+ if (!match) {
129
+ return {
130
+ name: typeString,
131
+ kind: "primitive",
132
+ file,
133
+ line,
134
+ };
135
+ }
136
+ return {
137
+ name: typeString,
138
+ kind: "conditional",
139
+ condition: {
140
+ checkType: match[1].trim(),
141
+ extendsType: match[2].trim(),
142
+ trueType: match[3].trim(),
143
+ falseType: match[4].trim(),
144
+ },
145
+ file,
146
+ line,
147
+ };
148
+ }
149
+ /**
150
+ * Split a type string by delimiter, respecting nested angle brackets
151
+ */
152
+ function splitTypeString(typeString, delimiter) {
153
+ const parts = [];
154
+ let current = "";
155
+ let depth = 0;
156
+ for (const char of typeString) {
157
+ if (char === "<")
158
+ depth++;
159
+ if (char === ">")
160
+ depth--;
161
+ if (char === delimiter && depth === 0) {
162
+ parts.push(current.trim());
163
+ current = "";
164
+ }
165
+ else {
166
+ current += char;
167
+ }
168
+ }
169
+ if (current.trim()) {
170
+ parts.push(current.trim());
171
+ }
172
+ return parts;
173
+ }
174
+ function splitTypeParams(paramsString) {
175
+ const params = [];
176
+ let current = "";
177
+ let depth = 0;
178
+ for (const char of paramsString) {
179
+ if (char === "<")
180
+ depth++;
181
+ if (char === ">")
182
+ depth--;
183
+ if (char === "," && depth === 0) {
184
+ params.push(current.trim());
185
+ current = "";
186
+ }
187
+ else {
188
+ current += char;
189
+ }
190
+ }
191
+ if (current.trim()) {
192
+ params.push(current.trim());
193
+ }
194
+ return params;
195
+ }
196
+ // ============================================================================
197
+ // Type Resolution
198
+ // ============================================================================
199
+ /**
200
+ * Resolve a complex type to its base type
201
+ * Expands type aliases, evaluates conditional types, etc.
202
+ */
203
+ export function resolveComplexType(typeInfo, typeDefinitions, context) {
204
+ // Check for circular references
205
+ if (context.pendingResolutions.has(typeInfo.name)) {
206
+ context.errors.push({
207
+ typeName: typeInfo.name,
208
+ file: typeInfo.file,
209
+ message: "Circular type reference detected",
210
+ line: typeInfo.line,
211
+ });
212
+ return typeInfo;
213
+ }
214
+ // Check if already resolved
215
+ if (context.resolvedTypes.has(typeInfo.name)) {
216
+ return context.resolvedTypes.get(typeInfo.name);
217
+ }
218
+ context.pendingResolutions.add(typeInfo.name);
219
+ let resolved;
220
+ switch (typeInfo.kind) {
221
+ case "union":
222
+ resolved = resolveUnionType(typeInfo, typeDefinitions, context);
223
+ break;
224
+ case "intersection":
225
+ resolved = resolveIntersectionType(typeInfo, typeDefinitions, context);
226
+ break;
227
+ case "generic":
228
+ resolved = resolveGenericType(typeInfo, typeDefinitions, context);
229
+ break;
230
+ case "mapped":
231
+ resolved = resolveMappedType(typeInfo, typeDefinitions, context);
232
+ break;
233
+ case "conditional":
234
+ resolved = resolveConditionalType(typeInfo, typeDefinitions, context);
235
+ break;
236
+ case "alias":
237
+ resolved = resolveAliasType(typeInfo, typeDefinitions, context);
238
+ break;
239
+ default:
240
+ resolved = typeInfo;
241
+ }
242
+ context.pendingResolutions.delete(typeInfo.name);
243
+ context.resolvedTypes.set(typeInfo.name, resolved);
244
+ return resolved;
245
+ }
246
+ function resolveUnionType(typeInfo, typeDefinitions, context) {
247
+ if (!typeInfo.constituents)
248
+ return typeInfo;
249
+ const resolvedConstituents = typeInfo.constituents.map(c => resolveComplexType(c, typeDefinitions, context));
250
+ // Flatten nested unions
251
+ const flattened = [];
252
+ for (const c of resolvedConstituents) {
253
+ if (c.kind === "union" && c.constituents) {
254
+ flattened.push(...c.constituents);
255
+ }
256
+ else {
257
+ flattened.push(c);
258
+ }
259
+ }
260
+ return {
261
+ ...typeInfo,
262
+ constituents: flattened,
263
+ resolvedType: flattened.map(c => c.resolvedType || c.name).join(" | "),
264
+ };
265
+ }
266
+ function resolveIntersectionType(typeInfo, typeDefinitions, context) {
267
+ if (!typeInfo.constituents)
268
+ return typeInfo;
269
+ const resolvedConstituents = typeInfo.constituents.map(c => resolveComplexType(c, typeDefinitions, context));
270
+ return {
271
+ ...typeInfo,
272
+ constituents: resolvedConstituents,
273
+ resolvedType: resolvedConstituents.map(c => c.resolvedType || c.name).join(" & "),
274
+ };
275
+ }
276
+ function resolveGenericType(typeInfo, typeDefinitions, context) {
277
+ if (!typeInfo.typeParameters)
278
+ return typeInfo;
279
+ const resolvedParams = typeInfo.typeParameters.map(p => {
280
+ const parsed = parseComplexType(p, typeInfo.file, typeInfo.line);
281
+ return resolveComplexType(parsed, typeDefinitions, context);
282
+ });
283
+ // Handle built-in generic types
284
+ if (typeInfo.baseType === "Array" || typeInfo.baseType === "Promise") {
285
+ return {
286
+ ...typeInfo,
287
+ resolvedType: `${typeInfo.baseType}<${resolvedParams[0]?.resolvedType || resolvedParams[0]?.name}>`,
288
+ };
289
+ }
290
+ return {
291
+ ...typeInfo,
292
+ resolvedType: `${typeInfo.baseType}<${resolvedParams.map(p => p.resolvedType || p.name).join(", ")}>`,
293
+ };
294
+ }
295
+ function resolveMappedType(typeInfo, typeDefinitions, context) {
296
+ if (!typeInfo.mappedType || !typeInfo.mappedTypeArgument)
297
+ return typeInfo;
298
+ const baseType = typeDefinitions.get(typeInfo.mappedTypeArgument);
299
+ if (!baseType) {
300
+ return {
301
+ ...typeInfo,
302
+ resolvedType: typeInfo.name,
303
+ };
304
+ }
305
+ const resolvedBase = resolveComplexType(baseType, typeDefinitions, context);
306
+ // Apply mapped type transformation
307
+ switch (typeInfo.mappedType) {
308
+ case "partial":
309
+ return {
310
+ ...typeInfo,
311
+ resolvedType: `Partial<${resolvedBase.resolvedType || resolvedBase.name}>`,
312
+ };
313
+ case "required":
314
+ return {
315
+ ...typeInfo,
316
+ resolvedType: `Required<${resolvedBase.resolvedType || resolvedBase.name}>`,
317
+ };
318
+ case "readonly":
319
+ return {
320
+ ...typeInfo,
321
+ resolvedType: `Readonly<${resolvedBase.resolvedType || resolvedBase.name}>`,
322
+ };
323
+ default:
324
+ return {
325
+ ...typeInfo,
326
+ resolvedType: typeInfo.name,
327
+ };
328
+ }
329
+ }
330
+ function resolveConditionalType(typeInfo, typeDefinitions, context) {
331
+ if (!typeInfo.condition)
332
+ return typeInfo;
333
+ const { checkType, extendsType, trueType, falseType } = typeInfo.condition;
334
+ // Simple case: check if checkType extends extendsType
335
+ // In a real implementation, this would be more sophisticated
336
+ const resolvedCheck = parseComplexType(checkType, typeInfo.file, typeInfo.line);
337
+ const resolvedExtends = parseComplexType(extendsType, typeInfo.file, typeInfo.line);
338
+ // For now, assume the condition is true if types match
339
+ const conditionResult = resolvedCheck.name === resolvedExtends.name;
340
+ const resultType = conditionResult ? trueType : falseType;
341
+ return {
342
+ ...typeInfo,
343
+ resolvedType: resultType,
344
+ };
345
+ }
346
+ function resolveAliasType(typeInfo, typeDefinitions, context) {
347
+ const aliasedType = typeDefinitions.get(typeInfo.name);
348
+ if (aliasedType) {
349
+ return resolveComplexType(aliasedType, typeDefinitions, context);
350
+ }
351
+ return typeInfo;
352
+ }
353
+ // ============================================================================
354
+ // Type Compatibility Checking
355
+ // ============================================================================
356
+ /**
357
+ * Check if a TypeScript type is compatible with a Python type
358
+ */
359
+ export function checkTypeCompatibility(tsType, pyType) {
360
+ const issues = [];
361
+ let score = 100;
362
+ // Normalize Python type
363
+ const normalizedPyType = normalizePythonType(pyType);
364
+ // Handle union types
365
+ if (tsType.kind === "union" && tsType.constituents) {
366
+ // Check if any constituent matches
367
+ const matches = tsType.constituents.some(c => {
368
+ const result = checkTypeCompatibility(c, pyType);
369
+ return result.compatible;
370
+ });
371
+ if (!matches) {
372
+ issues.push({
373
+ severity: "error",
374
+ message: `Union type '${tsType.name}' is not compatible with Python type '${pyType}'`,
375
+ frontendType: tsType.name,
376
+ backendType: pyType,
377
+ });
378
+ score = 0;
379
+ }
380
+ return { compatible: matches, score, issues };
381
+ }
382
+ // Check primitive type compatibility
383
+ const tsPrimitive = getPrimitiveTypeName(tsType);
384
+ const compatibility = getTypeCompatibility(tsPrimitive, normalizedPyType);
385
+ if (!compatibility.compatible) {
386
+ issues.push({
387
+ severity: "error",
388
+ message: `Type mismatch: TypeScript '${tsType.name}' is not compatible with Python '${pyType}'`,
389
+ frontendType: tsType.name,
390
+ backendType: pyType,
391
+ });
392
+ score = 0;
393
+ }
394
+ else if (compatibility.warning) {
395
+ issues.push({
396
+ severity: "warning",
397
+ message: compatibility.warning,
398
+ frontendType: tsType.name,
399
+ backendType: pyType,
400
+ });
401
+ score -= 20;
402
+ }
403
+ return { compatible: compatibility.compatible, score: Math.max(0, score), issues };
404
+ }
405
+ function normalizePythonType(pyType) {
406
+ return pyType
407
+ .replace(/Optional\[(.+?)\]/, "$1 | null")
408
+ .replace(/List\[(.+?)\]/, "Array<$1>")
409
+ .replace(/Dict\[(.+?),\s*(.+?)\]/, "Record<$1, $2>")
410
+ .replace(/Union\[(.+?)\]/, "$1")
411
+ .trim();
412
+ }
413
+ function getPrimitiveTypeName(typeInfo) {
414
+ if (typeInfo.resolvedType) {
415
+ return typeInfo.resolvedType;
416
+ }
417
+ // Handle generic types
418
+ if (typeInfo.kind === "generic" && typeInfo.baseType) {
419
+ if (typeInfo.baseType === "Array") {
420
+ return "array";
421
+ }
422
+ if (typeInfo.baseType === "Promise") {
423
+ return "promise";
424
+ }
425
+ if (typeInfo.baseType === "Record") {
426
+ return "record";
427
+ }
428
+ }
429
+ return typeInfo.name.toLowerCase();
430
+ }
431
+ function getTypeCompatibility(tsType, pyType) {
432
+ // TypeScript to Python type mapping
433
+ const typeMap = {
434
+ string: ["str", "string", "text"],
435
+ number: ["int", "float", "decimal", "number"],
436
+ boolean: ["bool", "boolean"],
437
+ null: ["none", "null"],
438
+ undefined: ["none", "null"],
439
+ any: ["any"],
440
+ unknown: ["any"],
441
+ array: ["list", "array", "sequence"],
442
+ record: ["dict", "mapping", "object"],
443
+ date: ["date", "datetime"],
444
+ bigint: ["int"],
445
+ symbol: [],
446
+ object: ["dict", "object"],
447
+ };
448
+ const normalizedTs = tsType.toLowerCase();
449
+ const normalizedPy = pyType.toLowerCase();
450
+ // Direct match
451
+ if (normalizedTs === normalizedPy) {
452
+ return { compatible: true };
453
+ }
454
+ // Check mapping
455
+ const compatibleTypes = typeMap[normalizedTs] || [];
456
+ if (compatibleTypes.includes(normalizedPy)) {
457
+ return { compatible: true };
458
+ }
459
+ // Special case: array types
460
+ if (normalizedTs === "array" && normalizedPy.startsWith("array<")) {
461
+ return { compatible: true };
462
+ }
463
+ // Special cases
464
+ if (normalizedTs === "string" && normalizedPy === "int") {
465
+ return {
466
+ compatible: false,
467
+ warning: "Type mismatch: string cannot be assigned to int",
468
+ };
469
+ }
470
+ if (normalizedTs === "number" && normalizedPy === "str") {
471
+ return {
472
+ compatible: true,
473
+ warning: "Implicit conversion: number to string",
474
+ };
475
+ }
476
+ if (normalizedTs === "array" && !["list", "array", "sequence"].includes(normalizedPy)) {
477
+ return {
478
+ compatible: false,
479
+ warning: "Type mismatch: array type requires Python List",
480
+ };
481
+ }
482
+ return { compatible: false };
483
+ }
484
+ // ============================================================================
485
+ // Import Resolution
486
+ // ============================================================================
487
+ /**
488
+ * Extract all type definitions from a TypeScript file
489
+ * Including imported types
490
+ */
491
+ export async function extractAllTypeDefinitions(filePath, projectPath) {
492
+ const typeMap = new Map();
493
+ try {
494
+ const content = await fs.readFile(filePath, "utf-8");
495
+ const parser = getParser("typescript");
496
+ const tree = parser.parse(content);
497
+ // Extract local type definitions
498
+ extractTypeDefinitionsFromAST(tree.rootNode, content, filePath, typeMap);
499
+ // Extract imports and resolve them
500
+ const imports = extractTypeImportsFromAST(tree.rootNode, content);
501
+ for (const importInfo of imports) {
502
+ const resolvedPath = resolveImportPath(importInfo.path, filePath, projectPath);
503
+ if (resolvedPath) {
504
+ try {
505
+ const importedTypes = await extractAllTypeDefinitions(resolvedPath, projectPath);
506
+ for (const [name, typeInfo] of importedTypes) {
507
+ if (!typeMap.has(name)) {
508
+ typeMap.set(name, typeInfo);
509
+ }
510
+ }
511
+ }
512
+ catch {
513
+ // Ignore import resolution errors
514
+ }
515
+ }
516
+ }
517
+ }
518
+ catch (err) {
519
+ logger.debug(`Failed to extract type definitions from ${filePath}: ${err}`);
520
+ }
521
+ return typeMap;
522
+ }
523
+ function extractTypeDefinitionsFromAST(node, content, filePath, typeMap) {
524
+ if (!node)
525
+ return;
526
+ // Type alias: type MyType = ...
527
+ if (node.type === "type_alias_declaration") {
528
+ const nameNode = node.childForFieldName("name");
529
+ const valueNode = node.childForFieldName("value");
530
+ if (nameNode && valueNode) {
531
+ const name = getNodeText(nameNode, content);
532
+ const value = getNodeText(valueNode, content);
533
+ const line = node.startPosition.row + 1;
534
+ const typeInfo = parseComplexType(value, filePath, line);
535
+ typeInfo.name = name;
536
+ typeInfo.kind = "alias";
537
+ typeMap.set(name, typeInfo);
538
+ }
539
+ }
540
+ // Interface declaration
541
+ if (node.type === "interface_declaration") {
542
+ const nameNode = node.childForFieldName("name");
543
+ if (nameNode) {
544
+ const name = getNodeText(nameNode, content);
545
+ const line = node.startPosition.row + 1;
546
+ typeMap.set(name, {
547
+ name,
548
+ kind: "primitive",
549
+ file: filePath,
550
+ line,
551
+ });
552
+ }
553
+ }
554
+ // Recursively traverse children
555
+ for (const child of node.children || []) {
556
+ extractTypeDefinitionsFromAST(child, content, filePath, typeMap);
557
+ }
558
+ }
559
+ function extractTypeImportsFromAST(node, content) {
560
+ const imports = [];
561
+ if (!node)
562
+ return imports;
563
+ if (node.type === "import_statement" || node.type === "import_declaration") {
564
+ const sourceNode = node.childForFieldName("source");
565
+ if (sourceNode) {
566
+ const importPath = getNodeText(sourceNode, content).replace(/['"]/g, "");
567
+ // Extract imported names
568
+ const clauseNode = node.childForFieldName("clause") || node.childForFieldName("importClause");
569
+ if (clauseNode) {
570
+ const names = [];
571
+ for (const child of clauseNode.children || []) {
572
+ if (child.type === "identifier" || child.type === "type_identifier") {
573
+ names.push(getNodeText(child, content));
574
+ }
575
+ if (child.type === "named_imports") {
576
+ for (const spec of child.children || []) {
577
+ if (spec.type === "import_specifier") {
578
+ const nameNode = spec.childForFieldName("name");
579
+ if (nameNode) {
580
+ names.push(getNodeText(nameNode, content));
581
+ }
582
+ }
583
+ }
584
+ }
585
+ }
586
+ imports.push({ names, path: importPath });
587
+ }
588
+ }
589
+ }
590
+ // Recursively traverse children
591
+ for (const child of node.children || []) {
592
+ imports.push(...extractTypeImportsFromAST(child, content));
593
+ }
594
+ return imports;
595
+ }
596
+ function resolveImportPath(importPath, fromFile, projectPath) {
597
+ // Handle relative imports
598
+ if (importPath.startsWith("./") || importPath.startsWith("../")) {
599
+ const fromDir = path.dirname(fromFile);
600
+ let resolvedPath = path.resolve(fromDir, importPath);
601
+ // Try common extensions
602
+ const extensions = [".ts", ".tsx", ".d.ts", "/index.ts", "/index.tsx"];
603
+ for (const ext of extensions) {
604
+ const fullPath = resolvedPath + ext;
605
+ try {
606
+ fsSync.accessSync(fullPath);
607
+ return fullPath;
608
+ }
609
+ catch {
610
+ // Try next extension
611
+ }
612
+ }
613
+ }
614
+ // Handle path aliases (simplified - would need tsconfig.json parsing)
615
+ if (importPath.startsWith("@/") || importPath.startsWith("~/")) {
616
+ // Try to resolve from project root
617
+ const relativePath = importPath.slice(2); // Remove @/ or ~/
618
+ const possiblePath = path.join(projectPath, "src", relativePath);
619
+ const extensions = [".ts", ".tsx", ".d.ts", "/index.ts", "/index.tsx"];
620
+ for (const ext of extensions) {
621
+ const fullPath = possiblePath + ext;
622
+ try {
623
+ fsSync.accessSync(fullPath);
624
+ return fullPath;
625
+ }
626
+ catch {
627
+ // Try next extension
628
+ }
629
+ }
630
+ }
631
+ return null;
632
+ }
633
+ import * as fsSync from "fs";
634
+ function getNodeText(node, content) {
635
+ if (!node)
636
+ return "";
637
+ return content.slice(node.startIndex, node.endIndex);
638
+ }
639
+ // ============================================================================
640
+ // Main Entry Point
641
+ // ============================================================================
642
+ /**
643
+ * Enhance ApiTypeDefinition with complex type information
644
+ */
645
+ export async function enhanceTypeWithComplexInfo(typeDef, projectPath) {
646
+ const typeMap = await extractAllTypeDefinitions(typeDef.file, projectPath);
647
+ const context = {
648
+ resolvedTypes: new Map(),
649
+ pendingResolutions: new Set(),
650
+ errors: [],
651
+ };
652
+ const enhancedFields = typeDef.fields.map(field => {
653
+ const complexType = parseComplexType(field.type, typeDef.file, typeDef.line);
654
+ const resolvedType = resolveComplexType(complexType, typeMap, context);
655
+ return {
656
+ ...field,
657
+ complexType: resolvedType,
658
+ };
659
+ });
660
+ return {
661
+ ...typeDef,
662
+ complexFields: enhancedFields,
663
+ };
664
+ }
665
+ //# sourceMappingURL=complexTypeSupport.js.map