@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,502 @@
|
|
|
1
|
+
// GCP-native InfraAdapter (v0).
|
|
2
|
+
//
|
|
3
|
+
// Covers Cloud Run, App Engine, and GKE (k8s manifests).
|
|
4
|
+
// Strategy:
|
|
5
|
+
// - Cloud Run Service (Knative) → `worker` (serverless container)
|
|
6
|
+
// - App Engine service → `worker` (or `static-site` for static-only handlers)
|
|
7
|
+
// - Cloud Functions → `worker`
|
|
8
|
+
// - k8s Deployment / StatefulSet / Job / CronJob → `container`
|
|
9
|
+
// - k8s Ingress → routing metadata ONLY; modelled as edges
|
|
10
|
+
// (Ingress→Service calls, Service→Deployment calls)
|
|
11
|
+
// NOT a node — no InfraModuleKind fits routing
|
|
12
|
+
// - k8s Service (clusterIP/LB) → same: emit as routing edges, not a node
|
|
13
|
+
// - Cloud SQL / Memorystore env refs → `datastore`
|
|
14
|
+
//
|
|
15
|
+
// Provenance is `declared` for every well-known shape here. The only shapes
|
|
16
|
+
// that go into `classificationsNeeded` would be genuinely ambiguous custom
|
|
17
|
+
// resources — there are none in v0 scope; the list is empty.
|
|
18
|
+
//
|
|
19
|
+
// Edges emitted:
|
|
20
|
+
// calls — Ingress → Service → Deployment (k8s routing chain)
|
|
21
|
+
// stores-in — workload → Cloud SQL / Memorystore datastore (env reference)
|
|
22
|
+
//
|
|
23
|
+
// DEFERRED (documented):
|
|
24
|
+
// - Deployment Manager .jinja
|
|
25
|
+
// - cloudbuild.yaml deploy-mechanism parsing
|
|
26
|
+
// - Per-env GKE namespace grouping / parentId zones ( ELK work)
|
|
27
|
+
// - Cross-service discovery (GCP service mesh, VPC connectors)
|
|
28
|
+
// Tracked under / .
|
|
29
|
+
import { readFileSync } from 'node:fs';
|
|
30
|
+
import { relative } from 'node:path';
|
|
31
|
+
import { findFiles } from '../walk.js';
|
|
32
|
+
import { extractSelector, extractIngressBackends, labelsOverlap, workloadSourceRoots } from '../k8s/index.js';
|
|
33
|
+
import { buildDockerfileIndex, resolveImageToSourceRoots } from '../image-resolve.js';
|
|
34
|
+
import { parseGcpFile } from './gcp-parse.js';
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// File discovery.
|
|
37
|
+
// Well-known GCP config filenames checked first in cheap detect().
|
|
38
|
+
const GCP_CONFIG_NAMES = new Set(['service.yaml', 'app.yaml', 'cloudbuild.yaml', 'functions.yaml']);
|
|
39
|
+
const GCP_SKIP_DIRS = [
|
|
40
|
+
'node_modules', '.git', 'dist', '.wrangler', '.next', 'build', 'coverage',
|
|
41
|
+
'__pycache__', '.venv', 'vendor',
|
|
42
|
+
];
|
|
43
|
+
/** Find every *.yaml / *.yml in the repo (bounded recursive walk). */
|
|
44
|
+
function findYamlFiles(repoDir) {
|
|
45
|
+
return findFiles(repoDir, (_abs, e) => e.name.endsWith('.yaml') || e.name.endsWith('.yml'), {
|
|
46
|
+
skipDirs: GCP_SKIP_DIRS,
|
|
47
|
+
maxDepth: 6,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Id helpers (adapter-local; registry prefixes `gcp:`).
|
|
52
|
+
const crId = (name) => `cloudrun:${name}`;
|
|
53
|
+
const aeId = (name) => `appengine:${name}`;
|
|
54
|
+
const cfId = (name) => `functions:${name}`;
|
|
55
|
+
const k8sWorkloadId = (name) => `k8s:workload:${name}`;
|
|
56
|
+
const datastoreId = (name) => `datastore:${name}`;
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Source-root path helpers.
|
|
59
|
+
/** Normalize a repo-relative path: backslashes→/, collapse `.`/`./`, strip trailing `/`. */
|
|
60
|
+
function normalizeRoot(p) {
|
|
61
|
+
return p.replace(/\\/g, '/').replace(/^\.(?:\/|$)/, '').replace(/\/+$/, '');
|
|
62
|
+
}
|
|
63
|
+
/** The repo-relative directory of a repo-relative file path ('' = repo root). */
|
|
64
|
+
function dirOfPath(relPath) {
|
|
65
|
+
const n = relPath.split('\\').join('/');
|
|
66
|
+
const i = n.lastIndexOf('/');
|
|
67
|
+
return i === -1 ? '' : n.slice(0, i);
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Cloud SQL / Memorystore env reference heuristics.
|
|
71
|
+
//
|
|
72
|
+
// Deployment manifests often pass connection strings via env vars:
|
|
73
|
+
// DATABASE_URL, CLOUDSQL_CONNECTION, CLOUD_SQL_CONN, DB_HOST, REDIS_URL, etc.
|
|
74
|
+
// We scan envFrom / env arrays for these patterns.
|
|
75
|
+
// Cloud SQL env heuristic — key must have one of the anchored suffixes
|
|
76
|
+
// (_URL / _HOST / _CONNECTION / _CONN / _DSN) or the key itself contains
|
|
77
|
+
// `cloudsql` or `cloud_sql`. Bare `POSTGRES` / `POSTGRES_VERSION` etc. are
|
|
78
|
+
// excluded on purpose; value is also checked for a `cloudsql` proxy path or
|
|
79
|
+
// postgres:// scheme as a tiebreaker.
|
|
80
|
+
const CLOUD_SQL_KEY_RE = /(?:cloud.?sql|database|db|pg|postgres)(?:_url|_host|_connection|_conn|_dsn)$/i;
|
|
81
|
+
const CLOUD_SQL_NAME_RE = /cloud.?sql/i; // covers CLOUDSQL_CONNECTION, CLOUD_SQL_CONN
|
|
82
|
+
const CLOUD_SQL_VALUE_RE = /cloudsql|postgres:\/\//i;
|
|
83
|
+
const MEMORYSTORE_RE = /redis.?url|memorystore|redis.?host/i;
|
|
84
|
+
function extractEnvDatastoreRefs(raw) {
|
|
85
|
+
const refs = [];
|
|
86
|
+
const seen = new Set();
|
|
87
|
+
// Pull env items from spec.template.spec.containers[].env
|
|
88
|
+
// or from spec.containers[].env (for simpler shapes)
|
|
89
|
+
const spec = raw['spec'];
|
|
90
|
+
const template = spec?.['template'];
|
|
91
|
+
const innerSpec = (template?.['spec'] ?? spec);
|
|
92
|
+
const containers = innerSpec?.['containers'];
|
|
93
|
+
if (!Array.isArray(containers))
|
|
94
|
+
return refs;
|
|
95
|
+
for (const c of containers) {
|
|
96
|
+
if (typeof c !== 'object' || c === null)
|
|
97
|
+
continue;
|
|
98
|
+
const env = c['env'];
|
|
99
|
+
if (!Array.isArray(env))
|
|
100
|
+
continue;
|
|
101
|
+
for (const e of env) {
|
|
102
|
+
if (typeof e !== 'object' || e === null)
|
|
103
|
+
continue;
|
|
104
|
+
const envObj = e;
|
|
105
|
+
const k = typeof envObj['name'] === 'string' ? envObj['name'] : '';
|
|
106
|
+
if (!k)
|
|
107
|
+
continue;
|
|
108
|
+
let id;
|
|
109
|
+
let label;
|
|
110
|
+
const v = typeof envObj['value'] === 'string' ? envObj['value'] : '';
|
|
111
|
+
const isCloudSql = CLOUD_SQL_KEY_RE.test(k) || CLOUD_SQL_NAME_RE.test(k) || CLOUD_SQL_VALUE_RE.test(v);
|
|
112
|
+
if (isCloudSql) {
|
|
113
|
+
id = datastoreId('cloud-sql');
|
|
114
|
+
label = 'Cloud SQL';
|
|
115
|
+
}
|
|
116
|
+
else if (MEMORYSTORE_RE.test(k)) {
|
|
117
|
+
id = datastoreId('memorystore');
|
|
118
|
+
label = 'Memorystore';
|
|
119
|
+
}
|
|
120
|
+
if (id && !seen.has(id)) {
|
|
121
|
+
seen.add(id);
|
|
122
|
+
refs.push({ datastoreNodeId: id, label: label });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return refs;
|
|
127
|
+
}
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// k8s selector-based Service→Deployment matching.
|
|
130
|
+
//
|
|
131
|
+
// A k8s Service selects Deployments by `.spec.selector.matchLabels` (Deployment)
|
|
132
|
+
// matched against `.spec.selector` (Service). We emit a `calls` edge when
|
|
133
|
+
// selector labels overlap — the most reliable heuristic without full label
|
|
134
|
+
// evaluation. The selector/overlap primitives are shared with the other cloud
|
|
135
|
+
// adapters (scripts/ingest/infra/k8s/). GCP wraps the shared extractSelector to
|
|
136
|
+
// (a) string-filter the labels and (b) default to `{}` — both behaviors its
|
|
137
|
+
// original selectorLabels had and its overlap matcher relies on (the shared
|
|
138
|
+
// helper stays raw/undefined to preserve Azure's verbatim behavior).
|
|
139
|
+
function selectorLabels(raw) {
|
|
140
|
+
const sel = extractSelector(raw['spec']);
|
|
141
|
+
if (!sel)
|
|
142
|
+
return {};
|
|
143
|
+
const result = {};
|
|
144
|
+
for (const [k, v] of Object.entries(sel)) {
|
|
145
|
+
if (typeof v === 'string')
|
|
146
|
+
result[k] = v;
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Pure graph builder.
|
|
152
|
+
/**
|
|
153
|
+
* Pure graph builder — takes already-parsed GcpResources and emits the
|
|
154
|
+
* InfraGraph. Separated from the file walk so it can be unit-tested.
|
|
155
|
+
*/
|
|
156
|
+
export function buildGcpGraph(resources, root, dockerfileIndex) {
|
|
157
|
+
const nodes = new Map();
|
|
158
|
+
const edges = [];
|
|
159
|
+
function addNode(n) {
|
|
160
|
+
if (!nodes.has(n.id))
|
|
161
|
+
nodes.set(n.id, n);
|
|
162
|
+
}
|
|
163
|
+
function addEdge(e) {
|
|
164
|
+
edges.push(e);
|
|
165
|
+
}
|
|
166
|
+
const rel = (file) => relative(root, file) || file;
|
|
167
|
+
// a k8s workload's source roots, resolved from its container
|
|
168
|
+
// image(s) via the resolver. Empty (→ no sourceRoots) when no index is
|
|
169
|
+
// injected or no image resolves to an in-repo Dockerfile (honest "Other").
|
|
170
|
+
const wlRoots = (raw) => dockerfileIndex ? workloadSourceRoots(raw, dockerfileIndex) : [];
|
|
171
|
+
// a Cloud Run service's source roots from its container image.
|
|
172
|
+
const imageRoots = (image) => dockerfileIndex && typeof image === 'string' && image ? resolveImageToSourceRoots(image, dockerfileIndex) : [];
|
|
173
|
+
// App Engine / Cloud Functions deploy the dir holding their config
|
|
174
|
+
// (app.yaml / functions config). That dir is the source root; the bare repo
|
|
175
|
+
// root ('') is dropped (no catch-all).
|
|
176
|
+
const configDirRoots = (file) => {
|
|
177
|
+
const d = normalizeRoot(dirOfPath(rel(file)));
|
|
178
|
+
return d ? [d] : [];
|
|
179
|
+
};
|
|
180
|
+
// Collect k8s workloads and routing objects for cross-matching.
|
|
181
|
+
const k8sWorkloads = [];
|
|
182
|
+
const k8sServices = [];
|
|
183
|
+
const k8sIngresses = [];
|
|
184
|
+
for (const r of resources) {
|
|
185
|
+
const file = r.file;
|
|
186
|
+
switch (r.kind) {
|
|
187
|
+
// --- Cloud Run --------------------------------------------------------
|
|
188
|
+
case 'cloud-run': {
|
|
189
|
+
const nodeId = crId(r.name);
|
|
190
|
+
// Extract container image from spec.template.spec.containers[0].image
|
|
191
|
+
const spec = r.raw['spec'];
|
|
192
|
+
const tmpl = spec?.['template'];
|
|
193
|
+
const innerSpec = tmpl?.['spec'];
|
|
194
|
+
const containers = innerSpec?.['containers'];
|
|
195
|
+
const image = Array.isArray(containers) && containers.length > 0
|
|
196
|
+
? typeof containers[0]['image'] === 'string'
|
|
197
|
+
? containers[0]['image']
|
|
198
|
+
: undefined
|
|
199
|
+
: undefined;
|
|
200
|
+
const crRoots = imageRoots(image); // resolve the container image
|
|
201
|
+
addNode({
|
|
202
|
+
id: nodeId,
|
|
203
|
+
label: r.name,
|
|
204
|
+
kind: 'worker',
|
|
205
|
+
provenance: 'declared',
|
|
206
|
+
metadata: { config: rel(file), image: image ?? undefined },
|
|
207
|
+
...(crRoots.length ? { sourceRoots: crRoots } : {}),
|
|
208
|
+
});
|
|
209
|
+
// Datastore env refs.
|
|
210
|
+
const envRefs = extractEnvDatastoreRefs(r.raw);
|
|
211
|
+
for (const ref of envRefs) {
|
|
212
|
+
addNode({ id: ref.datastoreNodeId, label: ref.label, kind: 'datastore', provenance: 'declared' });
|
|
213
|
+
addEdge({ source: nodeId, target: ref.datastoreNodeId, kind: 'stores-in', metadata: { config: rel(file) } });
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
// --- App Engine -------------------------------------------------------
|
|
218
|
+
case 'app-engine': {
|
|
219
|
+
const nodeId = aeId(r.name);
|
|
220
|
+
const runtime = typeof r.raw['runtime'] === 'string' ? r.raw['runtime'] : undefined;
|
|
221
|
+
// Static-only detection: handlers are all `static_files` or `static_dir`.
|
|
222
|
+
const handlers = r.raw['handlers'];
|
|
223
|
+
let isStatic = false;
|
|
224
|
+
if (Array.isArray(handlers) && handlers.length > 0) {
|
|
225
|
+
isStatic = handlers.every((h) => {
|
|
226
|
+
const ho = h;
|
|
227
|
+
return 'static_files' in ho || 'static_dir' in ho;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
const aeRoots = configDirRoots(file); // app.yaml dir = the source
|
|
231
|
+
addNode({
|
|
232
|
+
id: nodeId,
|
|
233
|
+
label: `App Engine: ${r.name}`,
|
|
234
|
+
kind: isStatic ? 'static-site' : 'worker',
|
|
235
|
+
provenance: 'declared',
|
|
236
|
+
metadata: { config: rel(file), runtime, service: r.name },
|
|
237
|
+
...(aeRoots.length ? { sourceRoots: aeRoots } : {}),
|
|
238
|
+
});
|
|
239
|
+
const envRefs = extractEnvDatastoreRefs(r.raw);
|
|
240
|
+
for (const ref of envRefs) {
|
|
241
|
+
addNode({ id: ref.datastoreNodeId, label: ref.label, kind: 'datastore', provenance: 'declared' });
|
|
242
|
+
addEdge({ source: nodeId, target: ref.datastoreNodeId, kind: 'stores-in', metadata: { config: rel(file) } });
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
// --- Cloud Functions --------------------------------------------------
|
|
247
|
+
case 'cloud-functions': {
|
|
248
|
+
const nodeId = cfId(r.name);
|
|
249
|
+
const runtime = typeof r.raw['runtime'] === 'string' ? r.raw['runtime'] : undefined;
|
|
250
|
+
const fnRoots = configDirRoots(file); // function config dir = the source
|
|
251
|
+
addNode({
|
|
252
|
+
id: nodeId,
|
|
253
|
+
label: r.name,
|
|
254
|
+
kind: 'worker',
|
|
255
|
+
provenance: 'declared',
|
|
256
|
+
metadata: { config: rel(file), runtime },
|
|
257
|
+
...(fnRoots.length ? { sourceRoots: fnRoots } : {}),
|
|
258
|
+
});
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
// --- k8s Deployment ---------------------------------------------------
|
|
262
|
+
case 'k8s-deployment': {
|
|
263
|
+
const nodeId = k8sWorkloadId(r.name);
|
|
264
|
+
const roots = wlRoots(r.raw);
|
|
265
|
+
addNode({
|
|
266
|
+
id: nodeId,
|
|
267
|
+
label: r.name,
|
|
268
|
+
kind: 'container',
|
|
269
|
+
provenance: 'declared',
|
|
270
|
+
metadata: { config: rel(file), k8sKind: 'Deployment' },
|
|
271
|
+
...(roots.length ? { sourceRoots: roots } : {}),
|
|
272
|
+
});
|
|
273
|
+
k8sWorkloads.push({ id: nodeId, selectors: selectorLabels(r.raw), raw: r.raw });
|
|
274
|
+
const envRefs = extractEnvDatastoreRefs(r.raw);
|
|
275
|
+
for (const ref of envRefs) {
|
|
276
|
+
addNode({ id: ref.datastoreNodeId, label: ref.label, kind: 'datastore', provenance: 'declared' });
|
|
277
|
+
addEdge({ source: nodeId, target: ref.datastoreNodeId, kind: 'stores-in', metadata: { config: rel(file) } });
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
// --- k8s StatefulSet --------------------------------------------------
|
|
282
|
+
case 'k8s-statefulset': {
|
|
283
|
+
const nodeId = k8sWorkloadId(r.name);
|
|
284
|
+
const roots = wlRoots(r.raw);
|
|
285
|
+
addNode({
|
|
286
|
+
id: nodeId,
|
|
287
|
+
label: r.name,
|
|
288
|
+
kind: 'container',
|
|
289
|
+
provenance: 'declared',
|
|
290
|
+
metadata: { config: rel(file), k8sKind: 'StatefulSet' },
|
|
291
|
+
...(roots.length ? { sourceRoots: roots } : {}),
|
|
292
|
+
});
|
|
293
|
+
k8sWorkloads.push({ id: nodeId, selectors: selectorLabels(r.raw), raw: r.raw });
|
|
294
|
+
const envRefs = extractEnvDatastoreRefs(r.raw);
|
|
295
|
+
for (const ref of envRefs) {
|
|
296
|
+
addNode({ id: ref.datastoreNodeId, label: ref.label, kind: 'datastore', provenance: 'declared' });
|
|
297
|
+
addEdge({ source: nodeId, target: ref.datastoreNodeId, kind: 'stores-in', metadata: { config: rel(file) } });
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
// --- k8s Job / CronJob ------------------------------------------------
|
|
302
|
+
case 'k8s-job':
|
|
303
|
+
case 'k8s-cronjob': {
|
|
304
|
+
const nodeId = k8sWorkloadId(r.name);
|
|
305
|
+
const roots = wlRoots(r.raw);
|
|
306
|
+
addNode({
|
|
307
|
+
id: nodeId,
|
|
308
|
+
label: r.name,
|
|
309
|
+
kind: 'container',
|
|
310
|
+
provenance: 'declared',
|
|
311
|
+
metadata: { config: rel(file), k8sKind: r.kind === 'k8s-cronjob' ? 'CronJob' : 'Job' },
|
|
312
|
+
...(roots.length ? { sourceRoots: roots } : {}),
|
|
313
|
+
});
|
|
314
|
+
k8sWorkloads.push({ id: nodeId, selectors: selectorLabels(r.raw), raw: r.raw });
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
// --- k8s Service -------------------------------------------------------
|
|
318
|
+
// k8s Services are routing — NOT emitted as nodes (no fitting InfraModuleKind).
|
|
319
|
+
// Instead they participate in the routing edge chain resolved below.
|
|
320
|
+
case 'k8s-service': {
|
|
321
|
+
k8sServices.push({ name: r.name, selectors: selectorLabels(r.raw), raw: r.raw });
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
// --- k8s Ingress -------------------------------------------------------
|
|
325
|
+
// Ingress is an edge-entry routing construct — similarly no InfraModuleKind fits.
|
|
326
|
+
// Captured here for cross-reference below.
|
|
327
|
+
case 'k8s-ingress': {
|
|
328
|
+
k8sIngresses.push({ name: r.name, raw: r.raw, file });
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
// Post-pass: resolve k8s routing edges.
|
|
335
|
+
//
|
|
336
|
+
// For each k8s Service, find the Deployment(s) it routes to via selector
|
|
337
|
+
// matching. Emit a `calls` edge Service→Deployment — but since k8s Service
|
|
338
|
+
// has no node, we use the *Ingress* → Deployment chain if an Ingress exists,
|
|
339
|
+
// otherwise we emit workload→workload `calls` via the matched service name as
|
|
340
|
+
// a synthetic annotation edge.
|
|
341
|
+
//
|
|
342
|
+
// Concretely:
|
|
343
|
+
// Ingress → workload (direct, when a matching Service name appears in Ingress backends)
|
|
344
|
+
// Service → Deployment (via selector match → calls edge between matched workloads)
|
|
345
|
+
//
|
|
346
|
+
// This avoids phantom nodes while still conveying the routing topology.
|
|
347
|
+
// Map service name → matched workload ids (from selector matching).
|
|
348
|
+
const serviceToWorkloads = new Map();
|
|
349
|
+
for (const svc of k8sServices) {
|
|
350
|
+
const matched = [];
|
|
351
|
+
for (const wl of k8sWorkloads) {
|
|
352
|
+
if (labelsOverlap(svc.selectors, wl.selectors)) {
|
|
353
|
+
matched.push(wl.id);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// If no selector match, record empty (service still exists, just unmatched).
|
|
357
|
+
serviceToWorkloads.set(svc.name, matched);
|
|
358
|
+
}
|
|
359
|
+
// Emit service→workload edges (calls).
|
|
360
|
+
// We emit from a virtual "service" perspective — but since k8s Service is not
|
|
361
|
+
// a node, we look for an Ingress to anchor from. If no Ingress, we emit a
|
|
362
|
+
// synthetic "external-entry" node as the call source.
|
|
363
|
+
const hasIngress = k8sIngresses.length > 0;
|
|
364
|
+
if (hasIngress) {
|
|
365
|
+
// Emit one `cdn` node per Ingress, keyed by its metadata.name.
|
|
366
|
+
// `cdn` is the closest InfraModuleKind — it's an edge termination / routing layer.
|
|
367
|
+
for (const ing of k8sIngresses) {
|
|
368
|
+
const ingressId = `k8s:ingress:${ing.name}`;
|
|
369
|
+
addNode({
|
|
370
|
+
id: ingressId,
|
|
371
|
+
label: `Ingress: ${ing.name}`,
|
|
372
|
+
kind: 'cdn',
|
|
373
|
+
provenance: 'declared',
|
|
374
|
+
metadata: { k8sKind: 'Ingress', name: ing.name },
|
|
375
|
+
});
|
|
376
|
+
// Ingress → workloads via service backend names. Backend extraction
|
|
377
|
+
// (1.19+ `service.name` + legacy `serviceName`) is the shared k8s
|
|
378
|
+
// primitive; we then map each backend Service to its selector-matched
|
|
379
|
+
// workloads and emit the routing edges.
|
|
380
|
+
let routedFromRules = false;
|
|
381
|
+
for (const svcName of extractIngressBackends(ing.raw['spec'])) {
|
|
382
|
+
const targets = serviceToWorkloads.get(svcName) ?? [];
|
|
383
|
+
for (const wlId of targets) {
|
|
384
|
+
// Ingress → workload (calls).
|
|
385
|
+
addEdge({ source: ingressId, target: wlId, kind: 'calls', metadata: { via: 'k8s-ingress-backend' } });
|
|
386
|
+
routedFromRules = true;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
// Fallback: when rules didn't resolve any targets but we have exactly
|
|
390
|
+
// one workload + one service (common simple case), wire them directly.
|
|
391
|
+
if (!routedFromRules && k8sWorkloads.length === 1 && k8sServices.length === 1) {
|
|
392
|
+
const wlId = k8sWorkloads[0].id;
|
|
393
|
+
addEdge({ source: ingressId, target: wlId, kind: 'calls', metadata: { via: 'k8s-routing-simple' } });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// Service → Deployment edges (routing chain within the cluster).
|
|
398
|
+
// When no Ingress exists, a LoadBalancer/NodePort Service is the external
|
|
399
|
+
// entrypoint — emit it as a `cdn` node regardless of whether its selector
|
|
400
|
+
// matched a workload (don't silently drop entrypoints).
|
|
401
|
+
if (!hasIngress) {
|
|
402
|
+
for (const svc of k8sServices) {
|
|
403
|
+
const svcNodeId = `k8s:service:${svc.name}`;
|
|
404
|
+
addNode({
|
|
405
|
+
id: svcNodeId,
|
|
406
|
+
label: `Service: ${svc.name}`,
|
|
407
|
+
kind: 'cdn',
|
|
408
|
+
provenance: 'declared',
|
|
409
|
+
metadata: { k8sKind: 'Service' },
|
|
410
|
+
});
|
|
411
|
+
const wlIds = serviceToWorkloads.get(svc.name) ?? [];
|
|
412
|
+
for (const wlId of wlIds) {
|
|
413
|
+
addEdge({ source: svcNodeId, target: wlId, kind: 'calls', metadata: { via: 'k8s-service-selector' } });
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
root,
|
|
419
|
+
adapter: 'gcp',
|
|
420
|
+
nodes: [...nodes.values()],
|
|
421
|
+
edges,
|
|
422
|
+
// No classificationsNeeded — all GCP/k8s shapes in v0 scope are statically
|
|
423
|
+
// mappable to InfraModuleKind. The open-ended GCP Terraform resources go
|
|
424
|
+
// through the terraform adapter's classify path instead.
|
|
425
|
+
classificationsNeeded: [],
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
// ---------------------------------------------------------------------------
|
|
429
|
+
// Cheap detect() helpers.
|
|
430
|
+
//
|
|
431
|
+
// detect() must be a fast existence check — no full YAML parse.
|
|
432
|
+
// Strategy:
|
|
433
|
+
// 1. Known GCP filename (service.yaml, app.yaml, etc.) → likely GCP.
|
|
434
|
+
// 2. Substring scan for strong GCP/k8s signals in the raw text:
|
|
435
|
+
// - "serving.knative.dev" → Cloud Run
|
|
436
|
+
// - "kind: Deployment" → k8s / GKE
|
|
437
|
+
// - top-level "runtime:" → App Engine / Cloud Functions
|
|
438
|
+
// - "apiVersion: apps/" → k8s
|
|
439
|
+
// - "apiVersion: networking.k8s.io/" → k8s Ingress
|
|
440
|
+
// No YAML parse happens in detect().
|
|
441
|
+
// Signals that are reliably GCP/k8s-specific (fast substring checks on raw text).
|
|
442
|
+
const DETECT_SUBSTRINGS = [
|
|
443
|
+
'serving.knative.dev',
|
|
444
|
+
'apiVersion: apps/',
|
|
445
|
+
'apiVersion: batch/',
|
|
446
|
+
'apiVersion: networking.k8s.io/',
|
|
447
|
+
'apiVersion: extensions/',
|
|
448
|
+
'apiVersion: v1\n',
|
|
449
|
+
'\nruntime:',
|
|
450
|
+
];
|
|
451
|
+
function fileContainsGcpSignal(content) {
|
|
452
|
+
for (const s of DETECT_SUBSTRINGS) {
|
|
453
|
+
if (content.includes(s))
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
// ---------------------------------------------------------------------------
|
|
459
|
+
// Adapter.
|
|
460
|
+
export const gcpAdapter = {
|
|
461
|
+
name: 'gcp',
|
|
462
|
+
async detect(repoDir) {
|
|
463
|
+
// Cheap existence check — no full YAML parse.
|
|
464
|
+
// 1. If a well-known GCP config filename exists anywhere in the tree, assume GCP.
|
|
465
|
+
// 2. Otherwise, scan YAML file text for strong GCP/k8s substrings.
|
|
466
|
+
const files = findYamlFiles(repoDir);
|
|
467
|
+
for (const file of files) {
|
|
468
|
+
const base = file.slice(file.lastIndexOf('/') + 1);
|
|
469
|
+
if (GCP_CONFIG_NAMES.has(base))
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
for (const file of files) {
|
|
473
|
+
try {
|
|
474
|
+
const content = readFileSync(file, 'utf8');
|
|
475
|
+
if (fileContainsGcpSignal(content))
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
// Unreadable file — skip.
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return false;
|
|
483
|
+
},
|
|
484
|
+
async extract(repoDir) {
|
|
485
|
+
// Single authoritative parse — no double-parse with detect().
|
|
486
|
+
const files = findYamlFiles(repoDir);
|
|
487
|
+
const resources = [];
|
|
488
|
+
for (const file of files) {
|
|
489
|
+
try {
|
|
490
|
+
const content = readFileSync(file, 'utf8');
|
|
491
|
+
resources.push(...parseGcpFile(content, file));
|
|
492
|
+
}
|
|
493
|
+
catch (err) {
|
|
494
|
+
console.warn(` [gcp] skipping unparseable ${relative(repoDir, file)}: ${err.message}`);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// build the in-repo Dockerfile index once so k8s (GKE) workloads
|
|
498
|
+
// can attribute their container images back to a build context.
|
|
499
|
+
return buildGcpGraph(resources, repoDir, buildDockerfileIndex(repoDir));
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
//# sourceMappingURL=gcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcp.js","sourceRoot":"","sources":["../../../src/infra/gcp/gcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** One entry from a Heroku Procfile. */
|
|
2
|
+
export interface ProcfileEntry {
|
|
3
|
+
processType: string;
|
|
4
|
+
command: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Parse a Procfile. Format: one `processType: command` per line. Lines that
|
|
8
|
+
* don't match (blank, comment, malformed) are silently skipped.
|
|
9
|
+
* Never throws.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseProcfile(text: string): ProcfileEntry[];
|
|
12
|
+
/** Normalized representation of one addon entry from app.json. */
|
|
13
|
+
export interface AppJsonAddon {
|
|
14
|
+
/** The raw addon slug string (e.g. 'heroku-postgresql', 'sendgrid'). */
|
|
15
|
+
slug: string;
|
|
16
|
+
/** Optional plan string if declared (e.g. 'mini', 'starter-0'). */
|
|
17
|
+
plan?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Subset of app.json we care about. */
|
|
20
|
+
export interface AppJson {
|
|
21
|
+
name?: string;
|
|
22
|
+
addons: AppJsonAddon[];
|
|
23
|
+
env: Record<string, unknown>;
|
|
24
|
+
formation: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse app.json (a standard JSON file). Returns a normalized AppJson or
|
|
28
|
+
* throws on unparseable input. Addon entries may be plain strings or objects
|
|
29
|
+
* `{ "id": "heroku-postgresql", "plan": "mini" }` — both are normalized to
|
|
30
|
+
* AppJsonAddon.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseAppJson(text: string): AppJson;
|
|
33
|
+
//# sourceMappingURL=heroku-parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heroku-parse.d.ts","sourceRoot":"","sources":["../../../src/infra/heroku/heroku-parse.ts"],"names":[],"mappings":"AAcA,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAa3D;AAKD,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA6BlD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Heroku config parsers (Procfile + app.json).
|
|
2
|
+
//
|
|
3
|
+
// Vendored, dependency-free. Procfile is a plain-text line format; app.json
|
|
4
|
+
// is JSON (using parseJsonc from the Cloudflare adapter for consistency).
|
|
5
|
+
//
|
|
6
|
+
// heroku.yml (Docker-based deploys) is DEFERRED — it is YAML, and there is
|
|
7
|
+
// no YAML parser available. detect() notes its presence; parsing is omitted
|
|
8
|
+
// for this v0. Tracked for expansion.
|
|
9
|
+
import { parseJsonc } from '../cloudflare/wrangler-parse.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parse a Procfile. Format: one `processType: command` per line. Lines that
|
|
12
|
+
* don't match (blank, comment, malformed) are silently skipped.
|
|
13
|
+
* Never throws.
|
|
14
|
+
*/
|
|
15
|
+
export function parseProcfile(text) {
|
|
16
|
+
const entries = [];
|
|
17
|
+
for (const raw of text.split('\n')) {
|
|
18
|
+
const line = raw.trim();
|
|
19
|
+
if (!line || line.startsWith('#'))
|
|
20
|
+
continue;
|
|
21
|
+
const colon = line.indexOf(':');
|
|
22
|
+
if (colon === -1)
|
|
23
|
+
continue;
|
|
24
|
+
const processType = line.slice(0, colon).trim();
|
|
25
|
+
const command = line.slice(colon + 1).trim();
|
|
26
|
+
if (!processType)
|
|
27
|
+
continue;
|
|
28
|
+
entries.push({ processType, command });
|
|
29
|
+
}
|
|
30
|
+
return entries;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse app.json (a standard JSON file). Returns a normalized AppJson or
|
|
34
|
+
* throws on unparseable input. Addon entries may be plain strings or objects
|
|
35
|
+
* `{ "id": "heroku-postgresql", "plan": "mini" }` — both are normalized to
|
|
36
|
+
* AppJsonAddon.
|
|
37
|
+
*/
|
|
38
|
+
export function parseAppJson(text) {
|
|
39
|
+
// parseJsonc handles both plain JSON and JSONC (comments/trailing commas)
|
|
40
|
+
const raw = parseJsonc(text);
|
|
41
|
+
const name = typeof raw.name === 'string' ? raw.name : undefined;
|
|
42
|
+
const addons = [];
|
|
43
|
+
const rawAddons = Array.isArray(raw.addons) ? raw.addons : [];
|
|
44
|
+
for (const a of rawAddons) {
|
|
45
|
+
if (typeof a === 'string' && a) {
|
|
46
|
+
addons.push({ slug: a });
|
|
47
|
+
}
|
|
48
|
+
else if (a && typeof a === 'object' && !Array.isArray(a)) {
|
|
49
|
+
const obj = a;
|
|
50
|
+
const slug = typeof obj.id === 'string' ? obj.id : typeof obj.slug === 'string' ? obj.slug : undefined;
|
|
51
|
+
if (!slug)
|
|
52
|
+
continue;
|
|
53
|
+
const plan = typeof obj.plan === 'string' ? obj.plan : undefined;
|
|
54
|
+
addons.push({ slug, ...(plan ? { plan } : {}) });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const env = raw.env && typeof raw.env === 'object' && !Array.isArray(raw.env) ? raw.env : {};
|
|
58
|
+
const formation = raw.formation && typeof raw.formation === 'object' && !Array.isArray(raw.formation)
|
|
59
|
+
? raw.formation
|
|
60
|
+
: {};
|
|
61
|
+
return { name, addons, env, formation };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=heroku-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heroku-parse.js","sourceRoot":"","sources":["../../../src/infra/heroku/heroku-parse.ts"],"names":[],"mappings":"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"}
|