@mirnoorata/codexa 0.2.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 (364) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +634 -0
  3. package/dist/artifacts.d.ts +2 -0
  4. package/dist/artifacts.js +375 -0
  5. package/dist/artifacts.js.map +1 -0
  6. package/dist/autonomy.d.ts +17 -0
  7. package/dist/autonomy.js +124 -0
  8. package/dist/autonomy.js.map +1 -0
  9. package/dist/autoverify/policy.d.ts +5 -0
  10. package/dist/autoverify/policy.js +18 -0
  11. package/dist/autoverify/policy.js.map +1 -0
  12. package/dist/autoverify.d.ts +45 -0
  13. package/dist/autoverify.js +1041 -0
  14. package/dist/autoverify.js.map +1 -0
  15. package/dist/cache-lock.d.ts +16 -0
  16. package/dist/cache-lock.js +181 -0
  17. package/dist/cache-lock.js.map +1 -0
  18. package/dist/cli/hooks.d.ts +5 -0
  19. package/dist/cli/hooks.js +264 -0
  20. package/dist/cli/hooks.js.map +1 -0
  21. package/dist/cli.d.ts +2 -0
  22. package/dist/cli.js +1034 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/codex-contract.d.ts +2 -0
  25. package/dist/codex-contract.js +78 -0
  26. package/dist/codex-contract.js.map +1 -0
  27. package/dist/command.d.ts +34 -0
  28. package/dist/command.js +162 -0
  29. package/dist/command.js.map +1 -0
  30. package/dist/doctor.d.ts +112 -0
  31. package/dist/doctor.js +518 -0
  32. package/dist/doctor.js.map +1 -0
  33. package/dist/eval/baseline.d.ts +7 -0
  34. package/dist/eval/baseline.js +146 -0
  35. package/dist/eval/baseline.js.map +1 -0
  36. package/dist/eval/historical.d.ts +4 -0
  37. package/dist/eval/historical.js +663 -0
  38. package/dist/eval/historical.js.map +1 -0
  39. package/dist/eval/render.d.ts +2 -0
  40. package/dist/eval/render.js +53 -0
  41. package/dist/eval/render.js.map +1 -0
  42. package/dist/eval/scoring.d.ts +21 -0
  43. package/dist/eval/scoring.js +618 -0
  44. package/dist/eval/scoring.js.map +1 -0
  45. package/dist/eval/synthetic.d.ts +36 -0
  46. package/dist/eval/synthetic.js +107 -0
  47. package/dist/eval/synthetic.js.map +1 -0
  48. package/dist/eval/types.d.ts +36 -0
  49. package/dist/eval/types.js +2 -0
  50. package/dist/eval/types.js.map +1 -0
  51. package/dist/eval.d.ts +140 -0
  52. package/dist/eval.js +551 -0
  53. package/dist/eval.js.map +1 -0
  54. package/dist/git.d.ts +17 -0
  55. package/dist/git.js +189 -0
  56. package/dist/git.js.map +1 -0
  57. package/dist/github-release.d.ts +47 -0
  58. package/dist/github-release.js +610 -0
  59. package/dist/github-release.js.map +1 -0
  60. package/dist/github-sync.d.ts +68 -0
  61. package/dist/github-sync.js +345 -0
  62. package/dist/github-sync.js.map +1 -0
  63. package/dist/graph.d.ts +10 -0
  64. package/dist/graph.js +665 -0
  65. package/dist/graph.js.map +1 -0
  66. package/dist/indexer/aliases.d.ts +2 -0
  67. package/dist/indexer/aliases.js +190 -0
  68. package/dist/indexer/aliases.js.map +1 -0
  69. package/dist/indexer/artifact-writing.d.ts +3 -0
  70. package/dist/indexer/artifact-writing.js +79 -0
  71. package/dist/indexer/artifact-writing.js.map +1 -0
  72. package/dist/indexer/discovery.d.ts +2 -0
  73. package/dist/indexer/discovery.js +5 -0
  74. package/dist/indexer/discovery.js.map +1 -0
  75. package/dist/indexer/external-facts.d.ts +6 -0
  76. package/dist/indexer/external-facts.js +45 -0
  77. package/dist/indexer/external-facts.js.map +1 -0
  78. package/dist/indexer/freshness.d.ts +8 -0
  79. package/dist/indexer/freshness.js +56 -0
  80. package/dist/indexer/freshness.js.map +1 -0
  81. package/dist/indexer/graph-stage.d.ts +2 -0
  82. package/dist/indexer/graph-stage.js +21 -0
  83. package/dist/indexer/graph-stage.js.map +1 -0
  84. package/dist/indexer/parsing.d.ts +30 -0
  85. package/dist/indexer/parsing.js +177 -0
  86. package/dist/indexer/parsing.js.map +1 -0
  87. package/dist/indexer/pipeline.d.ts +5 -0
  88. package/dist/indexer/pipeline.js +8 -0
  89. package/dist/indexer/pipeline.js.map +1 -0
  90. package/dist/indexer/ranking.d.ts +4 -0
  91. package/dist/indexer/ranking.js +134 -0
  92. package/dist/indexer/ranking.js.map +1 -0
  93. package/dist/indexer.d.ts +13 -0
  94. package/dist/indexer.js +395 -0
  95. package/dist/indexer.js.map +1 -0
  96. package/dist/init.d.ts +24 -0
  97. package/dist/init.js +566 -0
  98. package/dist/init.js.map +1 -0
  99. package/dist/language.d.ts +8 -0
  100. package/dist/language.js +123 -0
  101. package/dist/language.js.map +1 -0
  102. package/dist/live-index.d.ts +68 -0
  103. package/dist/live-index.js +215 -0
  104. package/dist/live-index.js.map +1 -0
  105. package/dist/lsp/assist.d.ts +44 -0
  106. package/dist/lsp/assist.js +331 -0
  107. package/dist/lsp/assist.js.map +1 -0
  108. package/dist/lsp/client.d.ts +59 -0
  109. package/dist/lsp/client.js +208 -0
  110. package/dist/lsp/client.js.map +1 -0
  111. package/dist/mcp/compaction.d.ts +15 -0
  112. package/dist/mcp/compaction.js +1249 -0
  113. package/dist/mcp/compaction.js.map +1 -0
  114. package/dist/mcp/envelope.d.ts +44 -0
  115. package/dist/mcp/envelope.js +425 -0
  116. package/dist/mcp/envelope.js.map +1 -0
  117. package/dist/mcp/prompts.d.ts +2 -0
  118. package/dist/mcp/prompts.js +109 -0
  119. package/dist/mcp/prompts.js.map +1 -0
  120. package/dist/mcp/resources.d.ts +2 -0
  121. package/dist/mcp/resources.js +132 -0
  122. package/dist/mcp/resources.js.map +1 -0
  123. package/dist/mcp/runtime.d.ts +15 -0
  124. package/dist/mcp/runtime.js +122 -0
  125. package/dist/mcp/runtime.js.map +1 -0
  126. package/dist/mcp/session-memory.d.ts +3 -0
  127. package/dist/mcp/session-memory.js +61 -0
  128. package/dist/mcp/session-memory.js.map +1 -0
  129. package/dist/mcp/tool-registry.d.ts +269 -0
  130. package/dist/mcp/tool-registry.js +284 -0
  131. package/dist/mcp/tool-registry.js.map +1 -0
  132. package/dist/mcp/tools.d.ts +53 -0
  133. package/dist/mcp/tools.js +372 -0
  134. package/dist/mcp/tools.js.map +1 -0
  135. package/dist/mcp-repo-root.d.ts +16 -0
  136. package/dist/mcp-repo-root.js +322 -0
  137. package/dist/mcp-repo-root.js.map +1 -0
  138. package/dist/mcp-tool-catalog.d.ts +2 -0
  139. package/dist/mcp-tool-catalog.js +2 -0
  140. package/dist/mcp-tool-catalog.js.map +1 -0
  141. package/dist/mcp.d.ts +11 -0
  142. package/dist/mcp.js +332 -0
  143. package/dist/mcp.js.map +1 -0
  144. package/dist/outcome-ranking.d.ts +5 -0
  145. package/dist/outcome-ranking.js +115 -0
  146. package/dist/outcome-ranking.js.map +1 -0
  147. package/dist/parser/context.d.ts +28 -0
  148. package/dist/parser/context.js +2 -0
  149. package/dist/parser/context.js.map +1 -0
  150. package/dist/parser/ecma.d.ts +5 -0
  151. package/dist/parser/ecma.js +388 -0
  152. package/dist/parser/ecma.js.map +1 -0
  153. package/dist/parser/facts.d.ts +12 -0
  154. package/dist/parser/facts.js +137 -0
  155. package/dist/parser/facts.js.map +1 -0
  156. package/dist/parser/json.d.ts +3 -0
  157. package/dist/parser/json.js +318 -0
  158. package/dist/parser/json.js.map +1 -0
  159. package/dist/parser/markdown.d.ts +3 -0
  160. package/dist/parser/markdown.js +180 -0
  161. package/dist/parser/markdown.js.map +1 -0
  162. package/dist/parser/nodes.d.ts +5 -0
  163. package/dist/parser/nodes.js +75 -0
  164. package/dist/parser/nodes.js.map +1 -0
  165. package/dist/parser/python.d.ts +2 -0
  166. package/dist/parser/python.js +307 -0
  167. package/dist/parser/python.js.map +1 -0
  168. package/dist/parser/references.d.ts +3 -0
  169. package/dist/parser/references.js +204 -0
  170. package/dist/parser/references.js.map +1 -0
  171. package/dist/parser/risks.d.ts +4 -0
  172. package/dist/parser/risks.js +62 -0
  173. package/dist/parser/risks.js.map +1 -0
  174. package/dist/parser/routes.d.ts +5 -0
  175. package/dist/parser/routes.js +97 -0
  176. package/dist/parser/routes.js.map +1 -0
  177. package/dist/parser/shallow.d.ts +3 -0
  178. package/dist/parser/shallow.js +545 -0
  179. package/dist/parser/shallow.js.map +1 -0
  180. package/dist/parser/source.d.ts +4 -0
  181. package/dist/parser/source.js +127 -0
  182. package/dist/parser/source.js.map +1 -0
  183. package/dist/parser.d.ts +2 -0
  184. package/dist/parser.js +2 -0
  185. package/dist/parser.js.map +1 -0
  186. package/dist/placeholder-signals.d.ts +15 -0
  187. package/dist/placeholder-signals.js +511 -0
  188. package/dist/placeholder-signals.js.map +1 -0
  189. package/dist/post-edit-outcomes.d.ts +167 -0
  190. package/dist/post-edit-outcomes.js +484 -0
  191. package/dist/post-edit-outcomes.js.map +1 -0
  192. package/dist/queries.d.ts +12 -0
  193. package/dist/queries.js +13 -0
  194. package/dist/queries.js.map +1 -0
  195. package/dist/query/change-plan.d.ts +48 -0
  196. package/dist/query/change-plan.js +858 -0
  197. package/dist/query/change-plan.js.map +1 -0
  198. package/dist/query/compact-data.d.ts +25 -0
  199. package/dist/query/compact-data.js +74 -0
  200. package/dist/query/compact-data.js.map +1 -0
  201. package/dist/query/context.d.ts +5 -0
  202. package/dist/query/context.js +1162 -0
  203. package/dist/query/context.js.map +1 -0
  204. package/dist/query/diff.d.ts +5 -0
  205. package/dist/query/diff.js +111 -0
  206. package/dist/query/diff.js.map +1 -0
  207. package/dist/query/edge-evidence.d.ts +3 -0
  208. package/dist/query/edge-evidence.js +36 -0
  209. package/dist/query/edge-evidence.js.map +1 -0
  210. package/dist/query/formatting.d.ts +14 -0
  211. package/dist/query/formatting.js +67 -0
  212. package/dist/query/formatting.js.map +1 -0
  213. package/dist/query/graph-traversal.d.ts +22 -0
  214. package/dist/query/graph-traversal.js +218 -0
  215. package/dist/query/graph-traversal.js.map +1 -0
  216. package/dist/query/graph.d.ts +14 -0
  217. package/dist/query/graph.js +102 -0
  218. package/dist/query/graph.js.map +1 -0
  219. package/dist/query/impact.d.ts +28 -0
  220. package/dist/query/impact.js +568 -0
  221. package/dist/query/impact.js.map +1 -0
  222. package/dist/query/inspection.d.ts +9 -0
  223. package/dist/query/inspection.js +290 -0
  224. package/dist/query/inspection.js.map +1 -0
  225. package/dist/query/next-tools.d.ts +3 -0
  226. package/dist/query/next-tools.js +25 -0
  227. package/dist/query/next-tools.js.map +1 -0
  228. package/dist/query/placeholders.d.ts +24 -0
  229. package/dist/query/placeholders.js +121 -0
  230. package/dist/query/placeholders.js.map +1 -0
  231. package/dist/query/post-edit/decision.d.ts +49 -0
  232. package/dist/query/post-edit/decision.js +130 -0
  233. package/dist/query/post-edit/decision.js.map +1 -0
  234. package/dist/query/post-edit/dirty-scope.d.ts +16 -0
  235. package/dist/query/post-edit/dirty-scope.js +21 -0
  236. package/dist/query/post-edit/dirty-scope.js.map +1 -0
  237. package/dist/query/post-edit/next-actions.d.ts +22 -0
  238. package/dist/query/post-edit/next-actions.js +44 -0
  239. package/dist/query/post-edit/next-actions.js.map +1 -0
  240. package/dist/query/post-edit/snapshot-contract.d.ts +8 -0
  241. package/dist/query/post-edit/snapshot-contract.js +111 -0
  242. package/dist/query/post-edit/snapshot-contract.js.map +1 -0
  243. package/dist/query/post-edit.d.ts +5 -0
  244. package/dist/query/post-edit.js +1108 -0
  245. package/dist/query/post-edit.js.map +1 -0
  246. package/dist/query/quality.d.ts +43 -0
  247. package/dist/query/quality.js +134 -0
  248. package/dist/query/quality.js.map +1 -0
  249. package/dist/query/raw-search.d.ts +23 -0
  250. package/dist/query/raw-search.js +147 -0
  251. package/dist/query/raw-search.js.map +1 -0
  252. package/dist/query/runtime.d.ts +11 -0
  253. package/dist/query/runtime.js +79 -0
  254. package/dist/query/runtime.js.map +1 -0
  255. package/dist/query/search.d.ts +25 -0
  256. package/dist/query/search.js +429 -0
  257. package/dist/query/search.js.map +1 -0
  258. package/dist/query/session-memory.d.ts +3 -0
  259. package/dist/query/session-memory.js +108 -0
  260. package/dist/query/session-memory.js.map +1 -0
  261. package/dist/query/session.d.ts +41 -0
  262. package/dist/query/session.js +90 -0
  263. package/dist/query/session.js.map +1 -0
  264. package/dist/query/targets.d.ts +25 -0
  265. package/dist/query/targets.js +97 -0
  266. package/dist/query/targets.js.map +1 -0
  267. package/dist/query/test-commands.d.ts +10 -0
  268. package/dist/query/test-commands.js +110 -0
  269. package/dist/query/test-commands.js.map +1 -0
  270. package/dist/query/test-plan.d.ts +6 -0
  271. package/dist/query/test-plan.js +104 -0
  272. package/dist/query/test-plan.js.map +1 -0
  273. package/dist/query/tests.d.ts +48 -0
  274. package/dist/query/tests.js +444 -0
  275. package/dist/query/tests.js.map +1 -0
  276. package/dist/query/verification/shell.d.ts +20 -0
  277. package/dist/query/verification/shell.js +164 -0
  278. package/dist/query/verification/shell.js.map +1 -0
  279. package/dist/query/verification.d.ts +47 -0
  280. package/dist/query/verification.js +1123 -0
  281. package/dist/query/verification.js.map +1 -0
  282. package/dist/query/workflow.d.ts +17 -0
  283. package/dist/query/workflow.js +252 -0
  284. package/dist/query/workflow.js.map +1 -0
  285. package/dist/query/workspace-guidance.d.ts +26 -0
  286. package/dist/query/workspace-guidance.js +214 -0
  287. package/dist/query/workspace-guidance.js.map +1 -0
  288. package/dist/query/worktree-state.d.ts +22 -0
  289. package/dist/query/worktree-state.js +32 -0
  290. package/dist/query/worktree-state.js.map +1 -0
  291. package/dist/query/worktree.d.ts +16 -0
  292. package/dist/query/worktree.js +194 -0
  293. package/dist/query/worktree.js.map +1 -0
  294. package/dist/query-data.d.ts +4 -0
  295. package/dist/query-data.js +112 -0
  296. package/dist/query-data.js.map +1 -0
  297. package/dist/repo-files.d.ts +24 -0
  298. package/dist/repo-files.js +105 -0
  299. package/dist/repo-files.js.map +1 -0
  300. package/dist/resolver.d.ts +9 -0
  301. package/dist/resolver.js +555 -0
  302. package/dist/resolver.js.map +1 -0
  303. package/dist/retrieval.d.ts +46 -0
  304. package/dist/retrieval.js +783 -0
  305. package/dist/retrieval.js.map +1 -0
  306. package/dist/risk-ingest.d.ts +16 -0
  307. package/dist/risk-ingest.js +458 -0
  308. package/dist/risk-ingest.js.map +1 -0
  309. package/dist/rules.d.ts +10 -0
  310. package/dist/rules.js +107 -0
  311. package/dist/rules.js.map +1 -0
  312. package/dist/semantic/python.d.ts +9 -0
  313. package/dist/semantic/python.js +817 -0
  314. package/dist/semantic/python.js.map +1 -0
  315. package/dist/semantic/typescript.d.ts +10 -0
  316. package/dist/semantic/typescript.js +714 -0
  317. package/dist/semantic/typescript.js.map +1 -0
  318. package/dist/semantic-retrieval.d.ts +53 -0
  319. package/dist/semantic-retrieval.js +673 -0
  320. package/dist/semantic-retrieval.js.map +1 -0
  321. package/dist/session-memory/derivation.d.ts +6 -0
  322. package/dist/session-memory/derivation.js +400 -0
  323. package/dist/session-memory/derivation.js.map +1 -0
  324. package/dist/session-memory/event-log.d.ts +23 -0
  325. package/dist/session-memory/event-log.js +126 -0
  326. package/dist/session-memory/event-log.js.map +1 -0
  327. package/dist/session-memory/formatting.d.ts +7 -0
  328. package/dist/session-memory/formatting.js +86 -0
  329. package/dist/session-memory/formatting.js.map +1 -0
  330. package/dist/session-memory/model.d.ts +94 -0
  331. package/dist/session-memory/model.js +17 -0
  332. package/dist/session-memory/model.js.map +1 -0
  333. package/dist/session-memory/runtime.d.ts +24 -0
  334. package/dist/session-memory/runtime.js +289 -0
  335. package/dist/session-memory/runtime.js.map +1 -0
  336. package/dist/session-memory/store.d.ts +27 -0
  337. package/dist/session-memory/store.js +447 -0
  338. package/dist/session-memory/store.js.map +1 -0
  339. package/dist/session-memory.d.ts +1 -0
  340. package/dist/session-memory.js +2 -0
  341. package/dist/session-memory.js.map +1 -0
  342. package/dist/static-analysis.d.ts +36 -0
  343. package/dist/static-analysis.js +505 -0
  344. package/dist/static-analysis.js.map +1 -0
  345. package/dist/symbol-report-ingest.d.ts +8 -0
  346. package/dist/symbol-report-ingest.js +504 -0
  347. package/dist/symbol-report-ingest.js.map +1 -0
  348. package/dist/task-snapshots.d.ts +41 -0
  349. package/dist/task-snapshots.js +430 -0
  350. package/dist/task-snapshots.js.map +1 -0
  351. package/dist/types.d.ts +848 -0
  352. package/dist/types.js +12 -0
  353. package/dist/types.js.map +1 -0
  354. package/dist/util.d.ts +11 -0
  355. package/dist/util.js +63 -0
  356. package/dist/util.js.map +1 -0
  357. package/dist/version.d.ts +1 -0
  358. package/dist/version.js +5 -0
  359. package/dist/version.js.map +1 -0
  360. package/package.json +81 -0
  361. package/plugins/codexa/.codex-plugin/plugin.json +38 -0
  362. package/plugins/codexa/.mcp.json +20 -0
  363. package/plugins/codexa/scripts/codexa-mcp.js +100 -0
  364. package/plugins/codexa/skills/codexa/SKILL.md +48 -0
