@backthread/extractor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/cluster/domain-grouping.d.ts +113 -0
  4. package/dist/cluster/domain-grouping.d.ts.map +1 -0
  5. package/dist/cluster/domain-grouping.js +277 -0
  6. package/dist/cluster/domain-grouping.js.map +1 -0
  7. package/dist/cluster/grouping-gate.d.ts +54 -0
  8. package/dist/cluster/grouping-gate.d.ts.map +1 -0
  9. package/dist/cluster/grouping-gate.js +0 -0
  10. package/dist/cluster/grouping-gate.js.map +1 -0
  11. package/dist/cluster/louvain.d.ts +88 -0
  12. package/dist/cluster/louvain.d.ts.map +1 -0
  13. package/dist/cluster/louvain.js +674 -0
  14. package/dist/cluster/louvain.js.map +1 -0
  15. package/dist/cluster/overrides.d.ts +19 -0
  16. package/dist/cluster/overrides.d.ts.map +1 -0
  17. package/dist/cluster/overrides.js +32 -0
  18. package/dist/cluster/overrides.js.map +1 -0
  19. package/dist/cluster/subsystem.d.ts +45 -0
  20. package/dist/cluster/subsystem.d.ts.map +1 -0
  21. package/dist/cluster/subsystem.js +299 -0
  22. package/dist/cluster/subsystem.js.map +1 -0
  23. package/dist/cluster/workspaces.d.ts +64 -0
  24. package/dist/cluster/workspaces.d.ts.map +1 -0
  25. package/dist/cluster/workspaces.js +739 -0
  26. package/dist/cluster/workspaces.js.map +1 -0
  27. package/dist/extract.d.ts +52 -0
  28. package/dist/extract.d.ts.map +1 -0
  29. package/dist/extract.js +48 -0
  30. package/dist/extract.js.map +1 -0
  31. package/dist/framework/celery/celery.d.ts +17 -0
  32. package/dist/framework/celery/celery.d.ts.map +1 -0
  33. package/dist/framework/celery/celery.js +524 -0
  34. package/dist/framework/celery/celery.js.map +1 -0
  35. package/dist/framework/contribute-step.d.ts +38 -0
  36. package/dist/framework/contribute-step.d.ts.map +1 -0
  37. package/dist/framework/contribute-step.js +403 -0
  38. package/dist/framework/contribute-step.js.map +1 -0
  39. package/dist/framework/detect-step.d.ts +8 -0
  40. package/dist/framework/detect-step.d.ts.map +1 -0
  41. package/dist/framework/detect-step.js +54 -0
  42. package/dist/framework/detect-step.js.map +1 -0
  43. package/dist/framework/detect-util.d.ts +24 -0
  44. package/dist/framework/detect-util.d.ts.map +1 -0
  45. package/dist/framework/detect-util.js +59 -0
  46. package/dist/framework/detect-util.js.map +1 -0
  47. package/dist/framework/django/django.d.ts +22 -0
  48. package/dist/framework/django/django.d.ts.map +1 -0
  49. package/dist/framework/django/django.js +940 -0
  50. package/dist/framework/django/django.js.map +1 -0
  51. package/dist/framework/fastapi/fastapi.d.ts +27 -0
  52. package/dist/framework/fastapi/fastapi.d.ts.map +1 -0
  53. package/dist/framework/fastapi/fastapi.js +477 -0
  54. package/dist/framework/fastapi/fastapi.js.map +1 -0
  55. package/dist/framework/faststream/faststream.d.ts +19 -0
  56. package/dist/framework/faststream/faststream.d.ts.map +1 -0
  57. package/dist/framework/faststream/faststream.js +765 -0
  58. package/dist/framework/faststream/faststream.js.map +1 -0
  59. package/dist/framework/flask/flask.d.ts +17 -0
  60. package/dist/framework/flask/flask.d.ts.map +1 -0
  61. package/dist/framework/flask/flask.js +507 -0
  62. package/dist/framework/flask/flask.js.map +1 -0
  63. package/dist/framework/graphql/graphql.d.ts +17 -0
  64. package/dist/framework/graphql/graphql.d.ts.map +1 -0
  65. package/dist/framework/graphql/graphql.js +708 -0
  66. package/dist/framework/graphql/graphql.js.map +1 -0
  67. package/dist/framework/grpc/grpc.d.ts +22 -0
  68. package/dist/framework/grpc/grpc.d.ts.map +1 -0
  69. package/dist/framework/grpc/grpc.js +618 -0
  70. package/dist/framework/grpc/grpc.js.map +1 -0
  71. package/dist/framework/litestar/litestar.d.ts +17 -0
  72. package/dist/framework/litestar/litestar.d.ts.map +1 -0
  73. package/dist/framework/litestar/litestar.js +536 -0
  74. package/dist/framework/litestar/litestar.js.map +1 -0
  75. package/dist/framework/nest/nest.d.ts +19 -0
  76. package/dist/framework/nest/nest.d.ts.map +1 -0
  77. package/dist/framework/nest/nest.js +613 -0
  78. package/dist/framework/nest/nest.js.map +1 -0
  79. package/dist/framework/next/next.d.ts +22 -0
  80. package/dist/framework/next/next.d.ts.map +1 -0
  81. package/dist/framework/next/next.js +449 -0
  82. package/dist/framework/next/next.js.map +1 -0
  83. package/dist/framework/node/node.d.ts +24 -0
  84. package/dist/framework/node/node.d.ts.map +1 -0
  85. package/dist/framework/node/node.js +1009 -0
  86. package/dist/framework/node/node.js.map +1 -0
  87. package/dist/framework/orchestrator/orchestrator.d.ts +34 -0
  88. package/dist/framework/orchestrator/orchestrator.d.ts.map +1 -0
  89. package/dist/framework/orchestrator/orchestrator.js +691 -0
  90. package/dist/framework/orchestrator/orchestrator.js.map +1 -0
  91. package/dist/framework/orm/orm.d.ts +61 -0
  92. package/dist/framework/orm/orm.d.ts.map +1 -0
  93. package/dist/framework/orm/orm.js +620 -0
  94. package/dist/framework/orm/orm.js.map +1 -0
  95. package/dist/framework/python/analyze.d.ts +38 -0
  96. package/dist/framework/python/analyze.d.ts.map +1 -0
  97. package/dist/framework/python/analyze.js +98 -0
  98. package/dist/framework/python/analyze.js.map +1 -0
  99. package/dist/framework/python/py-ast.d.ts +130 -0
  100. package/dist/framework/python/py-ast.d.ts.map +1 -0
  101. package/dist/framework/python/py-ast.js +344 -0
  102. package/dist/framework/python/py-ast.js.map +1 -0
  103. package/dist/framework/python-orm/python-orm.d.ts +19 -0
  104. package/dist/framework/python-orm/python-orm.d.ts.map +1 -0
  105. package/dist/framework/python-orm/python-orm.js +516 -0
  106. package/dist/framework/python-orm/python-orm.js.map +1 -0
  107. package/dist/framework/react-native/react-native.d.ts +35 -0
  108. package/dist/framework/react-native/react-native.d.ts.map +1 -0
  109. package/dist/framework/react-native/react-native.js +1181 -0
  110. package/dist/framework/react-native/react-native.js.map +1 -0
  111. package/dist/framework/register.d.ts +2 -0
  112. package/dist/framework/register.d.ts.map +1 -0
  113. package/dist/framework/register.js +59 -0
  114. package/dist/framework/register.js.map +1 -0
  115. package/dist/framework/registry.d.ts +31 -0
  116. package/dist/framework/registry.d.ts.map +1 -0
  117. package/dist/framework/registry.js +70 -0
  118. package/dist/framework/registry.js.map +1 -0
  119. package/dist/framework/routing/expo-router.d.ts +31 -0
  120. package/dist/framework/routing/expo-router.d.ts.map +1 -0
  121. package/dist/framework/routing/expo-router.js +356 -0
  122. package/dist/framework/routing/expo-router.js.map +1 -0
  123. package/dist/framework/routing/index.d.ts +4 -0
  124. package/dist/framework/routing/index.d.ts.map +1 -0
  125. package/dist/framework/routing/index.js +16 -0
  126. package/dist/framework/routing/index.js.map +1 -0
  127. package/dist/framework/routing/next-router.d.ts +45 -0
  128. package/dist/framework/routing/next-router.d.ts.map +1 -0
  129. package/dist/framework/routing/next-router.js +378 -0
  130. package/dist/framework/routing/next-router.js.map +1 -0
  131. package/dist/framework/routing/route-tree.d.ts +73 -0
  132. package/dist/framework/routing/route-tree.d.ts.map +1 -0
  133. package/dist/framework/routing/route-tree.js +120 -0
  134. package/dist/framework/routing/route-tree.js.map +1 -0
  135. package/dist/framework/types.d.ts +230 -0
  136. package/dist/framework/types.d.ts.map +1 -0
  137. package/dist/framework/types.js +25 -0
  138. package/dist/framework/types.js.map +1 -0
  139. package/dist/graph/cross-language.d.ts +11 -0
  140. package/dist/graph/cross-language.d.ts.map +1 -0
  141. package/dist/graph/cross-language.js +123 -0
  142. package/dist/graph/cross-language.js.map +1 -0
  143. package/dist/graph/extract.d.ts +13 -0
  144. package/dist/graph/extract.d.ts.map +1 -0
  145. package/dist/graph/extract.js +79 -0
  146. package/dist/graph/extract.js.map +1 -0
  147. package/dist/graph/file-graph.d.ts +186 -0
  148. package/dist/graph/file-graph.d.ts.map +1 -0
  149. package/dist/graph/file-graph.js +427 -0
  150. package/dist/graph/file-graph.js.map +1 -0
  151. package/dist/graph/http-callsites.d.ts +14 -0
  152. package/dist/graph/http-callsites.d.ts.map +1 -0
  153. package/dist/graph/http-callsites.js +107 -0
  154. package/dist/graph/http-callsites.js.map +1 -0
  155. package/dist/graph/incremental.d.ts +122 -0
  156. package/dist/graph/incremental.d.ts.map +1 -0
  157. package/dist/graph/incremental.js +448 -0
  158. package/dist/graph/incremental.js.map +1 -0
  159. package/dist/graph/language.d.ts +31 -0
  160. package/dist/graph/language.d.ts.map +1 -0
  161. package/dist/graph/language.js +146 -0
  162. package/dist/graph/language.js.map +1 -0
  163. package/dist/graph/noise-filter.d.ts +46 -0
  164. package/dist/graph/noise-filter.d.ts.map +1 -0
  165. package/dist/graph/noise-filter.js +199 -0
  166. package/dist/graph/noise-filter.js.map +1 -0
  167. package/dist/graph/python-adapter.d.ts +36 -0
  168. package/dist/graph/python-adapter.d.ts.map +1 -0
  169. package/dist/graph/python-adapter.js +402 -0
  170. package/dist/graph/python-adapter.js.map +1 -0
  171. package/dist/graph/python-manifest.d.ts +22 -0
  172. package/dist/graph/python-manifest.d.ts.map +1 -0
  173. package/dist/graph/python-manifest.js +137 -0
  174. package/dist/graph/python-manifest.js.map +1 -0
  175. package/dist/graph/python-stdlib.d.ts +2 -0
  176. package/dist/graph/python-stdlib.d.ts.map +1 -0
  177. package/dist/graph/python-stdlib.js +53 -0
  178. package/dist/graph/python-stdlib.js.map +1 -0
  179. package/dist/graph/ts-morph-adapter.d.ts +65 -0
  180. package/dist/graph/ts-morph-adapter.d.ts.map +1 -0
  181. package/dist/graph/ts-morph-adapter.js +265 -0
  182. package/dist/graph/ts-morph-adapter.js.map +1 -0
  183. package/dist/graph/types.d.ts +37 -0
  184. package/dist/graph/types.d.ts.map +1 -0
  185. package/dist/graph/types.js +50 -0
  186. package/dist/graph/types.js.map +1 -0
  187. package/dist/index.d.ts +45 -0
  188. package/dist/index.d.ts.map +1 -0
  189. package/dist/index.js +51 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/infra/aws/aws-parse.d.ts +39 -0
  192. package/dist/infra/aws/aws-parse.d.ts.map +1 -0
  193. package/dist/infra/aws/aws-parse.js +149 -0
  194. package/dist/infra/aws/aws-parse.js.map +1 -0
  195. package/dist/infra/aws/aws.d.ts +6 -0
  196. package/dist/infra/aws/aws.d.ts.map +1 -0
  197. package/dist/infra/aws/aws.js +425 -0
  198. package/dist/infra/aws/aws.js.map +1 -0
  199. package/dist/infra/azure/azure-parse.d.ts +73 -0
  200. package/dist/infra/azure/azure-parse.d.ts.map +1 -0
  201. package/dist/infra/azure/azure-parse.js +178 -0
  202. package/dist/infra/azure/azure-parse.js.map +1 -0
  203. package/dist/infra/azure/azure.d.ts +12 -0
  204. package/dist/infra/azure/azure.d.ts.map +1 -0
  205. package/dist/infra/azure/azure.js +673 -0
  206. package/dist/infra/azure/azure.js.map +1 -0
  207. package/dist/infra/cloudflare/cloudflare.d.ts +50 -0
  208. package/dist/infra/cloudflare/cloudflare.d.ts.map +1 -0
  209. package/dist/infra/cloudflare/cloudflare.js +382 -0
  210. package/dist/infra/cloudflare/cloudflare.js.map +1 -0
  211. package/dist/infra/cloudflare/wrangler-parse.d.ts +6 -0
  212. package/dist/infra/cloudflare/wrangler-parse.d.ts.map +1 -0
  213. package/dist/infra/cloudflare/wrangler-parse.js +278 -0
  214. package/dist/infra/cloudflare/wrangler-parse.js.map +1 -0
  215. package/dist/infra/compose/compose-parse.d.ts +24 -0
  216. package/dist/infra/compose/compose-parse.d.ts.map +1 -0
  217. package/dist/infra/compose/compose-parse.js +77 -0
  218. package/dist/infra/compose/compose-parse.js.map +1 -0
  219. package/dist/infra/compose/compose.d.ts +12 -0
  220. package/dist/infra/compose/compose.d.ts.map +1 -0
  221. package/dist/infra/compose/compose.js +201 -0
  222. package/dist/infra/compose/compose.js.map +1 -0
  223. package/dist/infra/convex/convex-parse.d.ts +28 -0
  224. package/dist/infra/convex/convex-parse.d.ts.map +1 -0
  225. package/dist/infra/convex/convex-parse.js +74 -0
  226. package/dist/infra/convex/convex-parse.js.map +1 -0
  227. package/dist/infra/convex/convex.d.ts +18 -0
  228. package/dist/infra/convex/convex.d.ts.map +1 -0
  229. package/dist/infra/convex/convex.js +199 -0
  230. package/dist/infra/convex/convex.js.map +1 -0
  231. package/dist/infra/digitalocean/digitalocean.d.ts +33 -0
  232. package/dist/infra/digitalocean/digitalocean.d.ts.map +1 -0
  233. package/dist/infra/digitalocean/digitalocean.js +204 -0
  234. package/dist/infra/digitalocean/digitalocean.js.map +1 -0
  235. package/dist/infra/firebase/firebase.d.ts +43 -0
  236. package/dist/infra/firebase/firebase.d.ts.map +1 -0
  237. package/dist/infra/firebase/firebase.js +271 -0
  238. package/dist/infra/firebase/firebase.js.map +1 -0
  239. package/dist/infra/fly/fly-parse.d.ts +52 -0
  240. package/dist/infra/fly/fly-parse.d.ts.map +1 -0
  241. package/dist/infra/fly/fly-parse.js +114 -0
  242. package/dist/infra/fly/fly-parse.js.map +1 -0
  243. package/dist/infra/fly/fly.d.ts +15 -0
  244. package/dist/infra/fly/fly.d.ts.map +1 -0
  245. package/dist/infra/fly/fly.js +265 -0
  246. package/dist/infra/fly/fly.js.map +1 -0
  247. package/dist/infra/gcp/gcp-parse.d.ts +24 -0
  248. package/dist/infra/gcp/gcp-parse.d.ts.map +1 -0
  249. package/dist/infra/gcp/gcp-parse.js +123 -0
  250. package/dist/infra/gcp/gcp-parse.js.map +1 -0
  251. package/dist/infra/gcp/gcp.d.ts +10 -0
  252. package/dist/infra/gcp/gcp.d.ts.map +1 -0
  253. package/dist/infra/gcp/gcp.js +502 -0
  254. package/dist/infra/gcp/gcp.js.map +1 -0
  255. package/dist/infra/heroku/heroku-parse.d.ts +33 -0
  256. package/dist/infra/heroku/heroku-parse.d.ts.map +1 -0
  257. package/dist/infra/heroku/heroku-parse.js +63 -0
  258. package/dist/infra/heroku/heroku-parse.js.map +1 -0
  259. package/dist/infra/heroku/heroku.d.ts +24 -0
  260. package/dist/infra/heroku/heroku.d.ts.map +1 -0
  261. package/dist/infra/heroku/heroku.js +253 -0
  262. package/dist/infra/heroku/heroku.js.map +1 -0
  263. package/dist/infra/image-resolve.d.ts +56 -0
  264. package/dist/infra/image-resolve.d.ts.map +1 -0
  265. package/dist/infra/image-resolve.js +229 -0
  266. package/dist/infra/image-resolve.js.map +1 -0
  267. package/dist/infra/infra-step.d.ts +39 -0
  268. package/dist/infra/infra-step.d.ts.map +1 -0
  269. package/dist/infra/infra-step.js +57 -0
  270. package/dist/infra/infra-step.js.map +1 -0
  271. package/dist/infra/k8s/index.d.ts +78 -0
  272. package/dist/infra/k8s/index.d.ts.map +1 -0
  273. package/dist/infra/k8s/index.js +251 -0
  274. package/dist/infra/k8s/index.js.map +1 -0
  275. package/dist/infra/kamal/kamal-parse.d.ts +23 -0
  276. package/dist/infra/kamal/kamal-parse.d.ts.map +1 -0
  277. package/dist/infra/kamal/kamal-parse.js +66 -0
  278. package/dist/infra/kamal/kamal-parse.js.map +1 -0
  279. package/dist/infra/kamal/kamal.d.ts +17 -0
  280. package/dist/infra/kamal/kamal.d.ts.map +1 -0
  281. package/dist/infra/kamal/kamal.js +162 -0
  282. package/dist/infra/kamal/kamal.js.map +1 -0
  283. package/dist/infra/netlify/netlify.d.ts +33 -0
  284. package/dist/infra/netlify/netlify.d.ts.map +1 -0
  285. package/dist/infra/netlify/netlify.js +247 -0
  286. package/dist/infra/netlify/netlify.js.map +1 -0
  287. package/dist/infra/opentofu/opentofu.d.ts +3 -0
  288. package/dist/infra/opentofu/opentofu.d.ts.map +1 -0
  289. package/dist/infra/opentofu/opentofu.js +157 -0
  290. package/dist/infra/opentofu/opentofu.js.map +1 -0
  291. package/dist/infra/pulumi/pulumi-parse.d.ts +60 -0
  292. package/dist/infra/pulumi/pulumi-parse.d.ts.map +1 -0
  293. package/dist/infra/pulumi/pulumi-parse.js +155 -0
  294. package/dist/infra/pulumi/pulumi-parse.js.map +1 -0
  295. package/dist/infra/pulumi/pulumi.d.ts +23 -0
  296. package/dist/infra/pulumi/pulumi.d.ts.map +1 -0
  297. package/dist/infra/pulumi/pulumi.js +260 -0
  298. package/dist/infra/pulumi/pulumi.js.map +1 -0
  299. package/dist/infra/railway/railway-parse.d.ts +54 -0
  300. package/dist/infra/railway/railway-parse.d.ts.map +1 -0
  301. package/dist/infra/railway/railway-parse.js +200 -0
  302. package/dist/infra/railway/railway-parse.js.map +1 -0
  303. package/dist/infra/railway/railway.d.ts +19 -0
  304. package/dist/infra/railway/railway.d.ts.map +1 -0
  305. package/dist/infra/railway/railway.js +397 -0
  306. package/dist/infra/railway/railway.js.map +1 -0
  307. package/dist/infra/register.d.ts +2 -0
  308. package/dist/infra/register.d.ts.map +1 -0
  309. package/dist/infra/register.js +81 -0
  310. package/dist/infra/register.js.map +1 -0
  311. package/dist/infra/registry.d.ts +64 -0
  312. package/dist/infra/registry.d.ts.map +1 -0
  313. package/dist/infra/registry.js +205 -0
  314. package/dist/infra/registry.js.map +1 -0
  315. package/dist/infra/relevance.d.ts +16 -0
  316. package/dist/infra/relevance.d.ts.map +1 -0
  317. package/dist/infra/relevance.js +132 -0
  318. package/dist/infra/relevance.js.map +1 -0
  319. package/dist/infra/render/render-parse.d.ts +76 -0
  320. package/dist/infra/render/render-parse.d.ts.map +1 -0
  321. package/dist/infra/render/render-parse.js +155 -0
  322. package/dist/infra/render/render-parse.js.map +1 -0
  323. package/dist/infra/render/render.d.ts +11 -0
  324. package/dist/infra/render/render.d.ts.map +1 -0
  325. package/dist/infra/render/render.js +303 -0
  326. package/dist/infra/render/render.js.map +1 -0
  327. package/dist/infra/sst/sst-parse.d.ts +25 -0
  328. package/dist/infra/sst/sst-parse.d.ts.map +1 -0
  329. package/dist/infra/sst/sst-parse.js +45 -0
  330. package/dist/infra/sst/sst-parse.js.map +1 -0
  331. package/dist/infra/sst/sst.d.ts +19 -0
  332. package/dist/infra/sst/sst.d.ts.map +1 -0
  333. package/dist/infra/sst/sst.js +236 -0
  334. package/dist/infra/sst/sst.js.map +1 -0
  335. package/dist/infra/supabase/supabase-parse.d.ts +34 -0
  336. package/dist/infra/supabase/supabase-parse.d.ts.map +1 -0
  337. package/dist/infra/supabase/supabase-parse.js +113 -0
  338. package/dist/infra/supabase/supabase-parse.js.map +1 -0
  339. package/dist/infra/supabase/supabase.d.ts +15 -0
  340. package/dist/infra/supabase/supabase.d.ts.map +1 -0
  341. package/dist/infra/supabase/supabase.js +198 -0
  342. package/dist/infra/supabase/supabase.js.map +1 -0
  343. package/dist/infra/terraform/hcl-parse.d.ts +34 -0
  344. package/dist/infra/terraform/hcl-parse.d.ts.map +1 -0
  345. package/dist/infra/terraform/hcl-parse.js +203 -0
  346. package/dist/infra/terraform/hcl-parse.js.map +1 -0
  347. package/dist/infra/terraform/terraform.d.ts +14 -0
  348. package/dist/infra/terraform/terraform.d.ts.map +1 -0
  349. package/dist/infra/terraform/terraform.js +264 -0
  350. package/dist/infra/terraform/terraform.js.map +1 -0
  351. package/dist/infra/types.d.ts +151 -0
  352. package/dist/infra/types.d.ts.map +1 -0
  353. package/dist/infra/types.js +14 -0
  354. package/dist/infra/types.js.map +1 -0
  355. package/dist/infra/vercel/vercel-parse.d.ts +70 -0
  356. package/dist/infra/vercel/vercel-parse.d.ts.map +1 -0
  357. package/dist/infra/vercel/vercel-parse.js +194 -0
  358. package/dist/infra/vercel/vercel-parse.js.map +1 -0
  359. package/dist/infra/vercel/vercel.d.ts +30 -0
  360. package/dist/infra/vercel/vercel.d.ts.map +1 -0
  361. package/dist/infra/vercel/vercel.js +523 -0
  362. package/dist/infra/vercel/vercel.js.map +1 -0
  363. package/dist/infra/walk.d.ts +36 -0
  364. package/dist/infra/walk.d.ts.map +1 -0
  365. package/dist/infra/walk.js +85 -0
  366. package/dist/infra/walk.js.map +1 -0
  367. package/dist/safety.d.ts +13 -0
  368. package/dist/safety.d.ts.map +1 -0
  369. package/dist/safety.js +67 -0
  370. package/dist/safety.js.map +1 -0
  371. package/dist/types.d.ts +47 -0
  372. package/dist/types.d.ts.map +1 -0
  373. package/dist/types.js +111 -0
  374. package/dist/types.js.map +1 -0
  375. package/dist/version.d.ts +2 -0
  376. package/dist/version.d.ts.map +1 -0
  377. package/dist/version.js +35 -0
  378. package/dist/version.js.map +1 -0
  379. package/package.json +65 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export interface CfnResource {
2
+ /** CloudFormation logical ID (the map key under `Resources:`). */
3
+ logicalId: string;
4
+ /** AWS resource type, e.g. `AWS::Lambda::Function`. */
5
+ type: string;
6
+ /**
7
+ * Raw text representation of this resource's block — used for reference
8
+ * scanning. We JSON-serialize the parsed JS value so tag quirks (which may
9
+ * leave some values as strings like "!Ref Foo") are preserved as-is and
10
+ * still searchable.
11
+ */
12
+ rawText: string;
13
+ /**
14
+ * Source discriminator: 'cfn' for resources from CloudFormation/SAM
15
+ * Resources blocks; 'serverless-fn' for synthetic Lambda nodes synthesized
16
+ * from a Serverless Framework `functions:` block. Used by aws.ts to
17
+ * namespace node IDs and avoid collisions between the two flat namespaces.
18
+ */
19
+ source: 'cfn' | 'serverless-fn';
20
+ /**
21
+ * repo-relative dir of the template/serverless file this resource came
22
+ * from ('' = repo root). parseCfnTemplate/parseServerlessConfig don't set it
23
+ * (they parse one text blob); aws.ts's extract() stamps it per file so a SAM
24
+ * `CodeUri` resolves against the template dir. Optional for back-compat.
25
+ */
26
+ dir?: string;
27
+ }
28
+ /**
29
+ * Parse a CloudFormation or SAM template from text (YAML or JSON).
30
+ * Returns [] (never throws) on any parse failure — callers skip-and-warn.
31
+ */
32
+ export declare function parseCfnTemplate(text: string): CfnResource[];
33
+ export declare function parseServerlessConfig(text: string): CfnResource[];
34
+ /** Returns true if the text looks like a CloudFormation template.
35
+ * Accepts both YAML (`AWSTemplateFormatVersion: '...'`, `Transform: AWS::Serverless`)
36
+ * and JSON (`"AWSTemplateFormatVersion"`, `"Transform": "AWS::Serverless-2016-10-31"`).
37
+ */
38
+ export declare function isCfnTemplate(text: string): boolean;
39
+ //# sourceMappingURL=aws-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-parse.d.ts","sourceRoot":"","sources":["../../../src/infra/aws/aws-parse.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,EAAE,KAAK,GAAG,eAAe,CAAC;IAChC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4CD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAY5D;AAsBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAmCjE;AAKD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
@@ -0,0 +1,149 @@
1
+ // AWS-native cluster adapter: CloudFormation/SAM/serverless.yml parser.
2
+ //
3
+ // Parses CloudFormation (YAML/JSON), SAM templates, synthesized CDK templates
4
+ // (cdk.out/*.template.json — which ARE just CFN JSON), and Serverless Framework
5
+ // (serverless.yml) into a flat list of { logicalId, type, rawText } records.
6
+ //
7
+ // CloudFormation YAML CAVEAT: CFN templates use YAML intrinsic short-form tags
8
+ // (!Ref, !GetAtt, !Sub, !Join, !Select, !If, !Equals, etc.). The `yaml`
9
+ // package v2 handles unknown tags gracefully when `logLevel: 'silent'` is set:
10
+ // scalar-tagged nodes resolve to their raw scalar value string, so
11
+ // `!Ref OrdersTable` → the string `"OrdersTable"` and
12
+ // `!GetAtt AssetsBucket.Arn` → the string `"AssetsBucket.Arn"`.
13
+ // This is exactly what we need: the logicalId appears in the JSON-serialized
14
+ // rawText as a quoted string value (or as a prefix of "Id.Attr" for GetAtt),
15
+ // enabling correct reference detection. Registering custom tags that return
16
+ // empty strings would ERASE the reference information we need, so we use
17
+ // logLevel:'silent' only.
18
+ //
19
+ // v0 scope: implemented here — CFN YAML/JSON, SAM, serverless.yml, cdk.out.
20
+ // DEFERRED: raw ECS task-def JSON (no declarative resource map), Elastic
21
+ // Beanstalk .elasticbeanstalk/config.yml (deployment config, not topology),
22
+ // CDK TypeScript source (synthesized cdk.out is handled as CFN JSON).
23
+ import { parse as parseYaml } from 'yaml';
24
+ // ---------------------------------------------------------------------------
25
+ // Internal helpers.
26
+ function tryParseYaml(text) {
27
+ // Use logLevel:'silent' — yaml v2 resolves unknown tags (!Ref, !GetAtt, etc.)
28
+ // to their scalar string value instead of throwing. This preserves the
29
+ // logicalId references we need for edge detection in rawText.
30
+ try {
31
+ return parseYaml(text, { logLevel: 'silent' });
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ /** Extract CfnResource[] from a parsed CloudFormation/SAM template object. */
38
+ function extractFromCfnObject(obj) {
39
+ if (!obj || typeof obj !== 'object')
40
+ return [];
41
+ const top = obj;
42
+ const resources = top['Resources'];
43
+ if (!resources || typeof resources !== 'object')
44
+ return [];
45
+ const map = resources;
46
+ const out = [];
47
+ for (const [logicalId, entry] of Object.entries(map)) {
48
+ if (!entry || typeof entry !== 'object')
49
+ continue;
50
+ const e = entry;
51
+ const type = typeof e['Type'] === 'string' ? e['Type'] : undefined;
52
+ if (!type)
53
+ continue;
54
+ // Serialize the whole resource block as the raw text for reference scanning.
55
+ let rawText;
56
+ try {
57
+ rawText = JSON.stringify(e);
58
+ }
59
+ catch {
60
+ rawText = String(e);
61
+ }
62
+ out.push({ logicalId, type, rawText, source: 'cfn' });
63
+ }
64
+ return out;
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Public: parse a CFN/SAM template (YAML or JSON).
68
+ /**
69
+ * Parse a CloudFormation or SAM template from text (YAML or JSON).
70
+ * Returns [] (never throws) on any parse failure — callers skip-and-warn.
71
+ */
72
+ export function parseCfnTemplate(text) {
73
+ // Attempt JSON first (CDK synthesized output, plain CFN JSON).
74
+ try {
75
+ const obj = JSON.parse(text);
76
+ const result = extractFromCfnObject(obj);
77
+ if (result.length > 0)
78
+ return result;
79
+ }
80
+ catch {
81
+ // not JSON
82
+ }
83
+ // Try YAML (CFN YAML, SAM templates).
84
+ const obj = tryParseYaml(text);
85
+ return extractFromCfnObject(obj);
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // Public: parse a Serverless Framework serverless.yml.
89
+ //
90
+ // Serverless Framework format:
91
+ // provider:
92
+ // name: aws
93
+ // functions:
94
+ // myFunction:
95
+ // handler: handler.main
96
+ // ...
97
+ // resources:
98
+ // Resources:
99
+ // MyTable:
100
+ // Type: AWS::DynamoDB::Table
101
+ // ...
102
+ //
103
+ // We synthesize:
104
+ // - One AWS::Lambda::Function node per `functions:` entry.
105
+ // - All raw CFN resources under `resources.Resources`.
106
+ export function parseServerlessConfig(text) {
107
+ const obj = tryParseYaml(text);
108
+ if (!obj || typeof obj !== 'object')
109
+ return [];
110
+ const top = obj;
111
+ const out = [];
112
+ // Functions → synthetic Lambda nodes.
113
+ const functions = top['functions'];
114
+ if (functions && typeof functions === 'object' && !Array.isArray(functions)) {
115
+ const fns = functions;
116
+ for (const [fnName, fnDef] of Object.entries(fns)) {
117
+ let rawText;
118
+ try {
119
+ rawText = JSON.stringify(fnDef ?? {});
120
+ }
121
+ catch {
122
+ rawText = '{}';
123
+ }
124
+ out.push({
125
+ logicalId: fnName,
126
+ type: 'AWS::Lambda::Function',
127
+ rawText,
128
+ source: 'serverless-fn',
129
+ });
130
+ }
131
+ }
132
+ // resources.Resources → raw CFN passthrough.
133
+ const resBlock = top['resources'];
134
+ if (resBlock && typeof resBlock === 'object') {
135
+ const synth = { Resources: resBlock['Resources'] };
136
+ out.push(...extractFromCfnObject(synth));
137
+ }
138
+ return out;
139
+ }
140
+ // ---------------------------------------------------------------------------
141
+ // Detect helpers (used by the bounded walk in aws.ts).
142
+ /** Returns true if the text looks like a CloudFormation template.
143
+ * Accepts both YAML (`AWSTemplateFormatVersion: '...'`, `Transform: AWS::Serverless`)
144
+ * and JSON (`"AWSTemplateFormatVersion"`, `"Transform": "AWS::Serverless-2016-10-31"`).
145
+ */
146
+ export function isCfnTemplate(text) {
147
+ return text.includes('AWSTemplateFormatVersion') || text.includes('AWS::Serverless');
148
+ }
149
+ //# sourceMappingURL=aws-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-parse.js","sourceRoot":"","sources":["../../../src/infra/aws/aws-parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { InfraAdapter, InfraGraph } from '../types.js';
2
+ import { type DockerfileIndex } from '../image-resolve.js';
3
+ import { type CfnResource } from './aws-parse.js';
4
+ export declare function buildAwsGraph(templates: CfnResource[], root: string, dockerfileIndex?: DockerfileIndex): InfraGraph;
5
+ export declare const awsAdapter: InfraAdapter;
6
+ //# sourceMappingURL=aws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../../../src/infra/aws/aws.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAa,UAAU,EAAgC,MAAM,aAAa,CAAC;AAGrG,OAAO,EAAmD,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC5G,OAAO,EAA0D,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA2R1G,wBAAgB,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,eAAe,GAAG,UAAU,CAyDnH;AAKD,eAAO,MAAM,UAAU,EAAE,YAkExB,CAAC"}
@@ -0,0 +1,425 @@
1
+ // AWS-native cluster InfraAdapter (v0).
2
+ //
3
+ // Covers: CloudFormation YAML/JSON, SAM templates (AWS::Serverless::*),
4
+ // Serverless Framework (serverless.yml/yaml), and synthesized CDK output
5
+ // (cdk.out/*.template.json — which is plain CFN JSON, so it's handled
6
+ // automatically by parseCfnTemplate).
7
+ //
8
+ // DEFERRED (tracked under expansion):
9
+ // * Raw ECS task-def JSON — no declarative resource map, topology requires
10
+ // ecs-compose or task-def relationship analysis, not a single template.
11
+ // * Elastic Beanstalk .elasticbeanstalk/config.yml — describes deployment
12
+ // environment, not the application topology. Worth a separate adapter when
13
+ // EB repos appear in the corpus.
14
+ // * CDK TypeScript source — synthesized cdk.out/*.template.json is CFN JSON
15
+ // and IS handled here. Raw CDK source (constructs) would need CDK API
16
+ // analysis; the synthesized output is the authoritative topology.
17
+ //
18
+ // Architecture mirrors terraform.ts:
19
+ // - Open-ended AWS resource types → heuristic `inferred` kind.
20
+ // - Per-resource `classificationsNeeded` entry (provider: 'aws/cloudformation').
21
+ // This SHARES the aws taxonomy with terraform (provider prefix 'aws/...' on
22
+ // both sides is intentional: the cache key is (provider, resourceType),
23
+ // so an `aws_lambda_function` from Terraform and an `AWS::Lambda::Function`
24
+ // from CFN use DIFFERENT keys — they're different type namespaces).
25
+ // - Cross-resource edges via reference-surface scan (Ref/GetAtt/DependsOn/Sub).
26
+ //
27
+ // Node ids are adapter-local; the registry prefixes 'aws:' at merge time.
28
+ import { readFileSync } from 'node:fs';
29
+ import { relative, sep } from 'node:path';
30
+ import { walkRepo } from '../walk.js';
31
+ import { buildDockerfileIndex, resolveImageToSourceRoots } from '../image-resolve.js';
32
+ import { parseCfnTemplate, parseServerlessConfig, isCfnTemplate } from './aws-parse.js';
33
+ // ---------------------------------------------------------------------------
34
+ // Source-root extraction. Deterministic, no LLM.
35
+ // * SAM/Lambda `CodeUri` (a local dir/zip) → that dir.
36
+ // * ECS task-def container `Image` → the resolver.
37
+ // CodeUri resolves against the template's dir; an s3:// CodeUri or a `${…}`
38
+ // intrinsic is unresolvable → skipped (honest "Other", never guess).
39
+ /** Normalize a repo-relative path: backslashes→/, collapse `.`/`./`, strip trailing `/`. */
40
+ function normalizeRoot(p) {
41
+ return p.replace(/\\/g, '/').replace(/^\.(?:\/|$)/, '').replace(/\/+$/, '');
42
+ }
43
+ /** The repo-relative directory of a repo-relative file path ('' = repo root). */
44
+ function dirOfPath(relPath) {
45
+ const n = normalizeRoot(relPath);
46
+ const i = n.lastIndexOf('/');
47
+ return i === -1 ? '' : n.slice(0, i);
48
+ }
49
+ /** Resolve `rel` against repo-relative `baseDir` → normalized. */
50
+ function resolveRel(baseDir, rel) {
51
+ const parts = (baseDir ? baseDir.split('/') : []).concat(rel.split('/'));
52
+ const out = [];
53
+ for (const p of parts) {
54
+ if (p === '' || p === '.')
55
+ continue;
56
+ if (p === '..')
57
+ out.pop();
58
+ else
59
+ out.push(p);
60
+ }
61
+ return out.join('/');
62
+ }
63
+ /** A CodeUri path → its source dir: a built artifact (.zip/.jar) → its dir; else the dir itself. */
64
+ function codeUriToDir(p) {
65
+ return /\.(zip|jar)$/i.test(p) ? dirOfPath(p) : normalizeRoot(p);
66
+ }
67
+ function awsSourceRoots(rawText, moduleDir, index) {
68
+ const roots = new Set();
69
+ // (1) SAM/Lambda CodeUri (skip s3:// remote packages + ${…} intrinsics).
70
+ const codeUriRe = /"CodeUri"\s*:\s*"([^"]+)"/g;
71
+ let m;
72
+ while ((m = codeUriRe.exec(rawText)) !== null) {
73
+ const v = m[1];
74
+ if (/^s3:\/\//i.test(v) || v.includes('${'))
75
+ continue;
76
+ const d = codeUriToDir(resolveRel(moduleDir, v));
77
+ if (d)
78
+ roots.add(d);
79
+ }
80
+ // (2) ECS task-def (and any) container Image refs → resolver.
81
+ if (index) {
82
+ const imageRe = /"Image"\s*:\s*"([^"]+)"/g;
83
+ while ((m = imageRe.exec(rawText)) !== null) {
84
+ const v = m[1];
85
+ if (v.includes('${'))
86
+ continue;
87
+ for (const r of resolveImageToSourceRoots(v, index))
88
+ roots.add(r);
89
+ }
90
+ }
91
+ return [...roots].sort();
92
+ }
93
+ // ---------------------------------------------------------------------------
94
+ // File discovery constants.
95
+ // `cdk.out` is deliberately NOT skipped — it holds synthesized CFN JSON we want.
96
+ const AWS_SKIP_DIRS = ['node_modules', '.git', 'dist', '.wrangler', '.next', 'build', 'coverage', '__pycache__', '.venv', 'vendor'];
97
+ // Names that always denote a Serverless Framework config.
98
+ const SERVERLESS_CONFIG_NAMES = new Set(['serverless.yml', 'serverless.yaml']);
99
+ // Names that are candidate CFN template files (heuristic; we check content).
100
+ const TEMPLATE_NAMES = new Set([
101
+ 'template.yaml', 'template.yml', 'template.json',
102
+ 'cloudformation.yaml', 'cloudformation.yml', 'cloudformation.json',
103
+ 'sam.yaml', 'sam.yml', 'sam.json',
104
+ 'stack.yaml', 'stack.yml', 'stack.json',
105
+ ]);
106
+ /**
107
+ * Walk the repo and collect AWS template files.
108
+ * - Always descend into cdk.out/ to pick up *.template.json (it's not in
109
+ * AWS_SKIP_DIRS, so the shared walker descends it like any other dir).
110
+ * - Skip AWS_SKIP_DIRS otherwise.
111
+ * - Returns files sorted by absolute path (localeCompare) so first-wins
112
+ * deduplication is deterministic across machines and CI.
113
+ */
114
+ function findAwsTemplates(repoDir) {
115
+ const found = [];
116
+ walkRepo(repoDir, {
117
+ skipDirs: AWS_SKIP_DIRS,
118
+ onFile: (abs, e) => {
119
+ const name = e.name;
120
+ if (SERVERLESS_CONFIG_NAMES.has(name)) {
121
+ found.push({ abs, kind: 'serverless' });
122
+ return;
123
+ }
124
+ // `inCdkOut`: true iff any ancestor directory of this file is `cdk.out`.
125
+ // (The legacy walk threaded a flag set on entering cdk.out; recovering it
126
+ // from the path is equivalent and keeps the shared walker stateless.)
127
+ const inCdkOut = relative(repoDir, abs).split(sep).slice(0, -1).includes('cdk.out');
128
+ if (inCdkOut && name.endsWith('.template.json')) {
129
+ // Synthesized CDK output — always CFN JSON.
130
+ found.push({ abs, kind: 'cfn' });
131
+ }
132
+ else if (TEMPLATE_NAMES.has(name)) {
133
+ // Check content before committing — avoid false positives.
134
+ // We'll verify in the extraction loop.
135
+ found.push({ abs, kind: 'cfn' });
136
+ }
137
+ },
138
+ });
139
+ // Sort by absolute path so first-wins deduplication is deterministic.
140
+ found.sort((a, b) => a.abs.localeCompare(b.abs));
141
+ return found;
142
+ }
143
+ // ---------------------------------------------------------------------------
144
+ // Kind heuristic (mirrors terraform.ts KIND_RULES; adapted for CFN type names).
145
+ // The LLM cache is the authority; this ensures a usable topology under
146
+ // --no-llm. Most-specific rules listed first.
147
+ const CFN_KIND_RULES = [
148
+ // Compute / function
149
+ [/AWS::Lambda::|AWS::Serverless::Function/, 'worker'],
150
+ [/AWS::AppRunner::|AWS::Batch::|AWS::ECS::TaskDefinition/, 'worker'],
151
+ // Container / ECS service
152
+ [/AWS::ECS::Service|AWS::EC2::Instance|AWS::ElasticBeanstalk::/, 'container'],
153
+ // Queue / event bus
154
+ [/AWS::SQS::|AWS::SNS::|AWS::Kinesis::|AWS::EventBridge::|AWS::Events::/, 'queue'],
155
+ // Datastore
156
+ [/AWS::DynamoDB::Table|AWS::Serverless::SimpleTable|AWS::RDS::/, 'datastore'],
157
+ [/AWS::S3::Bucket/, 'datastore'],
158
+ [/AWS::ElastiCache::|AWS::DAX::/, 'datastore'],
159
+ // Secret store / KMS
160
+ [/AWS::SecretsManager::|AWS::KMS::|AWS::SSM::Parameter/, 'secret-store'],
161
+ // CDN / distribution
162
+ [/AWS::CloudFront::/, 'cdn'],
163
+ // API gateway — no `gateway` kind in enum; map to `worker` (least-bad)
164
+ [/AWS::ApiGateway::|AWS::ApiGatewayV2::|AWS::Serverless::Api|AWS::Serverless::HttpApi/, 'worker'],
165
+ ];
166
+ function heuristicKind(resourceType) {
167
+ for (const [re, kind] of CFN_KIND_RULES) {
168
+ if (re.test(resourceType)) {
169
+ return { kind };
170
+ }
171
+ }
172
+ // Unknown type → datastore fallback (same rationale as terraform.ts).
173
+ return { kind: 'datastore' };
174
+ }
175
+ // ---------------------------------------------------------------------------
176
+ // Reference extraction via parsed object walk.
177
+ //
178
+ // CFN references between resources use:
179
+ // - { Ref: LogicalId } → we expect the string value to equal a logicalId
180
+ // - { Fn::GetAtt: [LId, Attr] } → first array element is the logicalId
181
+ // - DependsOn: LogicalId | [LId…] → string or array of strings
182
+ // - { Fn::Sub: "${LogicalId.Attr}" }→ placeholder in the Sub string
183
+ //
184
+ // We walk the parsed JS object once per resource, collecting every logicalId
185
+ // that appears as a Ref value, first element of Fn::GetAtt, DependsOn entry,
186
+ // or ${…} placeholder in Fn::Sub strings. This is O(R) (one walk per
187
+ // resource, not O(R²) re-compilation per pair) and eliminates the substring
188
+ // phantom-edge risk from the old rawText approach.
189
+ function extractRefs(value, knownIds, out) {
190
+ if (typeof value === 'string') {
191
+ // Case A: YAML-resolved scalar string.
192
+ // !Ref OrdersTable → the string "OrdersTable" (exact match)
193
+ // !GetAtt AssetsBucket.Arn → the string "AssetsBucket.Arn" (id.attr)
194
+ // !Sub "${OrdersTable.Arn}/..." → check ${…} placeholders below
195
+ // Check exact match first (covers !Ref).
196
+ if (knownIds.has(value)) {
197
+ out.add(value);
198
+ return;
199
+ }
200
+ // Check for id.attr form (covers !GetAtt resolved as scalar string).
201
+ const dotIdx = value.indexOf('.');
202
+ if (dotIdx > 0) {
203
+ const prefix = value.slice(0, dotIdx);
204
+ if (knownIds.has(prefix))
205
+ out.add(prefix);
206
+ }
207
+ // Check for ${LogicalId} / ${LogicalId.Attr} placeholders in Sub strings.
208
+ const placeholderRe = /\$\{([A-Za-z0-9]+)(?:\.[^}]*)?\}/g;
209
+ let m;
210
+ while ((m = placeholderRe.exec(value)) !== null) {
211
+ if (knownIds.has(m[1]))
212
+ out.add(m[1]);
213
+ }
214
+ return;
215
+ }
216
+ if (!value || typeof value !== 'object')
217
+ return;
218
+ if (Array.isArray(value)) {
219
+ for (const item of value)
220
+ extractRefs(item, knownIds, out);
221
+ return;
222
+ }
223
+ // Case B: JSON-form object with explicit CFN intrinsic function keys.
224
+ const obj = value;
225
+ for (const [key, val] of Object.entries(obj)) {
226
+ if (key === 'Ref' && typeof val === 'string') {
227
+ if (knownIds.has(val))
228
+ out.add(val);
229
+ }
230
+ else if (key === 'Fn::GetAtt' && Array.isArray(val) && val.length >= 1 && typeof val[0] === 'string') {
231
+ if (knownIds.has(val[0]))
232
+ out.add(val[0]);
233
+ }
234
+ else if (key === 'DependsOn') {
235
+ const deps = Array.isArray(val) ? val : [val];
236
+ for (const d of deps) {
237
+ if (typeof d === 'string' && knownIds.has(d))
238
+ out.add(d);
239
+ }
240
+ }
241
+ else if (key === 'Fn::Sub' && typeof val === 'string') {
242
+ const placeholderRe = /\$\{([A-Za-z0-9]+)(?:\.[^}]*)?\}/g;
243
+ let m;
244
+ while ((m = placeholderRe.exec(val)) !== null) {
245
+ if (knownIds.has(m[1]))
246
+ out.add(m[1]);
247
+ }
248
+ }
249
+ else {
250
+ extractRefs(val, knownIds, out);
251
+ }
252
+ }
253
+ }
254
+ /**
255
+ * Build a map from each resource's nodeId to the set of nodeIds it references,
256
+ * by walking the parsed object of each resource's rawText.
257
+ *
258
+ * We match against logicalIds (plain names in rawText like "OrdersTable"),
259
+ * then translate back to nodeIds via the logicalId→nodeId map.
260
+ *
261
+ * Returns Map<srcNodeId, Set<tgtNodeId>>.
262
+ */
263
+ function buildRefMap(resources) {
264
+ // Index logicalId → nodeId for translation after matching.
265
+ const logicalToNode = new Map(resources.map((r) => [r.logicalId, r.nodeId]));
266
+ // All logicalIds as a set for O(1) membership checks inside extractRefs.
267
+ const allLogicalIds = new Set(resources.map((r) => r.logicalId));
268
+ // Index nodeId → parsed rawText object.
269
+ const parsed = new Map();
270
+ for (const { nodeId, rawText } of resources) {
271
+ try {
272
+ parsed.set(nodeId, JSON.parse(rawText));
273
+ }
274
+ catch {
275
+ parsed.set(nodeId, null);
276
+ }
277
+ }
278
+ const result = new Map();
279
+ for (const { nodeId, logicalId } of resources) {
280
+ // Collect referenced logicalIds (not nodeIds) — rawText contains plain names.
281
+ const otherLogicalIds = new Set([...allLogicalIds].filter((id) => id !== logicalId));
282
+ const refLogicalIds = new Set();
283
+ extractRefs(parsed.get(nodeId), otherLogicalIds, refLogicalIds);
284
+ // Translate logicalId references → nodeIds.
285
+ const refNodeIds = new Set();
286
+ for (const refLogicalId of refLogicalIds) {
287
+ const refNodeId = logicalToNode.get(refLogicalId);
288
+ if (refNodeId)
289
+ refNodeIds.add(refNodeId);
290
+ }
291
+ result.set(nodeId, refNodeIds);
292
+ }
293
+ return result;
294
+ }
295
+ // ---------------------------------------------------------------------------
296
+ // Node ID helpers.
297
+ //
298
+ // Serverless Framework `functions:` entries get ids in the `fn:<name>` namespace
299
+ // to avoid collisions with PascalCase CFN logical IDs from the same template's
300
+ // `resources.Resources` block (e.g. a function named `Api` would otherwise collide
301
+ // with a CFN resource `Api`).
302
+ function nodeIdForResource(r) {
303
+ return r.source === 'serverless-fn' ? `fn:${r.logicalId}` : `resource:${r.logicalId}`;
304
+ }
305
+ // ---------------------------------------------------------------------------
306
+ // Pure graph builder.
307
+ export function buildAwsGraph(templates, root, dockerfileIndex) {
308
+ const nodes = [];
309
+ const classificationsNeeded = [];
310
+ for (const r of templates) {
311
+ const { kind } = heuristicKind(r.type);
312
+ const nodeId = nodeIdForResource(r);
313
+ // CodeUri / container Image → source roots.
314
+ const roots = awsSourceRoots(r.rawText, r.dir ?? '', dockerfileIndex);
315
+ nodes.push({
316
+ id: nodeId,
317
+ label: `${r.logicalId} (${r.type})`,
318
+ kind,
319
+ provenance: 'inferred',
320
+ metadata: {
321
+ provider: 'aws/cloudformation',
322
+ resourceType: r.type,
323
+ },
324
+ ...(roots.length ? { sourceRoots: roots } : {}),
325
+ });
326
+ classificationsNeeded.push({
327
+ provider: 'aws/cloudformation',
328
+ resourceType: r.type,
329
+ forNodeId: nodeId,
330
+ });
331
+ }
332
+ // Cross-resource edges: walk each resource's parsed rawText for Ref /
333
+ // Fn::GetAtt / DependsOn / Fn::Sub references to other resources' nodeIds.
334
+ // Using a pre-built ref-map is O(R) rather than O(R²) and avoids false
335
+ // positives from substring matches in the old rawText regex approach.
336
+ const edges = [];
337
+ const seenEdges = new Set();
338
+ const resourcesWithNodeIds = templates.map((r) => ({
339
+ nodeId: nodeIdForResource(r),
340
+ logicalId: r.logicalId,
341
+ rawText: r.rawText,
342
+ }));
343
+ const refMap = buildRefMap(resourcesWithNodeIds);
344
+ for (const [srcId, refs] of refMap) {
345
+ for (const tgtId of refs) {
346
+ if (srcId === tgtId)
347
+ continue;
348
+ const key = `${srcId}→${tgtId}`;
349
+ if (seenEdges.has(key))
350
+ continue;
351
+ seenEdges.add(key);
352
+ edges.push({
353
+ source: srcId,
354
+ target: tgtId,
355
+ kind: 'calls',
356
+ metadata: { via: 'cfn-ref' },
357
+ });
358
+ }
359
+ }
360
+ return { root, adapter: 'aws', nodes, edges, classificationsNeeded };
361
+ }
362
+ // ---------------------------------------------------------------------------
363
+ // Adapter: detect + extract.
364
+ export const awsAdapter = {
365
+ name: 'aws',
366
+ async detect(repoDir) {
367
+ return findAwsTemplates(repoDir).length > 0;
368
+ },
369
+ async extract(repoDir) {
370
+ const found = findAwsTemplates(repoDir); // already sorted by abs path
371
+ const allResources = [];
372
+ // Track (templateFile, logicalId) pairs to deduplicate within a single
373
+ // template. Sibling stacks (dev/prod, per-service templates) legitimately
374
+ // reuse logical IDs like `Api` or `Table` — those are DISTINCT resources
375
+ // and must all be included; only within one template file is a duplicate
376
+ // logicalId a no-op (CFN itself forbids duplicate keys in a Resources map).
377
+ const seenPerFile = new Map();
378
+ for (const { abs, kind } of found) {
379
+ let text;
380
+ try {
381
+ text = readFileSync(abs, 'utf8');
382
+ }
383
+ catch (err) {
384
+ console.warn(` [aws] skipping unreadable ${relative(repoDir, abs)}: ${err.message}`);
385
+ continue;
386
+ }
387
+ // For candidate CFN files (not serverless), verify content before parsing.
388
+ if (kind === 'cfn' && !abs.endsWith('.template.json') && !isCfnTemplate(text)) {
389
+ // The file exists in a template-named location but isn't actually a CFN
390
+ // template — skip silently (e.g. a plain JSON config named template.json).
391
+ continue;
392
+ }
393
+ let resources;
394
+ try {
395
+ if (kind === 'serverless') {
396
+ resources = parseServerlessConfig(text);
397
+ }
398
+ else {
399
+ resources = parseCfnTemplate(text);
400
+ }
401
+ }
402
+ catch (err) {
403
+ console.warn(` [aws] skipping unparseable ${relative(repoDir, abs)}: ${err.message}`);
404
+ continue;
405
+ }
406
+ // Dedupe within this file only. The nodeId incorporates source ('fn:'
407
+ // vs 'resource:') so a serverless-fn and a CFN resource with the same
408
+ // bare name won't collide globally either.
409
+ const fileSeenIds = seenPerFile.get(abs) ?? new Set();
410
+ seenPerFile.set(abs, fileSeenIds);
411
+ // stamp the template's repo-relative dir for CodeUri resolution.
412
+ const fileDir = dirOfPath((relative(repoDir, abs) || abs).split('\\').join('/'));
413
+ for (const r of resources) {
414
+ const nodeId = nodeIdForResource(r);
415
+ if (!fileSeenIds.has(nodeId)) {
416
+ fileSeenIds.add(nodeId);
417
+ allResources.push({ ...r, dir: fileDir });
418
+ }
419
+ }
420
+ }
421
+ // Dockerfile index for ECS image refs.
422
+ return buildAwsGraph(allResources, repoDir, buildDockerfileIndex(repoDir));
423
+ },
424
+ };
425
+ //# sourceMappingURL=aws.js.map