@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,151 @@
|
|
|
1
|
+
import type { EdgeKind, InfraModuleKind, NodeProvenance } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A discovery surface for one infra provider. Implementations live next to
|
|
4
|
+
* their parser (e.g. scripts/ingest/infra/cf/, scripts/ingest/infra/supabase/).
|
|
5
|
+
*
|
|
6
|
+
* `detect()` is cheap — a file-existence check (does `wrangler.toml` exist?
|
|
7
|
+
* does `supabase/config.toml` exist?). It runs first against every registered
|
|
8
|
+
* adapter, and only `detect()`-positive adapters get `extract()`-ed.
|
|
9
|
+
*
|
|
10
|
+
* `extract()` is deterministic parsing — read the config, walk its
|
|
11
|
+
* declarations, emit nodes/edges. The LLM never enters this path; the only
|
|
12
|
+
* LLM-touched layer is `classificationsNeeded` (queued for to label).
|
|
13
|
+
*/
|
|
14
|
+
export interface InfraAdapter {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
detect(repoDir: string): Promise<boolean>;
|
|
17
|
+
extract(repoDir: string): Promise<InfraGraph>;
|
|
18
|
+
/**
|
|
19
|
+
* does this adapter read application SOURCE (not just config/IaC)?
|
|
20
|
+
*
|
|
21
|
+
* Most adapters parse only config/IaC files (wrangler.toml, .tf), so the
|
|
22
|
+
* diff-driven hosted walk (container.ts) can safely CARRY their graph across
|
|
23
|
+
* a checkpoint whose diff touched no infra-config path. But a source-grep
|
|
24
|
+
* adapter (Supabase greps `.from(`/`.auth`/… in `.ts`/`.tsx`/…; Vercel reads
|
|
25
|
+
* App-Router route handlers, `pages/api` files, and `middleware.ts`) derives
|
|
26
|
+
* nodes/edges from ordinary source — so a `supabase.from(...)` added in plain
|
|
27
|
+
* `src` MUST force an infra re-extract, or the carried graph goes stale.
|
|
28
|
+
*
|
|
29
|
+
* An adapter that scans source declares `scansSourcePath(p)` returning true
|
|
30
|
+
* for any repo-relative path whose CONTENT it greps/reads. The relevance
|
|
31
|
+
* gate (relevance.ts) ORs these predicates (for the adapters whose detect()
|
|
32
|
+
* is positive on the current tree) into its carry/re-extract decision.
|
|
33
|
+
* Config-only adapters omit it and keep the carry optimization untouched.
|
|
34
|
+
*
|
|
35
|
+
* Returns true ⇒ "a change to this path could change my output" → re-extract.
|
|
36
|
+
*/
|
|
37
|
+
scansSourcePath?(path: string): boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* An infra node. Mirrors the code-side Module from src/types but lives in
|
|
41
|
+
* its own namespace until the merge step joins them — keeps the contracts
|
|
42
|
+
* decoupled while /8/9 land in parallel.
|
|
43
|
+
*
|
|
44
|
+
* `id` is unique WITHIN the emitting adapter's output. The registry's merge
|
|
45
|
+
* step uses (adapter, id) as the natural key, then prefixes external-facing
|
|
46
|
+
* ids with the adapter name (e.g. `cloudflare:queues_consumer:ingest-jobs`)
|
|
47
|
+
* so cross-adapter merges don't collide on common short names like 'main'.
|
|
48
|
+
*/
|
|
49
|
+
export interface InfraNode {
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
kind: InfraModuleKind;
|
|
53
|
+
/**
|
|
54
|
+
* Where this classification came from. The merge step uses this to resolve
|
|
55
|
+
* conflicts: `declared` wins over `inferred` wins over `llm-classified`.
|
|
56
|
+
* If two adapters both `declared` the same node, the first-registered
|
|
57
|
+
* adapter (= more-specific provider, see registry.ts) wins.
|
|
58
|
+
*/
|
|
59
|
+
provenance: NodeProvenance;
|
|
60
|
+
/**
|
|
61
|
+
* Adapter-specific shape — what config file declared this node, what
|
|
62
|
+
* binding name it carries inside wrangler.toml, the Terraform module
|
|
63
|
+
* path, etc. Not consumed by the renderer; useful for `view source`
|
|
64
|
+
* tooltips and debug dumps. Keep small (< ~500 bytes) so JSONB-tax stays
|
|
65
|
+
* negligible.
|
|
66
|
+
*/
|
|
67
|
+
metadata?: Record<string, unknown>;
|
|
68
|
+
/**
|
|
69
|
+
* repo-relative directory prefixes whose code THIS artifact deploys
|
|
70
|
+
* — the deployment-target signal read from IaaC config (a worker's config dir,
|
|
71
|
+
* a container's Dockerfile build context, a Pages/Vite SPA's source dir, a
|
|
72
|
+
* Supabase function's dir). Only DEPLOYABLE artifacts that run your own code
|
|
73
|
+
* set this (worker / static-site / container); datastores, queues, and
|
|
74
|
+
* external-apis don't run your code and leave it absent. The assemble step
|
|
75
|
+
* attributes each code module to the unit whose source root is the longest
|
|
76
|
+
* prefix of its files (`scripts/ingest/assemble/zones.ts`). Repo-relative,
|
|
77
|
+
* normalized (no leading `./`, no trailing `/`); survives the registry merge
|
|
78
|
+
* unprefixed (only ids are namespaced).
|
|
79
|
+
*/
|
|
80
|
+
sourceRoots?: string[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* An infra-to-infra edge. Uses the same 8-verb EdgeKind taxonomy as the
|
|
84
|
+
* code graph — there is no separate "infra edge kind." A CF Worker
|
|
85
|
+
* `writes` to a D1 Datastore the same way an internal `users` service
|
|
86
|
+
* `writes` to a `db` module. The merge step zips these into the unified
|
|
87
|
+
* graph the renderer reads.
|
|
88
|
+
*
|
|
89
|
+
* `source`/`target` may also reference CODE modules (post-merge), so the
|
|
90
|
+
* type stays string rather than InfraNode['id']. `mergeInfraGraphs` does NOT
|
|
91
|
+
* reject unresolved endpoints — an endpoint that isn't a known infra node is
|
|
92
|
+
* left untouched as a cross-graph-join hint (a Terraform `depends_on` may
|
|
93
|
+
* legitimately point at a code module the join step binds later). Once the
|
|
94
|
+
* full id space is known, `validateMergedGraph` (registry.ts) flags any
|
|
95
|
+
* endpoint that still doesn't resolve — that's the validation gate, not merge.
|
|
96
|
+
*/
|
|
97
|
+
export interface InfraEdge {
|
|
98
|
+
source: string;
|
|
99
|
+
target: string;
|
|
100
|
+
kind: EdgeKind;
|
|
101
|
+
metadata?: Record<string, unknown>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Resource-types the adapter found but does NOT know how to classify into
|
|
105
|
+
* an InfraModuleKind on its own. The registry collects these from every
|
|
106
|
+
* adapter, dedupes, and runs them through 's classifyResourceTypes()
|
|
107
|
+
* before merging — so the final InfraGraph has every node's `kind`
|
|
108
|
+
* decided by either the adapter (declared) or the LLM cache
|
|
109
|
+
* (llm-classified).
|
|
110
|
+
*
|
|
111
|
+
* Adapters with a tight static mapping (CF: `wrangler.toml` `[[queues]]`
|
|
112
|
+
* → `queue`) emit nothing here. Adapters parsing open-ended IaC (Terraform
|
|
113
|
+
* HCL with arbitrary `resource "aws_*"` blocks) emit one entry per unique
|
|
114
|
+
* unclassified `(provider, resource_type)` pair.
|
|
115
|
+
*/
|
|
116
|
+
export interface ClassificationRef {
|
|
117
|
+
provider: string;
|
|
118
|
+
resourceType: string;
|
|
119
|
+
/**
|
|
120
|
+
* The InfraNode.id this classification will populate once resolved. The
|
|
121
|
+
* registry rewrites the corresponding node's `kind` + `provenance` after
|
|
122
|
+
* returns.
|
|
123
|
+
*/
|
|
124
|
+
forNodeId: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* One adapter's view of the repo's infrastructure. The registry's
|
|
128
|
+
* `mergeInfraGraphs` consumes an array of these.
|
|
129
|
+
*/
|
|
130
|
+
export interface InfraGraph {
|
|
131
|
+
/** Absolute repo dir the graph was extracted from (provenance). */
|
|
132
|
+
root: string;
|
|
133
|
+
/** Mirror of the producing adapter's `name`. */
|
|
134
|
+
adapter: string;
|
|
135
|
+
nodes: InfraNode[];
|
|
136
|
+
edges: InfraEdge[];
|
|
137
|
+
classificationsNeeded: ClassificationRef[];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The output of merging every adapter's InfraGraph into one. Same shape as
|
|
141
|
+
* InfraGraph minus the per-adapter `adapter` field; nodes/edges carry their
|
|
142
|
+
* adapter-prefixed ids.
|
|
143
|
+
*/
|
|
144
|
+
export interface MergedInfraGraph {
|
|
145
|
+
root: string;
|
|
146
|
+
nodes: InfraNode[];
|
|
147
|
+
edges: InfraEdge[];
|
|
148
|
+
/** Pass-through to the classifier; populated nodes update in-place. */
|
|
149
|
+
classificationsNeeded: ClassificationRef[];
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/infra/types.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACf,MAAM,aAAa,CAAC;AAKrB;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9C;;;;;;;;;;;;;;;;;;OAkBG;IACH,eAAe,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACzC;AAKD;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,CAAC;IACtB;;;;;OAKG;IACH,UAAU,EAAE,cAAc,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,qBAAqB,EAAE,iBAAiB,EAAE,CAAC;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,wEAAwE;IACxE,qBAAqB,EAAE,iBAAiB,EAAE,CAAC;CAC5C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// the InfraAdapter contract.
|
|
2
|
+
//
|
|
3
|
+
// Mirrors the GraphExtractor seam (/325) on the code-extraction side:
|
|
4
|
+
// every infra-discovery surface targets this normalized shape, and every
|
|
5
|
+
// downstream layer ( salience scoring, ELK layout, the diagram
|
|
6
|
+
// renderer) consumes the merged InfraGraph + code NormalizedGraph as one.
|
|
7
|
+
// New providers (Vercel, Fly, Render, OpenTofu, AWS-native, GCP-native;
|
|
8
|
+
// tracked under ) are an ADDITIVE adapter, never a reshape.
|
|
9
|
+
//
|
|
10
|
+
// Why interface-only here: / / implement the three v0
|
|
11
|
+
// adapters (CF, Supabase, Terraform); 's 10 expansion children
|
|
12
|
+
// implement everything else. Freezing this contract before those land
|
|
13
|
+
// keeps the parallel-agent fan-out safe.
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/infra/types.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,EAAE;AACF,sEAAsE;AACtE,yEAAyE;AACzE,gEAAgE;AAChE,0EAA0E;AAC1E,wEAAwE;AACxE,4DAA4D;AAC5D,EAAE;AACF,yDAAyD;AACzD,+DAA+D;AAC/D,sEAAsE;AACtE,yCAAyC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export interface VercelConfig {
|
|
2
|
+
/** From vercel.json `framework` field */
|
|
3
|
+
framework?: string;
|
|
4
|
+
/** From vercel.json `regions` array (strings like 'iad1') */
|
|
5
|
+
regions?: string[];
|
|
6
|
+
/** Per-function overrides: key = route glob e.g. "api/large.js" */
|
|
7
|
+
functions?: Record<string, VercelFunctionConfig>;
|
|
8
|
+
/** Cron schedules: each entry names a path the cron invokes */
|
|
9
|
+
crons?: VercelCronConfig[];
|
|
10
|
+
/** Rewrites array (for annotation / metadata only, not topology) */
|
|
11
|
+
rewrites?: VercelRewrite[];
|
|
12
|
+
/** Headers array (for annotation only) */
|
|
13
|
+
headers?: VercelHeader[];
|
|
14
|
+
}
|
|
15
|
+
export interface VercelFunctionConfig {
|
|
16
|
+
runtime?: string;
|
|
17
|
+
memory?: number;
|
|
18
|
+
maxDuration?: number;
|
|
19
|
+
regions?: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface VercelCronConfig {
|
|
22
|
+
path: string;
|
|
23
|
+
schedule: string;
|
|
24
|
+
}
|
|
25
|
+
export interface VercelRewrite {
|
|
26
|
+
source: string;
|
|
27
|
+
destination: string;
|
|
28
|
+
}
|
|
29
|
+
export interface VercelHeader {
|
|
30
|
+
source: string;
|
|
31
|
+
headers?: Array<{
|
|
32
|
+
key: string;
|
|
33
|
+
value: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export interface PackageInfo {
|
|
37
|
+
name?: string;
|
|
38
|
+
/** True if any of the known Vercel-deployable framework deps are present */
|
|
39
|
+
detectedFramework?: FrameworkName;
|
|
40
|
+
/** True if `vercel` or `@vercel/*` packages appear in deps/devDeps */
|
|
41
|
+
hasVercelDep: boolean;
|
|
42
|
+
}
|
|
43
|
+
export type FrameworkName = 'next' | 'nuxt' | 'sveltekit' | 'astro' | 'remix';
|
|
44
|
+
/**
|
|
45
|
+
* The output mode from next.config.*:
|
|
46
|
+
* 'export' → purely static (SSG / export output; no serverless)
|
|
47
|
+
* 'standalone' → serverless with a self-contained server bundle
|
|
48
|
+
* 'serverless' → legacy Next.js serverless mode
|
|
49
|
+
* undefined → not set / could not parse (default Vercel serverless)
|
|
50
|
+
*/
|
|
51
|
+
export type NextOutputMode = 'export' | 'standalone' | 'serverless' | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Parse a vercel.json (JSONC-tolerant). Returns an empty object if the text
|
|
54
|
+
* is blank or unparseable — callers rely on graceful degradation.
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseVercelJson(text: string): VercelConfig;
|
|
57
|
+
/**
|
|
58
|
+
* Parse package.json to extract the app name, framework, and Vercel dep presence.
|
|
59
|
+
* Tolerates malformed or empty inputs without throwing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function parsePackageJson(text: string): PackageInfo;
|
|
62
|
+
export declare function parseNextConfigOutputMode(text: string): NextOutputMode;
|
|
63
|
+
export declare function routeFileToPath(repoRelPath: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Derive a human-readable label from a route path.
|
|
66
|
+
* /api/users/[id] → "api/users/[id]"
|
|
67
|
+
* / → "middleware"
|
|
68
|
+
*/
|
|
69
|
+
export declare function routePathToLabel(routePath: string, isMiddleware?: boolean): string;
|
|
70
|
+
//# sourceMappingURL=vercel-parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-parse.d.ts","sourceRoot":"","sources":["../../../src/infra/vercel/vercel-parse.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACjD,+DAA+D;IAC/D,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,0CAA0C;IAC1C,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,aAAa,CAAC;IAClC,sEAAsE;IACtE,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9E;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AAKhF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CA2D1D;AAgBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CA8B1D;AAcD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAatE;AAYD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAsB3D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,MAAM,CAGhF"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Vercel config + route parsing utilities.
|
|
2
|
+
//
|
|
3
|
+
// Pure parsing functions separated from fs IO so they can be unit-tested with
|
|
4
|
+
// inline inputs without a real repo. Handles:
|
|
5
|
+
// - vercel.json → functions, crons, regions, rewrites, headers, framework
|
|
6
|
+
// - package.json → framework detection, app name, Vercel-related deps
|
|
7
|
+
// - next.config.* → output mode detection (static / standalone / serverless)
|
|
8
|
+
// - API route file paths → route path derivation
|
|
9
|
+
//
|
|
10
|
+
// Dependency-free (no npm deps beyond what's already vendored). Reuses
|
|
11
|
+
// parseJsonc from the cloudflare adapter for JSON-with-comments/trailing-comma
|
|
12
|
+
// tolerance.
|
|
13
|
+
import { parseJsonc } from '../cloudflare/wrangler-parse.js';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// vercel.json parser.
|
|
16
|
+
/**
|
|
17
|
+
* Parse a vercel.json (JSONC-tolerant). Returns an empty object if the text
|
|
18
|
+
* is blank or unparseable — callers rely on graceful degradation.
|
|
19
|
+
*/
|
|
20
|
+
export function parseVercelJson(text) {
|
|
21
|
+
if (!text.trim())
|
|
22
|
+
return {};
|
|
23
|
+
let raw;
|
|
24
|
+
try {
|
|
25
|
+
raw = parseJsonc(text);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error(`vercel.json: invalid JSON — ${text.slice(0, 80)}`);
|
|
29
|
+
}
|
|
30
|
+
const out = {};
|
|
31
|
+
if (typeof raw.framework === 'string')
|
|
32
|
+
out.framework = raw.framework;
|
|
33
|
+
if (Array.isArray(raw.regions)) {
|
|
34
|
+
out.regions = raw.regions.filter((r) => typeof r === 'string');
|
|
35
|
+
}
|
|
36
|
+
if (raw.functions && typeof raw.functions === 'object' && !Array.isArray(raw.functions)) {
|
|
37
|
+
out.functions = {};
|
|
38
|
+
for (const [key, val] of Object.entries(raw.functions)) {
|
|
39
|
+
if (!val || typeof val !== 'object')
|
|
40
|
+
continue;
|
|
41
|
+
const v = val;
|
|
42
|
+
const fc = {};
|
|
43
|
+
if (typeof v.runtime === 'string')
|
|
44
|
+
fc.runtime = v.runtime;
|
|
45
|
+
if (typeof v.memory === 'number')
|
|
46
|
+
fc.memory = v.memory;
|
|
47
|
+
if (typeof v.maxDuration === 'number')
|
|
48
|
+
fc.maxDuration = v.maxDuration;
|
|
49
|
+
if (Array.isArray(v.regions))
|
|
50
|
+
fc.regions = v.regions.filter((r) => typeof r === 'string');
|
|
51
|
+
out.functions[key] = fc;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (Array.isArray(raw.crons)) {
|
|
55
|
+
out.crons = raw.crons.flatMap((c) => {
|
|
56
|
+
if (!c || typeof c !== 'object')
|
|
57
|
+
return [];
|
|
58
|
+
const cc = c;
|
|
59
|
+
if (typeof cc.path !== 'string' || typeof cc.schedule !== 'string')
|
|
60
|
+
return [];
|
|
61
|
+
return [{ path: cc.path, schedule: cc.schedule }];
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(raw.rewrites)) {
|
|
65
|
+
out.rewrites = raw.rewrites.flatMap((r) => {
|
|
66
|
+
if (!r || typeof r !== 'object')
|
|
67
|
+
return [];
|
|
68
|
+
const rr = r;
|
|
69
|
+
if (typeof rr.source !== 'string' || typeof rr.destination !== 'string')
|
|
70
|
+
return [];
|
|
71
|
+
return [{ source: rr.source, destination: rr.destination }];
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(raw.headers)) {
|
|
75
|
+
out.headers = raw.headers.flatMap((h) => {
|
|
76
|
+
if (!h || typeof h !== 'object')
|
|
77
|
+
return [];
|
|
78
|
+
const hh = h;
|
|
79
|
+
if (typeof hh.source !== 'string')
|
|
80
|
+
return [];
|
|
81
|
+
return [{ source: hh.source }];
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// package.json parser.
|
|
88
|
+
const FRAMEWORK_DEPS = {
|
|
89
|
+
next: 'next',
|
|
90
|
+
nuxt: 'nuxt',
|
|
91
|
+
'@nuxt/core': 'nuxt',
|
|
92
|
+
'@sveltejs/kit': 'sveltekit',
|
|
93
|
+
astro: 'astro',
|
|
94
|
+
'@remix-run/react': 'remix',
|
|
95
|
+
'@remix-run/node': 'remix',
|
|
96
|
+
'@remix-run/server-runtime': 'remix',
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Parse package.json to extract the app name, framework, and Vercel dep presence.
|
|
100
|
+
* Tolerates malformed or empty inputs without throwing.
|
|
101
|
+
*/
|
|
102
|
+
export function parsePackageJson(text) {
|
|
103
|
+
if (!text.trim())
|
|
104
|
+
return { hasVercelDep: false };
|
|
105
|
+
let raw;
|
|
106
|
+
try {
|
|
107
|
+
raw = JSON.parse(text);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
throw new Error(`package.json: invalid JSON`);
|
|
111
|
+
}
|
|
112
|
+
const info = { hasVercelDep: false };
|
|
113
|
+
if (typeof raw.name === 'string' && raw.name)
|
|
114
|
+
info.name = raw.name;
|
|
115
|
+
const allDeps = {
|
|
116
|
+
...(raw.dependencies ?? {}),
|
|
117
|
+
...(raw.devDependencies ?? {}),
|
|
118
|
+
...(raw.peerDependencies ?? {}),
|
|
119
|
+
};
|
|
120
|
+
for (const [dep, framework] of Object.entries(FRAMEWORK_DEPS)) {
|
|
121
|
+
if (dep in allDeps) {
|
|
122
|
+
info.detectedFramework = framework;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
info.hasVercelDep = Object.keys(allDeps).some((dep) => dep === 'vercel' || dep.startsWith('@vercel/'));
|
|
127
|
+
return info;
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// next.config.* output-mode heuristic.
|
|
131
|
+
//
|
|
132
|
+
// We deliberately do NOT execute or import the config file (security +
|
|
133
|
+
// complexity). A light regex over the raw text is sufficient for the
|
|
134
|
+
// common patterns:
|
|
135
|
+
// output: 'export' → static export
|
|
136
|
+
// output: "standalone" → standalone server bundle
|
|
137
|
+
// output: 'serverless' → legacy serverless mode
|
|
138
|
+
// Any other value (including "undefined" / absent) maps to `undefined` (the
|
|
139
|
+
// default Vercel serverless/ISR behaviour).
|
|
140
|
+
export function parseNextConfigOutputMode(text) {
|
|
141
|
+
// Strip line comments (// ...) and block comments (/* ... */) before
|
|
142
|
+
// matching, so a commented-out `// output: 'export'` is not picked up as
|
|
143
|
+
// the active output mode.
|
|
144
|
+
const stripped = text
|
|
145
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // block comments
|
|
146
|
+
.replace(/\/\/[^\n]*/g, ''); // line comments
|
|
147
|
+
const m = stripped.match(/\boutput\s*:\s*['"]([^'"]+)['"]/);
|
|
148
|
+
if (!m)
|
|
149
|
+
return undefined;
|
|
150
|
+
const val = m[1];
|
|
151
|
+
if (val === 'export' || val === 'standalone' || val === 'serverless')
|
|
152
|
+
return val;
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// API route file-path → route path derivation.
|
|
157
|
+
//
|
|
158
|
+
// Vercel/Next.js conventions:
|
|
159
|
+
// pages/api/users/[id].ts → /api/users/[id]
|
|
160
|
+
// app/api/users/route.ts → /api/users
|
|
161
|
+
// middleware.ts → / (edge middleware, intercepts all routes)
|
|
162
|
+
//
|
|
163
|
+
// The returned routePath is the canonical URL-path string used as the node id.
|
|
164
|
+
export function routeFileToPath(repoRelPath) {
|
|
165
|
+
// Normalise path separators.
|
|
166
|
+
const p = repoRelPath.replace(/\\/g, '/');
|
|
167
|
+
// middleware.ts / middleware.js at the root (or inside src/).
|
|
168
|
+
if (/^(?:src\/)?middleware\.[jt]sx?$/.test(p))
|
|
169
|
+
return '/';
|
|
170
|
+
// pages/api/** → /api/...
|
|
171
|
+
const pagesApi = p.match(/^(?:src\/)?pages\/api\/(.+)\.[jt]sx?$/);
|
|
172
|
+
if (pagesApi) {
|
|
173
|
+
return `/api/${pagesApi[1]}`;
|
|
174
|
+
}
|
|
175
|
+
// app/**/route.ts → derive path from directory
|
|
176
|
+
const appRoute = p.match(/^(?:src\/)?app\/(.+?)\/route\.[jt]sx?$/);
|
|
177
|
+
if (appRoute) {
|
|
178
|
+
// Strip trailing /route if the segment is literally "route"
|
|
179
|
+
return `/${appRoute[1]}`;
|
|
180
|
+
}
|
|
181
|
+
// Fallback: return the path as-is (caller will use it as an id).
|
|
182
|
+
return `/${p}`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Derive a human-readable label from a route path.
|
|
186
|
+
* /api/users/[id] → "api/users/[id]"
|
|
187
|
+
* / → "middleware"
|
|
188
|
+
*/
|
|
189
|
+
export function routePathToLabel(routePath, isMiddleware = false) {
|
|
190
|
+
if (isMiddleware || routePath === '/')
|
|
191
|
+
return 'middleware';
|
|
192
|
+
return routePath.replace(/^\//, '');
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=vercel-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-parse.js","sourceRoot":"","sources":["../../../src/infra/vercel/vercel-parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { InfraAdapter, InfraGraph } from '../types.js';
|
|
2
|
+
import { type VercelConfig, type PackageInfo, type NextOutputMode } from './vercel-parse.js';
|
|
3
|
+
export interface VercelProjectInputs {
|
|
4
|
+
/** Absolute path of this deployment root within the repo. */
|
|
5
|
+
projectDir: string;
|
|
6
|
+
/** Repo-relative path to vercel.json (or undefined if absent). */
|
|
7
|
+
vercelJsonPath?: string;
|
|
8
|
+
/** Parsed vercel.json (if present and valid). */
|
|
9
|
+
vercelConfig?: VercelConfig;
|
|
10
|
+
/** Parsed package.json (if present and valid). */
|
|
11
|
+
packageInfo?: PackageInfo;
|
|
12
|
+
/** Output mode from next.config.* (if present). */
|
|
13
|
+
nextOutputMode?: NextOutputMode;
|
|
14
|
+
/** Repo-relative paths to API route files. */
|
|
15
|
+
routeFiles: string[];
|
|
16
|
+
/**
|
|
17
|
+
* does `<projectDir>/src` exist? Used as the app's source-root
|
|
18
|
+
* fallback when the project sits at the repo root (so we never emit '' — a
|
|
19
|
+
* catch-all that swallows sibling units), mirroring the netlify base→root guard.
|
|
20
|
+
*/
|
|
21
|
+
srcExists?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build an InfraGraph from already-collected Vercel project inputs.
|
|
25
|
+
* Separated from fs IO so it can be unit-tested with synthetic inputs.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildVercelGraph(inputs: VercelProjectInputs[], root: string): InfraGraph;
|
|
28
|
+
export declare function vercelScansSourcePath(path: string): boolean;
|
|
29
|
+
export declare const vercelAdapter: InfraAdapter;
|
|
30
|
+
//# sourceMappingURL=vercel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../../src/infra/vercel/vercel.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,YAAY,EAAa,UAAU,EAAa,MAAM,aAAa,CAAC;AAElF,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AA8I3B,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,kDAAkD;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mDAAmD;IACnD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,8CAA8C;IAC9C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAwFD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAoKxF;AAmFD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM3D;AAKD,eAAO,MAAM,aAAa,EAAE,YA4C3B,CAAC"}
|