@@ -0,0 +1,714 @@
1
+ import { createHash } from "node:crypto";
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+ import ts from "typescript";
5
+ import { isSubpath, normalizePath, stableId } from "../util.js";
6
+ const MAX_COMPILER_PROJECT_CACHE_ENTRIES = 6;
7
+ const compilerProjectCache = new Map();
8
+ export async function applyTypeScriptSemanticAssist(index, options) {
9
+ const repoRoot = path.resolve(options.repoRoot);
10
+ const sourceFilesByPath = new Map(options.files.map((file) => [file.path, file.absolutePath]));
11
+ const contentHashesByPath = new Map(options.files.map((file) => [file.path, file.contentHash]));
12
+ const semanticFiles = index.files
13
+ .filter((file) => (file.language === "typescript" || file.language === "javascript") && sourceFilesByPath.has(file.path))
14
+ .map((file) => ({
15
+ path: file.path,
16
+ absolutePath: sourceFilesByPath.get(file.path),
17
+ contentHash: contentHashesByPath.get(file.path) ?? ""
18
+ }));
19
+ if (semanticFiles.length === 0) {
20
+ return index;
21
+ }
22
+ const context = {
23
+ repoRoot,
24
+ snapshotId: index.snapshot.snapshotId,
25
+ indexedAt: index.snapshot.indexedAt,
26
+ indexedPaths: new Set(index.files.map((file) => file.path)),
27
+ symbols: index.symbols.map((symbol) => ({ ...symbol })),
28
+ usageSites: index.usageSites.map((usage) => ({ ...usage })),
29
+ imports: index.imports.map((imp) => ({ ...imp })),
30
+ parserErrors: index.parserErrors.map((error) => ({ ...error })),
31
+ symbolById: new Map(),
32
+ symbolsByPath: new Map()
33
+ };
34
+ rebuildSymbolMaps(context);
35
+ const projects = groupSemanticProjects(index, semanticFiles, options.files);
36
+ for (const project of projects) {
37
+ try {
38
+ const compilerProject = await loadCompilerProject(repoRoot, project, context.snapshotId, context.indexedAt);
39
+ context.parserErrors.push(...compilerProject.warnings);
40
+ analyzeCompilerProject(compilerProject, context, new Set(project.files.map((file) => file.path)));
41
+ }
42
+ catch (error) {
43
+ context.parserErrors.push(semanticWarning(project.tsconfigPath ?? project.files[0]?.path ?? "tsconfig.json", context.snapshotId, context.indexedAt, `TypeScript semantic assist skipped: ${error instanceof Error ? error.message : String(error)}`));
44
+ }
45
+ }
46
+ return {
47
+ ...index,
48
+ symbols: sortSymbols(dedupeSymbols(context.symbols)),
49
+ usageSites: sortUsages(dedupeUsages(context.usageSites)),
50
+ imports: sortImports(dedupeImports(context.imports)),
51
+ parserErrors: sortParserErrors(dedupeParserErrors(context.parserErrors))
52
+ };
53
+ }
54
+ function groupSemanticProjects(index, files, allFiles) {
55
+ const tsconfigs = new Set(index.files.filter((file) => path.posix.basename(file.path) === "tsconfig.json").map((file) => file.path));
56
+ const contextHash = hashText(allFiles
57
+ .filter((file) => path.posix.basename(file.path) === "tsconfig.json" || path.posix.basename(file.path) === "package.json")
58
+ .map((file) => `${file.path}:${file.contentHash}`)
59
+ .sort()
60
+ .join("\n"));
61
+ const groups = new Map();
62
+ for (const file of files) {
63
+ const tsconfigPath = nearestTsconfig(file.path, tsconfigs);
64
+ const key = tsconfigPath ?? "<implicit>";
65
+ const existing = groups.get(key) ?? { key, tsconfigPath, contextHash, files: [] };
66
+ existing.files.push(file);
67
+ groups.set(key, existing);
68
+ }
69
+ return [...groups.values()]
70
+ .map((project) => ({ ...project, files: project.files.sort((a, b) => a.path.localeCompare(b.path)) }))
71
+ .sort((a, b) => a.key.localeCompare(b.key));
72
+ }
73
+ function nearestTsconfig(filePath, tsconfigs) {
74
+ let dir = path.posix.dirname(filePath);
75
+ while (true) {
76
+ const candidate = dir === "." ? "tsconfig.json" : `${dir}/tsconfig.json`;
77
+ if (tsconfigs.has(candidate)) {
78
+ return candidate;
79
+ }
80
+ if (dir === ".") {
81
+ return undefined;
82
+ }
83
+ dir = path.posix.dirname(dir);
84
+ }
85
+ }
86
+ async function loadCompilerProject(repoRoot, project, snapshotId, indexedAt) {
87
+ const config = await compilerOptionsForProject(repoRoot, project, snapshotId, indexedAt);
88
+ const rootsHash = hashText(project.files.map((file) => `${file.path}:${file.contentHash}`).join("\n"));
89
+ const cacheKey = `${repoRoot}:${project.key}:${config.configHash}:${project.contextHash}:${rootsHash}`;
90
+ const cached = compilerProjectCache.get(cacheKey);
91
+ if (cached) {
92
+ return cached;
93
+ }
94
+ const rootNames = project.files.map((file) => file.absolutePath);
95
+ const program = ts.createProgram({
96
+ rootNames,
97
+ options: config.options
98
+ });
99
+ const compilerProject = {
100
+ program,
101
+ checker: program.getTypeChecker(),
102
+ warnings: config.warnings
103
+ };
104
+ rememberCompilerProject(cacheKey, compilerProject);
105
+ return compilerProject;
106
+ }
107
+ function rememberCompilerProject(cacheKey, project) {
108
+ compilerProjectCache.set(cacheKey, project);
109
+ while (compilerProjectCache.size > MAX_COMPILER_PROJECT_CACHE_ENTRIES) {
110
+ const oldestKey = compilerProjectCache.keys().next().value;
111
+ if (!oldestKey) {
112
+ break;
113
+ }
114
+ compilerProjectCache.delete(oldestKey);
115
+ }
116
+ }
117
+ async function compilerOptionsForProject(repoRoot, project, snapshotId, indexedAt) {
118
+ const defaults = {
119
+ target: ts.ScriptTarget.ES2022,
120
+ module: ts.ModuleKind.NodeNext,
121
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
122
+ jsx: ts.JsxEmit.ReactJSX,
123
+ allowJs: true,
124
+ checkJs: false,
125
+ noEmit: true,
126
+ skipLibCheck: true,
127
+ esModuleInterop: true,
128
+ allowSyntheticDefaultImports: true
129
+ };
130
+ const warnings = [];
131
+ if (!project.tsconfigPath) {
132
+ return { options: defaults, configHash: "implicit", warnings };
133
+ }
134
+ const configPath = path.join(repoRoot, project.tsconfigPath);
135
+ let configText = "";
136
+ try {
137
+ configText = await fs.readFile(configPath, "utf8");
138
+ }
139
+ catch (error) {
140
+ warnings.push(semanticWarning(project.tsconfigPath, snapshotId, indexedAt, `Unable to read tsconfig: ${String(error)}`));
141
+ return { options: defaults, configHash: "missing", warnings };
142
+ }
143
+ const parsedJson = ts.parseConfigFileTextToJson(configPath, configText);
144
+ if (parsedJson.error) {
145
+ warnings.push(semanticWarning(project.tsconfigPath, snapshotId, indexedAt, flattenDiagnostic(parsedJson.error)));
146
+ return { options: defaults, configHash: hashText(configText), warnings };
147
+ }
148
+ const parsed = ts.parseJsonConfigFileContent(parsedJson.config, ts.sys, path.dirname(configPath), defaults, configPath);
149
+ for (const diagnostic of parsed.errors.slice(0, 5)) {
150
+ warnings.push(semanticWarning(project.tsconfigPath, snapshotId, indexedAt, flattenDiagnostic(diagnostic)));
151
+ }
152
+ return {
153
+ options: {
154
+ ...defaults,
155
+ ...parsed.options,
156
+ noEmit: true,
157
+ allowJs: true,
158
+ checkJs: false,
159
+ skipLibCheck: true
160
+ },
161
+ configHash: hashText(configText),
162
+ warnings
163
+ };
164
+ }
165
+ function analyzeCompilerProject(project, context, projectPaths) {
166
+ for (const sourceFile of project.program.getSourceFiles()) {
167
+ const relativePath = repoRelativePath(context.repoRoot, sourceFile.fileName);
168
+ if (!relativePath || !projectPaths.has(relativePath)) {
169
+ continue;
170
+ }
171
+ analyzeImports(sourceFile, project, context, relativePath);
172
+ analyzeExports(sourceFile, project, context, relativePath);
173
+ analyzeReferences(sourceFile, project, context, relativePath);
174
+ }
175
+ }
176
+ function analyzeImports(sourceFile, project, context, relativePath) {
177
+ const visit = (node) => {
178
+ if (ts.isImportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {
179
+ const specifier = node.moduleSpecifier.text;
180
+ const resolvedPath = resolveModulePath(specifier, sourceFile.fileName, project.program.getCompilerOptions(), context);
181
+ const clause = node.importClause;
182
+ if (!clause) {
183
+ mergeImport(context, importFact(context, sourceFile, node, relativePath, specifier, undefined, undefined, false, false, resolvedPath));
184
+ }
185
+ else {
186
+ if (clause.name) {
187
+ mergeImport(context, importFact(context, sourceFile, node, relativePath, specifier, "default", clause.name.text, false, Boolean(clause.isTypeOnly), resolvedPath));
188
+ }
189
+ if (clause.namedBindings && ts.isNamespaceImport(clause.namedBindings)) {
190
+ mergeImport(context, importFact(context, sourceFile, node, relativePath, specifier, "*", clause.namedBindings.name.text, false, Boolean(clause.isTypeOnly), resolvedPath));
191
+ }
192
+ if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {
193
+ for (const spec of clause.namedBindings.elements) {
194
+ mergeImport(context, importFact(context, sourceFile, spec, relativePath, specifier, (spec.propertyName ?? spec.name).text, spec.name.text, false, Boolean(clause.isTypeOnly || spec.isTypeOnly), resolvedPath));
195
+ }
196
+ }
197
+ }
198
+ }
199
+ if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteralLike(node.moduleSpecifier)) {
200
+ const specifier = node.moduleSpecifier.text;
201
+ const resolvedPath = resolveModulePath(specifier, sourceFile.fileName, project.program.getCompilerOptions(), context);
202
+ const typeOnly = Boolean(node.isTypeOnly);
203
+ if (!node.exportClause) {
204
+ mergeImport(context, importFact(context, sourceFile, node, relativePath, specifier, "*", "*", true, typeOnly, resolvedPath));
205
+ }
206
+ else if (ts.isNamespaceExport(node.exportClause)) {
207
+ mergeImport(context, importFact(context, sourceFile, node, relativePath, specifier, "*", node.exportClause.name.text, true, typeOnly, resolvedPath));
208
+ }
209
+ else if (ts.isNamedExports(node.exportClause)) {
210
+ for (const spec of node.exportClause.elements) {
211
+ mergeImport(context, importFact(context, sourceFile, spec, relativePath, specifier, (spec.propertyName ?? spec.name).text, spec.name.text, true, Boolean(typeOnly || spec.isTypeOnly), resolvedPath));
212
+ }
213
+ }
214
+ }
215
+ ts.forEachChild(node, visit);
216
+ };
217
+ visit(sourceFile);
218
+ }
219
+ function analyzeExports(sourceFile, project, context, relativePath) {
220
+ const moduleSymbol = project.checker.getSymbolAtLocation(sourceFile);
221
+ if (moduleSymbol) {
222
+ for (const exportSymbol of project.checker.getExportsOfModule(moduleSymbol)) {
223
+ const targetSymbol = symbolFromTsSymbol(exportSymbol, project, context);
224
+ if (targetSymbol) {
225
+ if (targetSymbol.path === relativePath) {
226
+ targetSymbol.exported = true;
227
+ }
228
+ const exportDeclaration = exportSymbol.declarations?.find((declaration) => repoRelativePath(context.repoRoot, declaration.getSourceFile().fileName) === relativePath);
229
+ if (exportDeclaration && targetSymbol.path !== relativePath) {
230
+ mergeUsage(context, usageFact(context, sourceFile, exportDeclaration, relativePath, exportSymbol.name, typeUsageKind(targetSymbol), `re-export ${exportSymbol.name}`, targetSymbol.id, "authoritative"));
231
+ }
232
+ }
233
+ }
234
+ }
235
+ const visit = (node) => {
236
+ if (ts.isExportDeclaration(node) && !node.moduleSpecifier && node.exportClause && ts.isNamedExports(node.exportClause)) {
237
+ for (const spec of node.exportClause.elements) {
238
+ if (spec.name.text !== "default") {
239
+ continue;
240
+ }
241
+ const target = symbolFromNode(spec.propertyName ?? spec.name, project, context);
242
+ const targetKind = target?.kind ?? "unknown";
243
+ const defaultSymbol = ensureSyntheticDefaultExport(context, sourceFile, spec.name, relativePath, targetKind);
244
+ if (target) {
245
+ mergeUsage(context, usageFact(context, sourceFile, spec, relativePath, (spec.propertyName ?? spec.name).text, typeUsageKind(target), "local default export alias", target.id, "authoritative"));
246
+ }
247
+ defaultSymbol.exported = true;
248
+ }
249
+ }
250
+ ts.forEachChild(node, visit);
251
+ };
252
+ visit(sourceFile);
253
+ }
254
+ function analyzeReferences(sourceFile, project, context, relativePath) {
255
+ const visit = (node) => {
256
+ if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
257
+ const target = symbolFromNode(node.tagName, project, context);
258
+ const name = node.tagName.getText(sourceFile);
259
+ if (target && /^[A-Z]/.test(name)) {
260
+ mergeUsage(context, usageFact(context, sourceFile, node.tagName, relativePath, name, "reference", `jsx component ${name}`, target.id, "authoritative"));
261
+ }
262
+ }
263
+ if (ts.isPropertyAccessExpression(node)) {
264
+ const target = symbolFromNode(node.name, project, context);
265
+ if (target) {
266
+ const name = compactTsName(node.getText(sourceFile));
267
+ const isCall = ts.isCallExpression(node.parent) && node.parent.expression === node;
268
+ mergeUsage(context, usageFact(context, sourceFile, node, relativePath, name, isCall ? "call" : "reference", isCall ? `method call ${name}` : `property reference ${name}`, target.id, "authoritative"));
269
+ }
270
+ }
271
+ if (ts.isTypeReferenceNode(node)) {
272
+ const target = symbolFromNode(node.typeName, project, context);
273
+ if (target) {
274
+ const name = compactTsName(node.typeName.getText(sourceFile));
275
+ mergeUsage(context, usageFact(context, sourceFile, node.typeName, relativePath, name, "type_reference", `type reference ${name}`, target.id, "authoritative"));
276
+ }
277
+ }
278
+ ts.forEachChild(node, visit);
279
+ };
280
+ visit(sourceFile);
281
+ }
282
+ function symbolFromNode(node, project, context) {
283
+ const symbol = project.checker.getSymbolAtLocation(node);
284
+ return symbol ? symbolFromTsSymbol(symbol, project, context) : undefined;
285
+ }
286
+ function symbolFromTsSymbol(symbol, project, context) {
287
+ const target = safeAliasedSymbol(project.checker, symbol);
288
+ const declarations = target.declarations ?? symbol.declarations ?? [];
289
+ for (const declaration of declarations) {
290
+ const sourceFile = declaration.getSourceFile();
291
+ const relativePath = repoRelativePath(context.repoRoot, sourceFile.fileName);
292
+ if (!relativePath || !context.indexedPaths.has(relativePath)) {
293
+ continue;
294
+ }
295
+ const symbolInfo = symbolInfoForDeclaration(declaration, sourceFile, target.name);
296
+ if (!symbolInfo) {
297
+ continue;
298
+ }
299
+ return ensureSymbol(context, sourceFile, declaration, relativePath, symbolInfo);
300
+ }
301
+ return undefined;
302
+ }
303
+ function safeAliasedSymbol(checker, symbol) {
304
+ if ((symbol.flags & ts.SymbolFlags.Alias) === 0) {
305
+ return symbol;
306
+ }
307
+ try {
308
+ return checker.getAliasedSymbol(symbol);
309
+ }
310
+ catch {
311
+ return symbol;
312
+ }
313
+ }
314
+ function symbolInfoForDeclaration(declaration, sourceFile, fallbackName) {
315
+ if (ts.isFunctionDeclaration(declaration)) {
316
+ const name = declaration.name?.text ?? (hasDefaultExport(declaration) ? "default" : fallbackName);
317
+ return { name, qualifiedName: name === "default" ? "default export" : name, kind: "function", exported: isExportedDeclaration(declaration) };
318
+ }
319
+ if (ts.isClassDeclaration(declaration)) {
320
+ const name = declaration.name?.text ?? (hasDefaultExport(declaration) ? "default" : fallbackName);
321
+ return { name, qualifiedName: name === "default" ? "default export" : name, kind: "class", exported: isExportedDeclaration(declaration) };
322
+ }
323
+ if (ts.isInterfaceDeclaration(declaration)) {
324
+ return { name: declaration.name.text, qualifiedName: declaration.name.text, kind: "interface", exported: isExportedDeclaration(declaration) };
325
+ }
326
+ if (ts.isTypeAliasDeclaration(declaration)) {
327
+ return { name: declaration.name.text, qualifiedName: declaration.name.text, kind: "type", exported: isExportedDeclaration(declaration) };
328
+ }
329
+ if (ts.isEnumDeclaration(declaration)) {
330
+ return { name: declaration.name.text, qualifiedName: declaration.name.text, kind: "enum", exported: isExportedDeclaration(declaration) };
331
+ }
332
+ if (ts.isMethodDeclaration(declaration) || ts.isMethodSignature(declaration)) {
333
+ const name = propertyNameText(declaration.name, sourceFile);
334
+ if (!name) {
335
+ return undefined;
336
+ }
337
+ const parentName = declaration.parent && (ts.isClassLike(declaration.parent) || ts.isInterfaceDeclaration(declaration.parent)) ? declaration.parent.name?.text : undefined;
338
+ const objectName = declaration.parent && ts.isObjectLiteralExpression(declaration.parent) ? objectLiteralOwnerName(declaration.parent) : undefined;
339
+ return {
340
+ name,
341
+ qualifiedName: parentName ? `${parentName}.${name}` : objectName ? `${objectName}.${name}` : name,
342
+ kind: "method",
343
+ exported: Boolean(parentName && isExportedDeclaration(declaration.parent))
344
+ };
345
+ }
346
+ if (ts.isPropertyAssignment(declaration)) {
347
+ const name = propertyNameText(declaration.name, sourceFile);
348
+ const objectName = declaration.parent && ts.isObjectLiteralExpression(declaration.parent) ? objectLiteralOwnerName(declaration.parent) : undefined;
349
+ if (name && objectName && declaration.initializer && (ts.isArrowFunction(declaration.initializer) || ts.isFunctionExpression(declaration.initializer))) {
350
+ return {
351
+ name,
352
+ qualifiedName: `${objectName}.${name}`,
353
+ kind: "method",
354
+ exported: objectLiteralOwnerExported(declaration.parent)
355
+ };
356
+ }
357
+ }
358
+ if (ts.isVariableDeclaration(declaration) && ts.isIdentifier(declaration.name)) {
359
+ const name = declaration.name.text;
360
+ return { name, qualifiedName: name, kind: variableSymbolKind(declaration), exported: variableDeclarationExported(declaration) };
361
+ }
362
+ if (ts.isFunctionExpression(declaration) && declaration.name) {
363
+ return { name: declaration.name.text, qualifiedName: declaration.name.text, kind: "function", exported: isDefaultExportAssignment(declaration) };
364
+ }
365
+ return undefined;
366
+ }
367
+ function ensureSymbol(context, sourceFile, declaration, relativePath, symbolInfo) {
368
+ const range = rangeFromNode(sourceFile, declaration);
369
+ const existing = findExistingSymbol(context, relativePath, symbolInfo, range);
370
+ if (existing) {
371
+ if (symbolInfo.exported && !existing.exported) {
372
+ existing.exported = true;
373
+ }
374
+ return existing;
375
+ }
376
+ const symbol = {
377
+ ...baseFact("Symbol", relativePath, context.snapshotId, context.indexedAt, "typescript-compiler", "authoritative", range),
378
+ id: stableId("ts-semantic-symbol", relativePath, symbolInfo.qualifiedName, symbolInfo.kind, range.startByte),
379
+ type: "Symbol",
380
+ path: relativePath,
381
+ name: symbolInfo.name,
382
+ qualifiedName: symbolInfo.qualifiedName,
383
+ kind: symbolInfo.kind,
384
+ language: relativePath.endsWith(".js") || relativePath.endsWith(".jsx") ? "javascript" : "typescript",
385
+ exported: symbolInfo.exported,
386
+ decorators: []
387
+ };
388
+ context.symbols.push(symbol);
389
+ addSymbolToMaps(context, symbol);
390
+ return symbol;
391
+ }
392
+ function ensureSyntheticDefaultExport(context, sourceFile, node, relativePath, kind) {
393
+ const range = rangeFromNode(sourceFile, node);
394
+ const existing = findExistingSymbol(context, relativePath, { name: "default", qualifiedName: "default export", kind }, range);
395
+ if (existing) {
396
+ existing.exported = true;
397
+ return existing;
398
+ }
399
+ const symbol = {
400
+ ...baseFact("Symbol", relativePath, context.snapshotId, context.indexedAt, "typescript-compiler", "authoritative", range),
401
+ id: stableId("ts-semantic-default", relativePath, range.startByte),
402
+ type: "Symbol",
403
+ path: relativePath,
404
+ name: "default",
405
+ qualifiedName: "default export",
406
+ kind,
407
+ language: relativePath.endsWith(".js") || relativePath.endsWith(".jsx") ? "javascript" : "typescript",
408
+ exported: true,
409
+ decorators: []
410
+ };
411
+ context.symbols.push(symbol);
412
+ addSymbolToMaps(context, symbol);
413
+ return symbol;
414
+ }
415
+ function findExistingSymbol(context, relativePath, symbolInfo, range) {
416
+ const candidates = context.symbolsByPath.get(relativePath) ?? [];
417
+ const requiresQualifiedMatch = symbolInfo.qualifiedName.includes(".");
418
+ return (candidates.find((symbol) => symbol.kind === symbolInfo.kind &&
419
+ (requiresQualifiedMatch ? symbol.qualifiedName === symbolInfo.qualifiedName : symbol.name === symbolInfo.name || symbol.qualifiedName === symbolInfo.qualifiedName) &&
420
+ Math.abs((symbol.range?.startByte ?? -1) - range.startByte) <= 4) ??
421
+ candidates.find((symbol) => symbol.kind === symbolInfo.kind &&
422
+ (requiresQualifiedMatch ? symbol.qualifiedName === symbolInfo.qualifiedName : symbol.name === symbolInfo.name || symbol.qualifiedName === symbolInfo.qualifiedName) &&
423
+ !symbol.parentSymbolId));
424
+ }
425
+ function mergeUsage(context, usage) {
426
+ const existing = context.usageSites.find((candidate) => candidate.path === usage.path &&
427
+ candidate.name === usage.name &&
428
+ candidate.kind === usage.kind &&
429
+ Math.abs((candidate.range?.startByte ?? -1) - (usage.range?.startByte ?? -2)) <= 4);
430
+ if (existing) {
431
+ if (!existing.targetSymbolId && usage.targetSymbolId) {
432
+ existing.targetSymbolId = usage.targetSymbolId;
433
+ existing.source = usage.source;
434
+ existing.confidence = usage.confidence;
435
+ existing.text = usage.text;
436
+ }
437
+ return;
438
+ }
439
+ context.usageSites.push(usage);
440
+ }
441
+ function mergeImport(context, imp) {
442
+ const existing = context.imports.find((candidate) => candidate.path === imp.path &&
443
+ candidate.specifier === imp.specifier &&
444
+ candidate.importedName === imp.importedName &&
445
+ candidate.localName === imp.localName &&
446
+ Boolean(candidate.reExport) === Boolean(imp.reExport) &&
447
+ Boolean(candidate.typeOnly) === Boolean(imp.typeOnly));
448
+ if (existing) {
449
+ if (!existing.resolvedPath && imp.resolvedPath) {
450
+ existing.resolvedPath = imp.resolvedPath;
451
+ }
452
+ return;
453
+ }
454
+ context.imports.push(imp);
455
+ }
456
+ function importFact(context, sourceFile, node, relativePath, specifier, importedName, localName, reExport = false, typeOnly = false, resolvedPath) {
457
+ const range = rangeFromNode(sourceFile, node);
458
+ return {
459
+ ...baseFact("ImportEdge", relativePath, context.snapshotId, context.indexedAt, "typescript-compiler", "authoritative", range),
460
+ id: stableId("ts-semantic-import", relativePath, specifier, importedName, localName, reExport ? "re-export" : "import", typeOnly ? "type" : "value", range.startByte),
461
+ type: "ImportEdge",
462
+ path: relativePath,
463
+ specifier,
464
+ importedName,
465
+ localName,
466
+ reExport,
467
+ typeOnly,
468
+ resolvedPath
469
+ };
470
+ }
471
+ function usageFact(context, sourceFile, node, relativePath, name, kind, text, targetSymbolId, confidence = "derived") {
472
+ const range = rangeFromNode(sourceFile, node);
473
+ return {
474
+ ...baseFact("UsageSite", relativePath, context.snapshotId, context.indexedAt, "typescript-compiler", confidence, range),
475
+ id: stableId("ts-semantic-usage", relativePath, name, kind, range.startByte, targetSymbolId),
476
+ type: "UsageSite",
477
+ path: relativePath,
478
+ name,
479
+ kind,
480
+ targetSymbolId,
481
+ usedBySymbolId: enclosingSymbolId(context, sourceFile, node, relativePath),
482
+ text: text.replace(/\s+/g, " ").slice(0, 240)
483
+ };
484
+ }
485
+ function enclosingSymbolId(context, sourceFile, node, relativePath) {
486
+ let current = node.parent;
487
+ while (current) {
488
+ const info = symbolInfoForDeclaration(current, sourceFile, "");
489
+ if (info) {
490
+ return findExistingSymbol(context, relativePath, info, rangeFromNode(sourceFile, current))?.id;
491
+ }
492
+ current = current.parent;
493
+ }
494
+ return undefined;
495
+ }
496
+ function resolveModulePath(specifier, containingFile, options, context) {
497
+ const resolved = ts.resolveModuleName(specifier, containingFile, options, ts.sys).resolvedModule?.resolvedFileName;
498
+ if (!resolved) {
499
+ return undefined;
500
+ }
501
+ const relativePath = repoRelativePath(context.repoRoot, resolved.replace(/\.d\.ts$/u, ".ts"));
502
+ if (relativePath && context.indexedPaths.has(relativePath)) {
503
+ return relativePath;
504
+ }
505
+ const directRelativePath = repoRelativePath(context.repoRoot, resolved);
506
+ return directRelativePath && context.indexedPaths.has(directRelativePath) ? directRelativePath : undefined;
507
+ }
508
+ function repoRelativePath(repoRoot, fileName) {
509
+ const absolute = path.resolve(fileName);
510
+ if (!isSubpath(absolute, repoRoot)) {
511
+ return undefined;
512
+ }
513
+ const relative = normalizePath(path.relative(repoRoot, absolute));
514
+ if (!relative || relative.startsWith("node_modules/")) {
515
+ return undefined;
516
+ }
517
+ return relative;
518
+ }
519
+ function baseFact(type, filePath, snapshotId, indexedAt, source, confidence, range) {
520
+ return {
521
+ type,
522
+ path: filePath,
523
+ source,
524
+ confidence,
525
+ snapshotId,
526
+ indexedAt,
527
+ range
528
+ };
529
+ }
530
+ function semanticWarning(pathValue, snapshotId, indexedAt, message) {
531
+ return {
532
+ ...baseFact("ParserError", pathValue, snapshotId, indexedAt, "typescript-compiler", "heuristic"),
533
+ id: stableId("ts-semantic-warning", pathValue, message),
534
+ type: "ParserError",
535
+ path: pathValue,
536
+ message
537
+ };
538
+ }
539
+ function rangeFromNode(sourceFile, node) {
540
+ const start = node.getStart(sourceFile);
541
+ return rangeFromOffsets(sourceFile.text, start, node.end);
542
+ }
543
+ function rangeFromOffsets(sourceText, start, end) {
544
+ let line = 1;
545
+ let lineStart = 0;
546
+ for (let index = 0; index < start; index += 1) {
547
+ if (sourceText.charCodeAt(index) === 10) {
548
+ line += 1;
549
+ lineStart = index + 1;
550
+ }
551
+ }
552
+ let endLine = line;
553
+ for (let index = start; index < end; index += 1) {
554
+ if (sourceText.charCodeAt(index) === 10) {
555
+ endLine += 1;
556
+ }
557
+ }
558
+ return {
559
+ startLine: line,
560
+ endLine,
561
+ startByte: start,
562
+ endByte: end
563
+ };
564
+ }
565
+ function rebuildSymbolMaps(context) {
566
+ context.symbolById = new Map();
567
+ context.symbolsByPath = new Map();
568
+ for (const symbol of context.symbols) {
569
+ addSymbolToMaps(context, symbol);
570
+ }
571
+ }
572
+ function addSymbolToMaps(context, symbol) {
573
+ context.symbolById.set(symbol.id, symbol);
574
+ const inPath = context.symbolsByPath.get(symbol.path) ?? [];
575
+ inPath.push(symbol);
576
+ context.symbolsByPath.set(symbol.path, inPath);
577
+ }
578
+ function variableSymbolKind(declaration) {
579
+ const initializer = declaration.initializer;
580
+ return initializer && (ts.isArrowFunction(initializer) || ts.isFunctionExpression(initializer)) ? "function" : "variable";
581
+ }
582
+ function variableDeclarationExported(declaration) {
583
+ const statement = declaration.parent?.parent;
584
+ return Boolean(statement && ts.isVariableStatement(statement) && isExportedDeclaration(statement));
585
+ }
586
+ function objectLiteralOwnerName(node) {
587
+ const parent = node.parent;
588
+ return parent && ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name) ? parent.name.text : undefined;
589
+ }
590
+ function objectLiteralOwnerExported(node) {
591
+ const parent = node.parent;
592
+ return parent && ts.isVariableDeclaration(parent) ? variableDeclarationExported(parent) : false;
593
+ }
594
+ function isExportedDeclaration(declaration) {
595
+ return Boolean(ts.canHaveModifiers(declaration) && ts.getModifiers(declaration)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
596
+ }
597
+ function hasDefaultExport(node) {
598
+ return Boolean(ts.canHaveModifiers(node) && ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword));
599
+ }
600
+ function isDefaultExportAssignment(declaration) {
601
+ let current = declaration.parent;
602
+ while (current) {
603
+ if (ts.isExportAssignment(current) && !current.isExportEquals) {
604
+ return true;
605
+ }
606
+ current = current.parent;
607
+ }
608
+ return false;
609
+ }
610
+ function propertyNameText(name, sourceFile) {
611
+ if (!name) {
612
+ return undefined;
613
+ }
614
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {
615
+ return name.text;
616
+ }
617
+ const text = name.getText(sourceFile).replace(/^["']|["']$/gu, "");
618
+ return /^[A-Za-z_$][\w$]*$/u.test(text) ? text : undefined;
619
+ }
620
+ function typeUsageKind(symbol) {
621
+ return symbol.kind === "interface" || symbol.kind === "type" || symbol.kind === "enum" ? "type_reference" : "reference";
622
+ }
623
+ function compactTsName(value) {
624
+ const compact = value.replace(/\s+/gu, " ").trim();
625
+ return compact.length <= 120 ? compact : `${compact.slice(0, 117)}...`;
626
+ }
627
+ function flattenDiagnostic(diagnostic) {
628
+ return ts.flattenDiagnosticMessageText(diagnostic.messageText, " ").slice(0, 500);
629
+ }
630
+ function hashText(value) {
631
+ return createHash("sha1").update(value).digest("hex");
632
+ }
633
+ function dedupeSymbols(symbols) {
634
+ const byKey = new Map();
635
+ for (const symbol of symbols) {
636
+ const key = `${symbol.path}\0${symbol.qualifiedName}\0${symbol.kind}\0${symbol.range?.startByte ?? -1}`;
637
+ const existing = byKey.get(key);
638
+ if (!existing) {
639
+ byKey.set(key, symbol);
640
+ }
641
+ else if (factSourcePriority(symbol.source) > factSourcePriority(existing.source)) {
642
+ byKey.set(key, { ...symbol, exported: symbol.exported || existing.exported });
643
+ }
644
+ else if (symbol.exported && !existing.exported) {
645
+ existing.exported = true;
646
+ }
647
+ }
648
+ return [...byKey.values()];
649
+ }
650
+ function dedupeUsages(usages) {
651
+ const byKey = new Map();
652
+ for (const usage of usages) {
653
+ const locationKey = usage.range ? String(usage.range.startByte) : `${usage.id}:${usage.text}`;
654
+ const key = `${usage.path}\0${usage.name}\0${usage.kind}\0${locationKey}`;
655
+ const existing = byKey.get(key);
656
+ if (!existing || factSourcePriority(usage.source) > factSourcePriority(existing.source) || (!existing.targetSymbolId && usage.targetSymbolId)) {
657
+ byKey.set(key, usage);
658
+ }
659
+ }
660
+ return [...byKey.values()];
661
+ }
662
+ function dedupeImports(imports) {
663
+ const byKey = new Map();
664
+ for (const imp of imports) {
665
+ const key = `${imp.path}\0${imp.specifier}\0${imp.importedName ?? ""}\0${imp.localName ?? ""}\0${Boolean(imp.reExport)}\0${Boolean(imp.typeOnly)}`;
666
+ const existing = byKey.get(key);
667
+ if (!existing) {
668
+ byKey.set(key, imp);
669
+ }
670
+ else if (!existing.resolvedPath && imp.resolvedPath) {
671
+ existing.resolvedPath = imp.resolvedPath;
672
+ }
673
+ }
674
+ return [...byKey.values()];
675
+ }
676
+ function factSourcePriority(source) {
677
+ if (source === "typescript-compiler") {
678
+ return 3;
679
+ }
680
+ if (source === "typescript-syntax") {
681
+ return 2;
682
+ }
683
+ return 1;
684
+ }
685
+ function dedupeParserErrors(errors) {
686
+ const seen = new Set();
687
+ const result = [];
688
+ for (const error of errors) {
689
+ const key = `${error.path}\0${error.source}\0${error.message}`;
690
+ if (seen.has(key)) {
691
+ continue;
692
+ }
693
+ seen.add(key);
694
+ result.push(error);
695
+ }
696
+ return result;
697
+ }
698
+ function sortSymbols(symbols) {
699
+ return symbols.sort((a, b) => a.path.localeCompare(b.path) || (a.range?.startByte ?? 0) - (b.range?.startByte ?? 0) || a.qualifiedName.localeCompare(b.qualifiedName));
700
+ }
701
+ function sortUsages(usages) {
702
+ return usages.sort((a, b) => a.path.localeCompare(b.path) || (a.range?.startByte ?? 0) - (b.range?.startByte ?? 0) || a.name.localeCompare(b.name));
703
+ }
704
+ function sortImports(imports) {
705
+ return imports.sort((a, b) => a.path.localeCompare(b.path) ||
706
+ (a.range?.startByte ?? 0) - (b.range?.startByte ?? 0) ||
707
+ a.specifier.localeCompare(b.specifier) ||
708
+ (a.importedName ?? "").localeCompare(b.importedName ?? "") ||
709
+ (a.localName ?? "").localeCompare(b.localName ?? ""));
710
+ }
711
+ function sortParserErrors(errors) {
712
+ return errors.sort((a, b) => a.path.localeCompare(b.path) || a.message.localeCompare(b.message));
713
+ }
714
+ //# sourceMappingURL=typescript.js.map