@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,236 @@
|
|
|
1
|
+
// the SST InfraAdapter (net-new infra coverage, child of ).
|
|
2
|
+
//
|
|
3
|
+
// SST v3 ("Ion") is an AWS-targeting IaC framework for TS apps: `sst.config.ts`
|
|
4
|
+
// declares Functions, Services, static sites, buckets, queues, secrets, etc. as
|
|
5
|
+
// `new sst.aws.*(...)` call sites. This is the config-as-code sibling of the
|
|
6
|
+
// Pulumi adapter — it reuses the same ts-morph construct extraction (sst-parse.ts)
|
|
7
|
+
// and the same image resolver for container image refs.
|
|
8
|
+
//
|
|
9
|
+
// Kind mapping (locked 8-kind InfraModuleKind enum — map onto it, never weaken):
|
|
10
|
+
// Function / Cron / Api / AppSync → worker (serverless compute)
|
|
11
|
+
// Nextjs / Astro / Remix / StaticSite /… → static-site (built artifact on a CDN)
|
|
12
|
+
// Service / Cluster / Task → container (ECS/Fargate workloads)
|
|
13
|
+
// Bucket / Dynamo / Postgres / Aurora /… → datastore
|
|
14
|
+
// Queue / SnsTopic / Bus / Realtime → queue
|
|
15
|
+
// Secret → secret-store
|
|
16
|
+
// Cdn / Router → cdn
|
|
17
|
+
// (NB: the epic ticket loosely grouped `Service` under worker/static-site; the
|
|
18
|
+
// locked enum has a dedicated `container` kind for exactly ECS/Fargate, so a
|
|
19
|
+
// Service maps to `container` — the more precise label, per the adapter discipline
|
|
20
|
+
// "map onto the enum correctly; fix the classifier, never weaken it.")
|
|
21
|
+
// An UNKNOWN `sst.*` construct (Vpc, Router-as-plumbing, a future type) emits NO
|
|
22
|
+
// node and is logged — graceful degradation with no catch-all guessed kind.
|
|
23
|
+
//
|
|
24
|
+
// sourceRoots, kind-aware + deterministic (literal strings only; a
|
|
25
|
+
// `${…}` interpolation is unresolvable → skipped, never guessed):
|
|
26
|
+
// worker → `handler:` / `job:` file path → its DIR
|
|
27
|
+
// static-site → `path:` → that dir
|
|
28
|
+
// container → `image: { context }` / `dockerfile:` → its dir; a bare
|
|
29
|
+
// `image: "ref"` → the resolver (image → in-repo Dockerfile
|
|
30
|
+
// build context). Unresolvable → none (honest "Other").
|
|
31
|
+
// A source root that resolves to the repo root ('') is dropped (never a catch-all).
|
|
32
|
+
//
|
|
33
|
+
// Edges: a construct that references another construct's variable (`link: [bucket]`,
|
|
34
|
+
// `{ cluster }`) → an edge, verb by the TARGET's kind (datastore→stores-in,
|
|
35
|
+
// queue→publishes, secret-store→reads, else calls) — the docker-compose precedent.
|
|
36
|
+
//
|
|
37
|
+
// Zone label: "SST" (PROVIDER_ZONE_LABEL['sst'] in assemble/zones.ts).
|
|
38
|
+
// Config-only (no scansSourcePath — it reads sst.config.ts, not app source; the
|
|
39
|
+
// relevance gate catches sst.config.* via diffTouchesInfra). Deterministic, no LLM.
|
|
40
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
41
|
+
import { join, relative } from 'node:path';
|
|
42
|
+
import { buildDockerfileIndex, resolveImageToSourceRoots } from '../image-resolve.js';
|
|
43
|
+
import { extractSstConstructs } from './sst-parse.js';
|
|
44
|
+
const CONFIG_NAMES = ['sst.config.ts', 'sst.config.mjs', 'sst.config.js', 'sst.config.cjs'];
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Construct → InfraModuleKind. Match on the construct's last segment.
|
|
47
|
+
const KIND_RULES = [
|
|
48
|
+
// Static sites / SSR frameworks (built artifact served from a CDN).
|
|
49
|
+
[/^(?:Nextjs|Astro|Remix|SvelteKit|SolidStart|Nuxt|React|Vue|Angular|TanStackStart|StaticSite)$/, 'static-site'],
|
|
50
|
+
// Serverless compute.
|
|
51
|
+
[/^(?:Function|Cron|Api|ApiGatewayV2|ApiGatewayV1|AppSync)$/, 'worker'],
|
|
52
|
+
// Long-running containers (ECS / Fargate).
|
|
53
|
+
[/^(?:Service|Cluster|Task)$/, 'container'],
|
|
54
|
+
// Persistent storage / databases.
|
|
55
|
+
[/^(?:Bucket|Dynamo|Postgres|Aurora|Mysql|Database|Redis|Efs|OpenSearch|Vector)$/, 'datastore'],
|
|
56
|
+
// Queues / pub-sub.
|
|
57
|
+
[/^(?:Queue|SnsTopic|Topic|Bus|EventBus|Realtime)$/, 'queue'],
|
|
58
|
+
// Secrets.
|
|
59
|
+
[/^Secret$/, 'secret-store'],
|
|
60
|
+
// CDN / edge routing.
|
|
61
|
+
[/^(?:Cdn|Router)$/, 'cdn'],
|
|
62
|
+
];
|
|
63
|
+
/** The InfraModuleKind for an SST construct type, or null when unrecognized. */
|
|
64
|
+
export function sstKind(constructType) {
|
|
65
|
+
for (const [re, kind] of KIND_RULES)
|
|
66
|
+
if (re.test(constructType))
|
|
67
|
+
return kind;
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Path helpers (repo-relative, normalized) — same idiom as pulumi.ts/compose.ts.
|
|
72
|
+
/** Normalize a repo-relative path: backslashes→/, collapse `.`/`./`, strip trailing `/`. */
|
|
73
|
+
function normalizeRoot(p) {
|
|
74
|
+
return p.replace(/\\/g, '/').replace(/^\.(?:\/|$)/, '').replace(/\/+$/, '');
|
|
75
|
+
}
|
|
76
|
+
/** The repo-relative directory of a repo-relative file path ('' = repo root). */
|
|
77
|
+
function dirOfPath(relPath) {
|
|
78
|
+
const n = normalizeRoot(relPath);
|
|
79
|
+
const i = n.lastIndexOf('/');
|
|
80
|
+
return i === -1 ? '' : n.slice(0, i);
|
|
81
|
+
}
|
|
82
|
+
/** An SST handler `path/to/file.exportName` → the handler file's DIR. */
|
|
83
|
+
function handlerDir(handler) {
|
|
84
|
+
// Strip the trailing `.export` segment to recover the file path, then its dir.
|
|
85
|
+
const file = handler.replace(/\.[^./]+$/, '');
|
|
86
|
+
return dirOfPath(file);
|
|
87
|
+
}
|
|
88
|
+
/** Literal capture-group-1 matches of `re` over `text`. */
|
|
89
|
+
function literalValues(text, re) {
|
|
90
|
+
const out = [];
|
|
91
|
+
let m;
|
|
92
|
+
re.lastIndex = 0;
|
|
93
|
+
while ((m = re.exec(text)) !== null)
|
|
94
|
+
out.push(m[1]);
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// kind-aware deployment-target source roots (deterministic, no LLM).
|
|
99
|
+
/**
|
|
100
|
+
* The repo-relative source roots an SST construct deploys, from its props-args
|
|
101
|
+
* text. Kind-aware so a static-site's `path:` and a route's `path:` can't
|
|
102
|
+
* cross-contaminate. `dockerfileIndex` powers the image→source resolver. Pure.
|
|
103
|
+
*/
|
|
104
|
+
export function sstSourceRoots(kind, argsText, dockerfileIndex) {
|
|
105
|
+
if (!argsText)
|
|
106
|
+
return [];
|
|
107
|
+
const roots = new Set();
|
|
108
|
+
const add = (d) => {
|
|
109
|
+
if (d)
|
|
110
|
+
roots.add(d);
|
|
111
|
+
};
|
|
112
|
+
if (kind === 'worker') {
|
|
113
|
+
// `handler: "src/api.handler"` / `job: "src/cron.handler"` → the file's dir.
|
|
114
|
+
for (const v of literalValues(argsText, /\b(?:handler|job|function)\s*:\s*["'`]([^"'`$]+)["'`]/g)) {
|
|
115
|
+
add(handlerDir(v));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (kind === 'static-site') {
|
|
119
|
+
// `path: "packages/web"` → that dir IS the site source.
|
|
120
|
+
for (const v of literalValues(argsText, /\bpath\s*:\s*["'`]([^"'`$]+)["'`]/g)) {
|
|
121
|
+
add(normalizeRoot(v));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else if (kind === 'container') {
|
|
125
|
+
// `image: { context: "packages/api" }` → the build-context dir.
|
|
126
|
+
for (const v of literalValues(argsText, /\bcontext\s*:\s*["'`]([^"'`$]+)["'`]/g))
|
|
127
|
+
add(normalizeRoot(v));
|
|
128
|
+
// `dockerfile: "packages/api/Dockerfile"` → its dir.
|
|
129
|
+
for (const v of literalValues(argsText, /\bdockerfile\s*:\s*["'`]([^"'`$]+)["'`]/g))
|
|
130
|
+
add(dirOfPath(v));
|
|
131
|
+
// A bare `image: "myorg/api:1"` (string) → the resolver. `image: {` has
|
|
132
|
+
// no quote after the colon, so this regex only matches the string form.
|
|
133
|
+
if (dockerfileIndex) {
|
|
134
|
+
for (const v of literalValues(argsText, /\bimage\s*:\s*["'`]([^"'`$]+)["'`]/g)) {
|
|
135
|
+
for (const r of resolveImageToSourceRoots(v, dockerfileIndex))
|
|
136
|
+
roots.add(r);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return [...roots].sort();
|
|
141
|
+
}
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Pure graph builder. ts-morph-extracted constructs injected so it's
|
|
144
|
+
// unit-testable with no real repo (the pulumi/netlify split).
|
|
145
|
+
/** Edge verb for a reference whose TARGET has `kind` (the docker-compose mapping). */
|
|
146
|
+
function edgeVerb(targetKind) {
|
|
147
|
+
if (targetKind === 'datastore')
|
|
148
|
+
return 'stores-in';
|
|
149
|
+
if (targetKind === 'queue')
|
|
150
|
+
return 'publishes';
|
|
151
|
+
if (targetKind === 'secret-store')
|
|
152
|
+
return 'reads';
|
|
153
|
+
return 'calls';
|
|
154
|
+
}
|
|
155
|
+
export function buildSstGraph({ constructs, root, dockerfileIndex, }) {
|
|
156
|
+
const nodes = [];
|
|
157
|
+
const kindByVar = new Map();
|
|
158
|
+
const nodeIdByVar = new Map();
|
|
159
|
+
// Keep only classifiable constructs; remember each one's resolved kind so edges
|
|
160
|
+
// can pick the right verb and so a ref to an unknown construct emits no edge.
|
|
161
|
+
const kept = [];
|
|
162
|
+
for (const c of constructs) {
|
|
163
|
+
const kind = sstKind(c.constructType);
|
|
164
|
+
if (!kind) {
|
|
165
|
+
console.warn(` [sst] skipping unrecognized construct '${c.construct}' (no InfraModuleKind mapping)`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const nodeId = `resource:${c.refAddr}`;
|
|
169
|
+
kept.push({ c, kind, nodeId });
|
|
170
|
+
if (c.varName) {
|
|
171
|
+
kindByVar.set(c.varName, kind);
|
|
172
|
+
nodeIdByVar.set(c.varName, nodeId);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
for (const { c, kind, nodeId } of kept) {
|
|
176
|
+
const roots = sstSourceRoots(kind, c.argsText, dockerfileIndex);
|
|
177
|
+
const label = c.name && !c.name.includes(':') ? c.name : c.constructType;
|
|
178
|
+
nodes.push({
|
|
179
|
+
id: nodeId,
|
|
180
|
+
label,
|
|
181
|
+
kind,
|
|
182
|
+
provenance: 'declared',
|
|
183
|
+
metadata: { provider: 'sst', construct: c.construct, ...(c.varName ? { varName: c.varName } : {}) },
|
|
184
|
+
...(roots.length ? { sourceRoots: roots } : {}),
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// Edges: a construct's referenced identifiers that name another construct's var.
|
|
188
|
+
// ts-morph identifier extraction never descends into string literals, so a name
|
|
189
|
+
// string can't invent a phantom edge (the pulumi-ref reasoning).
|
|
190
|
+
const edges = [];
|
|
191
|
+
const seen = new Set();
|
|
192
|
+
for (const { c, nodeId } of kept) {
|
|
193
|
+
for (const ident of c.referencedIdentifiers) {
|
|
194
|
+
const tgt = nodeIdByVar.get(ident);
|
|
195
|
+
if (!tgt || tgt === nodeId)
|
|
196
|
+
continue;
|
|
197
|
+
const key = `${nodeId}→${tgt}`;
|
|
198
|
+
if (seen.has(key))
|
|
199
|
+
continue;
|
|
200
|
+
seen.add(key);
|
|
201
|
+
edges.push({ source: nodeId, target: tgt, kind: edgeVerb(kindByVar.get(ident)), metadata: { via: 'sst-link' } });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return { root, adapter: 'sst', nodes, edges, classificationsNeeded: [] };
|
|
205
|
+
}
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
// Adapter.
|
|
208
|
+
function findConfig(repoDir) {
|
|
209
|
+
for (const name of CONFIG_NAMES) {
|
|
210
|
+
const p = join(repoDir, name);
|
|
211
|
+
if (existsSync(p))
|
|
212
|
+
return p;
|
|
213
|
+
}
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
export const sstAdapter = {
|
|
217
|
+
name: 'sst',
|
|
218
|
+
async detect(repoDir) {
|
|
219
|
+
return findConfig(repoDir) !== undefined;
|
|
220
|
+
},
|
|
221
|
+
async extract(repoDir) {
|
|
222
|
+
const configPath = findConfig(repoDir);
|
|
223
|
+
if (!configPath)
|
|
224
|
+
return { root: repoDir, adapter: 'sst', nodes: [], edges: [], classificationsNeeded: [] };
|
|
225
|
+
let constructs = [];
|
|
226
|
+
try {
|
|
227
|
+
constructs = extractSstConstructs(readFileSync(configPath, 'utf8'), relative(repoDir, configPath));
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
console.warn(` [sst] could not parse ${relative(repoDir, configPath)}: ${err.message}`);
|
|
231
|
+
}
|
|
232
|
+
// The image resolver needs the repo's Dockerfile index (Service image refs).
|
|
233
|
+
return buildSstGraph({ constructs, root: repoDir, dockerfileIndex: buildDockerfileIndex(repoDir) });
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=sst.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sst.js","sourceRoot":"","sources":["../../../src/infra/sst/sst.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Table names declared by a migration SQL file (public-schema CREATE TABLE). */
|
|
2
|
+
export declare function parseTableNames(sql: string): string[];
|
|
3
|
+
export interface TableRef {
|
|
4
|
+
/** repo-relative posix path of the file the reference was found in. */
|
|
5
|
+
file: string;
|
|
6
|
+
table: string;
|
|
7
|
+
op: 'reads' | 'writes';
|
|
8
|
+
}
|
|
9
|
+
export interface SupabaseUsage {
|
|
10
|
+
tableRefs: TableRef[];
|
|
11
|
+
usesAuth: boolean;
|
|
12
|
+
usesStorage: boolean;
|
|
13
|
+
usesRealtime: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Pure scan of one source file's text for Supabase usage. `file` is the
|
|
17
|
+
* repo-relative posix path stamped onto each TableRef (so the assemble join can
|
|
18
|
+
* resolve it to a code module via fileModuleMap).
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseSupabaseUsage(content: string, file: string): SupabaseUsage;
|
|
21
|
+
/** Merge per-file usage scans into one repo-level signal (refs deduped). */
|
|
22
|
+
export declare function mergeUsage(scans: SupabaseUsage[]): SupabaseUsage;
|
|
23
|
+
export interface SubServiceFlags {
|
|
24
|
+
auth?: boolean;
|
|
25
|
+
storage?: boolean;
|
|
26
|
+
realtime?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read `[auth]/[storage]/[realtime]` `enabled` flags from a parsed config.toml
|
|
30
|
+
* tree (see parseTomlSubset). A section that's present with no explicit
|
|
31
|
+
* `enabled = false` counts as enabled (Supabase's default).
|
|
32
|
+
*/
|
|
33
|
+
export declare function readSubServiceFlags(tree: Record<string, unknown>): SubServiceFlags;
|
|
34
|
+
//# sourceMappingURL=supabase-parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase-parse.d.ts","sourceRoot":"","sources":["../../../src/infra/supabase/supabase-parse.ts"],"names":[],"mappings":"AAaA,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBrD;AAED,MAAM,WAAW,QAAQ;IACvB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,GAAG,QAAQ,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;CACvB;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CA+B/E;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAkBhE;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAQlF"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Supabase config + migration + source-usage parsers.
|
|
2
|
+
//
|
|
3
|
+
// All pure (string/regex in, data out) and dependency-free — the same vitest
|
|
4
|
+
// invariant as classify/env-vars.ts and the CF parser: unit-testable without
|
|
5
|
+
// the Supabase/Anthropic import chain.
|
|
6
|
+
//
|
|
7
|
+
// Three deterministic signals feed the adapter:
|
|
8
|
+
// 1. supabase/migrations/*.sql → the table inventory (CREATE TABLE names)
|
|
9
|
+
// 2. source `.from('table')` → app→datastore read/write edges, with the
|
|
10
|
+
// operation verb inferred from the chain
|
|
11
|
+
// 3. source auth/storage/realtime usage → which managed sub-services are
|
|
12
|
+
// actually used (evidence-gated, so we never hallucinate a sub-service)
|
|
13
|
+
/** Table names declared by a migration SQL file (public-schema CREATE TABLE). */
|
|
14
|
+
export function parseTableNames(sql) {
|
|
15
|
+
const tables = new Set();
|
|
16
|
+
// Strip SQL comments first (PR #9 review): a `-- create table foo` line or a
|
|
17
|
+
// `/* … */` block must not register a phantom table.
|
|
18
|
+
const src = sql.replace(/--[^\n]*/g, ' ').replace(/\/\*[\s\S]*?\*\//g, ' ');
|
|
19
|
+
// create [ [global] temp|temporary | unlogged ] table [if not exists]
|
|
20
|
+
// [schema.]name — schema and name may be double-quoted, and a quoted name
|
|
21
|
+
// can contain non-word chars (e.g. "my-orders"), so capture the quoted and
|
|
22
|
+
// bare forms separately instead of the old loose `"?(\w+)"?` (which dropped
|
|
23
|
+
// everything after the first hyphen and missed temp/unlogged tables).
|
|
24
|
+
const re = /create\s+(?:(?:global\s+)?(?:temp|temporary|unlogged)\s+)?table\s+(?:if\s+not\s+exists\s+)?(?:(?:"([^"]+)"|(\w+))\s*\.\s*)?(?:"([^"]+)"|(\w+))/gi;
|
|
25
|
+
let m;
|
|
26
|
+
while ((m = re.exec(src))) {
|
|
27
|
+
const schema = m[1] ?? m[2];
|
|
28
|
+
const name = m[3] ?? m[4];
|
|
29
|
+
if (!name)
|
|
30
|
+
continue;
|
|
31
|
+
// Skip non-public schemas (auth.*, storage.*, realtime.*) — those are
|
|
32
|
+
// Supabase-internal, not the app's own tables.
|
|
33
|
+
if (schema && schema !== 'public')
|
|
34
|
+
continue;
|
|
35
|
+
tables.add(name);
|
|
36
|
+
}
|
|
37
|
+
return [...tables].sort();
|
|
38
|
+
}
|
|
39
|
+
const WRITE_OPS = /\.(insert|update|upsert|delete)\s*\(/;
|
|
40
|
+
/**
|
|
41
|
+
* Pure scan of one source file's text for Supabase usage. `file` is the
|
|
42
|
+
* repo-relative posix path stamped onto each TableRef (so the assemble join can
|
|
43
|
+
* resolve it to a code module via fileModuleMap).
|
|
44
|
+
*/
|
|
45
|
+
export function parseSupabaseUsage(content, file) {
|
|
46
|
+
const tableRefs = [];
|
|
47
|
+
// `.from('table')` — but NOT `.storage.from('bucket')` (a storage bucket, not
|
|
48
|
+
// a DB table), and NOT JS built-ins that also expose a string-arg `.from`
|
|
49
|
+
// (Array.from('abc'), Buffer.from(...), typed-array `.from`, etc.). The old
|
|
50
|
+
// code only excluded `storage`, so `Array.from('abc')` produced a phantom
|
|
51
|
+
// table `abc` (PR #9 review). We skip when the receiver token is one of these.
|
|
52
|
+
const re = /\.from\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
53
|
+
const NOT_SUPABASE = /(?:^|[^A-Za-z0-9_$])(?:storage|Array|Buffer|Object|Promise|Set|Map|Date|String|Number|JSON|Reflect|Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|BigInt64Array|BigUint64Array)$/;
|
|
54
|
+
let m;
|
|
55
|
+
while ((m = re.exec(content))) {
|
|
56
|
+
// Look back far enough to see the full receiver identifier before `.from`.
|
|
57
|
+
const before = content.slice(Math.max(0, m.index - 24), m.index);
|
|
58
|
+
if (NOT_SUPABASE.test(before))
|
|
59
|
+
continue;
|
|
60
|
+
// Infer the operation from THIS `.from(...)` chain only — bound the window
|
|
61
|
+
// at the next `.from(` call (and a 200-char hard cap) so a write op in a
|
|
62
|
+
// later statement doesn't bleed onto this read.
|
|
63
|
+
const tail = content.slice(m.index + m[0].length);
|
|
64
|
+
const nextFrom = tail.search(/\.from\(/);
|
|
65
|
+
const end = m.index + m[0].length + (nextFrom === -1 ? 200 : Math.min(nextFrom, 200));
|
|
66
|
+
const window = content.slice(m.index, end);
|
|
67
|
+
const op = WRITE_OPS.test(window) ? 'writes' : 'reads';
|
|
68
|
+
tableRefs.push({ file, table: m[1], op });
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
tableRefs,
|
|
72
|
+
usesAuth: /\.auth\./.test(content) || /supabase\.auth\b/.test(content),
|
|
73
|
+
usesStorage: /\.storage\./.test(content),
|
|
74
|
+
usesRealtime: /\.channel\s*\(/.test(content) || /\.realtime\b/.test(content),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** Merge per-file usage scans into one repo-level signal (refs deduped). */
|
|
78
|
+
export function mergeUsage(scans) {
|
|
79
|
+
const seen = new Set();
|
|
80
|
+
const tableRefs = [];
|
|
81
|
+
let usesAuth = false;
|
|
82
|
+
let usesStorage = false;
|
|
83
|
+
let usesRealtime = false;
|
|
84
|
+
for (const s of scans) {
|
|
85
|
+
for (const r of s.tableRefs) {
|
|
86
|
+
const key = `${r.file}\x1f${r.table}\x1f${r.op}`;
|
|
87
|
+
if (seen.has(key))
|
|
88
|
+
continue;
|
|
89
|
+
seen.add(key);
|
|
90
|
+
tableRefs.push(r);
|
|
91
|
+
}
|
|
92
|
+
usesAuth ||= s.usesAuth;
|
|
93
|
+
usesStorage ||= s.usesStorage;
|
|
94
|
+
usesRealtime ||= s.usesRealtime;
|
|
95
|
+
}
|
|
96
|
+
return { tableRefs, usesAuth, usesStorage, usesRealtime };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Read `[auth]/[storage]/[realtime]` `enabled` flags from a parsed config.toml
|
|
100
|
+
* tree (see parseTomlSubset). A section that's present with no explicit
|
|
101
|
+
* `enabled = false` counts as enabled (Supabase's default).
|
|
102
|
+
*/
|
|
103
|
+
export function readSubServiceFlags(tree) {
|
|
104
|
+
const flag = (key) => {
|
|
105
|
+
const section = tree[key];
|
|
106
|
+
if (!section || typeof section !== 'object')
|
|
107
|
+
return undefined;
|
|
108
|
+
const enabled = section.enabled;
|
|
109
|
+
return enabled === false ? false : true;
|
|
110
|
+
};
|
|
111
|
+
return { auth: flag('auth'), storage: flag('storage'), realtime: flag('realtime') };
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=supabase-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase-parse.js","sourceRoot":"","sources":["../../../src/infra/supabase/supabase-parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { InfraAdapter, InfraGraph } from '../types.js';
|
|
2
|
+
import { type SubServiceFlags, type SupabaseUsage } from './supabase-parse.js';
|
|
3
|
+
/**
|
|
4
|
+
* Pure graph builder. Separated from the fs/grep IO so it's unit-testable with
|
|
5
|
+
* synthetic inputs.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildSupabaseGraph(args: {
|
|
8
|
+
tables: string[];
|
|
9
|
+
functions: string[];
|
|
10
|
+
flags: SubServiceFlags;
|
|
11
|
+
usage: SupabaseUsage;
|
|
12
|
+
root: string;
|
|
13
|
+
}): InfraGraph;
|
|
14
|
+
export declare const supabaseAdapter: InfraAdapter;
|
|
15
|
+
//# sourceMappingURL=supabase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../../src/infra/supabase/supabase.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,YAAY,EAAa,UAAU,EAAa,MAAM,aAAa,CAAC;AAGlF,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAqF7B;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,UAAU,CA+Db;AAED,eAAO,MAAM,eAAe,EAAE,YAuB7B,CAAC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// the Supabase InfraAdapter (v0).
|
|
2
|
+
//
|
|
3
|
+
// Surfaces the managed-backend topology the code-import graph can't see: the
|
|
4
|
+
// Postgres datastore (with its table inventory), the edge functions, and the
|
|
5
|
+
// auth/storage/realtime sub-services — plus the app→datastore read/write edges
|
|
6
|
+
// that come from grepping `supabase.from('table')` call sites.
|
|
7
|
+
//
|
|
8
|
+
// Evidence-gated, never hallucinated (the DoD): a sub-service node is emitted
|
|
9
|
+
// only when config.toml enables it OR a source grep proves the app uses it.
|
|
10
|
+
// backthread's repo has no config.toml, so the dogfood path is pure source evidence.
|
|
11
|
+
//
|
|
12
|
+
// Kind mapping (respecting the locked 8-kind InfraModuleKind enum — we map onto
|
|
13
|
+
// it, never weaken it):
|
|
14
|
+
// Postgres / Storage → datastore (the enum's "DB, blob store, cache")
|
|
15
|
+
// Edge function → worker (serverless compute)
|
|
16
|
+
// Realtime → queue (pub/sub message bus)
|
|
17
|
+
// Auth → external-api (a managed identity service you call)
|
|
18
|
+
//
|
|
19
|
+
// v0 scope: tables live on the datastore node's metadata (per-table child nodes
|
|
20
|
+
// are a later refinement); app→datastore edges carry the table in edge metadata
|
|
21
|
+
// but resolve at datastore granularity.
|
|
22
|
+
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
23
|
+
import { join, relative } from 'node:path';
|
|
24
|
+
import { walkRepo } from '../walk.js';
|
|
25
|
+
import { parseTomlSubset } from '../cloudflare/wrangler-parse.js';
|
|
26
|
+
import { parseTableNames, parseSupabaseUsage, mergeUsage, readSubServiceFlags, } from './supabase-parse.js';
|
|
27
|
+
const SOURCE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs)$/;
|
|
28
|
+
const supabaseDir = (repoDir) => join(repoDir, 'supabase');
|
|
29
|
+
function hasSupabaseLayout(repoDir) {
|
|
30
|
+
const dir = supabaseDir(repoDir);
|
|
31
|
+
if (!existsSync(dir))
|
|
32
|
+
return false;
|
|
33
|
+
return (existsSync(join(dir, 'config.toml')) ||
|
|
34
|
+
existsSync(join(dir, 'migrations')) ||
|
|
35
|
+
existsSync(join(dir, 'functions')));
|
|
36
|
+
}
|
|
37
|
+
function listDir(dir) {
|
|
38
|
+
try {
|
|
39
|
+
return readdirSync(dir, { withFileTypes: true });
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Concatenate every migration SQL file's table declarations. */
|
|
46
|
+
function collectTables(repoDir) {
|
|
47
|
+
const dir = join(supabaseDir(repoDir), 'migrations');
|
|
48
|
+
if (!existsSync(dir))
|
|
49
|
+
return [];
|
|
50
|
+
const tables = new Set();
|
|
51
|
+
for (const e of listDir(dir)) {
|
|
52
|
+
if (e.isFile() && e.name.endsWith('.sql')) {
|
|
53
|
+
try {
|
|
54
|
+
for (const t of parseTableNames(readFileSync(join(dir, e.name), 'utf8')))
|
|
55
|
+
tables.add(t);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* skip unreadable migration */
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...tables].sort();
|
|
63
|
+
}
|
|
64
|
+
/** Each immediate subdirectory of supabase/functions is one edge function. */
|
|
65
|
+
function collectFunctions(repoDir) {
|
|
66
|
+
const dir = join(supabaseDir(repoDir), 'functions');
|
|
67
|
+
if (!existsSync(dir))
|
|
68
|
+
return [];
|
|
69
|
+
return listDir(dir)
|
|
70
|
+
.filter((e) => e.isDirectory() && !e.name.startsWith('_'))
|
|
71
|
+
.map((e) => e.name)
|
|
72
|
+
.sort();
|
|
73
|
+
}
|
|
74
|
+
function readConfigFlags(repoDir) {
|
|
75
|
+
const cfg = join(supabaseDir(repoDir), 'config.toml');
|
|
76
|
+
if (!existsSync(cfg))
|
|
77
|
+
return {};
|
|
78
|
+
try {
|
|
79
|
+
return readSubServiceFlags(parseTomlSubset(readFileSync(cfg, 'utf8')));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Walk repo source files and grep each for Supabase usage. */
|
|
86
|
+
function grepUsage(repoDir) {
|
|
87
|
+
const scans = [];
|
|
88
|
+
walkRepo(repoDir, {
|
|
89
|
+
onFile: (abs, e) => {
|
|
90
|
+
if (!SOURCE_EXT.test(e.name))
|
|
91
|
+
return;
|
|
92
|
+
let content;
|
|
93
|
+
try {
|
|
94
|
+
content = readFileSync(abs, 'utf8');
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!content.includes('.from(') && !content.includes('.auth') && !content.includes('.storage') && !content.includes('.channel') && !content.includes('.realtime')) {
|
|
100
|
+
return; // cheap pre-filter
|
|
101
|
+
}
|
|
102
|
+
const rel = relative(repoDir, abs).split('\\').join('/');
|
|
103
|
+
scans.push(parseSupabaseUsage(content, rel));
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
return mergeUsage(scans);
|
|
107
|
+
}
|
|
108
|
+
const DB_ID = 'db';
|
|
109
|
+
/**
|
|
110
|
+
* Pure graph builder. Separated from the fs/grep IO so it's unit-testable with
|
|
111
|
+
* synthetic inputs.
|
|
112
|
+
*/
|
|
113
|
+
export function buildSupabaseGraph(args) {
|
|
114
|
+
const { tables, functions, flags, usage, root } = args;
|
|
115
|
+
const nodes = [];
|
|
116
|
+
const edges = [];
|
|
117
|
+
// The Postgres datastore — the always-present anchor. Table inventory lives
|
|
118
|
+
// on its metadata.
|
|
119
|
+
nodes.push({
|
|
120
|
+
id: DB_ID,
|
|
121
|
+
label: 'Supabase Postgres',
|
|
122
|
+
kind: 'datastore',
|
|
123
|
+
provenance: 'declared',
|
|
124
|
+
metadata: { provider: 'supabase', tables: tables.slice(0, 50), tableCount: tables.length },
|
|
125
|
+
});
|
|
126
|
+
// Sub-services — evidence-gated. config.toml flag OR source grep proves use.
|
|
127
|
+
const subServices = [
|
|
128
|
+
['auth', 'Supabase Auth', 'external-api', flags.auth === true || usage.usesAuth],
|
|
129
|
+
['storage', 'Supabase Storage', 'datastore', flags.storage === true || usage.usesStorage],
|
|
130
|
+
['realtime', 'Supabase Realtime', 'queue', flags.realtime === true || usage.usesRealtime],
|
|
131
|
+
];
|
|
132
|
+
for (const [id, label, kind, present] of subServices) {
|
|
133
|
+
if (!present)
|
|
134
|
+
continue;
|
|
135
|
+
const node = { id, label, kind, provenance: 'declared', metadata: { provider: 'supabase' } };
|
|
136
|
+
nodes.push(node);
|
|
137
|
+
}
|
|
138
|
+
// Edge functions → worker nodes. each function deploys the code under
|
|
139
|
+
// `supabase/functions/<name>`, so its source attributes to the Supabase box.
|
|
140
|
+
for (const fn of functions) {
|
|
141
|
+
nodes.push({
|
|
142
|
+
id: `function:${fn}`,
|
|
143
|
+
label: `${fn} (edge function)`,
|
|
144
|
+
kind: 'worker',
|
|
145
|
+
provenance: 'declared',
|
|
146
|
+
metadata: { provider: 'supabase', function: fn },
|
|
147
|
+
sourceRoots: [`supabase/functions/${fn}`],
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// App→datastore read/write edges. Source is a repo-relative file path the
|
|
151
|
+
// assemble join resolves to a code module via fileModuleMap; unresolved refs
|
|
152
|
+
// (e.g. Deno edge-function files outside the TS cluster) drop there. Dedupe to
|
|
153
|
+
// one edge per (file, op) — the table set rides along in metadata.
|
|
154
|
+
const edgeKey = new Map();
|
|
155
|
+
for (const r of usage.tableRefs) {
|
|
156
|
+
const key = `${r.file} ${r.op}`;
|
|
157
|
+
const existing = edgeKey.get(key);
|
|
158
|
+
if (existing) {
|
|
159
|
+
const tablesMeta = existing.metadata.tables;
|
|
160
|
+
if (!tablesMeta.includes(r.table))
|
|
161
|
+
tablesMeta.push(r.table);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
edgeKey.set(key, {
|
|
165
|
+
source: r.file,
|
|
166
|
+
target: DB_ID,
|
|
167
|
+
kind: r.op,
|
|
168
|
+
metadata: { tables: [r.table], via: 'supabase-js' },
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
edges.push(...edgeKey.values());
|
|
172
|
+
return { root, adapter: 'supabase', nodes, edges, classificationsNeeded: [] };
|
|
173
|
+
}
|
|
174
|
+
export const supabaseAdapter = {
|
|
175
|
+
name: 'supabase',
|
|
176
|
+
async detect(repoDir) {
|
|
177
|
+
return hasSupabaseLayout(repoDir);
|
|
178
|
+
},
|
|
179
|
+
// this adapter greps ANY app source file (SOURCE_EXT) for
|
|
180
|
+
// `.from(`/`.auth`/`.storage`/`.channel`/`.realtime` to build app→Postgres
|
|
181
|
+
// edges and gate the Auth/Storage/Realtime sub-service nodes. So a change to
|
|
182
|
+
// any such source path can change the infra graph and MUST force a re-extract
|
|
183
|
+
// in the diff-driven hosted walk — the dogfood target (example-app, no
|
|
184
|
+
// config.toml) derives its ENTIRE Supabase topology from this source grep.
|
|
185
|
+
scansSourcePath(path) {
|
|
186
|
+
return SOURCE_EXT.test(path);
|
|
187
|
+
},
|
|
188
|
+
async extract(repoDir) {
|
|
189
|
+
return buildSupabaseGraph({
|
|
190
|
+
tables: collectTables(repoDir),
|
|
191
|
+
functions: collectFunctions(repoDir),
|
|
192
|
+
flags: readConfigFlags(repoDir),
|
|
193
|
+
usage: grepUsage(repoDir),
|
|
194
|
+
root: repoDir,
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
//# sourceMappingURL=supabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../../src/infra/supabase/supabase.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,+DAA+D;AAC/D,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,qFAAqF;AACrF,EAAE;AACF,gFAAgF;AAChF,wBAAwB;AACxB,0EAA0E;AAC1E,2DAA2D;AAC3D,4DAA4D;AAC5D,4EAA4E;AAC5E,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,wCAAwC;AAExC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAe,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,mBAAmB,GAGpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,UAAU,GAAG,4BAA4B,CAAC;AAEhD,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAEnE,SAAS,iBAAiB,CAAC,OAAe;IACxC,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACpC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACH,KAAK,MAAM,CAAC,IAAI,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1F,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SACzD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,+DAA+D;AAC/D,SAAS,SAAS,CAAC,OAAe;IAChC,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE;QAChB,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACjB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,OAAO;YACrC,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;YACT,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAClK,OAAO,CAAC,mBAAmB;YAC7B,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,KAAK,GAAG,IAAI,CAAC;AAEnB;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAMlC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACvD,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,4EAA4E;IAC5E,mBAAmB;IACnB,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,UAAU;QACtB,QAAQ,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;KAC3F,CAAC,CAAC;IAEH,6EAA6E;IAC7E,MAAM,WAAW,GAAwD;QACvE,CAAC,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC;QAChF,CAAC,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,WAAW,CAAC;QACzF,CAAC,UAAU,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,YAAY,CAAC;KAC1F,CAAC;IACF,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,WAAW,EAAE,CAAC;QACrD,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,IAAI,GAAc,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC;QACxG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,sEAAsE;IACtE,6EAA6E;IAC7E,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,YAAY,EAAE,EAAE;YACpB,KAAK,EAAE,GAAG,EAAE,kBAAkB;YAC9B,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;YAChD,WAAW,EAAE,CAAC,sBAAsB,EAAE,EAAE,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IAC1E,6EAA6E;IAC7E,+EAA+E;IAC/E,mEAAmE;IACnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,UAAU,GAAI,QAAQ,CAAC,QAAS,CAAC,MAAmB,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACf,MAAM,EAAE,CAAC,CAAC,IAAI;YACd,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,CAAC,CAAC,EAAE;YACV,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE;SACpD,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC3C,IAAI,EAAE,UAAU;IAChB,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,0DAA0D;IAC1D,2EAA2E;IAC3E,6EAA6E;IAC7E,8EAA8E;IAC9E,uEAAuE;IACvE,2EAA2E;IAC3E,eAAe,CAAC,IAAY;QAC1B,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,OAAO,kBAAkB,CAAC;YACxB,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC;YAC9B,SAAS,EAAE,gBAAgB,CAAC,OAAO,CAAC;YACpC,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC;YAC/B,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC;YACzB,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|