code-auditor-mcp 4.1.1 → 5.0.2

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 (1087) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +381 -0
  3. package/README.md +4 -4
  4. package/configs/hhra-compat.json +0 -8
  5. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts +1 -1
  6. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts.map +1 -1
  7. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js +7 -1
  8. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js.map +1 -1
  9. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts +2 -8
  10. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts.map +1 -1
  11. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js +4 -4
  12. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js.map +1 -1
  13. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts +1 -1
  14. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts.map +1 -1
  15. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js.map +1 -1
  16. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts +2 -2
  17. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts.map +1 -1
  18. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js.map +1 -1
  19. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts +1 -1
  20. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts.map +1 -1
  21. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js.map +1 -1
  22. package/dist/analyzers/applicability.d.ts +42 -0
  23. package/dist/analyzers/applicability.d.ts.map +1 -1
  24. package/dist/analyzers/applicability.js +74 -0
  25. package/dist/analyzers/applicability.js.map +1 -1
  26. package/dist/analyzers/cross-language/APIContractAnalyzer.js +18 -24
  27. package/dist/analyzers/cross-language/APIContractAnalyzer.js.map +1 -1
  28. package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts +30 -23
  29. package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
  30. package/dist/analyzers/cross-language/DependencyGraphBuilder.js +113 -76
  31. package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
  32. package/dist/analyzers/cross-language/SchemaValidator.d.ts +2 -0
  33. package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -1
  34. package/dist/analyzers/cross-language/SchemaValidator.js +8 -3
  35. package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -1
  36. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts.map +1 -1
  37. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js +210 -148
  38. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js.map +1 -1
  39. package/dist/analyzers/documentationAnalyzer.d.ts.map +1 -1
  40. package/dist/analyzers/documentationAnalyzer.js +23 -28
  41. package/dist/analyzers/documentationAnalyzer.js.map +1 -1
  42. package/dist/analyzers/handleIdentification.d.ts +356 -0
  43. package/dist/analyzers/handleIdentification.d.ts.map +1 -0
  44. package/dist/analyzers/handleIdentification.js +427 -0
  45. package/dist/analyzers/handleIdentification.js.map +1 -0
  46. package/dist/analyzers/manifestStaleness.d.ts +64 -0
  47. package/dist/analyzers/manifestStaleness.d.ts.map +1 -0
  48. package/dist/analyzers/manifestStaleness.js +115 -0
  49. package/dist/analyzers/manifestStaleness.js.map +1 -0
  50. package/dist/analyzers/orgFilterTiers.d.ts +73 -1
  51. package/dist/analyzers/orgFilterTiers.d.ts.map +1 -1
  52. package/dist/analyzers/orgFilterTiers.js +166 -1
  53. package/dist/analyzers/orgFilterTiers.js.map +1 -1
  54. package/dist/analyzers/provenance.d.ts +251 -57
  55. package/dist/analyzers/provenance.d.ts.map +1 -1
  56. package/dist/analyzers/provenance.js +1109 -429
  57. package/dist/analyzers/provenance.js.map +1 -1
  58. package/dist/analyzers/reactAnalyzer.d.ts +2 -0
  59. package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
  60. package/dist/analyzers/reactAnalyzer.js +2 -0
  61. package/dist/analyzers/reactAnalyzer.js.map +1 -1
  62. package/dist/analyzers/receiverResolution.d.ts +183 -0
  63. package/dist/analyzers/receiverResolution.d.ts.map +1 -0
  64. package/dist/analyzers/receiverResolution.js +540 -0
  65. package/dist/analyzers/receiverResolution.js.map +1 -0
  66. package/dist/analyzers/receiverRoot.d.ts +348 -0
  67. package/dist/analyzers/receiverRoot.d.ts.map +1 -0
  68. package/dist/analyzers/receiverRoot.js +1032 -0
  69. package/dist/analyzers/receiverRoot.js.map +1 -0
  70. package/dist/analyzers/ruleRegistry.d.ts +12 -68
  71. package/dist/analyzers/ruleRegistry.d.ts.map +1 -1
  72. package/dist/analyzers/ruleRegistry.js +32 -342
  73. package/dist/analyzers/ruleRegistry.js.map +1 -1
  74. package/dist/analyzers/ruleTiming.d.ts +10 -0
  75. package/dist/analyzers/ruleTiming.d.ts.map +1 -1
  76. package/dist/analyzers/ruleTiming.js +20 -0
  77. package/dist/analyzers/ruleTiming.js.map +1 -1
  78. package/dist/analyzers/sqlLiteral.d.ts +76 -0
  79. package/dist/analyzers/sqlLiteral.d.ts.map +1 -0
  80. package/dist/analyzers/sqlLiteral.js +419 -0
  81. package/dist/analyzers/sqlLiteral.js.map +1 -0
  82. package/dist/analyzers/tsEcosystem.d.ts +115 -0
  83. package/dist/analyzers/tsEcosystem.d.ts.map +1 -0
  84. package/dist/analyzers/tsEcosystem.js +241 -0
  85. package/dist/analyzers/tsEcosystem.js.map +1 -0
  86. package/dist/analyzers/tsExpressionDescriptor.d.ts +156 -0
  87. package/dist/analyzers/tsExpressionDescriptor.d.ts.map +1 -0
  88. package/dist/analyzers/tsExpressionDescriptor.js +374 -0
  89. package/dist/analyzers/tsExpressionDescriptor.js.map +1 -0
  90. package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts +6 -0
  91. package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts.map +1 -1
  92. package/dist/analyzers/universal/UniversalConventionsAnalyzer.js +107 -44
  93. package/dist/analyzers/universal/UniversalConventionsAnalyzer.js.map +1 -1
  94. package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
  95. package/dist/analyzers/universal/UniversalDRYAnalyzer.js +23 -35
  96. package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
  97. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +287 -49
  98. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
  99. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +2130 -512
  100. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
  101. package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
  102. package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +2 -18
  103. package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
  104. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +0 -33
  105. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
  106. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +20 -143
  107. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
  108. package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts +4 -3
  109. package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
  110. package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +36 -13
  111. package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
  112. package/dist/analyzers/universal/UniversalSecretsAnalyzer.d.ts.map +1 -1
  113. package/dist/analyzers/universal/UniversalSecretsAnalyzer.js +6 -0
  114. package/dist/analyzers/universal/UniversalSecretsAnalyzer.js.map +1 -1
  115. package/dist/analyzers/universal/UniversalSecurityAnalyzer.d.ts +15 -0
  116. package/dist/analyzers/universal/UniversalSecurityAnalyzer.d.ts.map +1 -1
  117. package/dist/analyzers/universal/UniversalSecurityAnalyzer.js +25 -0
  118. package/dist/analyzers/universal/UniversalSecurityAnalyzer.js.map +1 -1
  119. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +21 -32
  120. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
  121. package/dist/analyzers/universal/UniversalStylesAnalyzer.js +166 -196
  122. package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
  123. package/dist/analyzers/universal/functionConcerns.d.ts +3 -0
  124. package/dist/analyzers/universal/functionConcerns.d.ts.map +1 -1
  125. package/dist/analyzers/universal/functionConcerns.js +4 -1
  126. package/dist/analyzers/universal/functionConcerns.js.map +1 -1
  127. package/dist/analyzers/universal/schema/codeAnalysis.d.ts +310 -69
  128. package/dist/analyzers/universal/schema/codeAnalysis.d.ts.map +1 -1
  129. package/dist/analyzers/universal/schema/codeAnalysis.js +709 -383
  130. package/dist/analyzers/universal/schema/codeAnalysis.js.map +1 -1
  131. package/dist/analyzers/universal/schema/config.d.ts +3 -14
  132. package/dist/analyzers/universal/schema/config.d.ts.map +1 -1
  133. package/dist/analyzers/universal/schema/config.js +3 -16
  134. package/dist/analyzers/universal/schema/config.js.map +1 -1
  135. package/dist/analyzers/universal/schema/discovery.d.ts +22 -1
  136. package/dist/analyzers/universal/schema/discovery.d.ts.map +1 -1
  137. package/dist/analyzers/universal/schema/discovery.js +36 -20
  138. package/dist/analyzers/universal/schema/discovery.js.map +1 -1
  139. package/dist/analyzers/universal/schema/jsonSchema.d.ts.map +1 -1
  140. package/dist/analyzers/universal/schema/jsonSchema.js +13 -3
  141. package/dist/analyzers/universal/schema/jsonSchema.js.map +1 -1
  142. package/dist/analyzers/universal/schema/migrations.d.ts +187 -27
  143. package/dist/analyzers/universal/schema/migrations.d.ts.map +1 -1
  144. package/dist/analyzers/universal/schema/migrations.js +443 -186
  145. package/dist/analyzers/universal/schema/migrations.js.map +1 -1
  146. package/dist/analyzers/universal/schema/types.d.ts +17 -3
  147. package/dist/analyzers/universal/schema/types.d.ts.map +1 -1
  148. package/dist/analyzers/universal/schema/violations.js +1 -1
  149. package/dist/analyzers/universal/schema/violations.js.map +1 -1
  150. package/dist/analyzers/universal/styleScale.d.ts +52 -0
  151. package/dist/analyzers/universal/styleScale.d.ts.map +1 -0
  152. package/dist/analyzers/universal/styleScale.js +95 -0
  153. package/dist/analyzers/universal/styleScale.js.map +1 -0
  154. package/dist/applyDataDirEnv.js +1 -1
  155. package/dist/applyDataDirEnv.js.map +1 -1
  156. package/dist/auditRouter.d.ts +26 -30
  157. package/dist/auditRouter.d.ts.map +1 -1
  158. package/dist/auditRouter.js +373 -143
  159. package/dist/auditRouter.js.map +1 -1
  160. package/dist/auditRunner.d.ts +66 -1
  161. package/dist/auditRunner.d.ts.map +1 -1
  162. package/dist/auditRunner.js +1544 -1034
  163. package/dist/auditRunner.js.map +1 -1
  164. package/dist/baseline.d.ts +30 -3
  165. package/dist/baseline.d.ts.map +1 -1
  166. package/dist/baseline.js +70 -9
  167. package/dist/baseline.js.map +1 -1
  168. package/dist/cli.js +983 -821
  169. package/dist/cli.js.map +1 -1
  170. package/dist/codeIndex/analyzerConfig.d.ts +60 -0
  171. package/dist/codeIndex/analyzerConfig.d.ts.map +1 -0
  172. package/dist/codeIndex/analyzerConfig.js +98 -0
  173. package/dist/codeIndex/analyzerConfig.js.map +1 -0
  174. package/dist/codeIndex/auditResults.d.ts +39 -0
  175. package/dist/codeIndex/auditResults.d.ts.map +1 -0
  176. package/dist/codeIndex/auditResults.js +99 -0
  177. package/dist/codeIndex/auditResults.js.map +1 -0
  178. package/dist/codeIndex/codeMap.d.ts +59 -0
  179. package/dist/codeIndex/codeMap.d.ts.map +1 -0
  180. package/dist/codeIndex/codeMap.js +72 -0
  181. package/dist/codeIndex/codeMap.js.map +1 -0
  182. package/dist/codeIndex/conventions.d.ts +33 -0
  183. package/dist/codeIndex/conventions.d.ts.map +1 -0
  184. package/dist/codeIndex/conventions.js +84 -0
  185. package/dist/codeIndex/conventions.js.map +1 -0
  186. package/dist/codeIndex/coverage.d.ts +78 -0
  187. package/dist/codeIndex/coverage.d.ts.map +1 -0
  188. package/dist/codeIndex/coverage.js +164 -0
  189. package/dist/codeIndex/coverage.js.map +1 -0
  190. package/dist/codeIndex/dependencyGraph.d.ts +97 -0
  191. package/dist/codeIndex/dependencyGraph.d.ts.map +1 -0
  192. package/dist/codeIndex/dependencyGraph.js +241 -0
  193. package/dist/codeIndex/dependencyGraph.js.map +1 -0
  194. package/dist/codeIndex/functionIndex.d.ts +111 -0
  195. package/dist/codeIndex/functionIndex.d.ts.map +1 -0
  196. package/dist/codeIndex/functionIndex.js +306 -0
  197. package/dist/codeIndex/functionIndex.js.map +1 -0
  198. package/dist/codeIndex/inferredReceivers.d.ts +32 -0
  199. package/dist/codeIndex/inferredReceivers.d.ts.map +1 -0
  200. package/dist/codeIndex/inferredReceivers.js +41 -0
  201. package/dist/codeIndex/inferredReceivers.js.map +1 -0
  202. package/dist/codeIndex/meta.d.ts +30 -0
  203. package/dist/codeIndex/meta.d.ts.map +1 -0
  204. package/dist/codeIndex/meta.js +37 -0
  205. package/dist/codeIndex/meta.js.map +1 -0
  206. package/dist/codeIndex/migrations.d.ts +96 -0
  207. package/dist/codeIndex/migrations.d.ts.map +1 -0
  208. package/dist/codeIndex/migrations.js +1302 -0
  209. package/dist/codeIndex/migrations.js.map +1 -0
  210. package/dist/codeIndex/projectTasks.d.ts +54 -0
  211. package/dist/codeIndex/projectTasks.d.ts.map +1 -0
  212. package/dist/codeIndex/projectTasks.js +81 -0
  213. package/dist/codeIndex/projectTasks.js.map +1 -0
  214. package/dist/codeIndex/provenance.d.ts +47 -0
  215. package/dist/codeIndex/provenance.d.ts.map +1 -0
  216. package/dist/codeIndex/provenance.js +48 -0
  217. package/dist/codeIndex/provenance.js.map +1 -0
  218. package/dist/codeIndex/rawSql.d.ts +54 -0
  219. package/dist/codeIndex/rawSql.d.ts.map +1 -0
  220. package/dist/codeIndex/rawSql.js +71 -0
  221. package/dist/codeIndex/rawSql.js.map +1 -0
  222. package/dist/codeIndex/schema.d.ts +99 -0
  223. package/dist/codeIndex/schema.d.ts.map +1 -0
  224. package/dist/codeIndex/schema.js +174 -0
  225. package/dist/codeIndex/schema.js.map +1 -0
  226. package/dist/codeIndex/search.d.ts +40 -0
  227. package/dist/codeIndex/search.d.ts.map +1 -0
  228. package/dist/codeIndex/search.js +316 -0
  229. package/dist/codeIndex/search.js.map +1 -0
  230. package/dist/codeIndex/shared.d.ts +27 -0
  231. package/dist/codeIndex/shared.d.ts.map +1 -0
  232. package/dist/codeIndex/shared.js +46 -0
  233. package/dist/codeIndex/shared.js.map +1 -0
  234. package/dist/codeIndex/sqliteCollection.d.ts +81 -0
  235. package/dist/codeIndex/sqliteCollection.d.ts.map +1 -0
  236. package/dist/codeIndex/sqliteCollection.js +250 -0
  237. package/dist/codeIndex/sqliteCollection.js.map +1 -0
  238. package/dist/codeIndex/whitelist.d.ts +59 -0
  239. package/dist/codeIndex/whitelist.d.ts.map +1 -0
  240. package/dist/codeIndex/whitelist.js +188 -0
  241. package/dist/codeIndex/whitelist.js.map +1 -0
  242. package/dist/codeIndexDB.d.ts +132 -271
  243. package/dist/codeIndexDB.d.ts.map +1 -1
  244. package/dist/codeIndexDB.js +365 -2729
  245. package/dist/codeIndexDB.js.map +1 -1
  246. package/dist/codeIndexService.d.ts +87 -12
  247. package/dist/codeIndexService.d.ts.map +1 -1
  248. package/dist/codeIndexService.js +110 -34
  249. package/dist/codeIndexService.js.map +1 -1
  250. package/dist/componentScanner.d.ts +35 -0
  251. package/dist/componentScanner.d.ts.map +1 -1
  252. package/dist/componentScanner.js +114 -80
  253. package/dist/componentScanner.js.map +1 -1
  254. package/dist/config/configGeneratePath.d.ts +4 -0
  255. package/dist/config/configGeneratePath.d.ts.map +1 -1
  256. package/dist/config/configGeneratePath.js +4 -0
  257. package/dist/config/configGeneratePath.js.map +1 -1
  258. package/dist/config/configLoader.d.ts +15 -0
  259. package/dist/config/configLoader.d.ts.map +1 -1
  260. package/dist/config/configLoader.js +15 -16
  261. package/dist/config/configLoader.js.map +1 -1
  262. package/dist/config/defaults.d.ts +11 -7
  263. package/dist/config/defaults.d.ts.map +1 -1
  264. package/dist/config/defaults.js +16 -14
  265. package/dist/config/defaults.js.map +1 -1
  266. package/dist/config/effectiveConfig.d.ts +17 -2
  267. package/dist/config/effectiveConfig.d.ts.map +1 -1
  268. package/dist/config/effectiveConfig.js +32 -25
  269. package/dist/config/effectiveConfig.js.map +1 -1
  270. package/dist/config/lintConfigReader.d.ts +6 -0
  271. package/dist/config/lintConfigReader.d.ts.map +1 -1
  272. package/dist/config/lintConfigReader.js +6 -0
  273. package/dist/config/lintConfigReader.js.map +1 -1
  274. package/dist/config/staticObjectExtract.d.ts +4 -0
  275. package/dist/config/staticObjectExtract.d.ts.map +1 -1
  276. package/dist/config/staticObjectExtract.js +7 -3
  277. package/dist/config/staticObjectExtract.js.map +1 -1
  278. package/dist/config/thresholdRationales.d.ts +2 -0
  279. package/dist/config/thresholdRationales.d.ts.map +1 -1
  280. package/dist/config/thresholdRationales.js +5 -2
  281. package/dist/config/thresholdRationales.js.map +1 -1
  282. package/dist/constants.d.ts +1 -1
  283. package/dist/conventions/conventionMiner.d.ts +105 -2
  284. package/dist/conventions/conventionMiner.d.ts.map +1 -1
  285. package/dist/conventions/conventionMiner.js +334 -259
  286. package/dist/conventions/conventionMiner.js.map +1 -1
  287. package/dist/coverage/coverageService.js +4 -4
  288. package/dist/coverage/coverageService.js.map +1 -1
  289. package/dist/daemon/args.d.ts +3 -0
  290. package/dist/daemon/args.d.ts.map +1 -1
  291. package/dist/daemon/args.js +3 -0
  292. package/dist/daemon/args.js.map +1 -1
  293. package/dist/daemon/core.d.ts +33 -27
  294. package/dist/daemon/core.d.ts.map +1 -1
  295. package/dist/daemon/core.js +198 -162
  296. package/dist/daemon/core.js.map +1 -1
  297. package/dist/daemon/lspServer.d.ts +8 -0
  298. package/dist/daemon/lspServer.d.ts.map +1 -1
  299. package/dist/daemon/lspServer.js +8 -0
  300. package/dist/daemon/lspServer.js.map +1 -1
  301. package/dist/daemon/main.d.ts +2 -0
  302. package/dist/daemon/main.d.ts.map +1 -1
  303. package/dist/daemon/main.js +22 -4
  304. package/dist/daemon/main.js.map +1 -1
  305. package/dist/daemon/resolve.d.ts +18 -3
  306. package/dist/daemon/resolve.d.ts.map +1 -1
  307. package/dist/daemon/resolve.js +25 -4
  308. package/dist/daemon/resolve.js.map +1 -1
  309. package/dist/daemon/socketClient.d.ts +10 -1
  310. package/dist/daemon/socketClient.d.ts.map +1 -1
  311. package/dist/daemon/socketClient.js +10 -1
  312. package/dist/daemon/socketClient.js.map +1 -1
  313. package/dist/daemon/socketServer.d.ts +13 -0
  314. package/dist/daemon/socketServer.d.ts.map +1 -1
  315. package/dist/daemon/socketServer.js +13 -0
  316. package/dist/daemon/socketServer.js.map +1 -1
  317. package/dist/dataPaths.d.ts +17 -8
  318. package/dist/dataPaths.d.ts.map +1 -1
  319. package/dist/dataPaths.js +16 -44
  320. package/dist/dataPaths.js.map +1 -1
  321. package/dist/dismissals.d.ts +22 -1
  322. package/dist/dismissals.d.ts.map +1 -1
  323. package/dist/dismissals.js +22 -1
  324. package/dist/dismissals.js.map +1 -1
  325. package/dist/enforcement/gate.d.ts +1 -0
  326. package/dist/enforcement/gate.d.ts.map +1 -1
  327. package/dist/enforcement/gate.js +1 -0
  328. package/dist/enforcement/gate.js.map +1 -1
  329. package/dist/fingerprint.d.ts +6 -0
  330. package/dist/fingerprint.d.ts.map +1 -1
  331. package/dist/fingerprint.js +46 -1
  332. package/dist/fingerprint.js.map +1 -1
  333. package/dist/functionScanner.d.ts +30 -1
  334. package/dist/functionScanner.d.ts.map +1 -1
  335. package/dist/functionScanner.js +258 -256
  336. package/dist/functionScanner.js.map +1 -1
  337. package/dist/generators/AWSQConfigGenerator.d.ts +23 -0
  338. package/dist/generators/AWSQConfigGenerator.d.ts.map +1 -1
  339. package/dist/generators/AWSQConfigGenerator.js +23 -0
  340. package/dist/generators/AWSQConfigGenerator.js.map +1 -1
  341. package/dist/generators/BaseConfigGenerator.d.ts +7 -0
  342. package/dist/generators/BaseConfigGenerator.d.ts.map +1 -1
  343. package/dist/generators/BaseConfigGenerator.js +7 -0
  344. package/dist/generators/BaseConfigGenerator.js.map +1 -1
  345. package/dist/generators/ClaudeConfigGenerator.d.ts +23 -0
  346. package/dist/generators/ClaudeConfigGenerator.d.ts.map +1 -1
  347. package/dist/generators/ClaudeConfigGenerator.js +23 -0
  348. package/dist/generators/ClaudeConfigGenerator.js.map +1 -1
  349. package/dist/generators/ClineConfigGenerator.d.ts +23 -0
  350. package/dist/generators/ClineConfigGenerator.d.ts.map +1 -1
  351. package/dist/generators/ClineConfigGenerator.js +23 -0
  352. package/dist/generators/ClineConfigGenerator.js.map +1 -1
  353. package/dist/generators/CodeiumConfigGenerator.d.ts +23 -0
  354. package/dist/generators/CodeiumConfigGenerator.d.ts.map +1 -1
  355. package/dist/generators/CodeiumConfigGenerator.js +23 -0
  356. package/dist/generators/CodeiumConfigGenerator.js.map +1 -1
  357. package/dist/generators/CodexConfigGenerator.d.ts +23 -0
  358. package/dist/generators/CodexConfigGenerator.d.ts.map +1 -1
  359. package/dist/generators/CodexConfigGenerator.js +23 -0
  360. package/dist/generators/CodexConfigGenerator.js.map +1 -1
  361. package/dist/generators/ConfigGeneratorFactory.d.ts +9 -0
  362. package/dist/generators/ConfigGeneratorFactory.d.ts.map +1 -1
  363. package/dist/generators/ConfigGeneratorFactory.js +9 -0
  364. package/dist/generators/ConfigGeneratorFactory.js.map +1 -1
  365. package/dist/generators/ContinueConfigGenerator.d.ts +23 -0
  366. package/dist/generators/ContinueConfigGenerator.d.ts.map +1 -1
  367. package/dist/generators/ContinueConfigGenerator.js +23 -0
  368. package/dist/generators/ContinueConfigGenerator.js.map +1 -1
  369. package/dist/generators/CopilotConfigGenerator.d.ts +23 -0
  370. package/dist/generators/CopilotConfigGenerator.d.ts.map +1 -1
  371. package/dist/generators/CopilotConfigGenerator.js +23 -0
  372. package/dist/generators/CopilotConfigGenerator.js.map +1 -1
  373. package/dist/generators/CursorConfigGenerator.d.ts +23 -0
  374. package/dist/generators/CursorConfigGenerator.d.ts.map +1 -1
  375. package/dist/generators/CursorConfigGenerator.js +23 -0
  376. package/dist/generators/CursorConfigGenerator.js.map +1 -1
  377. package/dist/generators/GeminiConfigGenerator.d.ts +23 -0
  378. package/dist/generators/GeminiConfigGenerator.d.ts.map +1 -1
  379. package/dist/generators/GeminiConfigGenerator.js +23 -0
  380. package/dist/generators/GeminiConfigGenerator.js.map +1 -1
  381. package/dist/generators/VSCodeConfigGenerator.d.ts +23 -0
  382. package/dist/generators/VSCodeConfigGenerator.d.ts.map +1 -1
  383. package/dist/generators/VSCodeConfigGenerator.js +23 -0
  384. package/dist/generators/VSCodeConfigGenerator.js.map +1 -1
  385. package/dist/generators/ZCodeConfigGenerator.d.ts +23 -0
  386. package/dist/generators/ZCodeConfigGenerator.d.ts.map +1 -1
  387. package/dist/generators/ZCodeConfigGenerator.js +23 -0
  388. package/dist/generators/ZCodeConfigGenerator.js.map +1 -1
  389. package/dist/graph/blastRadius.d.ts.map +1 -1
  390. package/dist/graph/blastRadius.js +12 -7
  391. package/dist/graph/blastRadius.js.map +1 -1
  392. package/dist/graph/callGraph.d.ts +31 -0
  393. package/dist/graph/callGraph.d.ts.map +1 -1
  394. package/dist/graph/callGraph.js +62 -32
  395. package/dist/graph/callGraph.js.map +1 -1
  396. package/dist/graph/importClassification.d.ts +28 -0
  397. package/dist/graph/importClassification.d.ts.map +1 -1
  398. package/dist/graph/importClassification.js +57 -0
  399. package/dist/graph/importClassification.js.map +1 -1
  400. package/dist/graph/importGraph.d.ts +38 -0
  401. package/dist/graph/importGraph.d.ts.map +1 -1
  402. package/dist/graph/importGraph.js +38 -0
  403. package/dist/graph/importGraph.js.map +1 -1
  404. package/dist/graph/outputFormatter.d.ts +12 -4
  405. package/dist/graph/outputFormatter.d.ts.map +1 -1
  406. package/dist/graph/outputFormatter.js +12 -62
  407. package/dist/graph/outputFormatter.js.map +1 -1
  408. package/dist/graph/resolutionEnvironment.d.ts +61 -0
  409. package/dist/graph/resolutionEnvironment.d.ts.map +1 -0
  410. package/dist/graph/resolutionEnvironment.js +57 -0
  411. package/dist/graph/resolutionEnvironment.js.map +1 -0
  412. package/dist/hooks/codex.d.ts +8 -1
  413. package/dist/hooks/codex.d.ts.map +1 -1
  414. package/dist/hooks/codex.js +7 -0
  415. package/dist/hooks/codex.js.map +1 -1
  416. package/dist/hooks/core.d.ts +6 -0
  417. package/dist/hooks/core.d.ts.map +1 -1
  418. package/dist/hooks/core.js +6 -1
  419. package/dist/hooks/core.js.map +1 -1
  420. package/dist/hooks/cursor.d.ts +11 -1
  421. package/dist/hooks/cursor.d.ts.map +1 -1
  422. package/dist/hooks/cursor.js +10 -0
  423. package/dist/hooks/cursor.js.map +1 -1
  424. package/dist/index.d.ts +4 -0
  425. package/dist/index.d.ts.map +1 -1
  426. package/dist/index.js +4 -0
  427. package/dist/index.js.map +1 -1
  428. package/dist/installConfig.d.ts +23 -5
  429. package/dist/installConfig.d.ts.map +1 -1
  430. package/dist/installConfig.js +23 -5
  431. package/dist/installConfig.js.map +1 -1
  432. package/dist/installer.d.ts +6 -0
  433. package/dist/installer.d.ts.map +1 -1
  434. package/dist/installer.js +6 -0
  435. package/dist/installer.js.map +1 -1
  436. package/dist/invariants/ruleEngine.d.ts +3 -0
  437. package/dist/invariants/ruleEngine.d.ts.map +1 -1
  438. package/dist/invariants/ruleEngine.js +156 -119
  439. package/dist/invariants/ruleEngine.js.map +1 -1
  440. package/dist/invariants/ruleValidator.d.ts +3 -0
  441. package/dist/invariants/ruleValidator.d.ts.map +1 -1
  442. package/dist/invariants/ruleValidator.js +185 -178
  443. package/dist/invariants/ruleValidator.js.map +1 -1
  444. package/dist/languages/LanguageOrchestrator.d.ts +4 -1
  445. package/dist/languages/LanguageOrchestrator.d.ts.map +1 -1
  446. package/dist/languages/LanguageOrchestrator.js +8 -19
  447. package/dist/languages/LanguageOrchestrator.js.map +1 -1
  448. package/dist/languages/RuntimeManager.d.ts +8 -0
  449. package/dist/languages/RuntimeManager.d.ts.map +1 -1
  450. package/dist/languages/RuntimeManager.js +55 -5
  451. package/dist/languages/RuntimeManager.js.map +1 -1
  452. package/dist/languages/UniversalAnalyzer.js +1 -1
  453. package/dist/languages/UniversalAnalyzer.js.map +1 -1
  454. package/dist/languages/adapterBridge.d.ts +4 -0
  455. package/dist/languages/adapterBridge.d.ts.map +1 -1
  456. package/dist/languages/adapterBridge.js +37 -3
  457. package/dist/languages/adapterBridge.js.map +1 -1
  458. package/dist/languages/go/GoAdapter.d.ts.map +1 -1
  459. package/dist/languages/go/GoAdapter.js +11 -14
  460. package/dist/languages/go/GoAdapter.js.map +1 -1
  461. package/dist/languages/go/analyzer-darwin-amd64 +0 -0
  462. package/dist/languages/go/analyzer-darwin-arm64 +0 -0
  463. package/dist/languages/go/analyzer-linux-amd64 +0 -0
  464. package/dist/languages/go/analyzer-linux-arm64 +0 -0
  465. package/dist/languages/go/analyzer-src/analyzer.go +2 -0
  466. package/dist/languages/go/analyzer-src/dataaccess.go +388 -0
  467. package/dist/languages/go/analyzer-src/types.go +8 -0
  468. package/dist/languages/go/analyzer-windows-amd64.exe +0 -0
  469. package/dist/languages/go/database-packages.json +8 -0
  470. package/dist/languages/go/goResolution.d.ts +229 -0
  471. package/dist/languages/go/goResolution.d.ts.map +1 -0
  472. package/dist/languages/go/goResolution.js +799 -0
  473. package/dist/languages/go/goResolution.js.map +1 -0
  474. package/dist/languages/go/stdlib-packages.json +353 -0
  475. package/dist/languages/go/tenantInputs.d.ts +37 -0
  476. package/dist/languages/go/tenantInputs.d.ts.map +1 -0
  477. package/dist/languages/go/tenantInputs.js +121 -0
  478. package/dist/languages/go/tenantInputs.js.map +1 -0
  479. package/dist/languages/index.d.ts +1 -0
  480. package/dist/languages/index.d.ts.map +1 -1
  481. package/dist/languages/index.js +5 -0
  482. package/dist/languages/index.js.map +1 -1
  483. package/dist/languages/json/JsonAdapter.d.ts +177 -0
  484. package/dist/languages/json/JsonAdapter.d.ts.map +1 -0
  485. package/dist/languages/json/JsonAdapter.js +531 -0
  486. package/dist/languages/json/JsonAdapter.js.map +1 -0
  487. package/dist/languages/locationIndex.d.ts +41 -0
  488. package/dist/languages/locationIndex.d.ts.map +1 -0
  489. package/dist/languages/locationIndex.js +42 -0
  490. package/dist/languages/locationIndex.js.map +1 -0
  491. package/dist/languages/sql/dialectDetection.d.ts +57 -0
  492. package/dist/languages/sql/dialectDetection.d.ts.map +1 -0
  493. package/dist/languages/sql/dialectDetection.js +135 -0
  494. package/dist/languages/sql/dialectDetection.js.map +1 -0
  495. package/dist/languages/sql/sqlAst.d.ts +494 -0
  496. package/dist/languages/sql/sqlAst.d.ts.map +1 -0
  497. package/dist/languages/sql/sqlAst.js +1817 -0
  498. package/dist/languages/sql/sqlAst.js.map +1 -0
  499. package/dist/languages/testConventions.d.ts +12 -1
  500. package/dist/languages/testConventions.d.ts.map +1 -1
  501. package/dist/languages/testConventions.js +13 -1
  502. package/dist/languages/testConventions.js.map +1 -1
  503. package/dist/languages/tree-sitter/TreeSitterCssAdapter.js +1 -1
  504. package/dist/languages/tree-sitter/TreeSitterCssAdapter.js.map +1 -1
  505. package/dist/languages/tree-sitter/converter.js +2 -2
  506. package/dist/languages/tree-sitter/converter.js.map +1 -1
  507. package/dist/languages/tree-sitter/parser.d.ts +3 -4
  508. package/dist/languages/tree-sitter/parser.d.ts.map +1 -1
  509. package/dist/languages/tree-sitter/parser.js +10 -4
  510. package/dist/languages/tree-sitter/parser.js.map +1 -1
  511. package/dist/languages/tree-sitter/rawNode.d.ts +3 -0
  512. package/dist/languages/tree-sitter/rawNode.d.ts.map +1 -1
  513. package/dist/languages/tree-sitter/rawNode.js +3 -0
  514. package/dist/languages/tree-sitter/rawNode.js.map +1 -1
  515. package/dist/languages/types.d.ts +7 -0
  516. package/dist/languages/types.d.ts.map +1 -1
  517. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +36 -0
  518. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
  519. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +168 -45
  520. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
  521. package/dist/languages/typescript/database-packages.json +19 -0
  522. package/dist/ledger.d.ts +118 -2
  523. package/dist/ledger.d.ts.map +1 -1
  524. package/dist/ledger.js +167 -45
  525. package/dist/ledger.js.map +1 -1
  526. package/dist/legacyIndexNotice.d.ts +32 -0
  527. package/dist/legacyIndexNotice.d.ts.map +1 -0
  528. package/dist/legacyIndexNotice.js +89 -0
  529. package/dist/legacyIndexNotice.js.map +1 -0
  530. package/dist/mcp-tools/discoveryQueries.d.ts +55 -0
  531. package/dist/mcp-tools/discoveryQueries.d.ts.map +1 -0
  532. package/dist/mcp-tools/discoveryQueries.js +157 -0
  533. package/dist/mcp-tools/discoveryQueries.js.map +1 -0
  534. package/dist/mcp-tools/projectTasks.d.ts +9 -123
  535. package/dist/mcp-tools/projectTasks.d.ts.map +1 -1
  536. package/dist/mcp-tools/projectTasks.js +180 -170
  537. package/dist/mcp-tools/projectTasks.js.map +1 -1
  538. package/dist/mcp-tools/whitelistTools.d.ts +20 -0
  539. package/dist/mcp-tools/whitelistTools.d.ts.map +1 -1
  540. package/dist/mcp-tools/whitelistTools.js +20 -0
  541. package/dist/mcp-tools/whitelistTools.js.map +1 -1
  542. package/dist/mcp-tools/workflowGuide.d.ts +9 -0
  543. package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
  544. package/dist/mcp-tools/workflowGuide.js +13 -5
  545. package/dist/mcp-tools/workflowGuide.js.map +1 -1
  546. package/dist/mcp-tools-shared.d.ts +78 -0
  547. package/dist/mcp-tools-shared.d.ts.map +1 -1
  548. package/dist/mcp-tools-shared.js +203 -340
  549. package/dist/mcp-tools-shared.js.map +1 -1
  550. package/dist/mcp-ui-simple.d.ts +2 -0
  551. package/dist/mcp-ui-simple.d.ts.map +1 -1
  552. package/dist/mcp-ui-simple.js +12 -5
  553. package/dist/mcp-ui-simple.js.map +1 -1
  554. package/dist/mcp.d.ts +6 -0
  555. package/dist/mcp.d.ts.map +1 -1
  556. package/dist/mcp.js +827 -850
  557. package/dist/mcp.js.map +1 -1
  558. package/dist/mcpAuditJobs.d.ts +29 -33
  559. package/dist/mcpAuditJobs.d.ts.map +1 -1
  560. package/dist/mcpAuditJobs.js +102 -791
  561. package/dist/mcpAuditJobs.js.map +1 -1
  562. package/dist/mcpAutoIndex.d.ts +5 -0
  563. package/dist/mcpAutoIndex.d.ts.map +1 -1
  564. package/dist/mcpAutoIndex.js +7 -2
  565. package/dist/mcpAutoIndex.js.map +1 -1
  566. package/dist/mcpDiagnostics.d.ts +7 -0
  567. package/dist/mcpDiagnostics.d.ts.map +1 -1
  568. package/dist/mcpDiagnostics.js +34 -9
  569. package/dist/mcpDiagnostics.js.map +1 -1
  570. package/dist/mcpToolErrors.d.ts +16 -0
  571. package/dist/mcpToolErrors.d.ts.map +1 -1
  572. package/dist/mcpToolErrors.js +16 -0
  573. package/dist/mcpToolErrors.js.map +1 -1
  574. package/dist/nextFile.d.ts +6 -0
  575. package/dist/nextFile.d.ts.map +1 -1
  576. package/dist/nextFile.js +6 -0
  577. package/dist/nextFile.js.map +1 -1
  578. package/dist/nextFileIncremental.d.ts +44 -4
  579. package/dist/nextFileIncremental.d.ts.map +1 -1
  580. package/dist/nextFileIncremental.js +47 -7
  581. package/dist/nextFileIncremental.js.map +1 -1
  582. package/dist/phase/batchFunctions.d.ts +38 -0
  583. package/dist/phase/batchFunctions.d.ts.map +1 -0
  584. package/dist/phase/batchFunctions.js +64 -0
  585. package/dist/phase/batchFunctions.js.map +1 -0
  586. package/dist/phase/checks.d.ts +39 -0
  587. package/dist/phase/checks.d.ts.map +1 -0
  588. package/dist/phase/checks.js +48 -0
  589. package/dist/phase/checks.js.map +1 -0
  590. package/dist/phase/codeBlocks.d.ts +25 -0
  591. package/dist/phase/codeBlocks.d.ts.map +1 -0
  592. package/dist/phase/codeBlocks.js +268 -0
  593. package/dist/phase/codeBlocks.js.map +1 -0
  594. package/dist/phase/colorMath.d.ts +41 -0
  595. package/dist/phase/colorMath.d.ts.map +1 -0
  596. package/dist/phase/colorMath.js +109 -0
  597. package/dist/phase/colorMath.js.map +1 -0
  598. package/dist/phase/config.d.ts +29 -0
  599. package/dist/phase/config.d.ts.map +1 -0
  600. package/dist/phase/config.js +54 -0
  601. package/dist/phase/config.js.map +1 -0
  602. package/dist/phase/consumed.d.ts +47 -0
  603. package/dist/phase/consumed.d.ts.map +1 -0
  604. package/dist/phase/consumed.js +22 -0
  605. package/dist/phase/consumed.js.map +1 -0
  606. package/dist/phase/conventionMining.d.ts +59 -0
  607. package/dist/phase/conventionMining.d.ts.map +1 -0
  608. package/dist/phase/conventionMining.js +152 -0
  609. package/dist/phase/conventionMining.js.map +1 -0
  610. package/dist/phase/coverage.d.ts +65 -0
  611. package/dist/phase/coverage.d.ts.map +1 -0
  612. package/dist/phase/coverage.js +121 -0
  613. package/dist/phase/coverage.js.map +1 -0
  614. package/dist/phase/dag.d.ts +49 -0
  615. package/dist/phase/dag.d.ts.map +1 -0
  616. package/dist/phase/dag.js +120 -0
  617. package/dist/phase/dag.js.map +1 -0
  618. package/dist/phase/dataAccessCalls.d.ts +33 -0
  619. package/dist/phase/dataAccessCalls.d.ts.map +1 -0
  620. package/dist/phase/dataAccessCalls.js +42 -0
  621. package/dist/phase/dataAccessCalls.js.map +1 -0
  622. package/dist/phase/dataAccessCallsCandidates.d.ts +25 -0
  623. package/dist/phase/dataAccessCallsCandidates.d.ts.map +1 -0
  624. package/dist/phase/dataAccessCallsCandidates.js +27 -0
  625. package/dist/phase/dataAccessCallsCandidates.js.map +1 -0
  626. package/dist/phase/dynamicSql.d.ts +18 -0
  627. package/dist/phase/dynamicSql.d.ts.map +1 -0
  628. package/dist/phase/dynamicSql.js +20 -0
  629. package/dist/phase/dynamicSql.js.map +1 -0
  630. package/dist/phase/exportForm.d.ts +23 -0
  631. package/dist/phase/exportForm.d.ts.map +1 -0
  632. package/dist/phase/exportForm.js +29 -0
  633. package/dist/phase/exportForm.js.map +1 -0
  634. package/dist/phase/exportSymbols.d.ts +21 -0
  635. package/dist/phase/exportSymbols.d.ts.map +1 -0
  636. package/dist/phase/exportSymbols.js +28 -0
  637. package/dist/phase/exportSymbols.js.map +1 -0
  638. package/dist/phase/fileHeader.d.ts +15 -0
  639. package/dist/phase/fileHeader.d.ts.map +1 -0
  640. package/dist/phase/fileHeader.js +33 -0
  641. package/dist/phase/fileHeader.js.map +1 -0
  642. package/dist/phase/fileImports.d.ts +39 -0
  643. package/dist/phase/fileImports.d.ts.map +1 -0
  644. package/dist/phase/fileImports.js +138 -0
  645. package/dist/phase/fileImports.js.map +1 -0
  646. package/dist/phase/fileSymbols.d.ts +25 -0
  647. package/dist/phase/fileSymbols.d.ts.map +1 -0
  648. package/dist/phase/fileSymbols.js +302 -0
  649. package/dist/phase/fileSymbols.js.map +1 -0
  650. package/dist/phase/functionBodies.d.ts +28 -0
  651. package/dist/phase/functionBodies.d.ts.map +1 -0
  652. package/dist/phase/functionBodies.js +67 -0
  653. package/dist/phase/functionBodies.js.map +1 -0
  654. package/dist/phase/functionIndex.d.ts +28 -0
  655. package/dist/phase/functionIndex.d.ts.map +1 -0
  656. package/dist/phase/functionIndex.js +152 -0
  657. package/dist/phase/functionIndex.js.map +1 -0
  658. package/dist/phase/goFunctionAnalysis.d.ts +47 -0
  659. package/dist/phase/goFunctionAnalysis.d.ts.map +1 -0
  660. package/dist/phase/goFunctionAnalysis.js +291 -0
  661. package/dist/phase/goFunctionAnalysis.js.map +1 -0
  662. package/dist/phase/goFunctions.d.ts +38 -0
  663. package/dist/phase/goFunctions.d.ts.map +1 -0
  664. package/dist/phase/goFunctions.js +154 -0
  665. package/dist/phase/goFunctions.js.map +1 -0
  666. package/dist/phase/goImports.d.ts +29 -0
  667. package/dist/phase/goImports.d.ts.map +1 -0
  668. package/dist/phase/goImports.js +68 -0
  669. package/dist/phase/goImports.js.map +1 -0
  670. package/dist/phase/goPackageBindings.d.ts +22 -0
  671. package/dist/phase/goPackageBindings.d.ts.map +1 -0
  672. package/dist/phase/goPackageBindings.js +30 -0
  673. package/dist/phase/goPackageBindings.js.map +1 -0
  674. package/dist/phase/goSwitches.d.ts +28 -0
  675. package/dist/phase/goSwitches.d.ts.map +1 -0
  676. package/dist/phase/goSwitches.js +52 -0
  677. package/dist/phase/goSwitches.js.map +1 -0
  678. package/dist/phase/importForm.d.ts +20 -0
  679. package/dist/phase/importForm.d.ts.map +1 -0
  680. package/dist/phase/importForm.js +27 -0
  681. package/dist/phase/importForm.js.map +1 -0
  682. package/dist/phase/importSpecifiers.d.ts +20 -0
  683. package/dist/phase/importSpecifiers.d.ts.map +1 -0
  684. package/dist/phase/importSpecifiers.js +30 -0
  685. package/dist/phase/importSpecifiers.js.map +1 -0
  686. package/dist/phase/imports.d.ts +18 -0
  687. package/dist/phase/imports.d.ts.map +1 -0
  688. package/dist/phase/imports.js +25 -0
  689. package/dist/phase/imports.js.map +1 -0
  690. package/dist/phase/jsonDocument.d.ts +26 -0
  691. package/dist/phase/jsonDocument.d.ts.map +1 -0
  692. package/dist/phase/jsonDocument.js +36 -0
  693. package/dist/phase/jsonDocument.js.map +1 -0
  694. package/dist/phase/localBinding.d.ts +33 -0
  695. package/dist/phase/localBinding.d.ts.map +1 -0
  696. package/dist/phase/localBinding.js +208 -0
  697. package/dist/phase/localBinding.js.map +1 -0
  698. package/dist/phase/loopQueries.d.ts +31 -0
  699. package/dist/phase/loopQueries.d.ts.map +1 -0
  700. package/dist/phase/loopQueries.js +44 -0
  701. package/dist/phase/loopQueries.js.map +1 -0
  702. package/dist/phase/loopQueryCandidates.d.ts +26 -0
  703. package/dist/phase/loopQueryCandidates.d.ts.map +1 -0
  704. package/dist/phase/loopQueryCandidates.js +28 -0
  705. package/dist/phase/loopQueryCandidates.js.map +1 -0
  706. package/dist/phase/oracles.d.ts +216 -0
  707. package/dist/phase/oracles.d.ts.map +1 -0
  708. package/dist/phase/oracles.js +484 -0
  709. package/dist/phase/oracles.js.map +1 -0
  710. package/dist/phase/phaseModel.d.ts +190 -0
  711. package/dist/phase/phaseModel.d.ts.map +1 -0
  712. package/dist/phase/phaseModel.js +491 -0
  713. package/dist/phase/phaseModel.js.map +1 -0
  714. package/dist/phase/producers.d.ts +450 -0
  715. package/dist/phase/producers.d.ts.map +1 -0
  716. package/dist/phase/producers.js +1030 -0
  717. package/dist/phase/producers.js.map +1 -0
  718. package/dist/phase/querySiteCandidates.d.ts +27 -0
  719. package/dist/phase/querySiteCandidates.d.ts.map +1 -0
  720. package/dist/phase/querySiteCandidates.js +66 -0
  721. package/dist/phase/querySiteCandidates.js.map +1 -0
  722. package/dist/phase/querySites.d.ts +30 -0
  723. package/dist/phase/querySites.d.ts.map +1 -0
  724. package/dist/phase/querySites.js +93 -0
  725. package/dist/phase/querySites.js.map +1 -0
  726. package/dist/phase/reachability.d.ts +61 -0
  727. package/dist/phase/reachability.d.ts.map +1 -0
  728. package/dist/phase/reachability.js +104 -0
  729. package/dist/phase/reachability.js.map +1 -0
  730. package/dist/phase/reactComponents.d.ts +33 -0
  731. package/dist/phase/reactComponents.d.ts.map +1 -0
  732. package/dist/phase/reactComponents.js +47 -0
  733. package/dist/phase/reactComponents.js.map +1 -0
  734. package/dist/phase/receiverActivity.d.ts +35 -0
  735. package/dist/phase/receiverActivity.d.ts.map +1 -0
  736. package/dist/phase/receiverActivity.js +66 -0
  737. package/dist/phase/receiverActivity.js.map +1 -0
  738. package/dist/phase/receiverConsumers.d.ts +207 -0
  739. package/dist/phase/receiverConsumers.d.ts.map +1 -0
  740. package/dist/phase/receiverConsumers.js +1063 -0
  741. package/dist/phase/receiverConsumers.js.map +1 -0
  742. package/dist/phase/receiverProvenance.d.ts +120 -0
  743. package/dist/phase/receiverProvenance.d.ts.map +1 -0
  744. package/dist/phase/receiverProvenance.js +377 -0
  745. package/dist/phase/receiverProvenance.js.map +1 -0
  746. package/dist/phase/routing.d.ts +47 -0
  747. package/dist/phase/routing.d.ts.map +1 -0
  748. package/dist/phase/routing.js +62 -0
  749. package/dist/phase/routing.js.map +1 -0
  750. package/dist/phase/rules/conventions.d.ts +61 -0
  751. package/dist/phase/rules/conventions.d.ts.map +1 -0
  752. package/dist/phase/rules/conventions.js +403 -0
  753. package/dist/phase/rules/conventions.js.map +1 -0
  754. package/dist/phase/rules/crossDomain.d.ts +102 -0
  755. package/dist/phase/rules/crossDomain.d.ts.map +1 -0
  756. package/dist/phase/rules/crossDomain.js +918 -0
  757. package/dist/phase/rules/crossDomain.js.map +1 -0
  758. package/dist/phase/rules/dataAccess.d.ts +62 -0
  759. package/dist/phase/rules/dataAccess.d.ts.map +1 -0
  760. package/dist/phase/rules/dataAccess.js +480 -0
  761. package/dist/phase/rules/dataAccess.js.map +1 -0
  762. package/dist/phase/rules/dependencyGraph.d.ts +44 -0
  763. package/dist/phase/rules/dependencyGraph.d.ts.map +1 -0
  764. package/dist/phase/rules/dependencyGraph.js +260 -0
  765. package/dist/phase/rules/dependencyGraph.js.map +1 -0
  766. package/dist/phase/rules/documentation.d.ts +45 -0
  767. package/dist/phase/rules/documentation.d.ts.map +1 -0
  768. package/dist/phase/rules/documentation.js +340 -0
  769. package/dist/phase/rules/documentation.js.map +1 -0
  770. package/dist/phase/rules/dry.d.ts +109 -0
  771. package/dist/phase/rules/dry.d.ts.map +1 -0
  772. package/dist/phase/rules/dry.js +803 -0
  773. package/dist/phase/rules/dry.js.map +1 -0
  774. package/dist/phase/rules/fileDocumentation.d.ts +36 -0
  775. package/dist/phase/rules/fileDocumentation.d.ts.map +1 -0
  776. package/dist/phase/rules/fileDocumentation.js +134 -0
  777. package/dist/phase/rules/fileDocumentation.js.map +1 -0
  778. package/dist/phase/rules/functionBodies.d.ts +33 -0
  779. package/dist/phase/rules/functionBodies.d.ts.map +1 -0
  780. package/dist/phase/rules/functionBodies.js +71 -0
  781. package/dist/phase/rules/functionBodies.js.map +1 -0
  782. package/dist/phase/rules/goRules.d.ts +49 -0
  783. package/dist/phase/rules/goRules.d.ts.map +1 -0
  784. package/dist/phase/rules/goRules.js +209 -0
  785. package/dist/phase/rules/goRules.js.map +1 -0
  786. package/dist/phase/rules/querySites.d.ts +29 -0
  787. package/dist/phase/rules/querySites.d.ts.map +1 -0
  788. package/dist/phase/rules/querySites.js +94 -0
  789. package/dist/phase/rules/querySites.js.map +1 -0
  790. package/dist/phase/rules/react.d.ts +38 -0
  791. package/dist/phase/rules/react.d.ts.map +1 -0
  792. package/dist/phase/rules/react.js +202 -0
  793. package/dist/phase/rules/react.js.map +1 -0
  794. package/dist/phase/rules/registry.d.ts +170 -0
  795. package/dist/phase/rules/registry.d.ts.map +1 -0
  796. package/dist/phase/rules/registry.js +103 -0
  797. package/dist/phase/rules/registry.js.map +1 -0
  798. package/dist/phase/rules/schema.d.ts +79 -0
  799. package/dist/phase/rules/schema.d.ts.map +1 -0
  800. package/dist/phase/rules/schema.js +273 -0
  801. package/dist/phase/rules/schema.js.map +1 -0
  802. package/dist/phase/rules/schemaJson.d.ts +32 -0
  803. package/dist/phase/rules/schemaJson.d.ts.map +1 -0
  804. package/dist/phase/rules/schemaJson.js +81 -0
  805. package/dist/phase/rules/schemaJson.js.map +1 -0
  806. package/dist/phase/rules/schemaValidator.d.ts +38 -0
  807. package/dist/phase/rules/schemaValidator.d.ts.map +1 -0
  808. package/dist/phase/rules/schemaValidator.js +107 -0
  809. package/dist/phase/rules/schemaValidator.js.map +1 -0
  810. package/dist/phase/rules/secrets.d.ts +34 -0
  811. package/dist/phase/rules/secrets.d.ts.map +1 -0
  812. package/dist/phase/rules/secrets.js +208 -0
  813. package/dist/phase/rules/secrets.js.map +1 -0
  814. package/dist/phase/rules/security.d.ts +30 -0
  815. package/dist/phase/rules/security.d.ts.map +1 -0
  816. package/dist/phase/rules/security.js +85 -0
  817. package/dist/phase/rules/security.js.map +1 -0
  818. package/dist/phase/rules/securityDefects.d.ts +37 -0
  819. package/dist/phase/rules/securityDefects.d.ts.map +1 -0
  820. package/dist/phase/rules/securityDefects.js +167 -0
  821. package/dist/phase/rules/securityDefects.js.map +1 -0
  822. package/dist/phase/rules/solid.d.ts +61 -0
  823. package/dist/phase/rules/solid.d.ts.map +1 -0
  824. package/dist/phase/rules/solid.js +562 -0
  825. package/dist/phase/rules/solid.js.map +1 -0
  826. package/dist/phase/rules/styles.d.ts +77 -0
  827. package/dist/phase/rules/styles.d.ts.map +1 -0
  828. package/dist/phase/rules/styles.js +868 -0
  829. package/dist/phase/rules/styles.js.map +1 -0
  830. package/dist/phase/rules/unreferencedModule.d.ts +26 -0
  831. package/dist/phase/rules/unreferencedModule.d.ts.map +1 -0
  832. package/dist/phase/rules/unreferencedModule.js +61 -0
  833. package/dist/phase/rules/unreferencedModule.js.map +1 -0
  834. package/dist/phase/runner.d.ts +549 -0
  835. package/dist/phase/runner.d.ts.map +1 -0
  836. package/dist/phase/runner.js +1098 -0
  837. package/dist/phase/runner.js.map +1 -0
  838. package/dist/phase/schemaCode.d.ts +34 -0
  839. package/dist/phase/schemaCode.d.ts.map +1 -0
  840. package/dist/phase/schemaCode.js +53 -0
  841. package/dist/phase/schemaCode.js.map +1 -0
  842. package/dist/phase/schemaObjects.d.ts +37 -0
  843. package/dist/phase/schemaObjects.d.ts.map +1 -0
  844. package/dist/phase/schemaObjects.js +139 -0
  845. package/dist/phase/schemaObjects.js.map +1 -0
  846. package/dist/phase/schemaUsage.d.ts +30 -0
  847. package/dist/phase/schemaUsage.d.ts.map +1 -0
  848. package/dist/phase/schemaUsage.js +99 -0
  849. package/dist/phase/schemaUsage.js.map +1 -0
  850. package/dist/phase/schemaUsageCandidates.d.ts +32 -0
  851. package/dist/phase/schemaUsageCandidates.d.ts.map +1 -0
  852. package/dist/phase/schemaUsageCandidates.js +165 -0
  853. package/dist/phase/schemaUsageCandidates.js.map +1 -0
  854. package/dist/phase/schemaValidations.d.ts +34 -0
  855. package/dist/phase/schemaValidations.d.ts.map +1 -0
  856. package/dist/phase/schemaValidations.js +53 -0
  857. package/dist/phase/schemaValidations.js.map +1 -0
  858. package/dist/phase/secretCandidates.d.ts +28 -0
  859. package/dist/phase/secretCandidates.d.ts.map +1 -0
  860. package/dist/phase/secretCandidates.js +132 -0
  861. package/dist/phase/secretCandidates.js.map +1 -0
  862. package/dist/phase/securityCandidates.d.ts +29 -0
  863. package/dist/phase/securityCandidates.d.ts.map +1 -0
  864. package/dist/phase/securityCandidates.js +469 -0
  865. package/dist/phase/securityCandidates.js.map +1 -0
  866. package/dist/phase/seeded-defects.d.ts +18 -0
  867. package/dist/phase/seeded-defects.d.ts.map +1 -0
  868. package/dist/phase/seeded-defects.js +61 -0
  869. package/dist/phase/seeded-defects.js.map +1 -0
  870. package/dist/phase/stringLiterals.d.ts +24 -0
  871. package/dist/phase/stringLiterals.d.ts.map +1 -0
  872. package/dist/phase/stringLiterals.js +35 -0
  873. package/dist/phase/stringLiterals.js.map +1 -0
  874. package/dist/phase/stylesCss.d.ts +25 -0
  875. package/dist/phase/stylesCss.d.ts.map +1 -0
  876. package/dist/phase/stylesCss.js +34 -0
  877. package/dist/phase/stylesCss.js.map +1 -0
  878. package/dist/phase/stylesMarkup.d.ts +31 -0
  879. package/dist/phase/stylesMarkup.d.ts.map +1 -0
  880. package/dist/phase/stylesMarkup.js +48 -0
  881. package/dist/phase/stylesMarkup.js.map +1 -0
  882. package/dist/phase/stylesSource.d.ts +36 -0
  883. package/dist/phase/stylesSource.d.ts.map +1 -0
  884. package/dist/phase/stylesSource.js +50 -0
  885. package/dist/phase/stylesSource.js.map +1 -0
  886. package/dist/phase/typeDeclarations.d.ts +33 -0
  887. package/dist/phase/typeDeclarations.d.ts.map +1 -0
  888. package/dist/phase/typeDeclarations.js +76 -0
  889. package/dist/phase/typeDeclarations.js.map +1 -0
  890. package/dist/phase/types.d.ts +2199 -0
  891. package/dist/phase/types.d.ts.map +1 -0
  892. package/dist/phase/types.js +27 -0
  893. package/dist/phase/types.js.map +1 -0
  894. package/dist/phase/withinFileProvenance.d.ts +50 -0
  895. package/dist/phase/withinFileProvenance.d.ts.map +1 -0
  896. package/dist/phase/withinFileProvenance.js +112 -0
  897. package/dist/phase/withinFileProvenance.js.map +1 -0
  898. package/dist/pipeline.d.ts +37 -30
  899. package/dist/pipeline.d.ts.map +1 -1
  900. package/dist/pipeline.js +131 -326
  901. package/dist/pipeline.js.map +1 -1
  902. package/dist/pipelineAdapters.d.ts +104 -21
  903. package/dist/pipelineAdapters.d.ts.map +1 -1
  904. package/dist/pipelineAdapters.js +1144 -984
  905. package/dist/pipelineAdapters.js.map +1 -1
  906. package/dist/pipelineTypes.d.ts +21 -0
  907. package/dist/pipelineTypes.d.ts.map +1 -1
  908. package/dist/pipelineTypes.js +21 -10
  909. package/dist/pipelineTypes.js.map +1 -1
  910. package/dist/presets/presets.d.ts +9 -2
  911. package/dist/presets/presets.d.ts.map +1 -1
  912. package/dist/presets/presets.js +15 -26
  913. package/dist/presets/presets.js.map +1 -1
  914. package/dist/reporting/csvReportGenerator.d.ts +14 -3
  915. package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
  916. package/dist/reporting/csvReportGenerator.js +14 -3
  917. package/dist/reporting/csvReportGenerator.js.map +1 -1
  918. package/dist/reporting/htmlReportGenerator.d.ts +5 -1
  919. package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
  920. package/dist/reporting/htmlReportGenerator.js +5 -1
  921. package/dist/reporting/htmlReportGenerator.js.map +1 -1
  922. package/dist/reporting/jsonReportGenerator.d.ts +9 -2
  923. package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
  924. package/dist/reporting/jsonReportGenerator.js +19 -5
  925. package/dist/reporting/jsonReportGenerator.js.map +1 -1
  926. package/dist/reporting/reportGenerator.d.ts +9 -2
  927. package/dist/reporting/reportGenerator.d.ts.map +1 -1
  928. package/dist/reporting/reportGenerator.js +9 -2
  929. package/dist/reporting/reportGenerator.js.map +1 -1
  930. package/dist/reporting/sarifReportGenerator.d.ts +14 -0
  931. package/dist/reporting/sarifReportGenerator.d.ts.map +1 -1
  932. package/dist/reporting/sarifReportGenerator.js +14 -0
  933. package/dist/reporting/sarifReportGenerator.js.map +1 -1
  934. package/dist/reporting/sizeDistribution.d.ts +19 -2
  935. package/dist/reporting/sizeDistribution.d.ts.map +1 -1
  936. package/dist/reporting/sizeDistribution.js +23 -5
  937. package/dist/reporting/sizeDistribution.js.map +1 -1
  938. package/dist/ruleAliases.d.ts +6 -8
  939. package/dist/ruleAliases.d.ts.map +1 -1
  940. package/dist/ruleAliases.js +29 -4
  941. package/dist/ruleAliases.js.map +1 -1
  942. package/dist/search/QueryParser.d.ts +1 -0
  943. package/dist/search/QueryParser.d.ts.map +1 -1
  944. package/dist/search/QueryParser.js +32 -91
  945. package/dist/search/QueryParser.js.map +1 -1
  946. package/dist/services/CodeMapGenerator.d.ts +19 -20
  947. package/dist/services/CodeMapGenerator.d.ts.map +1 -1
  948. package/dist/services/CodeMapGenerator.js +214 -194
  949. package/dist/services/CodeMapGenerator.js.map +1 -1
  950. package/dist/services/ProjectTaskRepository.d.ts +65 -3
  951. package/dist/services/ProjectTaskRepository.d.ts.map +1 -1
  952. package/dist/services/ProjectTaskRepository.js +94 -25
  953. package/dist/services/ProjectTaskRepository.js.map +1 -1
  954. package/dist/services/auditJobService.d.ts +17 -1
  955. package/dist/services/auditJobService.d.ts.map +1 -1
  956. package/dist/services/auditJobService.js +16 -0
  957. package/dist/services/auditJobService.js.map +1 -1
  958. package/dist/services/fileAccounting.d.ts +43 -5
  959. package/dist/services/fileAccounting.d.ts.map +1 -1
  960. package/dist/services/fileAccounting.js +48 -9
  961. package/dist/services/fileAccounting.js.map +1 -1
  962. package/dist/services/projectTaskHelpers.d.ts +45 -0
  963. package/dist/services/projectTaskHelpers.d.ts.map +1 -1
  964. package/dist/services/projectTaskHelpers.js +45 -0
  965. package/dist/services/projectTaskHelpers.js.map +1 -1
  966. package/dist/services/whitelistService.d.ts +40 -5
  967. package/dist/services/whitelistService.d.ts.map +1 -1
  968. package/dist/services/whitelistService.js +87 -46
  969. package/dist/services/whitelistService.js.map +1 -1
  970. package/dist/sqlite/betterSqlite3.d.ts +35 -1
  971. package/dist/sqlite/betterSqlite3.d.ts.map +1 -1
  972. package/dist/sqlite/betterSqlite3.js +35 -1
  973. package/dist/sqlite/betterSqlite3.js.map +1 -1
  974. package/dist/sqlite/driver.d.ts +23 -0
  975. package/dist/sqlite/driver.d.ts.map +1 -1
  976. package/dist/sqlite/driver.js +23 -0
  977. package/dist/sqlite/driver.js.map +1 -1
  978. package/dist/sqlite/nodeSqlite.d.ts +35 -1
  979. package/dist/sqlite/nodeSqlite.d.ts.map +1 -1
  980. package/dist/sqlite/nodeSqlite.js +35 -1
  981. package/dist/sqlite/nodeSqlite.js.map +1 -1
  982. package/dist/structuralSignature.d.ts +9 -0
  983. package/dist/structuralSignature.d.ts.map +1 -1
  984. package/dist/structuralSignature.js +9 -0
  985. package/dist/structuralSignature.js.map +1 -1
  986. package/dist/styles/cssAstExtractor.d.ts +15 -0
  987. package/dist/styles/cssAstExtractor.d.ts.map +1 -1
  988. package/dist/styles/cssAstExtractor.js +15 -0
  989. package/dist/styles/cssAstExtractor.js.map +1 -1
  990. package/dist/styles/normalizer.d.ts +6 -0
  991. package/dist/styles/normalizer.d.ts.map +1 -1
  992. package/dist/styles/normalizer.js +6 -0
  993. package/dist/styles/normalizer.js.map +1 -1
  994. package/dist/styles/styleExtractor.d.ts +29 -2
  995. package/dist/styles/styleExtractor.d.ts.map +1 -1
  996. package/dist/styles/styleExtractor.js +67 -48
  997. package/dist/styles/styleExtractor.js.map +1 -1
  998. package/dist/styles/styleIndexer.d.ts +8 -0
  999. package/dist/styles/styleIndexer.d.ts.map +1 -1
  1000. package/dist/styles/styleIndexer.js +135 -138
  1001. package/dist/styles/styleIndexer.js.map +1 -1
  1002. package/dist/styles/tailwindConfigLoader.d.ts +12 -0
  1003. package/dist/styles/tailwindConfigLoader.d.ts.map +1 -1
  1004. package/dist/styles/tailwindConfigLoader.js +12 -0
  1005. package/dist/styles/tailwindConfigLoader.js.map +1 -1
  1006. package/dist/styles/tailwindExpander.d.ts +3 -0
  1007. package/dist/styles/tailwindExpander.d.ts.map +1 -1
  1008. package/dist/styles/tailwindExpander.js +8 -4
  1009. package/dist/styles/tailwindExpander.js.map +1 -1
  1010. package/dist/styles/tailwindProbe.d.ts +9 -0
  1011. package/dist/styles/tailwindProbe.d.ts.map +1 -1
  1012. package/dist/styles/tailwindProbe.js +181 -166
  1013. package/dist/styles/tailwindProbe.js.map +1 -1
  1014. package/dist/styles/tailwindUtilityExpander.d.ts +13 -0
  1015. package/dist/styles/tailwindUtilityExpander.d.ts.map +1 -1
  1016. package/dist/styles/tailwindUtilityExpander.js +13 -0
  1017. package/dist/styles/tailwindUtilityExpander.js.map +1 -1
  1018. package/dist/symbols.d.ts +13 -11
  1019. package/dist/symbols.d.ts.map +1 -1
  1020. package/dist/symbols.js +14 -21
  1021. package/dist/symbols.js.map +1 -1
  1022. package/dist/telemetry.d.ts +31 -3
  1023. package/dist/telemetry.d.ts.map +1 -1
  1024. package/dist/telemetry.js +31 -3
  1025. package/dist/telemetry.js.map +1 -1
  1026. package/dist/tool-registry.d.ts +37 -1
  1027. package/dist/tool-registry.d.ts.map +1 -1
  1028. package/dist/tool-registry.js +37 -1
  1029. package/dist/tool-registry.js.map +1 -1
  1030. package/dist/types.d.ts +114 -71
  1031. package/dist/types.d.ts.map +1 -1
  1032. package/dist/types.js +7 -16
  1033. package/dist/types.js.map +1 -1
  1034. package/dist/ui/InteractivePrompts.d.ts +12 -0
  1035. package/dist/ui/InteractivePrompts.d.ts.map +1 -1
  1036. package/dist/ui/InteractivePrompts.js +12 -0
  1037. package/dist/ui/InteractivePrompts.js.map +1 -1
  1038. package/dist/utils/astParser.d.ts +15 -0
  1039. package/dist/utils/astParser.d.ts.map +1 -1
  1040. package/dist/utils/astParser.js +15 -0
  1041. package/dist/utils/astParser.js.map +1 -1
  1042. package/dist/utils/astUtils.d.ts +60 -0
  1043. package/dist/utils/astUtils.d.ts.map +1 -1
  1044. package/dist/utils/astUtils.js +350 -362
  1045. package/dist/utils/astUtils.js.map +1 -1
  1046. package/dist/utils/contentHash.d.ts +22 -0
  1047. package/dist/utils/contentHash.d.ts.map +1 -0
  1048. package/dist/utils/contentHash.js +26 -0
  1049. package/dist/utils/contentHash.js.map +1 -0
  1050. package/dist/utils/dependencyExtractor.d.ts +28 -0
  1051. package/dist/utils/dependencyExtractor.d.ts.map +1 -1
  1052. package/dist/utils/dependencyExtractor.js +28 -1
  1053. package/dist/utils/dependencyExtractor.js.map +1 -1
  1054. package/dist/utils/errorMessage.d.ts +10 -0
  1055. package/dist/utils/errorMessage.d.ts.map +1 -0
  1056. package/dist/utils/errorMessage.js +12 -0
  1057. package/dist/utils/errorMessage.js.map +1 -0
  1058. package/dist/utils/fileDiscovery.d.ts +61 -2
  1059. package/dist/utils/fileDiscovery.d.ts.map +1 -1
  1060. package/dist/utils/fileDiscovery.js +131 -23
  1061. package/dist/utils/fileDiscovery.js.map +1 -1
  1062. package/dist/utils/reactDetection.d.ts +34 -5
  1063. package/dist/utils/reactDetection.d.ts.map +1 -1
  1064. package/dist/utils/reactDetection.js +73 -52
  1065. package/dist/utils/reactDetection.js.map +1 -1
  1066. package/dist/version.generated.d.ts +1 -1
  1067. package/dist/version.generated.js +1 -1
  1068. package/dist/workers/auditWorker.js +7 -3
  1069. package/dist/workers/auditWorker.js.map +1 -1
  1070. package/examples/.auditrc.example.json +0 -8
  1071. package/examples/.auditrc.json +0 -11
  1072. package/examples/.code-auditor.json +0 -2
  1073. package/examples/nextjs.auditrc.json +0 -8
  1074. package/examples/node-api.auditrc.json +0 -7
  1075. package/examples/react.auditrc.json +0 -6
  1076. package/examples/tolerant-solid.auditrc.json +0 -5
  1077. package/package.json +18 -9
  1078. package/plugin/.claude-plugin/manifest.json +16 -0
  1079. package/plugin/.claude-plugin/plugin.json +1 -1
  1080. package/plugin/hooks/hooks.json +7 -3
  1081. package/plugin/scripts/hook-audit.sh +46 -16
  1082. package/plugin/scripts/hook-common.sh +81 -12
  1083. package/plugin/scripts/hook-drift-check.sh +76 -0
  1084. package/plugin/scripts/hook-self-audit.sh +22 -14
  1085. package/plugin/scripts/hook-warm.sh +5 -6
  1086. package/plugin/skills/code-auditor/SKILL.md +1 -1
  1087. package/server.json +10 -4
