@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.
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/cluster/domain-grouping.d.ts +113 -0
- package/dist/cluster/domain-grouping.d.ts.map +1 -0
- package/dist/cluster/domain-grouping.js +277 -0
- package/dist/cluster/domain-grouping.js.map +1 -0
- package/dist/cluster/grouping-gate.d.ts +54 -0
- package/dist/cluster/grouping-gate.d.ts.map +1 -0
- package/dist/cluster/grouping-gate.js +0 -0
- package/dist/cluster/grouping-gate.js.map +1 -0
- package/dist/cluster/louvain.d.ts +88 -0
- package/dist/cluster/louvain.d.ts.map +1 -0
- package/dist/cluster/louvain.js +674 -0
- package/dist/cluster/louvain.js.map +1 -0
- package/dist/cluster/overrides.d.ts +19 -0
- package/dist/cluster/overrides.d.ts.map +1 -0
- package/dist/cluster/overrides.js +32 -0
- package/dist/cluster/overrides.js.map +1 -0
- package/dist/cluster/subsystem.d.ts +45 -0
- package/dist/cluster/subsystem.d.ts.map +1 -0
- package/dist/cluster/subsystem.js +299 -0
- package/dist/cluster/subsystem.js.map +1 -0
- package/dist/cluster/workspaces.d.ts +64 -0
- package/dist/cluster/workspaces.d.ts.map +1 -0
- package/dist/cluster/workspaces.js +739 -0
- package/dist/cluster/workspaces.js.map +1 -0
- package/dist/extract.d.ts +52 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +48 -0
- package/dist/extract.js.map +1 -0
- package/dist/framework/celery/celery.d.ts +17 -0
- package/dist/framework/celery/celery.d.ts.map +1 -0
- package/dist/framework/celery/celery.js +524 -0
- package/dist/framework/celery/celery.js.map +1 -0
- package/dist/framework/contribute-step.d.ts +38 -0
- package/dist/framework/contribute-step.d.ts.map +1 -0
- package/dist/framework/contribute-step.js +403 -0
- package/dist/framework/contribute-step.js.map +1 -0
- package/dist/framework/detect-step.d.ts +8 -0
- package/dist/framework/detect-step.d.ts.map +1 -0
- package/dist/framework/detect-step.js +54 -0
- package/dist/framework/detect-step.js.map +1 -0
- package/dist/framework/detect-util.d.ts +24 -0
- package/dist/framework/detect-util.d.ts.map +1 -0
- package/dist/framework/detect-util.js +59 -0
- package/dist/framework/detect-util.js.map +1 -0
- package/dist/framework/django/django.d.ts +22 -0
- package/dist/framework/django/django.d.ts.map +1 -0
- package/dist/framework/django/django.js +940 -0
- package/dist/framework/django/django.js.map +1 -0
- package/dist/framework/fastapi/fastapi.d.ts +27 -0
- package/dist/framework/fastapi/fastapi.d.ts.map +1 -0
- package/dist/framework/fastapi/fastapi.js +477 -0
- package/dist/framework/fastapi/fastapi.js.map +1 -0
- package/dist/framework/faststream/faststream.d.ts +19 -0
- package/dist/framework/faststream/faststream.d.ts.map +1 -0
- package/dist/framework/faststream/faststream.js +765 -0
- package/dist/framework/faststream/faststream.js.map +1 -0
- package/dist/framework/flask/flask.d.ts +17 -0
- package/dist/framework/flask/flask.d.ts.map +1 -0
- package/dist/framework/flask/flask.js +507 -0
- package/dist/framework/flask/flask.js.map +1 -0
- package/dist/framework/graphql/graphql.d.ts +17 -0
- package/dist/framework/graphql/graphql.d.ts.map +1 -0
- package/dist/framework/graphql/graphql.js +708 -0
- package/dist/framework/graphql/graphql.js.map +1 -0
- package/dist/framework/grpc/grpc.d.ts +22 -0
- package/dist/framework/grpc/grpc.d.ts.map +1 -0
- package/dist/framework/grpc/grpc.js +618 -0
- package/dist/framework/grpc/grpc.js.map +1 -0
- package/dist/framework/litestar/litestar.d.ts +17 -0
- package/dist/framework/litestar/litestar.d.ts.map +1 -0
- package/dist/framework/litestar/litestar.js +536 -0
- package/dist/framework/litestar/litestar.js.map +1 -0
- package/dist/framework/nest/nest.d.ts +19 -0
- package/dist/framework/nest/nest.d.ts.map +1 -0
- package/dist/framework/nest/nest.js +613 -0
- package/dist/framework/nest/nest.js.map +1 -0
- package/dist/framework/next/next.d.ts +22 -0
- package/dist/framework/next/next.d.ts.map +1 -0
- package/dist/framework/next/next.js +449 -0
- package/dist/framework/next/next.js.map +1 -0
- package/dist/framework/node/node.d.ts +24 -0
- package/dist/framework/node/node.d.ts.map +1 -0
- package/dist/framework/node/node.js +1009 -0
- package/dist/framework/node/node.js.map +1 -0
- package/dist/framework/orchestrator/orchestrator.d.ts +34 -0
- package/dist/framework/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/framework/orchestrator/orchestrator.js +691 -0
- package/dist/framework/orchestrator/orchestrator.js.map +1 -0
- package/dist/framework/orm/orm.d.ts +61 -0
- package/dist/framework/orm/orm.d.ts.map +1 -0
- package/dist/framework/orm/orm.js +620 -0
- package/dist/framework/orm/orm.js.map +1 -0
- package/dist/framework/python/analyze.d.ts +38 -0
- package/dist/framework/python/analyze.d.ts.map +1 -0
- package/dist/framework/python/analyze.js +98 -0
- package/dist/framework/python/analyze.js.map +1 -0
- package/dist/framework/python/py-ast.d.ts +130 -0
- package/dist/framework/python/py-ast.d.ts.map +1 -0
- package/dist/framework/python/py-ast.js +344 -0
- package/dist/framework/python/py-ast.js.map +1 -0
- package/dist/framework/python-orm/python-orm.d.ts +19 -0
- package/dist/framework/python-orm/python-orm.d.ts.map +1 -0
- package/dist/framework/python-orm/python-orm.js +516 -0
- package/dist/framework/python-orm/python-orm.js.map +1 -0
- package/dist/framework/react-native/react-native.d.ts +35 -0
- package/dist/framework/react-native/react-native.d.ts.map +1 -0
- package/dist/framework/react-native/react-native.js +1181 -0
- package/dist/framework/react-native/react-native.js.map +1 -0
- package/dist/framework/register.d.ts +2 -0
- package/dist/framework/register.d.ts.map +1 -0
- package/dist/framework/register.js +59 -0
- package/dist/framework/register.js.map +1 -0
- package/dist/framework/registry.d.ts +31 -0
- package/dist/framework/registry.d.ts.map +1 -0
- package/dist/framework/registry.js +70 -0
- package/dist/framework/registry.js.map +1 -0
- package/dist/framework/routing/expo-router.d.ts +31 -0
- package/dist/framework/routing/expo-router.d.ts.map +1 -0
- package/dist/framework/routing/expo-router.js +356 -0
- package/dist/framework/routing/expo-router.js.map +1 -0
- package/dist/framework/routing/index.d.ts +4 -0
- package/dist/framework/routing/index.d.ts.map +1 -0
- package/dist/framework/routing/index.js +16 -0
- package/dist/framework/routing/index.js.map +1 -0
- package/dist/framework/routing/next-router.d.ts +45 -0
- package/dist/framework/routing/next-router.d.ts.map +1 -0
- package/dist/framework/routing/next-router.js +378 -0
- package/dist/framework/routing/next-router.js.map +1 -0
- package/dist/framework/routing/route-tree.d.ts +73 -0
- package/dist/framework/routing/route-tree.d.ts.map +1 -0
- package/dist/framework/routing/route-tree.js +120 -0
- package/dist/framework/routing/route-tree.js.map +1 -0
- package/dist/framework/types.d.ts +230 -0
- package/dist/framework/types.d.ts.map +1 -0
- package/dist/framework/types.js +25 -0
- package/dist/framework/types.js.map +1 -0
- package/dist/graph/cross-language.d.ts +11 -0
- package/dist/graph/cross-language.d.ts.map +1 -0
- package/dist/graph/cross-language.js +123 -0
- package/dist/graph/cross-language.js.map +1 -0
- package/dist/graph/extract.d.ts +13 -0
- package/dist/graph/extract.d.ts.map +1 -0
- package/dist/graph/extract.js +79 -0
- package/dist/graph/extract.js.map +1 -0
- package/dist/graph/file-graph.d.ts +186 -0
- package/dist/graph/file-graph.d.ts.map +1 -0
- package/dist/graph/file-graph.js +427 -0
- package/dist/graph/file-graph.js.map +1 -0
- package/dist/graph/http-callsites.d.ts +14 -0
- package/dist/graph/http-callsites.d.ts.map +1 -0
- package/dist/graph/http-callsites.js +107 -0
- package/dist/graph/http-callsites.js.map +1 -0
- package/dist/graph/incremental.d.ts +122 -0
- package/dist/graph/incremental.d.ts.map +1 -0
- package/dist/graph/incremental.js +448 -0
- package/dist/graph/incremental.js.map +1 -0
- package/dist/graph/language.d.ts +31 -0
- package/dist/graph/language.d.ts.map +1 -0
- package/dist/graph/language.js +146 -0
- package/dist/graph/language.js.map +1 -0
- package/dist/graph/noise-filter.d.ts +46 -0
- package/dist/graph/noise-filter.d.ts.map +1 -0
- package/dist/graph/noise-filter.js +199 -0
- package/dist/graph/noise-filter.js.map +1 -0
- package/dist/graph/python-adapter.d.ts +36 -0
- package/dist/graph/python-adapter.d.ts.map +1 -0
- package/dist/graph/python-adapter.js +402 -0
- package/dist/graph/python-adapter.js.map +1 -0
- package/dist/graph/python-manifest.d.ts +22 -0
- package/dist/graph/python-manifest.d.ts.map +1 -0
- package/dist/graph/python-manifest.js +137 -0
- package/dist/graph/python-manifest.js.map +1 -0
- package/dist/graph/python-stdlib.d.ts +2 -0
- package/dist/graph/python-stdlib.d.ts.map +1 -0
- package/dist/graph/python-stdlib.js +53 -0
- package/dist/graph/python-stdlib.js.map +1 -0
- package/dist/graph/ts-morph-adapter.d.ts +65 -0
- package/dist/graph/ts-morph-adapter.d.ts.map +1 -0
- package/dist/graph/ts-morph-adapter.js +265 -0
- package/dist/graph/ts-morph-adapter.js.map +1 -0
- package/dist/graph/types.d.ts +37 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +50 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/aws/aws-parse.d.ts +39 -0
- package/dist/infra/aws/aws-parse.d.ts.map +1 -0
- package/dist/infra/aws/aws-parse.js +149 -0
- package/dist/infra/aws/aws-parse.js.map +1 -0
- package/dist/infra/aws/aws.d.ts +6 -0
- package/dist/infra/aws/aws.d.ts.map +1 -0
- package/dist/infra/aws/aws.js +425 -0
- package/dist/infra/aws/aws.js.map +1 -0
- package/dist/infra/azure/azure-parse.d.ts +73 -0
- package/dist/infra/azure/azure-parse.d.ts.map +1 -0
- package/dist/infra/azure/azure-parse.js +178 -0
- package/dist/infra/azure/azure-parse.js.map +1 -0
- package/dist/infra/azure/azure.d.ts +12 -0
- package/dist/infra/azure/azure.d.ts.map +1 -0
- package/dist/infra/azure/azure.js +673 -0
- package/dist/infra/azure/azure.js.map +1 -0
- package/dist/infra/cloudflare/cloudflare.d.ts +50 -0
- package/dist/infra/cloudflare/cloudflare.d.ts.map +1 -0
- package/dist/infra/cloudflare/cloudflare.js +382 -0
- package/dist/infra/cloudflare/cloudflare.js.map +1 -0
- package/dist/infra/cloudflare/wrangler-parse.d.ts +6 -0
- package/dist/infra/cloudflare/wrangler-parse.d.ts.map +1 -0
- package/dist/infra/cloudflare/wrangler-parse.js +278 -0
- package/dist/infra/cloudflare/wrangler-parse.js.map +1 -0
- package/dist/infra/compose/compose-parse.d.ts +24 -0
- package/dist/infra/compose/compose-parse.d.ts.map +1 -0
- package/dist/infra/compose/compose-parse.js +77 -0
- package/dist/infra/compose/compose-parse.js.map +1 -0
- package/dist/infra/compose/compose.d.ts +12 -0
- package/dist/infra/compose/compose.d.ts.map +1 -0
- package/dist/infra/compose/compose.js +201 -0
- package/dist/infra/compose/compose.js.map +1 -0
- package/dist/infra/convex/convex-parse.d.ts +28 -0
- package/dist/infra/convex/convex-parse.d.ts.map +1 -0
- package/dist/infra/convex/convex-parse.js +74 -0
- package/dist/infra/convex/convex-parse.js.map +1 -0
- package/dist/infra/convex/convex.d.ts +18 -0
- package/dist/infra/convex/convex.d.ts.map +1 -0
- package/dist/infra/convex/convex.js +199 -0
- package/dist/infra/convex/convex.js.map +1 -0
- package/dist/infra/digitalocean/digitalocean.d.ts +33 -0
- package/dist/infra/digitalocean/digitalocean.d.ts.map +1 -0
- package/dist/infra/digitalocean/digitalocean.js +204 -0
- package/dist/infra/digitalocean/digitalocean.js.map +1 -0
- package/dist/infra/firebase/firebase.d.ts +43 -0
- package/dist/infra/firebase/firebase.d.ts.map +1 -0
- package/dist/infra/firebase/firebase.js +271 -0
- package/dist/infra/firebase/firebase.js.map +1 -0
- package/dist/infra/fly/fly-parse.d.ts +52 -0
- package/dist/infra/fly/fly-parse.d.ts.map +1 -0
- package/dist/infra/fly/fly-parse.js +114 -0
- package/dist/infra/fly/fly-parse.js.map +1 -0
- package/dist/infra/fly/fly.d.ts +15 -0
- package/dist/infra/fly/fly.d.ts.map +1 -0
- package/dist/infra/fly/fly.js +265 -0
- package/dist/infra/fly/fly.js.map +1 -0
- package/dist/infra/gcp/gcp-parse.d.ts +24 -0
- package/dist/infra/gcp/gcp-parse.d.ts.map +1 -0
- package/dist/infra/gcp/gcp-parse.js +123 -0
- package/dist/infra/gcp/gcp-parse.js.map +1 -0
- package/dist/infra/gcp/gcp.d.ts +10 -0
- package/dist/infra/gcp/gcp.d.ts.map +1 -0
- package/dist/infra/gcp/gcp.js +502 -0
- package/dist/infra/gcp/gcp.js.map +1 -0
- package/dist/infra/heroku/heroku-parse.d.ts +33 -0
- package/dist/infra/heroku/heroku-parse.d.ts.map +1 -0
- package/dist/infra/heroku/heroku-parse.js +63 -0
- package/dist/infra/heroku/heroku-parse.js.map +1 -0
- package/dist/infra/heroku/heroku.d.ts +24 -0
- package/dist/infra/heroku/heroku.d.ts.map +1 -0
- package/dist/infra/heroku/heroku.js +253 -0
- package/dist/infra/heroku/heroku.js.map +1 -0
- package/dist/infra/image-resolve.d.ts +56 -0
- package/dist/infra/image-resolve.d.ts.map +1 -0
- package/dist/infra/image-resolve.js +229 -0
- package/dist/infra/image-resolve.js.map +1 -0
- package/dist/infra/infra-step.d.ts +39 -0
- package/dist/infra/infra-step.d.ts.map +1 -0
- package/dist/infra/infra-step.js +57 -0
- package/dist/infra/infra-step.js.map +1 -0
- package/dist/infra/k8s/index.d.ts +78 -0
- package/dist/infra/k8s/index.d.ts.map +1 -0
- package/dist/infra/k8s/index.js +251 -0
- package/dist/infra/k8s/index.js.map +1 -0
- package/dist/infra/kamal/kamal-parse.d.ts +23 -0
- package/dist/infra/kamal/kamal-parse.d.ts.map +1 -0
- package/dist/infra/kamal/kamal-parse.js +66 -0
- package/dist/infra/kamal/kamal-parse.js.map +1 -0
- package/dist/infra/kamal/kamal.d.ts +17 -0
- package/dist/infra/kamal/kamal.d.ts.map +1 -0
- package/dist/infra/kamal/kamal.js +162 -0
- package/dist/infra/kamal/kamal.js.map +1 -0
- package/dist/infra/netlify/netlify.d.ts +33 -0
- package/dist/infra/netlify/netlify.d.ts.map +1 -0
- package/dist/infra/netlify/netlify.js +247 -0
- package/dist/infra/netlify/netlify.js.map +1 -0
- package/dist/infra/opentofu/opentofu.d.ts +3 -0
- package/dist/infra/opentofu/opentofu.d.ts.map +1 -0
- package/dist/infra/opentofu/opentofu.js +157 -0
- package/dist/infra/opentofu/opentofu.js.map +1 -0
- package/dist/infra/pulumi/pulumi-parse.d.ts +60 -0
- package/dist/infra/pulumi/pulumi-parse.d.ts.map +1 -0
- package/dist/infra/pulumi/pulumi-parse.js +155 -0
- package/dist/infra/pulumi/pulumi-parse.js.map +1 -0
- package/dist/infra/pulumi/pulumi.d.ts +23 -0
- package/dist/infra/pulumi/pulumi.d.ts.map +1 -0
- package/dist/infra/pulumi/pulumi.js +260 -0
- package/dist/infra/pulumi/pulumi.js.map +1 -0
- package/dist/infra/railway/railway-parse.d.ts +54 -0
- package/dist/infra/railway/railway-parse.d.ts.map +1 -0
- package/dist/infra/railway/railway-parse.js +200 -0
- package/dist/infra/railway/railway-parse.js.map +1 -0
- package/dist/infra/railway/railway.d.ts +19 -0
- package/dist/infra/railway/railway.d.ts.map +1 -0
- package/dist/infra/railway/railway.js +397 -0
- package/dist/infra/railway/railway.js.map +1 -0
- package/dist/infra/register.d.ts +2 -0
- package/dist/infra/register.d.ts.map +1 -0
- package/dist/infra/register.js +81 -0
- package/dist/infra/register.js.map +1 -0
- package/dist/infra/registry.d.ts +64 -0
- package/dist/infra/registry.d.ts.map +1 -0
- package/dist/infra/registry.js +205 -0
- package/dist/infra/registry.js.map +1 -0
- package/dist/infra/relevance.d.ts +16 -0
- package/dist/infra/relevance.d.ts.map +1 -0
- package/dist/infra/relevance.js +132 -0
- package/dist/infra/relevance.js.map +1 -0
- package/dist/infra/render/render-parse.d.ts +76 -0
- package/dist/infra/render/render-parse.d.ts.map +1 -0
- package/dist/infra/render/render-parse.js +155 -0
- package/dist/infra/render/render-parse.js.map +1 -0
- package/dist/infra/render/render.d.ts +11 -0
- package/dist/infra/render/render.d.ts.map +1 -0
- package/dist/infra/render/render.js +303 -0
- package/dist/infra/render/render.js.map +1 -0
- package/dist/infra/sst/sst-parse.d.ts +25 -0
- package/dist/infra/sst/sst-parse.d.ts.map +1 -0
- package/dist/infra/sst/sst-parse.js +45 -0
- package/dist/infra/sst/sst-parse.js.map +1 -0
- package/dist/infra/sst/sst.d.ts +19 -0
- package/dist/infra/sst/sst.d.ts.map +1 -0
- package/dist/infra/sst/sst.js +236 -0
- package/dist/infra/sst/sst.js.map +1 -0
- package/dist/infra/supabase/supabase-parse.d.ts +34 -0
- package/dist/infra/supabase/supabase-parse.d.ts.map +1 -0
- package/dist/infra/supabase/supabase-parse.js +113 -0
- package/dist/infra/supabase/supabase-parse.js.map +1 -0
- package/dist/infra/supabase/supabase.d.ts +15 -0
- package/dist/infra/supabase/supabase.d.ts.map +1 -0
- package/dist/infra/supabase/supabase.js +198 -0
- package/dist/infra/supabase/supabase.js.map +1 -0
- package/dist/infra/terraform/hcl-parse.d.ts +34 -0
- package/dist/infra/terraform/hcl-parse.d.ts.map +1 -0
- package/dist/infra/terraform/hcl-parse.js +203 -0
- package/dist/infra/terraform/hcl-parse.js.map +1 -0
- package/dist/infra/terraform/terraform.d.ts +14 -0
- package/dist/infra/terraform/terraform.d.ts.map +1 -0
- package/dist/infra/terraform/terraform.js +264 -0
- package/dist/infra/terraform/terraform.js.map +1 -0
- package/dist/infra/types.d.ts +151 -0
- package/dist/infra/types.d.ts.map +1 -0
- package/dist/infra/types.js +14 -0
- package/dist/infra/types.js.map +1 -0
- package/dist/infra/vercel/vercel-parse.d.ts +70 -0
- package/dist/infra/vercel/vercel-parse.d.ts.map +1 -0
- package/dist/infra/vercel/vercel-parse.js +194 -0
- package/dist/infra/vercel/vercel-parse.js.map +1 -0
- package/dist/infra/vercel/vercel.d.ts +30 -0
- package/dist/infra/vercel/vercel.d.ts.map +1 -0
- package/dist/infra/vercel/vercel.js +523 -0
- package/dist/infra/vercel/vercel.js.map +1 -0
- package/dist/infra/walk.d.ts +36 -0
- package/dist/infra/walk.d.ts.map +1 -0
- package/dist/infra/walk.js +85 -0
- package/dist/infra/walk.js.map +1 -0
- package/dist/safety.d.ts +13 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +67 -0
- package/dist/safety.js.map +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +111 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +35 -0
- package/dist/version.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface HclBlock {
|
|
2
|
+
type: string;
|
|
3
|
+
labels: string[];
|
|
4
|
+
body: string;
|
|
5
|
+
/**
|
|
6
|
+
* repo-relative dir of the `.tf`/`.tofu` file this block came from
|
|
7
|
+
* ('' = repo root). parseHcl doesn't set it (it parses one text blob); the
|
|
8
|
+
* adapter's extract() stamps it per file so source-dir attributes (and
|
|
9
|
+
* `${path.module}` refs) resolve against the right module dir.
|
|
10
|
+
*/
|
|
11
|
+
dir?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Parse top-level HCL blocks. Nested blocks stay inside their parent's body. */
|
|
14
|
+
export declare function parseHcl(text: string): HclBlock[];
|
|
15
|
+
/**
|
|
16
|
+
* The "reference surface" of an HCL body: the text where a resource reference
|
|
17
|
+
* could legitimately live — bare HCL traversals (outside any string) plus the
|
|
18
|
+
* contents of `${…}` interpolations (which may sit inside strings). PR #9
|
|
19
|
+
* review: a plain substring scan matched addresses inside prose
|
|
20
|
+
* (`description = "see aws_lambda_function.api docs"`) and invented phantom
|
|
21
|
+
* edges. Stripping string prose (but keeping interpolations) + dropping heredoc
|
|
22
|
+
* bodies removes that false-positive class. Bias is toward MISSING a reference
|
|
23
|
+
* over INVENTING one — an absent edge is recoverable, a phantom edge lies.
|
|
24
|
+
*/
|
|
25
|
+
export declare function referenceSurface(body: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether `text` references the Terraform address `addr` (e.g. `aws_x.api` or
|
|
28
|
+
* `data.aws_y.foo`). Matches the address not preceded by a word char/dot and
|
|
29
|
+
* not followed by a word char — so attribute access (`addr.arn`) counts but a
|
|
30
|
+
* longer sibling name (`addr2`) does not. Callers pass `referenceSurface(body)`
|
|
31
|
+
* so prose inside string literals can't produce phantom matches.
|
|
32
|
+
*/
|
|
33
|
+
export declare function bodyReferences(text: string, addr: string): boolean;
|
|
34
|
+
//# sourceMappingURL=hcl-parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hcl-parse.d.ts","sourceRoot":"","sources":["../../../src/infra/terraform/hcl-parse.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4ED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CA0BjD;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkDrD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAOlE"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// a dependency-free HCL-subset parser.
|
|
2
|
+
//
|
|
3
|
+
// DECISION (v0): rather than take an npm HCL dependency (the ticket floats
|
|
4
|
+
// `hcl2-parser` "if mature"), we parse the HCL SUBSET Terraform configs use
|
|
5
|
+
// with the standard library only. Rationale: (1) it preserves the phase's
|
|
6
|
+
// vitest pure-import invariant — a parser that drags no transitive deps stays
|
|
7
|
+
// unit-testable in isolation; (2) it avoids a supply-chain dependency on an
|
|
8
|
+
// HCL parser of uncertain maintenance for a v0; (3) the dogfood repo (backthread) has
|
|
9
|
+
// no `.tf` at all, so Terraform support is validated by fixtures, not the
|
|
10
|
+
// dogfood. The subset covers what the topology needs: top-level blocks
|
|
11
|
+
// (provider / resource / data / module / variable / output …), their labels,
|
|
12
|
+
// and the raw body text (for cross-resource reference scanning). It does NOT
|
|
13
|
+
// evaluate expressions, resolve variables, or recurse into module sources —
|
|
14
|
+
// those are tracked refinements, not v0 requirements.
|
|
15
|
+
// Strip `#` and `//` line comments and C-style block comments (string-aware).
|
|
16
|
+
function stripComments(text) {
|
|
17
|
+
let out = '';
|
|
18
|
+
let inString = false;
|
|
19
|
+
let escaped = false;
|
|
20
|
+
for (let i = 0; i < text.length; i++) {
|
|
21
|
+
const c = text[i];
|
|
22
|
+
const next = text[i + 1];
|
|
23
|
+
if (inString) {
|
|
24
|
+
out += c;
|
|
25
|
+
if (escaped)
|
|
26
|
+
escaped = false;
|
|
27
|
+
else if (c === '\\')
|
|
28
|
+
escaped = true;
|
|
29
|
+
else if (c === '"')
|
|
30
|
+
inString = false;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (c === '"') {
|
|
34
|
+
inString = true;
|
|
35
|
+
out += c;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (c === '#') {
|
|
39
|
+
while (i < text.length && text[i] !== '\n')
|
|
40
|
+
i++;
|
|
41
|
+
out += '\n';
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (c === '/' && next === '/') {
|
|
45
|
+
while (i < text.length && text[i] !== '\n')
|
|
46
|
+
i++;
|
|
47
|
+
out += '\n';
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (c === '/' && next === '*') {
|
|
51
|
+
i += 2;
|
|
52
|
+
while (i < text.length && !(text[i] === '*' && text[i + 1] === '/'))
|
|
53
|
+
i++;
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
out += c;
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
// Index of the `}` matching the `{` at openIndex (string-aware brace balance).
|
|
62
|
+
function matchBrace(src, openIndex) {
|
|
63
|
+
let depth = 0;
|
|
64
|
+
let inString = false;
|
|
65
|
+
let escaped = false;
|
|
66
|
+
for (let i = openIndex; i < src.length; i++) {
|
|
67
|
+
const c = src[i];
|
|
68
|
+
if (inString) {
|
|
69
|
+
if (escaped)
|
|
70
|
+
escaped = false;
|
|
71
|
+
else if (c === '\\')
|
|
72
|
+
escaped = true;
|
|
73
|
+
else if (c === '"')
|
|
74
|
+
inString = false;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (c === '"')
|
|
78
|
+
inString = true;
|
|
79
|
+
else if (c === '{')
|
|
80
|
+
depth++;
|
|
81
|
+
else if (c === '}') {
|
|
82
|
+
depth--;
|
|
83
|
+
if (depth === 0)
|
|
84
|
+
return i;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return src.length - 1; // unbalanced — treat rest of file as the body
|
|
88
|
+
}
|
|
89
|
+
function parseLabels(raw) {
|
|
90
|
+
const labels = [];
|
|
91
|
+
const re = /"([^"]*)"|([A-Za-z0-9_.-]+)/g;
|
|
92
|
+
let m;
|
|
93
|
+
while ((m = re.exec(raw)))
|
|
94
|
+
labels.push(m[1] ?? m[2]);
|
|
95
|
+
return labels;
|
|
96
|
+
}
|
|
97
|
+
const HEADER = /^([A-Za-z_]\w*)((?:\s+(?:"[^"]*"|[A-Za-z0-9_.-]+))*)\s*\{/;
|
|
98
|
+
/** Parse top-level HCL blocks. Nested blocks stay inside their parent's body. */
|
|
99
|
+
export function parseHcl(text) {
|
|
100
|
+
const src = stripComments(text);
|
|
101
|
+
const blocks = [];
|
|
102
|
+
let i = 0;
|
|
103
|
+
while (i < src.length) {
|
|
104
|
+
const c = src[i];
|
|
105
|
+
// Only attempt a header at a token boundary (start, after whitespace or a
|
|
106
|
+
// closing brace) — keeps the scan O(n) in practice on real configs.
|
|
107
|
+
const boundary = i === 0 || /[\s}]/.test(src[i - 1]);
|
|
108
|
+
if (boundary && /[A-Za-z_]/.test(c)) {
|
|
109
|
+
const m = HEADER.exec(src.slice(i));
|
|
110
|
+
if (m) {
|
|
111
|
+
const bodyOpen = i + m[0].length - 1; // index of the `{`
|
|
112
|
+
const bodyClose = matchBrace(src, bodyOpen);
|
|
113
|
+
blocks.push({
|
|
114
|
+
type: m[1],
|
|
115
|
+
labels: parseLabels(m[2]),
|
|
116
|
+
body: src.slice(bodyOpen + 1, bodyClose),
|
|
117
|
+
});
|
|
118
|
+
i = bodyClose + 1;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
i++;
|
|
123
|
+
}
|
|
124
|
+
return blocks;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The "reference surface" of an HCL body: the text where a resource reference
|
|
128
|
+
* could legitimately live — bare HCL traversals (outside any string) plus the
|
|
129
|
+
* contents of `${…}` interpolations (which may sit inside strings). PR #9
|
|
130
|
+
* review: a plain substring scan matched addresses inside prose
|
|
131
|
+
* (`description = "see aws_lambda_function.api docs"`) and invented phantom
|
|
132
|
+
* edges. Stripping string prose (but keeping interpolations) + dropping heredoc
|
|
133
|
+
* bodies removes that false-positive class. Bias is toward MISSING a reference
|
|
134
|
+
* over INVENTING one — an absent edge is recoverable, a phantom edge lies.
|
|
135
|
+
*/
|
|
136
|
+
export function referenceSurface(body) {
|
|
137
|
+
// Drop heredoc bodies wholesale (policy docs / prose; rarely carry real
|
|
138
|
+
// traversals, and keeping them risks phantom edges).
|
|
139
|
+
const s = body.replace(/<<-?\s*(["']?)(\w+)\1[^\n]*\n[\s\S]*?\n[ \t]*\2\b/g, ' ');
|
|
140
|
+
let out = '';
|
|
141
|
+
let inString = false;
|
|
142
|
+
let escaped = false;
|
|
143
|
+
for (let i = 0; i < s.length; i++) {
|
|
144
|
+
const c = s[i];
|
|
145
|
+
if (inString) {
|
|
146
|
+
if (escaped) {
|
|
147
|
+
escaped = false;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (c === '\\') {
|
|
151
|
+
escaped = true;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (c === '"') {
|
|
155
|
+
inString = false;
|
|
156
|
+
out += ' ';
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (c === '$' && s[i + 1] === '{') {
|
|
160
|
+
// Keep brace-balanced interpolation contents — a real reference.
|
|
161
|
+
let depth = 0;
|
|
162
|
+
let j = i;
|
|
163
|
+
for (; j < s.length; j++) {
|
|
164
|
+
if (s[j] === '{')
|
|
165
|
+
depth++;
|
|
166
|
+
else if (s[j] === '}') {
|
|
167
|
+
depth--;
|
|
168
|
+
if (depth === 0) {
|
|
169
|
+
j++;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
out += ` ${s.slice(i, j)} `;
|
|
175
|
+
i = j - 1;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
continue; // ordinary in-string prose — drop
|
|
179
|
+
}
|
|
180
|
+
if (c === '"') {
|
|
181
|
+
inString = true;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
out += c;
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Whether `text` references the Terraform address `addr` (e.g. `aws_x.api` or
|
|
190
|
+
* `data.aws_y.foo`). Matches the address not preceded by a word char/dot and
|
|
191
|
+
* not followed by a word char — so attribute access (`addr.arn`) counts but a
|
|
192
|
+
* longer sibling name (`addr2`) does not. Callers pass `referenceSurface(body)`
|
|
193
|
+
* so prose inside string literals can't produce phantom matches.
|
|
194
|
+
*/
|
|
195
|
+
export function bodyReferences(text, addr) {
|
|
196
|
+
// Terraform addresses are `[A-Za-z0-9_.]` only, so the sole regex-special
|
|
197
|
+
// char to escape is `.` — keeps the pattern construction simple and avoids a
|
|
198
|
+
// brittle full-escape regex literal.
|
|
199
|
+
const escaped = addr.replace(/\./g, '\\.');
|
|
200
|
+
const re = new RegExp('(?<![\\w.])' + escaped + '(?![\\w])');
|
|
201
|
+
return re.test(text);
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=hcl-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hcl-parse.js","sourceRoot":"","sources":["../../../src/infra/terraform/hcl-parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { InfraAdapter, InfraGraph } from '../types.js';
|
|
2
|
+
import { type DockerfileIndex } from '../image-resolve.js';
|
|
3
|
+
import { type HclBlock } from './hcl-parse.js';
|
|
4
|
+
/**
|
|
5
|
+
* The repo-relative source roots a Terraform resource deploys. `dockerfileIndex`
|
|
6
|
+
* (when present) powers the image→source resolver path. Pure.
|
|
7
|
+
*/
|
|
8
|
+
export declare function terraformSourceRoots(resourceType: string, body: string, moduleDir: string, dockerfileIndex?: DockerfileIndex): string[];
|
|
9
|
+
/**
|
|
10
|
+
* Pure graph builder from parsed HCL blocks (one flattened list across files).
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildTerraformGraph(blocks: HclBlock[], root: string, dockerfileIndex?: DockerfileIndex): InfraGraph;
|
|
13
|
+
export declare const terraformAdapter: InfraAdapter;
|
|
14
|
+
//# sourceMappingURL=terraform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["../../../src/infra/terraform/terraform.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,YAAY,EAAa,UAAU,EAAgC,MAAM,aAAa,CAAC;AAGrG,OAAO,EAAmD,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC5G,OAAO,EAA8C,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAoH3F;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,eAAe,GAChC,MAAM,EAAE,CAyBV;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,eAAe,GAAG,UAAU,CA+DnH;AAED,eAAO,MAAM,gBAAgB,EAAE,YAqB9B,CAAC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// the Terraform InfraAdapter (v0): the universal IaC unlock.
|
|
2
|
+
//
|
|
3
|
+
// One adapter covers AWS / GCP / Azure / Cloudflare / Vercel / fly for any repo
|
|
4
|
+
// that uses Terraform — no per-cloud adapter needed. It parses the HCL subset
|
|
5
|
+
// (hcl-parse.ts), emits a node per `resource`/`data` block, and lets 's
|
|
6
|
+
// classifyResourceTypes decide each node's kind + domain-risk (an
|
|
7
|
+
// `aws_lambda_function` is `worker`, an `aws_sqs_queue` is `queue`, …). That
|
|
8
|
+
// classification is CACHED per (provider, resourceType) in
|
|
9
|
+
// resource_type_classifications, so `aws_lambda_function` is labelled once and
|
|
10
|
+
// reused across every Terraform repo forever.
|
|
11
|
+
//
|
|
12
|
+
// This is the ONLY v0 adapter that emits `classificationsNeeded`: CF and
|
|
13
|
+
// Supabase have tight static binding models, but Terraform's `resource` space
|
|
14
|
+
// is open-ended, so the kind decision is exactly the cross-vendor judgement the
|
|
15
|
+
// LLM cache exists for. We still emit a deterministic heuristic kind +
|
|
16
|
+
// `inferred` provenance up front so a --no-llm run (or a classifier miss) still
|
|
17
|
+
// yields a usable topology; the classify step upgrades it to `llm-classified`.
|
|
18
|
+
//
|
|
19
|
+
// Cross-resource references (`${aws_lambda_function.api.arn}`) become edges,
|
|
20
|
+
// deterministically — the reference exists in the HCL or it doesn't.
|
|
21
|
+
//
|
|
22
|
+
// v0 scope: per-provider PLATFORM/zone nodes are deferred (the locked 8-kind
|
|
23
|
+
// InfraModuleKind enum has no "platform" kind; grouping belongs to 's ELK
|
|
24
|
+
// zones + parentId, not a forced enum value). Variable/tfvars resolution and
|
|
25
|
+
// `module {}` recursion are also deferred (tracked under ).
|
|
26
|
+
import { readFileSync } from 'node:fs';
|
|
27
|
+
import { relative } from 'node:path';
|
|
28
|
+
import { findFiles } from '../walk.js';
|
|
29
|
+
import { buildDockerfileIndex, resolveImageToSourceRoots } from '../image-resolve.js';
|
|
30
|
+
import { parseHcl, bodyReferences, referenceSurface } from './hcl-parse.js';
|
|
31
|
+
const TF_SKIP_DIRS = ['node_modules', '.git', 'dist', '.wrangler', '.terraform', '.next', 'build'];
|
|
32
|
+
/** Find every `*.tf` file in the repo (bounded recursive walk). */
|
|
33
|
+
function findTfFiles(repoDir) {
|
|
34
|
+
return findFiles(repoDir, (_abs, e) => e.name.endsWith('.tf'), { skipDirs: TF_SKIP_DIRS, maxDepth: 8 });
|
|
35
|
+
}
|
|
36
|
+
// Map a resource-type prefix to its cloud, for the classify `provider` field.
|
|
37
|
+
const CLOUD_PREFIX = [
|
|
38
|
+
[/^aws_/, 'aws'],
|
|
39
|
+
[/^google_/, 'google'],
|
|
40
|
+
[/^azurerm_/, 'azure'],
|
|
41
|
+
[/^azuread_/, 'azure'],
|
|
42
|
+
[/^cloudflare_/, 'cloudflare'],
|
|
43
|
+
[/^vercel_/, 'vercel'],
|
|
44
|
+
[/^fly/, 'fly'],
|
|
45
|
+
[/^render_/, 'render'],
|
|
46
|
+
[/^digitalocean_/, 'digitalocean'],
|
|
47
|
+
];
|
|
48
|
+
function cloudFor(resourceType) {
|
|
49
|
+
for (const [re, cloud] of CLOUD_PREFIX)
|
|
50
|
+
if (re.test(resourceType))
|
|
51
|
+
return cloud;
|
|
52
|
+
// Fallback: the prefix before the first underscore (e.g. `kubernetes_x`).
|
|
53
|
+
const us = resourceType.indexOf('_');
|
|
54
|
+
return us > 0 ? resourceType.slice(0, us) : 'unknown';
|
|
55
|
+
}
|
|
56
|
+
// Deterministic fallback kind (used pre-classification / under --no-llm). The
|
|
57
|
+
// LLM cache is the authority when available; this just keeps the diagram sane
|
|
58
|
+
// without it. Substring rules, most-specific first.
|
|
59
|
+
const KIND_RULES = [
|
|
60
|
+
[/lambda|function|cloud_run|cloudfunction|app_runner|fargate|ecs_task/, 'worker'],
|
|
61
|
+
[/container|ecs_service|kubernetes|instance|compute|droplet|machine/, 'container'],
|
|
62
|
+
[/sqs|pubsub|queue|kinesis|eventbridge|event_bus|kafka|sns/, 'queue'],
|
|
63
|
+
[/dynamodb|rds|s3_bucket|bucket|database|_db|sql|spanner|firestore|bigtable|redis|elasticache|table|storage_bucket/, 'datastore'],
|
|
64
|
+
[/secret|kms|vault|key_vault/, 'secret-store'],
|
|
65
|
+
[/cloudfront|cdn|fastly/, 'cdn'],
|
|
66
|
+
[/api_gateway|cdn_domain/, 'cdn'],
|
|
67
|
+
];
|
|
68
|
+
function heuristicKind(resourceType) {
|
|
69
|
+
for (const [re, kind] of KIND_RULES)
|
|
70
|
+
if (re.test(resourceType))
|
|
71
|
+
return kind;
|
|
72
|
+
// PR #9 review: there is no neutral "unknown" member in the locked
|
|
73
|
+
// InfraModuleKind enum (and adding one ripples through the cache CHECK
|
|
74
|
+
// constraint, KIND_COLUMN, salience, icons — not worth it for a debug path).
|
|
75
|
+
// `datastore` is the single most common infra resource, so it's the
|
|
76
|
+
// least-bad heuristic guess — but it is NOT load-bearing: when the LLM runs
|
|
77
|
+
// (the real pipeline always classifies), classifyResourceTypes overwrites
|
|
78
|
+
// this kind; only a --no-llm run keeps it, and edges no longer depend on it
|
|
79
|
+
// (see below). A future neutral kind is tracked under the expansion.
|
|
80
|
+
return 'datastore';
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// source-root extraction (deterministic, no LLM).
|
|
84
|
+
//
|
|
85
|
+
// Two signals: (1) DIRECT source dirs declared in HCL (archive/lambda
|
|
86
|
+
// `source_dir`, lambda `filename`, docker `build { context }`) → that dir; and
|
|
87
|
+
// (2) image refs (`image = "…"`, docker `name = "…"`) → the resolver.
|
|
88
|
+
// Unresolvable / interpolated → nothing (honest "Other").
|
|
89
|
+
/** Normalize a repo-relative path: backslashes→/, collapse `.`/`./`, strip trailing `/`. */
|
|
90
|
+
function normalizeRoot(p) {
|
|
91
|
+
return p.replace(/\\/g, '/').replace(/^\.(?:\/|$)/, '').replace(/\/+$/, '');
|
|
92
|
+
}
|
|
93
|
+
/** The repo-relative directory of a repo-relative file path ('' = repo root). */
|
|
94
|
+
function dirOfPath(relPath) {
|
|
95
|
+
const i = relPath.lastIndexOf('/');
|
|
96
|
+
return i === -1 ? '' : relPath.slice(0, i);
|
|
97
|
+
}
|
|
98
|
+
/** Resolve `rel` (may contain `./`/`../`) against repo-relative `baseDir` → normalized. */
|
|
99
|
+
function resolveRel(baseDir, rel) {
|
|
100
|
+
const parts = (baseDir ? baseDir.split('/') : []).concat(rel.split('/'));
|
|
101
|
+
const out = [];
|
|
102
|
+
for (const p of parts) {
|
|
103
|
+
if (p === '' || p === '.')
|
|
104
|
+
continue;
|
|
105
|
+
if (p === '..')
|
|
106
|
+
out.pop();
|
|
107
|
+
else
|
|
108
|
+
out.push(p);
|
|
109
|
+
}
|
|
110
|
+
return out.join('/');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Resolve an HCL path value (`source_dir`/`filename`/`context`) to a repo-relative
|
|
114
|
+
* dir. Handles `${path.module}` (relative to the .tf file's dir) and `${path.root}`
|
|
115
|
+
* (repo root). Returns '' when the value carries any OTHER `${…}` interpolation
|
|
116
|
+
* (unresolvable → skip, never guess).
|
|
117
|
+
*/
|
|
118
|
+
function resolveTfPath(moduleDir, raw) {
|
|
119
|
+
let v = raw.trim();
|
|
120
|
+
let base = moduleDir;
|
|
121
|
+
if (v.includes('${path.root}'))
|
|
122
|
+
base = '';
|
|
123
|
+
v = v.replace(/\$\{path\.(module|root|cwd)\}/g, '');
|
|
124
|
+
if (v.includes('${'))
|
|
125
|
+
return ''; // an unresolved var/ref — don't guess
|
|
126
|
+
v = v.replace(/^\/+/, '');
|
|
127
|
+
return resolveRel(base, v);
|
|
128
|
+
}
|
|
129
|
+
/** All `attr = "VALUE"` (HCL) and `"attr": "VALUE"` (JSON-in-HCL) literal values. */
|
|
130
|
+
function attrValues(body, attr) {
|
|
131
|
+
const re = new RegExp(`(?:"${attr}"|\\b${attr})\\s*[=:]\\s*"([^"]+)"`, 'g');
|
|
132
|
+
const out = [];
|
|
133
|
+
let m;
|
|
134
|
+
while ((m = re.exec(body)) !== null)
|
|
135
|
+
out.push(m[1]);
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The repo-relative source roots a Terraform resource deploys. `dockerfileIndex`
|
|
140
|
+
* (when present) powers the image→source resolver path. Pure.
|
|
141
|
+
*/
|
|
142
|
+
export function terraformSourceRoots(resourceType, body, moduleDir, dockerfileIndex) {
|
|
143
|
+
const roots = new Set();
|
|
144
|
+
const addDir = (d) => {
|
|
145
|
+
const n = normalizeRoot(d);
|
|
146
|
+
if (n)
|
|
147
|
+
roots.add(n);
|
|
148
|
+
};
|
|
149
|
+
const isDocker = /docker/i.test(resourceType);
|
|
150
|
+
const isLambdaish = /lambda|function/i.test(resourceType);
|
|
151
|
+
// (1) Direct source dirs.
|
|
152
|
+
for (const v of attrValues(body, 'source_dir'))
|
|
153
|
+
addDir(resolveTfPath(moduleDir, v)); // archive_file / lambda
|
|
154
|
+
if (isLambdaish)
|
|
155
|
+
for (const v of attrValues(body, 'filename'))
|
|
156
|
+
addDir(dirOfPath(resolveTfPath(moduleDir, v)));
|
|
157
|
+
if (isDocker)
|
|
158
|
+
for (const v of attrValues(body, 'context'))
|
|
159
|
+
addDir(resolveTfPath(moduleDir, v)); // docker build context
|
|
160
|
+
// (2) Image refs → resolver (literal refs only; interpolated → skip).
|
|
161
|
+
if (dockerfileIndex) {
|
|
162
|
+
const imageRefs = attrValues(body, 'image');
|
|
163
|
+
if (isDocker)
|
|
164
|
+
imageRefs.push(...attrValues(body, 'name')); // docker_image `name`
|
|
165
|
+
for (const ref of imageRefs) {
|
|
166
|
+
if (!ref || ref.includes('${'))
|
|
167
|
+
continue;
|
|
168
|
+
for (const r of resolveImageToSourceRoots(ref, dockerfileIndex))
|
|
169
|
+
roots.add(r);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return [...roots].sort();
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Pure graph builder from parsed HCL blocks (one flattened list across files).
|
|
176
|
+
*/
|
|
177
|
+
export function buildTerraformGraph(blocks, root, dockerfileIndex) {
|
|
178
|
+
const resources = [];
|
|
179
|
+
for (const b of blocks) {
|
|
180
|
+
if ((b.type === 'resource' || b.type === 'data') && b.labels.length >= 2) {
|
|
181
|
+
const [resourceType, name] = b.labels;
|
|
182
|
+
const isData = b.type === 'data';
|
|
183
|
+
resources.push({
|
|
184
|
+
nodeId: `${isData ? 'data' : 'resource'}:${resourceType}.${name}`,
|
|
185
|
+
refAddr: `${isData ? 'data.' : ''}${resourceType}.${name}`,
|
|
186
|
+
resourceType,
|
|
187
|
+
body: b.body,
|
|
188
|
+
isData,
|
|
189
|
+
dir: b.dir ?? '',
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const nodes = [];
|
|
194
|
+
const classificationsNeeded = [];
|
|
195
|
+
for (const r of resources) {
|
|
196
|
+
const kind = heuristicKind(r.resourceType);
|
|
197
|
+
// deployment-target source roots (direct dirs + image→resolver).
|
|
198
|
+
const roots = terraformSourceRoots(r.resourceType, r.body, r.dir, dockerfileIndex);
|
|
199
|
+
nodes.push({
|
|
200
|
+
id: r.nodeId,
|
|
201
|
+
label: r.refAddr,
|
|
202
|
+
kind,
|
|
203
|
+
provenance: 'inferred', // upgraded to llm-classified by the classify step
|
|
204
|
+
metadata: { provider: cloudFor(r.resourceType), resourceType: r.resourceType, ...(r.isData ? { data: true } : {}) },
|
|
205
|
+
...(roots.length ? { sourceRoots: roots } : {}),
|
|
206
|
+
});
|
|
207
|
+
classificationsNeeded.push({
|
|
208
|
+
provider: `terraform/${cloudFor(r.resourceType)}`,
|
|
209
|
+
resourceType: r.resourceType,
|
|
210
|
+
forNodeId: r.nodeId,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
// Cross-resource edges: a resource that references another's address depends
|
|
214
|
+
// on it. The verb is ALWAYS `calls` (PR #9 review): an HCL reference is a
|
|
215
|
+
// structural dependency, not a known read/write/publish — and deriving the
|
|
216
|
+
// verb from the *heuristic* target kind was both a guess and stale (the LLM
|
|
217
|
+
// rewrites kinds afterward, but the edge verb was never recomputed). `calls`
|
|
218
|
+
// is the honest general structural verb (what coerceEdgeKind maps onto), so
|
|
219
|
+
// it stays correct regardless of how classification later labels the target.
|
|
220
|
+
// Matching runs over each source's reference SURFACE (string prose stripped)
|
|
221
|
+
// so a resource named in a description doesn't invent a phantom edge.
|
|
222
|
+
const surfaceById = new Map(resources.map((r) => [r.nodeId, referenceSurface(r.body)]));
|
|
223
|
+
const edges = [];
|
|
224
|
+
const seen = new Set();
|
|
225
|
+
for (const src of resources) {
|
|
226
|
+
const surface = surfaceById.get(src.nodeId);
|
|
227
|
+
for (const tgt of resources) {
|
|
228
|
+
if (src.nodeId === tgt.nodeId)
|
|
229
|
+
continue;
|
|
230
|
+
if (!bodyReferences(surface, tgt.refAddr))
|
|
231
|
+
continue;
|
|
232
|
+
const key = `${src.nodeId}→${tgt.nodeId}`;
|
|
233
|
+
if (seen.has(key))
|
|
234
|
+
continue;
|
|
235
|
+
seen.add(key);
|
|
236
|
+
edges.push({ source: src.nodeId, target: tgt.nodeId, kind: 'calls', metadata: { via: 'tf-ref' } });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return { root, adapter: 'terraform', nodes, edges, classificationsNeeded };
|
|
240
|
+
}
|
|
241
|
+
export const terraformAdapter = {
|
|
242
|
+
name: 'terraform',
|
|
243
|
+
async detect(repoDir) {
|
|
244
|
+
return findTfFiles(repoDir).length > 0;
|
|
245
|
+
},
|
|
246
|
+
async extract(repoDir) {
|
|
247
|
+
const blocks = [];
|
|
248
|
+
for (const file of findTfFiles(repoDir)) {
|
|
249
|
+
const dir = dirOfPath((relative(repoDir, file) || file).split('\\').join('/'));
|
|
250
|
+
try {
|
|
251
|
+
for (const b of parseHcl(readFileSync(file, 'utf8'))) {
|
|
252
|
+
b.dir = dir; // module dir for source-path resolution
|
|
253
|
+
blocks.push(b);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
console.warn(` [terraform] skipping unparseable ${relative(repoDir, file)}: ${err.message}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Dockerfile index for image-referencing resources.
|
|
261
|
+
return buildTerraformGraph(blocks, repoDir, buildDockerfileIndex(repoDir));
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
//# sourceMappingURL=terraform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform.js","sourceRoot":"","sources":["../../../src/infra/terraform/terraform.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,wEAAwE;AACxE,kEAAkE;AAClE,6EAA6E;AAC7E,2DAA2D;AAC3D,+EAA+E;AAC/E,8CAA8C;AAC9C,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,gFAAgF;AAChF,uEAAuE;AACvE,gFAAgF;AAChF,+EAA+E;AAC/E,EAAE;AACF,6EAA6E;AAC7E,qEAAqE;AACrE,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,6EAA6E;AAC7E,4DAA4D;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAwB,MAAM,qBAAqB,CAAC;AAC5G,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAiB,MAAM,gBAAgB,CAAC;AAE3F,MAAM,YAAY,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAEnG,mEAAmE;AACnE,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AAC1G,CAAC;AAED,8EAA8E;AAC9E,MAAM,YAAY,GAA4B;IAC5C,CAAC,OAAO,EAAE,KAAK,CAAC;IAChB,CAAC,UAAU,EAAE,QAAQ,CAAC;IACtB,CAAC,WAAW,EAAE,OAAO,CAAC;IACtB,CAAC,WAAW,EAAE,OAAO,CAAC;IACtB,CAAC,cAAc,EAAE,YAAY,CAAC;IAC9B,CAAC,UAAU,EAAE,QAAQ,CAAC;IACtB,CAAC,MAAM,EAAE,KAAK,CAAC;IACf,CAAC,UAAU,EAAE,QAAQ,CAAC;IACtB,CAAC,gBAAgB,EAAE,cAAc,CAAC;CACnC,CAAC;AACF,SAAS,QAAQ,CAAC,YAAoB;IACpC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,YAAY;QAAE,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,KAAK,CAAC;IAChF,0EAA0E;IAC1E,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,8EAA8E;AAC9E,oDAAoD;AACpD,MAAM,UAAU,GAAqC;IACnD,CAAC,qEAAqE,EAAE,QAAQ,CAAC;IACjF,CAAC,mEAAmE,EAAE,WAAW,CAAC;IAClF,CAAC,0DAA0D,EAAE,OAAO,CAAC;IACrE,CAAC,kHAAkH,EAAE,WAAW,CAAC;IACjI,CAAC,4BAA4B,EAAE,cAAc,CAAC;IAC9C,CAAC,uBAAuB,EAAE,KAAK,CAAC;IAChC,CAAC,wBAAwB,EAAE,KAAK,CAAC;CAClC,CAAC;AACF,SAAS,aAAa,CAAC,YAAoB;IACzC,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,UAAU;QAAE,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;IAC5E,mEAAmE;IACnE,uEAAuE;IACvE,6EAA6E;IAC7E,oEAAoE;IACpE,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,sEAAsE;IACtE,OAAO,WAAW,CAAC;AACrB,CAAC;AAWD,8EAA8E;AAC9E,kDAAkD;AAClD,EAAE;AACF,sEAAsE;AACtE,+EAA+E;AAC/E,uEAAuE;AACvE,0DAA0D;AAE1D,4FAA4F;AAC5F,SAAS,aAAa,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC9E,CAAC;AACD,iFAAiF;AACjF,SAAS,SAAS,CAAC,OAAe;IAChC,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC;AACD,2FAA2F;AAC3F,SAAS,UAAU,CAAC,OAAe,EAAE,GAAW;IAC9C,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACzE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG;YAAE,SAAS;QACpC,IAAI,CAAC,KAAK,IAAI;YAAE,GAAG,CAAC,GAAG,EAAE,CAAC;;YACrB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,SAAiB,EAAE,GAAW;IACnD,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACnB,IAAI,IAAI,GAAG,SAAS,CAAC;IACrB,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,IAAI,GAAG,EAAE,CAAC;IAC1C,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,gCAAgC,EAAE,EAAE,CAAC,CAAC;IACpD,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC,CAAC,sCAAsC;IACvE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1B,OAAO,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,qFAAqF;AACrF,SAAS,UAAU,CAAC,IAAY,EAAE,IAAY;IAC5C,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,OAAO,IAAI,QAAQ,IAAI,wBAAwB,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,IAAY,EACZ,SAAiB,EACjB,eAAiC;IAEjC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE;QAC3B,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAE1D,0BAA0B;IAC1B,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC;QAAE,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IAC7G,IAAI,WAAW;QAAE,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC;YAAE,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9G,IAAI,QAAQ;QAAE,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;YAAE,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;IAEvH,sEAAsE;IACtE,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,QAAQ;YAAE,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,sBAAsB;QACjF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,SAAS;YACzC,KAAK,MAAM,CAAC,IAAI,yBAAyB,CAAC,GAAG,EAAE,eAAe,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB,EAAE,IAAY,EAAE,eAAiC;IACrG,MAAM,SAAS,GAAiB,EAAE,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACzE,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YACtC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;YACjC,SAAS,CAAC,IAAI,CAAC;gBACb,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,YAAY,IAAI,IAAI,EAAE;gBACjE,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,IAAI,IAAI,EAAE;gBAC1D,YAAY;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM;gBACN,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,qBAAqB,GAAwB,EAAE,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QAC3C,iEAAiE;QACjE,MAAM,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,CAAC,CAAC,MAAM;YACZ,KAAK,EAAE,CAAC,CAAC,OAAO;YAChB,IAAI;YACJ,UAAU,EAAE,UAAU,EAAE,kDAAkD;YAC1E,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;YACnH,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,qBAAqB,CAAC,IAAI,CAAC;YACzB,QAAQ,EAAE,aAAa,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;YACjD,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,SAAS,EAAE,CAAC,CAAC,MAAM;SACpB,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,0EAA0E;IAC1E,2EAA2E;IAC3E,4EAA4E;IAC5E,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,sEAAsE;IACtE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM;gBAAE,SAAS;YACxC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS;YACpD,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,WAAW;IACjB,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,MAAM,MAAM,GAAe,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC;gBACH,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;oBACrD,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,wCAAwC;oBACrD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,sCAAsC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3G,CAAC;QACH,CAAC;QACD,oDAAoD;QACpD,OAAO,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7E,CAAC;CACF,CAAC"}
|