@@ -18,28 +18,19 @@
18
18
  * provenance — strict provenance only, never consults name lists
19
19
  * names — legacy English-only name matching (opt-in escape hatch)
20
20
  */
21
+ import { dialectForPackage } from '../languages/sql/dialectDetection.js';
22
+ import { DB_PACKAGES, handleTypesForPackage } from './tsEcosystem.js';
23
+ import { buildBindingEnv, classifyRootIdentifier, extractInterfaceFields, resolveReceiverRoot, findEnclosingClassHeritage, } from './receiverRoot.js';
24
+ import { identifyHandle } from './handleIdentification.js';
25
+ import { stripSqlQuotes } from './sqlLiteral.js';
21
26
  // ═══════════════════════════════════════════════════════════════════════════
22
- // Constants — the universal vocabulary (package names are language-invariant)
27
+ // Constants — validator packages
28
+ //
29
+ // The DB ecosystem (DB_PACKAGES / ORM_METHODS) was TypeScript/npm-only and
30
+ // moved behind the resolution interface to `tsEcosystem.ts`
31
+ // (correction-seams-not-placement §4). What remains here is the
32
+ // validator-package vocabulary, a distinct concern.
23
33
  // ═══════════════════════════════════════════════════════════════════════════
24
- /** Database packages — spec R1.1 */
25
- export const DB_PACKAGES = new Set([
26
- 'better-sqlite3',
27
- 'drizzle-orm',
28
- '@prisma/client',
29
- 'pg',
30
- 'mysql2',
31
- 'postgres',
32
- 'kysely',
33
- 'knex',
34
- 'mongodb',
35
- 'mongoose',
36
- '@libsql/client',
37
- '@planetscale/database',
38
- '@neondatabase/serverless',
39
- '@vercel/postgres',
40
- 'bun:sqlite',
41
- 'node:sqlite',
42
- ]);
43
34
  /** Validator packages — spec R4.1 */
44
35
  export const VALIDATOR_PACKAGES = new Set([
45
36
  'zod',
@@ -52,79 +43,6 @@ export const VALIDATOR_PACKAGES = new Set([
52
43
  '@sinclair/typebox',
53
44
  'class-validator',
54
45
  ]);
55
- /** Known DB type names — spec R1.1 (propagation rule 8) */
56
- export const DB_TYPES = new Set([
57
- 'D1Database',
58
- 'D1PreparedStatement',
59
- 'D1Result',
60
- 'Database',
61
- 'Pool',
62
- 'PrismaClient',
63
- 'Kysely',
64
- 'Connection',
65
- 'SqliteDatabase',
66
- 'BetterSQLite3Database',
67
- ]);
68
- /**
69
- * DB call methods — the fixed API surface (language-invariant).
70
- *
71
- * Spec 33 Item 11 FP category 5: the bare-identifier hybrid fallback in
72
- * `isDBProvenanced` treated any `get(...)` / `each(...)` / `values(...)` call
73
- * as a DB query, flagging lodash-style object accessors (e.g.
74
- * `@directus/utils`'s `get(item, ...)`) as sql-injection. Those three names
75
- * are also common non-DB methods (lodash `get`, jQuery/iterator
76
- * `each`, Map/WebSocket `.values()`), so they are removed from the fallback —
77
- * mirroring the `get`/`each` trim in CHANGELOG 3.4.9 (DB_CALL_METHOD_NAMES).
78
- *
79
- * `query` is deliberately RETAINED: it is a genuine query-execution method on
80
- * mysql2, pg, node-postgres, D1 and Planetscale (`.query(...)`), and the
81
- * spec-19 data-access fixtures exercise it as a canonical DB entry point.
82
- * Removing it would turn real SQL-injection positives into false negatives.
83
- *
84
- * `raw` is deliberately retained: it is a genuine raw-execution method on
85
- * D1 prepared statements, Knex, and Kysely, and the Item-6 taint-tracking
86
- * fixtures exercise it as the canonical raw-SQL entry point.
87
- */
88
- export const DB_CALL_METHODS = new Set([
89
- 'exec',
90
- 'prepare',
91
- 'batch',
92
- 'run',
93
- 'all',
94
- 'first',
95
- 'query',
96
- 'raw',
97
- ]);
98
- /** ORM method patterns — fixed API surface for ORM recognition (Spec 21 R1) */
99
- export const ORM_METHODS = new Set([
100
- 'find',
101
- 'findOne',
102
- 'findMany',
103
- 'findFirst',
104
- 'findUnique',
105
- 'select',
106
- 'insert',
107
- 'insertMany',
108
- 'update',
109
- 'updateOne',
110
- 'updateMany',
111
- 'delete',
112
- 'deleteOne',
113
- 'deleteMany',
114
- 'from',
115
- 'where',
116
- 'join',
117
- 'leftJoin',
118
- 'rightJoin',
119
- 'innerJoin',
120
- 'create',
121
- 'createMany',
122
- 'aggregate',
123
- 'count',
124
- 'distinct',
125
- 'execute',
126
- 'query',
127
- ]);
128
46
  // ═══════════════════════════════════════════════════════════════════════════
129
47
  // Package matching
130
48
  // ═══════════════════════════════════════════════════════════════════════════
@@ -132,6 +50,20 @@ export const ORM_METHODS = new Set([
132
50
  function matchesDBPackage(specifier) {
133
51
  return [...DB_PACKAGES].some((pkg) => specifier === pkg || specifier.startsWith(pkg + '/'));
134
52
  }
53
+ /**
54
+ * The base npm package name of a module specifier — `pg` for `pg`/`pg/lib`,
55
+ * `@neondatabase/serverless` for `@neondatabase/serverless` and its subpaths,
56
+ * `mysql2` for `mysql2/promise`. Used to stamp {@link ProvenanceEvidence.packageName}
57
+ * with the exact key `dialectForPackage` maps, so a subpath import still resolves
58
+ * to its driver's dialect.
59
+ */
60
+ function basePackageName(specifier) {
61
+ if (specifier.startsWith('@')) {
62
+ const parts = specifier.split('/');
63
+ return parts.slice(0, 2).join('/');
64
+ }
65
+ return specifier.split('/')[0];
66
+ }
135
67
  /** Check if a module specifier matches a validator package. */
136
68
  function matchesValidatorPackage(specifier) {
137
69
  return [...VALIDATOR_PACKAGES].some((pkg) => specifier === pkg || specifier.startsWith(pkg + '/'));
@@ -144,19 +76,38 @@ function matchesValidatorPackage(specifier) {
144
76
  * An import like `import Database from 'better-sqlite3'` produces `Database` as
145
77
  * provenanced with reason "package". Shared by the DB and validator variants,
146
78
  * which differ only in the package predicate.
79
+ *
80
+ * `handleTypesFor` is the Decision A type filter. It maps a matched specifier to
81
+ * the package's handle-name set, or `undefined` when the caller wants no type
82
+ * filter (the validator variant — a validator package's every export is a
83
+ * validator). When the set is present, a *named* import seeds only if its
84
+ * original export name (`spec.name`, not the local alias) is in the set; a
85
+ * default or namespace import seeds unconditionally, because a DB package's
86
+ * default/namespace *is* its handle and tree-sitter records no original export
87
+ * name for a default import to match. This is what stops
88
+ * `import { KVNamespace } from '@cloudflare/workers-types'` from seeding while
89
+ * `import { D1Database }` still does.
90
+ *
147
91
  * @param ast
148
92
  * @param adapter
149
93
  * @param matchesPackage
94
+ * @param handleTypesFor
150
95
  * @returns
151
96
  */
152
- function extractProvenancedImports(ast, adapter, matchesPackage) {
97
+ function extractProvenancedImports(ast, adapter, matchesPackage, handleTypesFor = () => undefined) {
153
98
  const seedMap = new Map();
154
99
  const imports = adapter.extractImports(ast);
155
100
  for (const imp of imports) {
156
101
  const specifier = imp.source;
157
102
  if (!matchesPackage(specifier))
158
103
  continue;
104
+ const handleTypes = handleTypesFor(specifier);
159
105
  for (const spec of imp.specifiers) {
106
+ // Decision A: a named import seeds only when the package's manifest lists
107
+ // the original export name as a handle. Default/namespace imports seed
108
+ // unconditionally (see the doc above).
109
+ if (handleTypes && !spec.isDefault && !spec.isNamespace && !handleTypes.has(spec.name))
110
+ continue;
160
111
  const localName = spec.alias ?? spec.name;
161
112
  const label = spec.isDefault
162
113
  ? `default import from ${specifier}`
@@ -170,6 +121,7 @@ function extractProvenancedImports(ast, adapter, matchesPackage) {
170
121
  reason: 'package',
171
122
  source: label,
172
123
  chain: [],
124
+ packageName: basePackageName(specifier),
173
125
  });
174
126
  }
175
127
  }
@@ -184,7 +136,7 @@ function extractProvenancedImports(ast, adapter, matchesPackage) {
184
136
  * @returns a map of local identifier → DB-provenance evidence
185
137
  */
186
138
  export function extractDBProvenancedImports(ast, adapter) {
187
- return extractProvenancedImports(ast, adapter, matchesDBPackage);
139
+ return extractProvenancedImports(ast, adapter, matchesDBPackage, handleTypesForPackage);
188
140
  }
189
141
  /**
190
142
  * Extract all validator-provenanced identifiers from a file's imports.
@@ -204,40 +156,17 @@ export function extractValidatorProvenancedImports(ast, adapter) {
204
156
  * Returns true if any new identifier was added.
205
157
  */
206
158
  function propagateVariableDeclaration(node, ctx) {
207
- const { nameNode, valueNode, typeAnnotationNode } = splitVariableDeclarator(node, ctx.adapter);
159
+ const { nameNode, valueNode } = splitVariableDeclarator(node, ctx.adapter);
208
160
  if (!nameNode)
209
161
  return false;
210
- let mutated = false;
211
- // Rule 8: type annotation — let x: D1Database
212
- if (typeAnnotationNode) {
213
- mutated = propagateFromTypeAnnotation(nameNode, typeAnnotationNode, ctx);
214
- }
215
162
  if (valueNode) {
216
- mutated = propagateFromValue(nameNode, valueNode, ctx) || mutated;
163
+ return propagateFromValue(nameNode, valueNode, ctx);
217
164
  }
218
- return mutated;
219
- }
220
- /** Rule 8: type annotation — `let x: D1Database`. */
221
- function propagateFromTypeAnnotation(nameNode, typeAnnotationNode, ctx) {
222
- if (nameNode.type !== 'identifier')
223
- return false;
224
- const typeText = ctx.adapter.getNodeText(typeAnnotationNode, ctx.sourceCode).trim();
225
- if (!DB_TYPES.has(typeText))
226
- return false;
227
- const name = ctx.adapter.getNodeText(nameNode, ctx.sourceCode);
228
- if (ctx.provenanceMap.has(name))
229
- return false;
230
- ctx.provenanceMap.set(name, {
231
- identifier: name,
232
- reason: 'type',
233
- source: `type annotation ${typeText}`,
234
- chain: [],
235
- });
236
- return true;
165
+ return false;
237
166
  }
238
167
  /** Propagate provenance from a declarator's value expression into its names. */
239
168
  function propagateFromValue(nameNode, valueNode, ctx) {
240
- const propagated = tryPropagateFromExpression(valueNode, ctx.adapter, ctx.sourceCode, ctx.provenanceMap);
169
+ const propagated = tryPropagateFromExpression(valueNode, ctx.adapter, ctx.sourceCode, ctx.provenanceMap, ctx.localFunctions);
241
170
  if (!propagated)
242
171
  return false;
243
172
  let mutated = false;
@@ -248,6 +177,7 @@ function propagateFromValue(nameNode, valueNode, ctx) {
248
177
  reason: 'propagation',
249
178
  source: propagated.source,
250
179
  chain: [...propagated.chain, propagated.identifier],
180
+ packageName: propagated.packageName,
251
181
  });
252
182
  mutated = true;
253
183
  }
@@ -258,7 +188,7 @@ function propagateFromValue(nameNode, valueNode, ctx) {
258
188
  * Propagate provenance through a default parameter (rule 6).
259
189
  * Returns true if a new identifier was added.
260
190
  */
261
- function propagateDefaultParameter(node, adapter, sourceCode, provenanceMap) {
191
+ function propagateDefaultParameter(node, adapter, sourceCode, provenanceMap, localFunctions) {
262
192
  const children = adapter.getChildren(node);
263
193
  // assignment_pattern has [left, right]
264
194
  if (children.length < 2)
@@ -268,13 +198,14 @@ function propagateDefaultParameter(node, adapter, sourceCode, provenanceMap) {
268
198
  if (leftNode.type !== 'identifier')
269
199
  return false;
270
200
  const paramName = adapter.getNodeText(leftNode, sourceCode);
271
- const propagated = tryPropagateFromExpression(rightNode, adapter, sourceCode, provenanceMap);
201
+ const propagated = tryPropagateFromExpression(rightNode, adapter, sourceCode, provenanceMap, localFunctions);
272
202
  if (propagated && !provenanceMap.has(paramName)) {
273
203
  provenanceMap.set(paramName, {
274
204
  identifier: paramName,
275
205
  reason: 'propagation',
276
206
  source: `default parameter = ${propagated.source}`,
277
207
  chain: [...propagated.chain, propagated.identifier],
208
+ packageName: propagated.packageName,
278
209
  });
279
210
  return true;
280
211
  }
@@ -284,33 +215,81 @@ function propagateDefaultParameter(node, adapter, sourceCode, provenanceMap) {
284
215
  * Propagate provenance through a class field initialization (rule 7).
285
216
  * Returns true if a new identifier was added.
286
217
  */
287
- function propagateClassField(node, adapter, sourceCode, provenanceMap) {
218
+ function propagateClassField(node, adapter, sourceCode, provenanceMap, localFunctions) {
288
219
  const children = adapter.getChildren(node);
289
- // Typically [name, value] or [decorators..., name, value]
220
+ // Typically [name, value], [modifier, name, type], or [decorators..., name, value].
290
221
  const nameChild = children.find((c) => c.type === 'property_identifier');
222
+ if (!nameChild)
223
+ return false;
224
+ const fieldName = adapter.getNodeText(nameChild, sourceCode);
225
+ // Rule 7 — class field initialized with a DB value (`private db = new Database()`).
226
+ // `accessibility_modifier` and `type_annotation` are excluded so the value is
227
+ // found even on a modified or annotated field.
291
228
  const valueChild = children.find((c) => c.type !== 'property_identifier' &&
292
229
  c.type !== 'decorator' &&
230
+ c.type !== 'accessibility_modifier' &&
293
231
  c.type !== 'private' &&
294
232
  c.type !== 'public' &&
295
233
  c.type !== 'protected' &&
296
234
  c.type !== 'static' &&
297
235
  c.type !== 'readonly' &&
298
- c.type !== 'abstract');
299
- if (nameChild && valueChild) {
300
- const fieldName = adapter.getNodeText(nameChild, sourceCode);
301
- const propagated = tryPropagateFromExpression(valueChild, adapter, sourceCode, provenanceMap);
236
+ c.type !== 'abstract' &&
237
+ c.type !== 'type_annotation');
238
+ if (valueChild) {
239
+ const propagated = tryPropagateFromExpression(valueChild, adapter, sourceCode, provenanceMap, localFunctions);
302
240
  if (propagated && !provenanceMap.has(fieldName)) {
303
241
  provenanceMap.set(fieldName, {
304
242
  identifier: fieldName,
305
243
  reason: 'propagation',
306
244
  source: `class field initialized from ${propagated.source}`,
307
245
  chain: [...propagated.chain, propagated.identifier],
246
+ packageName: propagated.packageName,
308
247
  });
309
248
  return true;
310
249
  }
311
250
  }
312
251
  return false;
313
252
  }
253
+ /**
254
+ * S5b (form 4) — propagate provenance through a member assignment
255
+ * (`this.db = new Database()`). The RHS is a DB-provenanced expression (a
256
+ * `new X()` where X is an in-repo class that resolves, or a provenanced
257
+ * identifier), so the assigned field is a DB handle. This is the `new X()`
258
+ * binding form for the `this.<field> = …` assignment shape that no
259
+ * `variable_declarator`/`field_definition` rule covers.
260
+ */
261
+ function propagateMemberAssignment(node, ctx) {
262
+ const { adapter, sourceCode, provenanceMap } = ctx;
263
+ const children = adapter.getChildren(node);
264
+ // children: [member_expression (this.db), <RHS expression>].
265
+ const lhs = children.find((c) => c.type === 'member_expression' || c.type === 'selector_expression');
266
+ if (!lhs)
267
+ return false;
268
+ const lhsChildren = adapter.getChildren(lhs);
269
+ const obj = lhsChildren.find((c) => c.type === 'this' || c.type === 'super');
270
+ if (!obj)
271
+ return false;
272
+ const prop = lhsChildren.find((c) => c.type === 'property_identifier' || c.type === 'field_identifier');
273
+ if (!prop)
274
+ return false;
275
+ const fieldName = adapter.getNodeText(prop, sourceCode);
276
+ if (!fieldName || provenanceMap.has(fieldName))
277
+ return false;
278
+ const rhs = children[children.length - 1];
279
+ if (!rhs || rhs.type === 'member_expression' || rhs.type === 'selector_expression')
280
+ return false;
281
+ const propagated = tryPropagateFromExpression(rhs, adapter, sourceCode, provenanceMap, ctx.localFunctions);
282
+ if (!propagated)
283
+ return false;
284
+ provenanceMap.set(fieldName, {
285
+ identifier: fieldName,
286
+ reason: 'propagation',
287
+ source: `this.${fieldName} assigned from ${propagated.source}`,
288
+ chain: [...propagated.chain, propagated.identifier],
289
+ packageName: propagated.packageName,
290
+ });
291
+ return true;
292
+ }
314
293
  function applyPropagationRule(node, parent, ctx) {
315
294
  const { adapter, sourceCode, provenanceMap } = ctx;
316
295
  if (node.type === 'variable_declarator') {
@@ -318,19 +297,22 @@ function applyPropagationRule(node, parent, ctx) {
318
297
  }
319
298
  if (node.type === 'assignment_pattern' &&
320
299
  parent?.type === 'formal_parameters') {
321
- return propagateDefaultParameter(node, adapter, sourceCode, provenanceMap);
300
+ return propagateDefaultParameter(node, adapter, sourceCode, provenanceMap, ctx.localFunctions);
301
+ }
302
+ if (node.type === 'public_field_definition') {
303
+ return propagateClassField(node, adapter, sourceCode, provenanceMap, ctx.localFunctions);
322
304
  }
323
- if (node.type === 'public_field_definition' ||
324
- node.type === 'field_definition') {
325
- return propagateClassField(node, adapter, sourceCode, provenanceMap);
305
+ // S5b (form 4) — `this.db = new Database()` / `this.db = <provenanced>`.
306
+ if (node.type === 'assignment_expression') {
307
+ return propagateMemberAssignment(node, ctx);
326
308
  }
327
309
  return false;
328
310
  }
329
311
  /**
330
- * Propagate provenance through assignments, destructuring, parameters,
331
- * class fields, and type annotations within a single file.
312
+ * Propagate provenance through assignments, destructuring, default
313
+ * parameters, and class-field initializers within a single file.
332
314
  *
333
- * The 8 single-file propagation rules (spec R1):
315
+ * The 7 single-file propagation rules (spec R1):
334
316
  * 1. new Expression → variable
335
317
  * 2. DB-provenanced call return → variable
336
318
  * 3. member expression on DB receiver → variable
@@ -338,7 +320,6 @@ function applyPropagationRule(node, parent, ctx) {
338
320
  * 5. array destructuring from DB source
339
321
  * 6. default parameter with DB value
340
322
  * 7. class field initialized with DB value
341
- * 8. type annotation with known DB type
342
323
  * @param adapter
343
324
  * @param ast
344
325
  * @param seedMap
@@ -348,7 +329,12 @@ function applyPropagationRule(node, parent, ctx) {
348
329
  export function propagateProvenance(ast, adapter, sourceCode, seedMap) {
349
330
  // Work on a copy so we can add newly-provenanced identifiers during the walk
350
331
  const provenanceMap = new Map(seedMap);
351
- const ctx = { adapter, sourceCode, provenanceMap };
332
+ const ctx = {
333
+ adapter,
334
+ sourceCode,
335
+ provenanceMap,
336
+ localFunctions: collectLocalFunctionNames(ast, adapter, sourceCode),
337
+ };
352
338
  // Keep iterating until no new identifiers are discovered (handles chains)
353
339
  let changed = true;
354
340
  let iterations = 0;
@@ -364,6 +350,37 @@ export function propagateProvenance(ast, adapter, sourceCode, seedMap) {
364
350
  }
365
351
  return provenanceMap;
366
352
  }
353
+ /**
354
+ * Names of functions *declared in this file* — named function declarations,
355
+ * method definitions, and arrow/function expressions bound to a variable.
356
+ * S5f consults this to refuse to forward a provenanced argument through a local
357
+ * function: the local function's own return is resolved by
358
+ * `detectDbReturningFunctions` (returned construction), not by
359
+ * the "it takes a handle, so it must return one" heuristic that is only sound
360
+ * for *external* factories like `enhancePrisma(PrismaClient)`.
361
+ */
362
+ function collectLocalFunctionNames(ast, adapter, sourceCode) {
363
+ const names = new Set();
364
+ walkAST(ast.root, (node) => {
365
+ if (FUNCTION_NODE_TYPES.has(node.type)) {
366
+ const name = adapter.getNodeName(node);
367
+ if (name)
368
+ names.add(name);
369
+ return;
370
+ }
371
+ if (node.type === 'variable_declarator') {
372
+ const { nameNode, valueNode } = splitVariableDeclarator(node, adapter);
373
+ if (!nameNode || !valueNode)
374
+ return;
375
+ const vt = valueNode.type;
376
+ if (vt === 'arrow_function' || vt === 'function_expression' || vt === 'generator_function') {
377
+ for (const n of extractPatternNames(nameNode, adapter, sourceCode))
378
+ names.add(n);
379
+ }
380
+ }
381
+ });
382
+ return names;
383
+ }
367
384
  // ═══════════════════════════════════════════════════════════════════════════
368
385
  // Propagation helpers
369
386
  // ═══════════════════════════════════════════════════════════════════════════
@@ -371,7 +388,22 @@ export function propagateProvenance(ast, adapter, sourceCode, seedMap) {
371
388
  * Given a value expression node, check if it indicates DB provenance
372
389
  * and return the evidence of the provenanced source if so.
373
390
  */
374
- function tryPropagateFromExpression(node, adapter, sourceCode, provenanceMap) {
391
+ function tryPropagateFromExpression(node, adapter, sourceCode, provenanceMap, localFunctions) {
392
+ // ── Rule 0: await x — unwrap the await and propagate from its operand ──
393
+ // Mirrors getCallExpressionCallee, which already recurses through
394
+ // await_expression. `await` is a significant anonymous child (converter.ts
395
+ // SIGNIFICANT_ANONYMOUS_TYPES) and is skipped; the operand carries the
396
+ // provenance (e.g. `const x = await factory()`).
397
+ if (node.type === 'await_expression') {
398
+ for (const child of adapter.getChildren(node)) {
399
+ if (child.type === 'await')
400
+ continue;
401
+ const result = tryPropagateFromExpression(child, adapter, sourceCode, provenanceMap, localFunctions);
402
+ if (result)
403
+ return result;
404
+ }
405
+ return null;
406
+ }
375
407
  // ── Rule 1: new Database(...) ──
376
408
  if (node.type === 'new_expression') {
377
409
  const constructorNode = findChildOfType(node, [
@@ -388,7 +420,7 @@ function tryPropagateFromExpression(node, adapter, sourceCode, provenanceMap) {
388
420
  // ── Rule 2: drizzle(env.DB) — call where callee is DB-provenanced ──
389
421
  // ── Rule 3: db.prepare(sql) — member expression call on DB receiver ──
390
422
  if (node.type === 'call_expression') {
391
- const viaCall = tryCallProvenance(node, adapter, sourceCode, provenanceMap);
423
+ const viaCall = tryCallProvenance(node, adapter, sourceCode, provenanceMap, localFunctions);
392
424
  if (viaCall)
393
425
  return viaCall;
394
426
  }
@@ -423,7 +455,7 @@ function lookupEvidence(provenanceMap, name) {
423
455
  * identifier (e.g. `drizzle(...)`) or a member expression on a DB receiver
424
456
  * (e.g. `db.prepare(sql)`).
425
457
  */
426
- function tryCallProvenance(node, adapter, sourceCode, provenanceMap) {
458
+ function tryCallProvenance(node, adapter, sourceCode, provenanceMap, localFunctions) {
427
459
  const calleeNode = getCallExpressionCallee(node, adapter);
428
460
  if (!calleeNode)
429
461
  return null;
@@ -433,6 +465,12 @@ function tryCallProvenance(node, adapter, sourceCode, provenanceMap) {
433
465
  const evidence = lookupEvidence(provenanceMap, name);
434
466
  if (evidence)
435
467
  return evidence;
468
+ // S5f — higher-order wrapper: a plain-identifier call whose callee is NOT
469
+ // provenanced but forwards a provenanced DB-handle argument
470
+ // (`enhancePrisma(PrismaClient)`). The call result is treated as a DB handle.
471
+ const argEvidence = tryProvenancedArgument(node, adapter, sourceCode, provenanceMap, localFunctions);
472
+ if (argEvidence)
473
+ return argEvidence;
436
474
  }
437
475
  // Case: member expression — db.prepare(...)
438
476
  if (calleeNode.type === 'member_expression') {
@@ -444,14 +482,55 @@ function tryCallProvenance(node, adapter, sourceCode, provenanceMap) {
444
482
  return null;
445
483
  }
446
484
  /**
447
- * Split a variable_declarator into its name, value, and type annotation
448
- * child nodes.
485
+ * S5f — a call whose callee is unprovenanced but whose *argument* is a
486
+ * DB-provenanced expression (`enhancePrisma(PrismaClient)`) forwards the handle,
487
+ * so the call result is a DB handle (a wrapper constructor / factory). Restricted
488
+ * to a plain-identifier callee so member-expression calls like `JSON.stringify(db)`
489
+ * or `console.log(db)` — whose result is a string / undefined, not a handle — are
490
+ * not swept in.
491
+ */
492
+ function tryProvenancedArgument(node, adapter, sourceCode, provenanceMap, localFunctions) {
493
+ // S5f is only sound for *external* factories (`enhancePrisma(PrismaClient)`).
494
+ // A local function that merely takes a handle does not therefore return one —
495
+ // e.g. `loadCallGraphData(indexHandle)` returns an in-memory graph, not a
496
+ // handle — and its return is resolved by `detectDbReturningFunctions`. Refusing
497
+ // to forward through a locally-declared function breaks the cascade that labels
498
+ // plain Maps/Sets as DB handles (the source of the index-code N+1 false
499
+ // positives). `localFunctions` is undefined in the `detectDbReturningFunctions`
500
+ // return-check, where S5f's canonical imported-factory case must still fire.
501
+ if (localFunctions) {
502
+ const calleeNode = getCallExpressionCallee(node, adapter);
503
+ if (calleeNode?.type === 'identifier') {
504
+ const calleeName = adapter.getNodeText(calleeNode, sourceCode);
505
+ if (calleeName && localFunctions.has(calleeName))
506
+ return null;
507
+ }
508
+ }
509
+ const argsNode = adapter.getChildren(node).find((c) => c.type === 'arguments');
510
+ if (!argsNode)
511
+ return null;
512
+ for (const arg of adapter.getChildren(argsNode)) {
513
+ if (arg.type === '(' || arg.type === ')' || arg.type === ',')
514
+ continue;
515
+ const evidence = tryPropagateFromExpression(arg, adapter, sourceCode, provenanceMap, localFunctions);
516
+ if (evidence) {
517
+ return {
518
+ identifier: evidence.identifier,
519
+ reason: 'wrapper',
520
+ source: `higher-order wrapper forwards DB handle \`${evidence.identifier}\``,
521
+ chain: evidence.chain,
522
+ };
523
+ }
524
+ }
525
+ return null;
526
+ }
527
+ /**
528
+ * Split a variable_declarator into its name and value child nodes.
449
529
  */
450
530
  function splitVariableDeclarator(node, adapter) {
451
531
  const children = adapter.getChildren(node);
452
532
  let nameNode = null;
453
533
  let valueNode = null;
454
- let typeAnnotationNode = null;
455
534
  let pastEquals = false;
456
535
  for (const child of children) {
457
536
  if (child.type === '=' || child.type === 'equals') {
@@ -460,10 +539,8 @@ function splitVariableDeclarator(node, adapter) {
460
539
  }
461
540
  if (child.type === ':')
462
541
  continue;
463
- if (child.type === 'type_annotation') {
464
- typeAnnotationNode = child;
542
+ if (child.type === 'type_annotation')
465
543
  continue;
466
- }
467
544
  if (!pastEquals && !nameNode) {
468
545
  // First non-syntax child is the name/pattern
469
546
  if (child.type === 'identifier' ||
@@ -482,7 +559,7 @@ function splitVariableDeclarator(node, adapter) {
482
559
  }
483
560
  }
484
561
  }
485
- return { nameNode, valueNode, typeAnnotationNode };
562
+ return { nameNode, valueNode };
486
563
  }
487
564
  /**
488
565
  * Extract all variable names from a destructuring or identifier pattern.
@@ -562,8 +639,21 @@ function collectChildren(node, adapter, sourceCode, names) {
562
639
  * `env.DB.prepare` yields "env.DB", not "env"); a `this`/`super` child returns
563
640
  * `thisSuperResult` (null for the receiver walker, 'this' for the root walker);
564
641
  * any other child returns null.
642
+ *
643
+ * A `call_expression` child is the fluent/builder-chain case (`db.selectFrom(…)
644
+ * .selectAll().execute()` — the object of `.execute` is a call): descend into
645
+ * the call's *callee* and resolve that, so the root receiver is reached through
646
+ * the chain rather than dropped. Without this, every ORM whose queries are
647
+ * builder chains (kysely, drizzle, knex, prisma fluent API) resolves to `null`
648
+ * at the first call boundary.
565
649
  */
566
650
  function resolveReceiverText(firstChild, adapter, sourceCode, thisSuperResult) {
651
+ if (firstChild.type === 'call_expression') {
652
+ const callee = getCallExpressionCallee(firstChild, adapter);
653
+ if (!callee)
654
+ return null;
655
+ return resolveReceiverText(callee, adapter, sourceCode, thisSuperResult);
656
+ }
567
657
  if (firstChild.type === 'identifier' ||
568
658
  firstChild.type === 'member_expression' ||
569
659
  firstChild.type === 'selector_expression') {
@@ -578,8 +668,13 @@ function resolveReceiverText(firstChild, adapter, sourceCode, thisSuperResult) {
578
668
  * Extract the "receiver" identifier from a member expression chain.
579
669
  * For `db.prepare` → "db"
580
670
  * For `this.db.prepare` → "db" (walk to the deepest non-member identifier)
671
+ *
672
+ * @param node the member/selector expression node
673
+ * @param adapter the language adapter used to walk child nodes
674
+ * @param sourceCode the file source text for reading node text
675
+ * @returns the receiver identifier text, or `null`
581
676
  */
582
- function getMemberExpressionReceiver(node, adapter, sourceCode) {
677
+ export function getMemberExpressionReceiver(node, adapter, sourceCode) {
583
678
  // Walk down the member expression chain to find the root object
584
679
  let current = node;
585
680
  while (current.type === 'member_expression' ||
@@ -604,6 +699,9 @@ function getMemberExpressionReceiver(node, adapter, sourceCode) {
604
699
  * guards must agree on: a bare `identifier`, a `member_expression`/`selector`,
605
700
  * and — for `await fn<T>(...)` — an `await_expression` wrapping the callee plus
606
701
  * a `type_arguments` child (skipped, not mistaken for the callee).
702
+ * @param node The call-expression node whose callee to extract.
703
+ * @param adapter The language adapter for child traversal.
704
+ * @returns The callee node, or null when none is found.
607
705
  */
608
706
  export function getCallExpressionCallee(node, adapter) {
609
707
  for (const child of adapter.getChildren(node)) {
@@ -675,104 +773,297 @@ export function buildProvenanceContext(ast, adapter, sourceCode, options) {
675
773
  const mode = options.mode;
676
774
  // 1. Extract seed identifiers from imports
677
775
  const dbSeeds = extractDBProvenancedImports(ast, adapter);
678
- const validatorSeeds = options.mode !== 'names'
679
- ? extractValidatorProvenancedImports(ast, adapter)
680
- : new Map();
776
+ const validatorSeeds = extractValidatorProvenancedImports(ast, adapter);
777
+ // 1a. Merge cross-file resolution seeds (declaration-based, not name-based).
778
+ // These replace the deleted name-list fallback (Spec 69 §10): the
779
+ // `seedProvenance` map is the per-file DB-provenanced identifier set
780
+ // produced by `computeReceiverProvenance` for this file.
781
+ if (options.seedProvenance) {
782
+ for (const [name, evidence] of options.seedProvenance) {
783
+ if (!dbSeeds.has(name))
784
+ dbSeeds.set(name, evidence);
785
+ }
786
+ }
681
787
  // 2. Propagate provenance through assignments
682
788
  let dbProvenanced = propagateProvenance(ast, adapter, sourceCode, dbSeeds);
683
- let validatorProvenanced = mode !== 'names'
684
- ? propagateProvenance(ast, adapter, sourceCode, validatorSeeds)
685
- : new Map();
686
- // 3. Fallback: in hybrid mode, add identifiers that match name lists
687
- // but weren't caught by provenance (R3)
688
- if (mode === 'hybrid') {
689
- dbProvenanced = addNameListFallbacks(dbProvenanced, sourceCode, {
690
- dbReceiverNames: options.dbReceiverNames ?? [],
691
- dbBindingNames: options.dbBindingNames ?? [],
692
- dbWrapperNames: options.dbWrapperNames ?? [],
693
- });
694
- // 3a. Wrapper detection: learn DB-wrapper function names from function
695
- // bodies (a D1 REST fetch, or delegation to an already-provenanced
696
- // receiver). A bare call like `d1(sql)` then resolves as DB-provenanced
697
- // and its SQL reaches the table rules instead of bypassing them.
698
- dbProvenanced = detectDbWrapperFunctions(ast, adapter, sourceCode, dbProvenanced);
699
- }
700
- // 4. In names mode, use ONLY name lists
701
- if (mode === 'names') {
702
- dbProvenanced = buildNamesOnlyProvenance(sourceCode, options.dbReceiverNames ?? [], options.dbBindingNames ?? [], options.dbWrapperNames ?? []);
703
- }
789
+ const validatorProvenanced = propagateProvenance(ast, adapter, sourceCode, validatorSeeds);
790
+ // 2a. DB-shaped activity — receiver roots of DB/ORM call sites, proven or
791
+ // unproven. This is the file-gate signal, not a handle decision: it must
792
+ // run before the R3 dialect gate so a type-annotated handle with a dynamic
793
+ // SQL argument (unproven under criterion 9, no dialect to parse) still
794
+ // passes the gate and reaches the analyzers instead of being dropped.
795
+ const dbActivity = collectDbActivity(ast, adapter, sourceCode, dbProvenanced);
796
+ // 3. R3 — a call whose argument parses as SQL proves its receiver a handle
797
+ // (criterion 8). This is the replacement for the type-name handle tests
798
+ // criterion 9 deleted: `const db: D1Database = getDb()` no longer proves `db`
799
+ // by its annotation, but `db.query('SELECT …')` still does — by the parsed
800
+ // argument, not the name. Runs before wrapper detection so a wrapper body's
801
+ // `db.prepare('SELECT …')` is already visible as a DB call to
802
+ // `detectDbWrappers`. Runs even without a named dialect: `identifyHandle`
803
+ // parses the literal under DEFAULT_SQL_DIALECT when the dialect is null
804
+ // (Spec 70 R2), so a sibling's parseable literal still proves the receiver.
805
+ dbProvenanced = applySqlArgumentInference(ast, adapter, sourceCode, dbProvenanced, options.sqlDialect ?? null);
806
+ // 4. Wrapper detection (structural, not name-based): learn DB-wrapper function
807
+ // names from function bodies — a body that constructs/calls a DB driver.
808
+ // A bare call like `d1(sql)` then resolves as DB-provenanced and its SQL
809
+ // reaches the table rules instead of bypassing them.
810
+ dbProvenanced = detectDbWrappers(ast, adapter, sourceCode, dbProvenanced);
704
811
  return {
705
812
  dbProvenanced,
706
813
  validatorProvenanced,
707
814
  mode,
815
+ dbActivity,
708
816
  };
709
817
  }
710
- function addNameListFallbacks(provenanceMap, sourceCode, nameLists) {
711
- const { dbReceiverNames, dbBindingNames, dbWrapperNames } = nameLists;
712
- const result = new Map(provenanceMap);
713
- addIdentifierFallbacks(result, sourceCode, dbReceiverNames, 'dbReceiverNames');
714
- addBindingFallbacks(result, sourceCode, dbBindingNames);
715
- addIdentifierFallbacks(result, sourceCode, dbWrapperNames, 'dbWrapperNames');
716
- return result;
818
+ // ═══════════════════════════════════════════════════════════════════════════
819
+ // R3 — sql-argument handle inference (criterion 8)
820
+ // ═══════════════════════════════════════════════════════════════════════════
821
+ /**
822
+ * Build the TS receiver-classification env each local fold constructs. The three
823
+ * receiver folds (`collectDbActivity`, `applySqlArgumentInference`,
824
+ * `delegatesToProvenanced`) once each hand-built a near-identical `env` literal;
825
+ * this constructor keeps the classifier's inputs in one place. `interfaceFields`
826
+ * is omitted by the bare-root callers that classify a receiver with no member
827
+ * chain (the B3 arm reads it only for `env.DB`-shaped chains); `delegatesToProvenanced`
828
+ * passes an empty provenance map so the receiver's own declaration — not its
829
+ * propagated provenance — decides its disposition.
830
+ */
831
+ function buildRootEnv(adapter, sourceCode, provenance, bindings, interfaceFields) {
832
+ return { provenance, bindings, interfaceFields, adapter, sourceCode };
717
833
  }
718
- /** Add fallback entries for identifiers that appear in source but lack provenance. */
719
- function addIdentifierFallbacks(result, sourceCode, names, label) {
720
- for (const name of names) {
721
- if (result.has(name))
722
- continue; // already provenanced — provenance wins
723
- if (identifierAppearsInSource(sourceCode, name)) {
724
- result.set(name, {
725
- identifier: name,
726
- reason: 'fallback',
727
- source: `name list match: ${label} contains "${name}"`,
728
- chain: [],
729
- });
834
+ /**
835
+ * Collect the receiver roots of DB-shaped call sites (a member/selector call
836
+ * whose first argument is a static SQL string literal, or whose receiver root
837
+ * resolves handle/unproven), *proven or unproven*. This is the file-gate signal
838
+ * — see `ProvenanceContext.dbActivity` — not a handle decision (that is
839
+ * `identifyHandle`'s job alone, criterion 2).
840
+ *
841
+ * The discriminator is the package discriminant — the receiver root's
842
+ * disposition — not the method name: `join` is `Array.prototype.join` and also
843
+ * `SQL JOIN`. A static SQL literal proves DB shape outright; a dynamic SQL
844
+ * argument (`db.exec('DROP ' + x)`, `db.prepare(sql)`) is admitted by the
845
+ * receiver's resolution (`db` → handle/unproven) while `array.join(',')` is
846
+ * dropped because `array` resolves to a JS global (not-handle). Unlike R3
847
+ * (`applySqlArgumentInference`) it needs no dialect. Runs unconditionally,
848
+ * before R3's dialect gate.
849
+ * @param ast - The file's parsed AST.
850
+ * @param adapter - The language adapter (used for the callee walk and Go skip).
851
+ * @param sourceCode - The file's source text (for node-text reads).
852
+ * @param dbProvenanced - the propagated DB-provenanced map the receiver
853
+ * discriminant reads as its provenance seed.
854
+ * @returns The set of DB-shaped receiver roots, or an empty set for Go.
855
+ */
856
+ export function collectDbActivity(ast, adapter, sourceCode, dbProvenanced = new Map()) {
857
+ const activity = new Set();
858
+ // Go resolves cross-file; a member-receiver root has no local binding to key
859
+ // the gate on, and Go files are gated by their own import resolution instead.
860
+ if (adapter.name === 'go')
861
+ return activity;
862
+ const env = buildRootEnv(adapter, sourceCode, dbProvenanced, buildBindingEnv(ast, adapter, sourceCode), extractInterfaceFields(ast, adapter, sourceCode));
863
+ walkAST(ast.root, (node) => {
864
+ if (node.type !== 'call_expression')
865
+ return;
866
+ const callee = getCallExpressionCallee(node, adapter);
867
+ if (!callee)
868
+ return;
869
+ if (callee.type !== 'member_expression' && callee.type !== 'selector_expression')
870
+ return;
871
+ const root = resolveReceiverRoot(callee, adapter, sourceCode);
872
+ if (root === null)
873
+ return;
874
+ // A static SQL literal proves DB shape regardless of the receiver's package
875
+ // (`db.query('SELECT …')`). A dynamic SQL argument is admitted by the
876
+ // package discriminant: the receiver's disposition — not the method name —
877
+ // distinguishes `db.prepare(sql)` (handle/unproven) from `array.join(',')`
878
+ // (root `Array` → not-handle).
879
+ if (extractStaticSqlArgument(node, adapter, sourceCode) !== null) {
880
+ activity.add(root);
881
+ return;
730
882
  }
731
- }
883
+ if (classifyRootIdentifier(root, env) !== 'not-handle')
884
+ activity.add(root);
885
+ });
886
+ return activity;
732
887
  }
733
- /** Add fallback entries for binding names like `env.DB` (plus their short forms). */
734
- function addBindingFallbacks(result, sourceCode, bindings) {
735
- for (const binding of bindings) {
736
- if (!sourceCode.includes(binding))
737
- continue;
738
- const dotIdx = binding.lastIndexOf('.');
739
- const shortName = dotIdx >= 0 ? binding.substring(dotIdx + 1) : binding;
740
- if (!result.has(binding)) {
741
- result.set(binding, {
742
- identifier: binding,
743
- reason: 'fallback',
744
- source: `name list match: dbBindingNames contains "${binding}"`,
745
- chain: [],
746
- });
747
- }
748
- if (shortName !== binding && !result.has(shortName)) {
749
- result.set(shortName, {
750
- identifier: shortName,
751
- reason: 'fallback',
752
- source: `from binding ${binding}`,
888
+ /**
889
+ * R3: a call whose argument parses as SQL proves its receiver a DB handle.
890
+ * Folds the one entry point `identifyHandle` (criterion 2: no second decision
891
+ * path) over DB-shaped call sites and adds every receiver it proves a handle to
892
+ * `dbProvenanced`. This is the replacement for the type-name handle tests
893
+ * criterion 9 deleted: a receiver typed `D1Database` / `MockDB` is no longer
894
+ * proven by its annotation, but `db.query('SELECT …')` still is — by the parsed
895
+ * argument, not the name.
896
+ *
897
+ * The declaration-resolution arm of `identifyHandle` re-runs here, but it is
898
+ * harmless and already the same evidence `propagateProvenance` produced: for a
899
+ * type-annotated receiver it now returns `unproven` (criterion 9), and
900
+ * `combineVerdicts`' `handle > not-handle > unproven` precedence lets the
901
+ * sql-argument proof win. A receiver already in the map is left untouched.
902
+ *
903
+ * @param ast - the parsed file AST whose call sites R3 folds over.
904
+ * @param adapter - the language adapter (name, extraction helpers) for the file.
905
+ * @param sourceCode - the raw file source, for callee/method text extraction.
906
+ * @param dbProvenanced - the running receiver→evidence map to extend in place.
907
+ * @param sqlDialect - the corpus's named SQL dialect (or null), threaded to the SQL parser.
908
+ * @returns the same `dbProvenanced` map, now also carrying every receiver R3 proved.
909
+ */
910
+ export function applySqlArgumentInference(ast, adapter, sourceCode, dbProvenanced, sqlDialect) {
911
+ if (adapter.name === 'go')
912
+ return dbProvenanced; // Go resolves cross-file; no TS env here.
913
+ const env = buildRootEnv(adapter, sourceCode, dbProvenanced, buildBindingEnv(ast, adapter, sourceCode), extractInterfaceFields(ast, adapter, sourceCode));
914
+ walkAST(ast.root, (node) => {
915
+ if (node.type !== 'call_expression')
916
+ return;
917
+ const callee = getCallExpressionCallee(node, adapter);
918
+ if (!callee)
919
+ return;
920
+ // Only member-expression calls carry the receiver whose handle-ness R3
921
+ // proves. A bare-identifier call (`query('…')`) has no receiver to add.
922
+ if (callee.type !== 'member_expression' && callee.type !== 'selector_expression')
923
+ return;
924
+ const method = extractMemberExpressionProperty(callee, adapter, sourceCode);
925
+ if (!method)
926
+ return;
927
+ // The SQL argument — not the method name — is the admission proof. R3 folds
928
+ // `identifyHandle` over every member call; a null static literal simply can't
929
+ // prove a handle, so it falls through. No method-name set is consulted.
930
+ const root = resolveReceiverRoot(callee, adapter, sourceCode);
931
+ if (root === null)
932
+ return;
933
+ const receiver = getMemberExpressionReceiver(callee, adapter, sourceCode) ?? root;
934
+ const sqlArgument = extractStaticSqlArgument(node, adapter, sourceCode);
935
+ if (sqlArgument === null)
936
+ return;
937
+ const thisField = receiverRootIsThis(callee, adapter);
938
+ const thisHeritage = thisField
939
+ ? findEnclosingClassHeritage(ast, adapter, node, sourceCode)
940
+ : null;
941
+ const verdict = identifyHandle({
942
+ format: 'typescript',
943
+ root,
944
+ receiver,
945
+ method,
946
+ sqlArgument,
947
+ thisField,
948
+ thisHeritage,
949
+ }, {
950
+ imports: new Map(),
951
+ typeAnnotations: new Map(),
952
+ bindings: new Map(),
953
+ withinFileProvenance: new Map(),
954
+ sqlDialect,
955
+ resolution: { dialect: 'ts', env },
956
+ });
957
+ if (verdict.kind === 'handle' && !dbProvenanced.has(root)) {
958
+ dbProvenanced.set(root, {
959
+ identifier: root,
960
+ reason: 'sql-argument',
961
+ source: 'SQL argument parses as a statement (Spec 70 R3)',
753
962
  chain: [],
754
963
  });
755
964
  }
756
- }
965
+ });
966
+ return dbProvenanced;
757
967
  }
758
968
  /**
759
- * Build a provenance map using ONLY name lists (for names mode).
969
+ * Extract the R3 sites of a TS-family file — the member calls whose static SQL
970
+ * argument proves their receiver a handle (Spec 70 criterion 8). This is the
971
+ * provenance-free extraction half of {@link applySqlArgumentInference}: the same
972
+ * candidate filter (DB/ORM shape) and the same static-argument test, but it
973
+ * records the site instead of folding `identifyHandle`. The corpus-side
974
+ * `applyR3FromSites` mirror re-runs the verdict once the seeded provenance and
975
+ * bindings are known.
976
+ * @param ast - The file's parsed AST.
977
+ * @param adapter - The language adapter (used for the callee walk and Go skip).
978
+ * @param sourceCode - The file's source text (for static-argument reads).
979
+ * @returns The recorded R3 sites, or `[]` for Go.
760
980
  */
761
- function buildNamesOnlyProvenance(sourceCode, dbReceiverNames, dbBindingNames, dbWrapperNames) {
762
- return addNameListFallbacks(new Map(), sourceCode, {
763
- dbReceiverNames,
764
- dbBindingNames,
765
- dbWrapperNames,
981
+ export function extractR3Sites(ast, adapter, sourceCode) {
982
+ if (adapter.name === 'go')
983
+ return []; // Go resolves cross-file; no TS env here.
984
+ const sites = [];
985
+ walkAST(ast.root, (node) => {
986
+ if (node.type !== 'call_expression')
987
+ return;
988
+ const callee = getCallExpressionCallee(node, adapter);
989
+ if (!callee)
990
+ return;
991
+ // Only member-expression calls carry the receiver whose handle-ness R3
992
+ // proves. A bare-identifier call (`query('…')`) has no receiver to add.
993
+ if (callee.type !== 'member_expression' && callee.type !== 'selector_expression')
994
+ return;
995
+ const method = extractMemberExpressionProperty(callee, adapter, sourceCode);
996
+ if (!method)
997
+ return;
998
+ // The SQL argument — not the method name — is the admission proof. R3 folds
999
+ // `identifyHandle` over every member call; a null static literal simply can't
1000
+ // prove a handle, so it falls through. No method-name set is consulted.
1001
+ const root = resolveReceiverRoot(callee, adapter, sourceCode);
1002
+ if (root === null)
1003
+ return;
1004
+ const receiver = getMemberExpressionReceiver(callee, adapter, sourceCode) ?? root;
1005
+ const sqlArgument = extractStaticSqlArgument(node, adapter, sourceCode);
1006
+ if (sqlArgument === null)
1007
+ return;
1008
+ const thisField = receiverRootIsThis(callee, adapter);
1009
+ const thisHeritage = thisField
1010
+ ? findEnclosingClassHeritage(ast, adapter, node, sourceCode)
1011
+ : null;
1012
+ sites.push({
1013
+ root,
1014
+ receiver,
1015
+ method,
1016
+ sqlArgument,
1017
+ thisField,
1018
+ thisHeritage,
1019
+ });
766
1020
  });
1021
+ return sites;
767
1022
  }
768
- /** Check if an identifier name appears as a standalone identifier in source. */
769
- function identifierAppearsInSource(sourceCode, name) {
770
- // Use word boundary matching to avoid partial matches
771
- const pattern = new RegExp(`\\b${escapeRegex(name)}\\b`);
772
- return pattern.test(sourceCode);
1023
+ /** True when a member/selector chain bottoms out at `this`/`super`. */
1024
+ function receiverRootIsThis(callee, adapter) {
1025
+ let current = callee;
1026
+ while (current.type === 'member_expression' || current.type === 'selector_expression') {
1027
+ const children = adapter.getChildren(current);
1028
+ const object = children.find((c) => c.type !== '.' && c.type !== 'property_identifier' && c.type !== 'field_identifier');
1029
+ if (!object)
1030
+ return false;
1031
+ current = object;
1032
+ }
1033
+ return current.type === 'this' || current.type === 'super';
773
1034
  }
774
- function escapeRegex(s) {
775
- return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1035
+ /**
1036
+ * The statically-present SQL text of a call's first argument (string/template
1037
+ * literal), unquoted — or null when the first argument is not a literal or the
1038
+ * template carries a `${…}` substitution (dynamic). Mirrors the literal-argument
1039
+ * slice of the data-access analyzer's `extractStaticSql`; the tagged-template
1040
+ * and variable-assignment cases are not R3's concern here because a member
1041
+ * receiver already names the handle.
1042
+ */
1043
+ function extractStaticSqlArgument(node, adapter, sourceCode) {
1044
+ const children = adapter.getChildren(node);
1045
+ const args = children.find((c) => {
1046
+ const t = adapter.getNodeType(c);
1047
+ return t === 'arguments' || t === 'argument_list';
1048
+ });
1049
+ if (!args)
1050
+ return null;
1051
+ for (const arg of adapter.getChildren(args)) {
1052
+ const t = adapter.getNodeType(arg);
1053
+ if (t === '(' || t === ')' || t === ',')
1054
+ continue;
1055
+ if (t === 'string' || t === 'template_string') {
1056
+ if (t === 'template_string') {
1057
+ const kids = adapter.getChildren(arg) ?? [];
1058
+ if (kids.some((c) => adapter.getNodeType(c) === 'template_substitution'))
1059
+ return null;
1060
+ }
1061
+ const raw = adapter.getNodeText(arg, sourceCode) ?? '';
1062
+ return stripSqlQuotes(raw);
1063
+ }
1064
+ return null; // first non-trivia argument is not a literal → cannot parse.
1065
+ }
1066
+ return null;
776
1067
  }
777
1068
  // ═══════════════════════════════════════════════════════════════════════════
778
1069
  // Wrapper detection — learn DB-wrapper function names from function bodies
@@ -784,62 +1075,211 @@ const FUNCTION_NODE_TYPES = new Set([
784
1075
  'arrow_function',
785
1076
  'method_definition',
786
1077
  'generator_function_declaration',
787
- 'generator_function_expression',
1078
+ 'generator_function',
1079
+ ]);
1080
+ /** Learn DB-wrapper names from nodes of `spec.nodeTypes` whose bodies wrap a DB
1081
+ * operation, merging each learned name into `dbProvenanced`. */
1082
+ function learnWrapperNames(ast, adapter, sourceCode, dbProvenanced, spec, bindings) {
1083
+ const nodes = adapter.findNodes(ast, {
1084
+ custom: (node) => spec.nodeTypes.has(node.type),
1085
+ });
1086
+ for (const node of nodes) {
1087
+ const name = adapter.getNodeName(node);
1088
+ if (!name)
1089
+ continue;
1090
+ if (dbProvenanced.has(name))
1091
+ continue;
1092
+ if (!spec.isWrapper(node, adapter, sourceCode, dbProvenanced, bindings))
1093
+ continue;
1094
+ dbProvenanced.set(name, {
1095
+ identifier: name,
1096
+ reason: 'wrapper',
1097
+ source: spec.source,
1098
+ chain: [],
1099
+ });
1100
+ }
1101
+ return dbProvenanced;
1102
+ }
1103
+ /** Class-node types that may wrap a DB handle (Spec 69 §10 — cross-file anchor). */
1104
+ const WRAPPER_CLASS_TYPES = new Set([
1105
+ 'class_declaration',
1106
+ 'abstract_class_declaration',
1107
+ 'class',
788
1108
  ]);
789
1109
  /**
790
- * Learn DB-wrapper function names from function bodies and merge them into the
791
- * provenance map.
1110
+ * Learn DB-wrapper names and merge them into the provenance map.
792
1111
  *
793
- * A wrapper is a named function whose own body performs a DB operation — either
794
- * a `fetch` to the Cloudflare D1 HTTP query API, or a call that delegates to an
795
- * already DB-provenanced identifier/receiver. Adding the wrapper's name to
1112
+ * A wrapper is a named function/class whose own body performs a DB operation —
1113
+ * either a `fetch` to the Cloudflare D1 HTTP query API, or a call that delegates
1114
+ * to an already DB-provenanced identifier/receiver. Adding the wrapper's name to
796
1115
  * `dbProvenanced` lets `isDBProvenanced` treat a bare call like `d1(sql)` as a
797
1116
  * DB call, so its SQL argument reaches the table rules (unknown-table /
798
1117
  * stale-table-reference) and the data-access rules instead of bypassing them.
799
1118
  *
800
- * This is structural evidence, not name matching — the function's body literally
801
- * talks to a database — so it is only run in hybrid mode (alongside the name
802
- * fallbacks), never strict `provenance`/`names` modes.
1119
+ * The class form (`options.classes`) is the object-form of the function form: its
1120
+ * body (fields + methods + constructor) constructs or calls a DB driver, so the
1121
+ * class *is* a DB handle — e.g. `export class Database { constructor() {
1122
+ * this.sql = neon(url) } query(t) { return this.sql(t) } }`. Class bodies are
1123
+ * scanned *through* method bodies (the driver call lives in the constructor) but
1124
+ * never into nested classes or nested function declarations — an inner named
1125
+ * function's DB op is not mis-attributed to the outer class.
1126
+ *
1127
+ * This is structural evidence, not name matching, so it is only run in hybrid
1128
+ * mode (alongside the name fallbacks), never strict `provenance`/`names` modes.
803
1129
  *
804
- * @param ast The parsed file AST.
805
- * @param adapter The language adapter for the file's syntax.
806
- * @param sourceCode The raw source text.
807
- * @param dbProvenanced The current provenance map (mutated in place and returned).
808
- * @returns The provenance map with any learned wrapper names added.
1130
+ * @param ast the parsed file AST
1131
+ * @param adapter the language adapter used to walk nodes
1132
+ * @param sourceCode the file source text for reading node text
1133
+ * @param dbProvenanced the provenance map to merge learned wrapper names into
1134
+ * @param options when `classes` is true, also scan wrapper classes
1135
+ * @returns the provenance map with wrapper names added
809
1136
  */
810
- function detectDbWrapperFunctions(ast, adapter, sourceCode, dbProvenanced) {
1137
+ export function detectDbWrappers(ast, adapter, sourceCode, dbProvenanced, options) {
1138
+ const bindings = buildBindingEnv(ast, adapter, sourceCode);
1139
+ learnWrapperNames(ast, adapter, sourceCode, dbProvenanced, {
1140
+ nodeTypes: FUNCTION_NODE_TYPES,
1141
+ isWrapper: isDbWrapperBody,
1142
+ source: 'function body performs a DB operation',
1143
+ }, bindings);
1144
+ if (options?.classes) {
1145
+ learnWrapperNames(ast, adapter, sourceCode, dbProvenanced, {
1146
+ nodeTypes: WRAPPER_CLASS_TYPES,
1147
+ isWrapper: isDbWrapperClass,
1148
+ source: 'class body constructs or calls a DB driver',
1149
+ }, bindings);
1150
+ }
1151
+ return dbProvenanced;
1152
+ }
1153
+ /**
1154
+ * Form-5 (Spec 69 §10 S5f) — function return resolution.
1155
+ *
1156
+ * A call to an in-repo function resolves to its *returned construction*,
1157
+ * transitively: `export function getDB() { return new Database() }` proves
1158
+ * `getDB` is a DB handle because the returned expression is already provenanced —
1159
+ * the identifier's name is irrelevant. It is the binding form the two
1160
+ * `cli-integration` fixtures need: `const db = getDB()` in an importing file
1161
+ * resolves through the export fixed point (a provenanced `getDB` export is seeded
1162
+ * in importers) and then propagates via the existing rule 2 (call to a provenanced
1163
+ * identifier).
1164
+ *
1165
+ * This deliberately does NOT learn to accept mocks: a `getDB(): MockDB` with no
1166
+ * provenanced client anywhere in its chain is honestly not a handle, and stays
1167
+ * unprovenanced.
1168
+ *
1169
+ * @param ast the parsed file AST
1170
+ * @param adapter the language adapter used to find function nodes
1171
+ * @param sourceCode the file source text for reading return expressions
1172
+ * @param dbProvenanced the provenance map to merge learned names into
1173
+ * @returns the provenance map with DB-returning function names added
1174
+ */
1175
+ export function detectDbReturningFunctions(ast, adapter, sourceCode, dbProvenanced) {
811
1176
  const functionNodes = adapter.findNodes(ast, {
812
1177
  custom: (node) => FUNCTION_NODE_TYPES.has(node.type),
813
1178
  });
814
1179
  for (const fn of functionNodes) {
815
1180
  const name = adapter.getNodeName(fn);
816
- if (!name)
817
- continue;
818
- if (dbProvenanced.has(name))
819
- continue;
820
- if (!isDbWrapperBody(fn, adapter, sourceCode, dbProvenanced))
1181
+ if (!name || dbProvenanced.has(name))
821
1182
  continue;
822
- dbProvenanced.set(name, {
823
- identifier: name,
824
- reason: 'wrapper',
825
- source: 'function body performs a DB operation',
826
- chain: [],
827
- });
1183
+ // A `return` whose expression is an already-provenanced construction
1184
+ // (`return new Database(...)`, `return db`, `return drizzle(...)`).
1185
+ if (functionReturnsProvenanced(fn, adapter, sourceCode, dbProvenanced)) {
1186
+ dbProvenanced.set(name, {
1187
+ identifier: name,
1188
+ reason: 'propagation',
1189
+ source: 'returns a DB-provenanced construction',
1190
+ chain: [],
1191
+ });
1192
+ }
828
1193
  }
829
1194
  return dbProvenanced;
830
1195
  }
1196
+ /**
1197
+ * True when any `return` statement in a function body returns an expression that
1198
+ * is itself a DB-provenanced construction — a provenanced identifier, a
1199
+ * `new`/call whose constructor/callee is provenanced, or a member expression on a
1200
+ * provenanced receiver.
1201
+ */
1202
+ function functionReturnsProvenanced(fn, adapter, sourceCode, dbProvenanced) {
1203
+ let found = false;
1204
+ walkAST(fn, (node) => {
1205
+ if (found || node.type !== 'return_statement')
1206
+ return;
1207
+ const arg = adapter.getChildren(node).find((c) => c.type !== 'return');
1208
+ if (!arg)
1209
+ return;
1210
+ if (tryPropagateFromExpression(arg, adapter, sourceCode, dbProvenanced)) {
1211
+ found = true;
1212
+ }
1213
+ });
1214
+ return found;
1215
+ }
1216
+ /**
1217
+ * Decide whether a class's own body performs a DB operation: a D1 REST fetch, a
1218
+ * call delegating to an already DB-provenanced identifier/receiver, or a
1219
+ * `new`/call to a DB-provenanced constructor/function (the driver a wrapper
1220
+ * class *owns*). Method bodies are included (the constructor is where the driver
1221
+ * call lives); nested classes and nested function declarations are excluded.
1222
+ */
1223
+ function isDbWrapperClass(cls, adapter, sourceCode, dbProvenanced, bindings) {
1224
+ for (const expr of collectClassCallExpressions(cls, adapter)) {
1225
+ if (expr.type === 'new_expression') {
1226
+ const ctor = findChildOfType(expr, ['identifier', 'member_expression']);
1227
+ if (ctor) {
1228
+ const ctorName = extractIdentifierName(ctor, adapter, sourceCode);
1229
+ if (ctorName && dbProvenanced.has(ctorName))
1230
+ return true;
1231
+ }
1232
+ continue;
1233
+ }
1234
+ if (isD1RestCall(expr, adapter, sourceCode))
1235
+ return true;
1236
+ if (delegatesToProvenanced(expr, adapter, sourceCode, dbProvenanced, bindings))
1237
+ return true;
1238
+ }
1239
+ return false;
1240
+ }
1241
+ /**
1242
+ * Collect `call_expression`/`new_expression` nodes within a class body, descending
1243
+ * through method bodies but never into nested classes or nested function
1244
+ * declarations (so an inner function's DB op doesn't make the class a wrapper).
1245
+ */
1246
+ function collectClassCallExpressions(cls, adapter) {
1247
+ const expressions = [];
1248
+ const NESTED_SKIP = new Set([
1249
+ 'class_declaration',
1250
+ 'abstract_class_declaration',
1251
+ 'class',
1252
+ 'function_declaration',
1253
+ 'function_expression',
1254
+ 'arrow_function',
1255
+ 'generator_function_declaration',
1256
+ 'generator_function',
1257
+ ]);
1258
+ const walk = (node) => {
1259
+ for (const child of adapter.getChildren(node)) {
1260
+ if (NESTED_SKIP.has(child.type))
1261
+ continue;
1262
+ if (child.type === 'call_expression' || child.type === 'new_expression') {
1263
+ expressions.push(child);
1264
+ }
1265
+ walk(child);
1266
+ }
1267
+ };
1268
+ walk(cls);
1269
+ return expressions;
1270
+ }
831
1271
  /**
832
1272
  * Decide whether a function's own body performs a DB operation: a D1 REST fetch,
833
1273
  * or a call delegating to an already DB-provenanced receiver/identifier.
834
1274
  * Nested function bodies are excluded so an inner function's DB op is not
835
1275
  * mis-attributed to an outer wrapper.
836
1276
  */
837
- function isDbWrapperBody(fn, adapter, sourceCode, dbProvenanced) {
1277
+ function isDbWrapperBody(fn, adapter, sourceCode, dbProvenanced, bindings) {
838
1278
  const calls = collectOwnCallExpressions(fn, adapter);
839
1279
  for (const call of calls) {
840
1280
  if (isD1RestCall(call, adapter, sourceCode))
841
1281
  return true;
842
- if (delegatesToProvenanced(call, adapter, sourceCode, dbProvenanced))
1282
+ if (delegatesToProvenanced(call, adapter, sourceCode, dbProvenanced, bindings))
843
1283
  return true;
844
1284
  }
845
1285
  return false;
@@ -867,22 +1307,56 @@ function collectOwnCallExpressions(fn, adapter) {
867
1307
  * True when `call` is a `fetch(...)` to the Cloudflare D1 HTTP query API
868
1308
  * (`…/d1/database/<id>/query`). That endpoint is specific enough that a match
869
1309
  * is conclusive evidence the surrounding function is a D1 wrapper.
1310
+ *
1311
+ * @param call the candidate call-expression node
1312
+ * @param adapter the language adapter used to read the callee and arguments
1313
+ * @param sourceCode the file source text for reading node text
1314
+ * @returns true when the call names `fetch` with a literal `/d1/database/` URL
870
1315
  */
871
- function isD1RestCall(call, adapter, sourceCode) {
1316
+ export function isD1RestCall(call, adapter, sourceCode) {
1317
+ if (adapter.getNodeType(call) !== 'call_expression')
1318
+ return false;
872
1319
  const callee = getCallExpressionCallee(call, adapter);
873
1320
  if (!callee)
874
1321
  return false;
875
- const calleeText = adapter.getNodeText(callee, sourceCode) ?? '';
876
- if (calleeText !== 'fetch' && !calleeText.endsWith('.fetch'))
1322
+ // The callee must *name* fetch: a bare `fetch(…)` identifier, or a member
1323
+ // `….fetch(…)` whose property node is `fetch`. Reading the property node (not
1324
+ // the callee's whole text) keeps a string inside a subscript/argument from
1325
+ // being read as the method name.
1326
+ const calleeType = adapter.getNodeType(callee);
1327
+ if (calleeType === 'identifier') {
1328
+ if (adapter.getNodeText(callee, sourceCode) !== 'fetch')
1329
+ return false;
1330
+ }
1331
+ else if (calleeType === 'member_expression' || calleeType === 'selector_expression') {
1332
+ if (extractMemberExpressionProperty(callee, adapter, sourceCode) !== 'fetch')
1333
+ return false;
1334
+ }
1335
+ else {
877
1336
  return false;
878
- const callText = adapter.getNodeText(call, sourceCode) ?? '';
879
- return callText.includes('/d1/database/');
1337
+ }
1338
+ // The URL is the first string/template-literal argument. A non-literal first
1339
+ // argument (`fetch(makeUrl(…))`) abstains — the value fetch receives is the
1340
+ // *result* of that call, not a literal, so there is no URL to read.
1341
+ const args = adapter.getChildren(call).find((c) => adapter.getNodeType(c) === 'arguments');
1342
+ if (!args)
1343
+ return false;
1344
+ for (const arg of adapter.getChildren(args)) {
1345
+ const t = adapter.getNodeType(arg);
1346
+ if (t === '(' || t === ')' || t === ',')
1347
+ continue;
1348
+ if (t === 'string' || t === 'template_string') {
1349
+ return (adapter.getNodeText(arg, sourceCode) ?? '').includes('/d1/database/');
1350
+ }
1351
+ break; // first argument is not a literal — abstain
1352
+ }
1353
+ return false;
880
1354
  }
881
1355
  /**
882
1356
  * True when `call` delegates to an identifier or member-receiver that is already
883
1357
  * DB-provenanced (e.g. `db.prepare(...)` inside a `d1Query(sql)` wrapper).
884
1358
  */
885
- function delegatesToProvenanced(call, adapter, sourceCode, dbProvenanced) {
1359
+ function delegatesToProvenanced(call, adapter, sourceCode, dbProvenanced, bindings) {
886
1360
  const callee = getCallExpressionCallee(call, adapter);
887
1361
  if (!callee)
888
1362
  return false;
@@ -894,159 +1368,84 @@ function delegatesToProvenanced(call, adapter, sourceCode, dbProvenanced) {
894
1368
  const receiver = getMemberExpressionReceiver(callee, adapter, sourceCode);
895
1369
  if (!receiver)
896
1370
  return false;
897
- if (dbProvenanced.has(receiver))
898
- return true;
899
- // Compound receivers ("env.DB", "db.users") — match any dotted segment.
900
- return receiver.split('.').some((part) => dbProvenanced.has(part));
1371
+ const receiverProvenanced = dbProvenanced.has(receiver) ||
1372
+ // Compound receivers ("env.DB", "db.users") — match any dotted segment.
1373
+ receiver.split('.').some((part) => dbProvenanced.has(part));
1374
+ if (!receiverProvenanced)
1375
+ return false;
1376
+ // The receiver root's declaration — not the method name — decides whether
1377
+ // this is a DB operation (`db.prepare(…)`) or an in-memory mutation on a
1378
+ // provenanced *result* (`provenancedMap.set(k, v)`, `rows.map(…)`):
1379
+ // `join` is both `Array.prototype.join` and `SQL JOIN`, so a method name
1380
+ // cannot discriminate. Provenance is deliberately left out of the env so the
1381
+ // receiver's own declaration (an array/Map/Set/JS-global/primitive →
1382
+ // not-handle) is consulted rather than its propagated provenance.
1383
+ const root = resolveReceiverRoot(callee, adapter, sourceCode);
1384
+ if (root === null)
1385
+ return false;
1386
+ const env = buildRootEnv(adapter, sourceCode, new Map(), bindings);
1387
+ return classifyRootIdentifier(root, env) !== 'not-handle';
901
1388
  }
902
1389
  return false;
903
1390
  }
1391
+ // ═══════════════════════════════════════════════════════════════════════════
1392
+ // Per-call-site dialect (Spec 70)
1393
+ // ═══════════════════════════════════════════════════════════════════════════
1394
+ /** The SQL dialect a DB-driver package's evidence names, or null when the
1395
+ * evidence carries no package or the package names no single dialect. */
1396
+ function dialectForEvidence(evidence) {
1397
+ if (!evidence?.packageName)
1398
+ return null;
1399
+ return dialectForPackage(evidence.packageName);
1400
+ }
904
1401
  /**
905
- * Determine if a call-expression node's callee is DB-provenanced.
1402
+ * Resolve the SQL dialect a call site should parse its SQL argument under, from
1403
+ * the package its receiver traces to (Spec 70 — per-site dialect). The dialect
1404
+ * is a property of the *located fact*, not the repo: `pool.query(…)` where
1405
+ * `pool` resolves to `pg` is postgres, `conn.query(…)` where `conn` resolves to
1406
+ * `mysql2` is mysql. A repo with two drivers is therefore not "ambiguous" for a
1407
+ * site whose receiver resolves to one of them — that site names its dialect and
1408
+ * parses honestly.
906
1409
  *
907
- * This replaces the old `isDBCallee()` / `isDbCallNode()` name-based
908
- * pattern matching in UniversalDataAccessAnalyzer.
1410
+ * Returns null when the receiver carries no package (a wrapper, a type
1411
+ * annotation, an in-repo module, a cross-dialect ORM like `knex`) or when that
1412
+ * package names no single dialect — the caller then falls back to repo-level
1413
+ * detection (`detectDialect`), and abstains only when that is also null.
909
1414
  *
910
- * Checks:
911
- * 1. Simple identifier call → is the identifier DB-provenanced?
912
- * 2. Member expression call → is the receiver DB-provenanced AND is the
913
- * method in the DB call method set?
914
- * 3. ORM patterns → receiver is DB-provenanced and method matches ORM API
915
- *
916
- * @param node the call-expression node whose callee is under test
917
- * @param query bundled adapter, source, provenance context, and DB methods
918
- * @returns true if the call's callee resolves to a DB-provenanced target
1415
+ * @param node The call-expression node whose callee is under test.
1416
+ * @param adapter The language adapter for child traversal.
1417
+ * @param sourceCode The file source text (for reading node text).
1418
+ * @param provenanceContext The resolved provenance context for this file.
1419
+ * @returns The receiver's dialect, or null when the receiver doesn't resolve to one.
919
1420
  */
920
- export function isDBProvenanced(node, query) {
921
- if (node.type !== 'call_expression')
922
- return false;
923
- const { adapter, sourceCode, context, methods } = query;
1421
+ export function resolveSiteDialect(node, adapter, sourceCode, provenanceContext) {
1422
+ if (!provenanceContext)
1423
+ return null;
924
1424
  const calleeNode = getCallExpressionCallee(node, adapter);
925
1425
  if (!calleeNode)
926
- return false;
927
- // Case 1: Simple identifier call — e.g. query(...)
1426
+ return null;
1427
+ // Bare-identifier call (a wrapper like `d1(sql)`) → the identifier's package.
928
1428
  if (calleeNode.type === 'identifier') {
929
1429
  const name = adapter.getNodeText(calleeNode, sourceCode);
930
- if (name !== null && context.dbProvenanced.has(name)) {
931
- return true;
932
- }
933
- // Hybrid fallback: standalone calls to dbCallMethods (query, execute, etc.)
934
- // qualify as likely DB calls when provenance couldn't resolve the import.
935
- // This catches patterns like `import { query } from './db'` where './db' is
936
- // a local re-export of a known package — provenance can't see through it,
937
- // but the method name is strong evidence.
938
- if (context.mode === 'hybrid' && name !== null && methods.has(name)) {
939
- return true;
940
- }
941
- return false;
1430
+ if (!name)
1431
+ return null;
1432
+ return dialectForEvidence(provenanceContext.dbProvenanced.get(name));
942
1433
  }
943
- // Case 2: Member expression — e.g. db.prepare(...)
1434
+ // Member-expression call (`pool.query(...)`) → the receiver's package. Match the
1435
+ // full receiver text and each dotted segment, mirroring
1436
+ // `isMemberExpressionDBProvenanced` (`env.DB` / `db.users` / `this.db`).
944
1437
  if (calleeNode.type === 'member_expression' || calleeNode.type === 'selector_expression') {
945
- return isMemberExpressionDBProvenanced(calleeNode, query);
946
- }
947
- return false;
948
- }
949
- /**
950
- * Check if a member_expression call is DB-provenanced.
951
- *
952
- * Traverses the member chain to find the root receiver,
953
- * checks if it's in the provenance context, and verifies
954
- * the method matches the DB call/ORM API.
955
- */
956
- function isMemberExpressionDBProvenanced(node, query) {
957
- const { adapter, sourceCode, context } = query;
958
- const rootReceiver = findRootReceiver(node, adapter, sourceCode);
959
- if (!rootReceiver)
960
- return false;
961
- // In names mode, check the method name directly
962
- if (context.mode === 'names') {
963
- return isDBMethodCall(node, query);
964
- }
965
- // Check if the root receiver is DB-provenanced.
966
- // Compound receivers (e.g. "db.users" or "env.DB") need to match both
967
- // the full text (for bindings like "env.DB") and each sub-identifier
968
- // (for receivers like "db.users" where "db" is in dbReceiverNames).
969
- const matchesProvenance = (r) => {
970
- if (context.dbProvenanced.has(r))
971
- return true;
972
- for (const part of r.split('.')) {
973
- if (context.dbProvenanced.has(part))
974
- return true;
1438
+ const receiver = getMemberExpressionReceiver(calleeNode, adapter, sourceCode);
1439
+ if (!receiver)
1440
+ return null;
1441
+ for (const candidate of [receiver, ...receiver.split('.')]) {
1442
+ const dialect = dialectForEvidence(provenanceContext.dbProvenanced.get(candidate));
1443
+ if (dialect)
1444
+ return dialect;
975
1445
  }
976
- return false;
977
- };
978
- if (!matchesProvenance(rootReceiver)) {
979
- if (rootReceiver !== 'this')
980
- return false;
981
- // For `this.xxx`, check if the method chain itself suggests DB usage
982
- return isDBMethodOnThis(node, query);
983
- }
984
- // Check that the method is in the DB call/ORM API
985
- return isDBMethodCall(node, query);
986
- }
987
- /**
988
- * Walk a member/selector expression chain to its root receiver text.
989
- * Returns `'this'` for `this.xxx` chains and `null` when no root is found.
990
- */
991
- function findRootReceiver(node, adapter, sourceCode) {
992
- let current = node;
993
- while (current.type === 'member_expression' || current.type === 'selector_expression') {
994
- const children = adapter.getChildren(current);
995
- const firstChild = children[0];
996
- if (!firstChild)
997
- break;
998
- return resolveReceiverText(firstChild, adapter, sourceCode, 'this');
999
1446
  }
1000
1447
  return null;
1001
1448
  }
1002
- /**
1003
- * Walk a member/selector-expression chain, returning true when any property in
1004
- * the chain is a DB or ORM method. Shared by isDBMethodCall and
1005
- * isDBMethodOnThis, which differ only in how they read a node's children.
1006
- */
1007
- function dbMethodInMemberChain(node, query, getChildren) {
1008
- const { adapter, sourceCode, methods } = query;
1009
- let current = node;
1010
- while (current.type === 'member_expression' ||
1011
- current.type === 'selector_expression') {
1012
- const children = getChildren(current);
1013
- // The property is typically the second or third child
1014
- for (const child of children) {
1015
- if (child.type === 'property_identifier' ||
1016
- child.type === 'field_identifier') {
1017
- const propName = adapter.getNodeText(child, sourceCode);
1018
- const lower = propName.toLowerCase();
1019
- if (methods.has(lower) || ORM_METHODS.has(lower)) {
1020
- return true;
1021
- }
1022
- }
1023
- }
1024
- // Go deeper if there's a nested member/selector expression
1025
- const firstChild = children[0];
1026
- if (firstChild?.type === 'member_expression' ||
1027
- firstChild?.type === 'selector_expression') {
1028
- current = firstChild;
1029
- }
1030
- else {
1031
- break;
1032
- }
1033
- }
1034
- return false;
1035
- }
1036
- /**
1037
- * Check if a call through a member expression uses a DB method
1038
- * (exec, prepare, all, etc.) or an ORM method (find, insert, etc.).
1039
- */
1040
- function isDBMethodCall(node, query) {
1041
- return dbMethodInMemberChain(node, query, (n) => n.children ?? []);
1042
- }
1043
- /**
1044
- * For `this.xxx.method()` calls — check if the method chain suggests DB access.
1045
- * Used when the receiver is `this` (not directly DB-provenanced).
1046
- */
1047
- function isDBMethodOnThis(node, query) {
1048
- return dbMethodInMemberChain(node, query, (n) => query.adapter.getChildren(n));
1049
- }
1050
1449
  /**
1051
1450
  * Check if an identifier is validator-provenanced (R4 infrastructure).
1052
1451
  *
@@ -1097,7 +1496,7 @@ function inferReceiverFromCall(node, ctx) {
1097
1496
  if (!callee || (callee.type !== 'member_expression' && callee.type !== 'selector_expression'))
1098
1497
  return;
1099
1498
  const methodName = extractMemberExpressionProperty(callee, adapter, sourceCode);
1100
- if (!methodName || !DB_CALL_METHODS.has(methodName.toLowerCase()))
1499
+ if (!methodName || extractStaticSqlArgument(node, adapter, sourceCode) === null)
1101
1500
  return;
1102
1501
  const receiver = getMemberExpressionReceiver(callee, adapter, sourceCode);
1103
1502
  if (!receiver)
@@ -1106,7 +1505,7 @@ function inferReceiverFromCall(node, ctx) {
1106
1505
  if (provenancedSet.has(receiver) || seen.has(receiver))
1107
1506
  return;
1108
1507
  // Step 3: Trace receiver through assignment chain to a provenanced source
1109
- const traced = traceAssignmentChain(receiver, assignmentGraph, provenancedSet);
1508
+ const traced = traceAssignmentChain(receiver, assignmentGraph, provenancedSet, adapter, sourceCode);
1110
1509
  if (traced.found) {
1111
1510
  seen.add(receiver);
1112
1511
  inferred.identifiers.push(receiver);
@@ -1118,7 +1517,8 @@ function inferReceiverFromCall(node, ctx) {
1118
1517
  }
1119
1518
  /**
1120
1519
  * Build a reverse assignment graph from the AST.
1121
- * Maps variable name → the text of its initializer expression.
1520
+ * Maps variable name → the *node* of its initializer expression (not its text,
1521
+ * so the trace can walk it structurally rather than regex over a string).
1122
1522
  * Handles: const/let/var declarations, parameter defaults, class fields.
1123
1523
  */
1124
1524
  function buildAssignmentGraph(ast, adapter, sourceCode) {
@@ -1142,10 +1542,9 @@ function recordVariableDeclarator(node, ctx) {
1142
1542
  if (!nameNode || !valueNode)
1143
1543
  return;
1144
1544
  const names = extractPatternNames(nameNode, ctx.adapter, ctx.sourceCode);
1145
- const valueText = ctx.adapter.getNodeText(valueNode, ctx.sourceCode);
1146
1545
  for (const name of names) {
1147
1546
  if (!ctx.graph.has(name))
1148
- ctx.graph.set(name, valueText);
1547
+ ctx.graph.set(name, valueNode);
1149
1548
  }
1150
1549
  }
1151
1550
  /** Record parameter defaults (`function foo(x = <expr>)`) into the graph. */
@@ -1161,14 +1560,12 @@ function recordParameterDefault(node, parent, ctx) {
1161
1560
  if (leftNode.type !== 'identifier')
1162
1561
  return;
1163
1562
  const paramName = ctx.adapter.getNodeText(leftNode, ctx.sourceCode);
1164
- const valueText = ctx.adapter.getNodeText(rightNode, ctx.sourceCode);
1165
1563
  if (!ctx.graph.has(paramName))
1166
- ctx.graph.set(paramName, valueText);
1564
+ ctx.graph.set(paramName, rightNode);
1167
1565
  }
1168
1566
  /** Record class-field initializers (`fieldName = <expr>`) into the graph. */
1169
1567
  function recordClassField(node, ctx) {
1170
- if (node.type !== 'public_field_definition' &&
1171
- node.type !== 'field_definition') {
1568
+ if (node.type !== 'public_field_definition') {
1172
1569
  return;
1173
1570
  }
1174
1571
  const children = ctx.adapter.getChildren(node);
@@ -1185,15 +1582,14 @@ function recordClassField(node, ctx) {
1185
1582
  if (!nameChild || !valueChild)
1186
1583
  return;
1187
1584
  const fieldName = ctx.adapter.getNodeText(nameChild, ctx.sourceCode);
1188
- const valueText = ctx.adapter.getNodeText(valueChild, ctx.sourceCode);
1189
1585
  if (!ctx.graph.has(fieldName))
1190
- ctx.graph.set(fieldName, valueText);
1586
+ ctx.graph.set(fieldName, valueChild);
1191
1587
  }
1192
1588
  /**
1193
1589
  * Trace a receiver identifier through the assignment graph to see if it
1194
1590
  * ultimately resolves to a provenanced source.
1195
1591
  */
1196
- function traceAssignmentChain(receiver, assignmentGraph, provenancedSet) {
1592
+ function traceAssignmentChain(receiver, assignmentGraph, provenancedSet, adapter, sourceCode) {
1197
1593
  const visited = new Set();
1198
1594
  const chain = [receiver];
1199
1595
  let current = receiver;
@@ -1208,9 +1604,9 @@ function traceAssignmentChain(receiver, assignmentGraph, provenancedSet) {
1208
1604
  reason: provenancedSet.get(current).source,
1209
1605
  };
1210
1606
  }
1211
- const initText = assignmentGraph.get(current);
1212
- if (initText) {
1213
- const idents = extractTopLevelIdentifiers(initText);
1607
+ const initNode = assignmentGraph.get(current);
1608
+ if (initNode) {
1609
+ const idents = extractTopLevelIdentifiers(initNode, adapter, sourceCode);
1214
1610
  for (const ident of idents) {
1215
1611
  if (provenancedSet.has(ident)) {
1216
1612
  chain.push(current);
@@ -1222,10 +1618,10 @@ function traceAssignmentChain(receiver, assignmentGraph, provenancedSet) {
1222
1618
  }
1223
1619
  }
1224
1620
  }
1225
- if (!initText || visited.has(initText))
1621
+ if (!initNode || visited.has(initNode))
1226
1622
  break;
1227
- visited.add(initText);
1228
- const next = findNextTraceIdentifier(initText, assignmentGraph, visited);
1623
+ visited.add(initNode);
1624
+ const next = findNextTraceIdentifier(initNode, assignmentGraph, visited, adapter, sourceCode);
1229
1625
  if (!next)
1230
1626
  break;
1231
1627
  chain.push(next);
@@ -1235,33 +1631,93 @@ function traceAssignmentChain(receiver, assignmentGraph, provenancedSet) {
1235
1631
  return { found: false, chains: [], reason: '' };
1236
1632
  }
1237
1633
  /** Find the next assignment-graph identifier to trace, if any. */
1238
- function findNextTraceIdentifier(initText, assignmentGraph, visited) {
1239
- const idents = extractTopLevelIdentifiers(initText);
1634
+ function findNextTraceIdentifier(initNode, assignmentGraph, visited, adapter, sourceCode) {
1635
+ const idents = extractTopLevelIdentifiers(initNode, adapter, sourceCode);
1240
1636
  for (const ident of idents) {
1241
- if (assignmentGraph.has(ident) && !visited.has(ident)) {
1637
+ const nextNode = assignmentGraph.get(ident);
1638
+ if (nextNode && !visited.has(nextNode)) {
1242
1639
  return ident;
1243
1640
  }
1244
1641
  }
1245
1642
  return null;
1246
1643
  }
1247
1644
  /**
1248
- * Extract top-level identifier names from an expression text.
1249
- * E.g., "db.prepare(sql)" → ["db"], "getConnection()" → ["getConnection"]
1645
+ * Extract the top-level identifier name from an initializer-expression node.
1646
+ * Walks the node structurally to its root identifier — through `await`,
1647
+ * parentheses, calls, member access, and subscripts — so `await db.connect()`
1648
+ * yields `db` rather than `await`, and `(db.prepare(sql))` yields `db`.
1649
+ * E.g., `db.prepare(sql)` → ["db"], `getConnection()` → ["getConnection"].
1650
+ *
1651
+ * @param node the initializer-expression node to walk from
1652
+ * @param adapter the language adapter used to walk child nodes
1653
+ * @param sourceCode the file source text for reading node text
1654
+ * @returns the root identifier name, or an empty array when there is none
1655
+ */
1656
+ export function extractTopLevelIdentifiers(node, adapter, sourceCode) {
1657
+ const root = rootIdentifierNode(node, adapter);
1658
+ if (!root)
1659
+ return [];
1660
+ const name = adapter.getNodeText(root, sourceCode);
1661
+ return name ? [name] : [];
1662
+ }
1663
+ /**
1664
+ * The root identifier a value node resolves to, or null when the value is not a
1665
+ * bare identifier chain (e.g. a binary expression or literal). Descends through
1666
+ * `await_expression`, `parenthesized_expression`, `call_expression`/
1667
+ * `new_expression` (via their callee), `member_expression`/`selector_expression`
1668
+ * (via their receiver), and `subscript_expression` (via their object).
1250
1669
  */
1251
- function extractTopLevelIdentifiers(text) {
1252
- // Strip member access and arguments to get the root identifier
1253
- // Match the first identifier before any '.' or '('
1254
- const match = text.match(/^[\p{L}_$][\p{L}\p{N}_$]*/u);
1255
- if (match && match[0]) {
1256
- return [match[0]];
1670
+ function rootIdentifierNode(node, adapter) {
1671
+ let current = node;
1672
+ for (let depth = 0; depth < 64; depth++) {
1673
+ const t = adapter.getNodeType(current);
1674
+ if (t === 'identifier')
1675
+ return current;
1676
+ const children = adapter.getChildren(current) ?? [];
1677
+ let next = null;
1678
+ if (t === 'await_expression') {
1679
+ next = children.find((c) => adapter.getNodeType(c) !== 'await') ?? null;
1680
+ }
1681
+ else if (t === 'parenthesized_expression') {
1682
+ next = children.find((c) => {
1683
+ const ct = adapter.getNodeType(c);
1684
+ return ct !== '(' && ct !== ')';
1685
+ }) ?? null;
1686
+ }
1687
+ else if (t === 'call_expression' || t === 'new_expression') {
1688
+ next = getCallExpressionCallee(current, adapter);
1689
+ }
1690
+ else if (t === 'member_expression' || t === 'selector_expression') {
1691
+ next = children.find((c) => {
1692
+ const ct = adapter.getNodeType(c);
1693
+ return ct !== '.' && ct !== 'property_identifier' && ct !== 'field_identifier';
1694
+ }) ?? null;
1695
+ }
1696
+ else if (t === 'subscript_expression') {
1697
+ next = children.find((c) => {
1698
+ const ct = adapter.getNodeType(c);
1699
+ return ct !== '[' && ct !== ']';
1700
+ }) ?? null;
1701
+ }
1702
+ else {
1703
+ break;
1704
+ }
1705
+ if (!next)
1706
+ break;
1707
+ current = next;
1257
1708
  }
1258
- return [];
1709
+ return adapter.getNodeType(current) === 'identifier' ? current : null;
1259
1710
  }
1260
1711
  /**
1261
1712
  * Extract the property name from a member expression node.
1262
1713
  * For `db.prepare` → "prepare", for `db.sql.prepare` → "prepare"
1714
+ *
1715
+ * @param node the member/selector expression node
1716
+ * @param adapter the language adapter used to read children
1717
+ * @param sourceCode the file source text for reading node text
1718
+ * @returns the property identifier text, or `null`
1263
1719
  */
1264
- function extractMemberExpressionProperty(node, adapter, sourceCode) {
1720
+ export function extractMemberExpressionProperty(node, adapter, sourceCode) {
1265
1721
  const children = adapter.getChildren(node);
1266
1722
  // The property is the last non-dot child
1267
1723
  for (let i = children.length - 1; i >= 0; i--) {
@@ -1272,4 +1728,228 @@ function extractMemberExpressionProperty(node, adapter, sourceCode) {
1272
1728
  }
1273
1729
  return null;
1274
1730
  }
1731
+ // ═══════════════════════════════════════════════════════════════════════════
1732
+ // TS within-file-provenance split — the extract arm (Spec 70 Item 4 / Item 3)
1733
+ // ═══════════════════════════════════════════════════════════════════════════
1734
+ //
1735
+ // `extractTsWithinFileProvenance` projects everything `computeTsWithinFileProvenance`
1736
+ // reads from a single file's AST into a serializable `TsWithinFileProvenanceExtract`
1737
+ // (see tsExpressionDescriptor.ts). The classify arm re-runs the fixed point over the
1738
+ // projection with no AST. The two are pinned byte-identical by the parity spec.
1739
+ //
1740
+ // Every helper below is the *structural* half — provenance-free — so it may run at
1741
+ // extract time. The semantic half (which name resolves to which evidence) is
1742
+ // deferred to classify, where the provenance map is known.
1743
+ /** Project an `await` expression: the first non-`await` child carries the value. */
1744
+ function describeAwaitExpression(node, adapter, sourceCode) {
1745
+ for (const child of adapter.getChildren(node)) {
1746
+ if (child.type === 'await')
1747
+ continue;
1748
+ return { kind: 'await', operand: describeTsExpression(child, adapter, sourceCode) };
1749
+ }
1750
+ return { kind: 'await', operand: null };
1751
+ }
1752
+ /** Project a `new` expression: the leftmost identifier of its constructor. */
1753
+ function describeNewExpression(node, adapter, sourceCode) {
1754
+ const ctor = findChildOfType(node, ['identifier', 'member_expression']);
1755
+ return { kind: 'new', ctorName: ctor ? extractIdentifierName(ctor, adapter, sourceCode) : null };
1756
+ }
1757
+ /** Project a call expression: the callee (via `getCallExpressionCallee`) + its args. */
1758
+ function describeCallExpression(node, adapter, sourceCode) {
1759
+ const calleeNode = getCallExpressionCallee(node, adapter);
1760
+ const callee = calleeNode ? describeTsExpression(calleeNode, adapter, sourceCode) : null;
1761
+ const argsNode = adapter.getChildren(node).find((c) => c.type === 'arguments');
1762
+ const args = [];
1763
+ if (argsNode) {
1764
+ for (const arg of adapter.getChildren(argsNode)) {
1765
+ if (arg.type === '(' || arg.type === ')' || arg.type === ',')
1766
+ continue;
1767
+ args.push(describeTsExpression(arg, adapter, sourceCode));
1768
+ }
1769
+ }
1770
+ return { kind: 'call', callee, args };
1771
+ }
1772
+ /** Project a member expression: receiver (object) + property + full source text. */
1773
+ function describeMemberExpression(node, adapter, sourceCode) {
1774
+ const children = adapter.getChildren(node);
1775
+ const receiver = children[0] ? describeTsExpression(children[0], adapter, sourceCode) : null;
1776
+ let property = null;
1777
+ for (const child of children) {
1778
+ if (child.type === 'property_identifier' || child.type === 'field_identifier') {
1779
+ property = adapter.getNodeText(child, sourceCode);
1780
+ break;
1781
+ }
1782
+ }
1783
+ return { kind: 'member', receiver, property, text: adapter.getNodeText(node, sourceCode) };
1784
+ }
1785
+ /**
1786
+ * Project a value-expression node into a {@link TsExpressionDescriptor}. Mirrors
1787
+ * the *structural* dispatch of `tryPropagateFromExpression`: `await` → `new` →
1788
+ * `call` → `identifier` → `member`, and anything else collapses to `unproven`.
1789
+ */
1790
+ function describeTsExpression(node, adapter, sourceCode) {
1791
+ switch (node.type) {
1792
+ case 'await_expression':
1793
+ return describeAwaitExpression(node, adapter, sourceCode);
1794
+ case 'new_expression':
1795
+ return describeNewExpression(node, adapter, sourceCode);
1796
+ case 'call_expression':
1797
+ return describeCallExpression(node, adapter, sourceCode);
1798
+ case 'identifier':
1799
+ return { kind: 'identifier', name: adapter.getNodeText(node, sourceCode) };
1800
+ case 'member_expression':
1801
+ return describeMemberExpression(node, adapter, sourceCode);
1802
+ default:
1803
+ return { kind: 'unproven' };
1804
+ }
1805
+ }
1806
+ /** Child types excluded when locating a class-field initializer (mirrors `propagateClassField`). */
1807
+ const CLASS_FIELD_EXCLUDED = new Set([
1808
+ 'property_identifier',
1809
+ 'decorator',
1810
+ 'accessibility_modifier',
1811
+ 'private',
1812
+ 'public',
1813
+ 'protected',
1814
+ 'static',
1815
+ 'readonly',
1816
+ 'abstract',
1817
+ 'type_annotation',
1818
+ ]);
1819
+ /**
1820
+ * Project a single file's AST into the serializable {@link TsWithinFileProvenanceExtract}
1821
+ * that `classifyTsWithinFileProvenance` re-runs the provenance fixed point over.
1822
+ *
1823
+ * Everything here is provenance-free (structural reads of the AST + source text),
1824
+ * so it can run once at parse time and be carried as a file fact. The semantic
1825
+ * resolution — which name a value resolves to under the current provenance map —
1826
+ * is deferred to the classify arm.
1827
+ * @param ast - The file's parsed AST.
1828
+ * @param adapter - The language adapter (drives the walk + node-text reads).
1829
+ * @param sourceCode - The file's source text (for structural reads).
1830
+ * @returns The provenance-free `TsWithinFileProvenanceExtract` projection.
1831
+ */
1832
+ export function extractTsWithinFileProvenance(ast, adapter, sourceCode) {
1833
+ const seeds = extractDBProvenancedImports(ast, adapter);
1834
+ const localFunctions = collectLocalFunctionNames(ast, adapter, sourceCode);
1835
+ const bindings = buildBindingEnv(ast, adapter, sourceCode);
1836
+ const interfaceFields = extractInterfaceFields(ast, adapter, sourceCode);
1837
+ // ── Propagation rules, in `walkAST` pre-order ─────────────────────────────
1838
+ const propagationRules = [];
1839
+ walkAST(ast.root, (node, parent) => {
1840
+ if (node.type === 'variable_declarator') {
1841
+ const { nameNode, valueNode } = splitVariableDeclarator(node, adapter);
1842
+ if (!nameNode)
1843
+ return;
1844
+ const names = extractPatternNames(nameNode, adapter, sourceCode);
1845
+ const value = valueNode ? describeTsExpression(valueNode, adapter, sourceCode) : null;
1846
+ propagationRules.push({ kind: 'variable-declarator', names, value });
1847
+ return;
1848
+ }
1849
+ if (node.type === 'assignment_pattern' && parent?.type === 'formal_parameters') {
1850
+ const children = adapter.getChildren(node);
1851
+ if (children.length < 2 || children[0].type !== 'identifier')
1852
+ return;
1853
+ propagationRules.push({
1854
+ kind: 'default-parameter',
1855
+ name: adapter.getNodeText(children[0], sourceCode),
1856
+ value: describeTsExpression(children[1], adapter, sourceCode),
1857
+ });
1858
+ return;
1859
+ }
1860
+ if (node.type === 'public_field_definition') {
1861
+ const children = adapter.getChildren(node);
1862
+ const nameChild = children.find((c) => c.type === 'property_identifier');
1863
+ if (!nameChild)
1864
+ return;
1865
+ const valueChild = children.find((c) => !CLASS_FIELD_EXCLUDED.has(c.type));
1866
+ if (!valueChild)
1867
+ return;
1868
+ propagationRules.push({
1869
+ kind: 'class-field',
1870
+ field: adapter.getNodeText(nameChild, sourceCode),
1871
+ value: describeTsExpression(valueChild, adapter, sourceCode),
1872
+ });
1873
+ return;
1874
+ }
1875
+ if (node.type === 'assignment_expression') {
1876
+ const children = adapter.getChildren(node);
1877
+ const lhs = children.find((c) => c.type === 'member_expression' || c.type === 'selector_expression');
1878
+ if (!lhs)
1879
+ return;
1880
+ const lhsChildren = adapter.getChildren(lhs);
1881
+ const obj = lhsChildren.find((c) => c.type === 'this' || c.type === 'super');
1882
+ if (!obj)
1883
+ return;
1884
+ const prop = lhsChildren.find((c) => c.type === 'property_identifier' || c.type === 'field_identifier');
1885
+ if (!prop)
1886
+ return;
1887
+ const fieldName = adapter.getNodeText(prop, sourceCode);
1888
+ if (!fieldName)
1889
+ return;
1890
+ const rhs = children[children.length - 1];
1891
+ if (!rhs || rhs.type === 'member_expression' || rhs.type === 'selector_expression')
1892
+ return;
1893
+ propagationRules.push({
1894
+ kind: 'member-assignment',
1895
+ field: fieldName,
1896
+ value: describeTsExpression(rhs, adapter, sourceCode),
1897
+ });
1898
+ return;
1899
+ }
1900
+ });
1901
+ // ── Wrapper functions, wrapper classes, returning functions ────────────────
1902
+ // One `findNodes` pass for functions (wrappers + returning) and one for classes,
1903
+ // matching the order `detectDbWrappers` / `detectDbReturningFunctions` consume.
1904
+ const wrapperFunctions = [];
1905
+ const returningFunctions = [];
1906
+ const functionNodes = adapter.findNodes(ast, {
1907
+ custom: (n) => FUNCTION_NODE_TYPES.has(n.type),
1908
+ });
1909
+ for (const fn of functionNodes) {
1910
+ const name = adapter.getNodeName(fn);
1911
+ if (!name)
1912
+ continue;
1913
+ const ownCalls = collectOwnCallExpressions(fn, adapter).map((call) => ({
1914
+ callee: getCallExpressionCallee(call, adapter)
1915
+ ? describeTsExpression(getCallExpressionCallee(call, adapter), adapter, sourceCode)
1916
+ : null,
1917
+ isD1Rest: isD1RestCall(call, adapter, sourceCode),
1918
+ }));
1919
+ wrapperFunctions.push({ name, ownCalls });
1920
+ const returnExprs = [];
1921
+ walkAST(fn, (n) => {
1922
+ if (n.type !== 'return_statement')
1923
+ return;
1924
+ const arg = adapter.getChildren(n).find((c) => c.type !== 'return');
1925
+ if (!arg)
1926
+ return;
1927
+ returnExprs.push(describeTsExpression(arg, adapter, sourceCode));
1928
+ });
1929
+ returningFunctions.push({ name, returnExprs });
1930
+ }
1931
+ const wrapperClasses = [];
1932
+ const classNodes = adapter.findNodes(ast, {
1933
+ custom: (n) => WRAPPER_CLASS_TYPES.has(n.type),
1934
+ });
1935
+ for (const cls of classNodes) {
1936
+ const name = adapter.getNodeName(cls);
1937
+ if (!name)
1938
+ continue;
1939
+ const classCalls = collectClassCallExpressions(cls, adapter).map((expr) => {
1940
+ if (expr.type === 'new_expression') {
1941
+ const ctor = findChildOfType(expr, ['identifier', 'member_expression']);
1942
+ return { kind: 'new', ctorName: ctor ? extractIdentifierName(ctor, adapter, sourceCode) : null };
1943
+ }
1944
+ const calleeNode = getCallExpressionCallee(expr, adapter);
1945
+ return {
1946
+ kind: 'call',
1947
+ callee: calleeNode ? describeTsExpression(calleeNode, adapter, sourceCode) : null,
1948
+ isD1Rest: isD1RestCall(expr, adapter, sourceCode),
1949
+ };
1950
+ });
1951
+ wrapperClasses.push({ name, classCalls });
1952
+ }
1953
+ return { seeds, bindings, localFunctions, propagationRules, wrapperFunctions, wrapperClasses, returningFunctions, interfaceFields };
1954
+ }
1275
1955
  //# sourceMappingURL=provenance.js.map