@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,85 @@
|
|
|
1
|
+
// the shared bounded repo-walker for infra adapters.
|
|
2
|
+
//
|
|
3
|
+
// Every adapter (cloudflare, supabase, terraform, vercel, fly, render,
|
|
4
|
+
// railway, aws, gcp, azure, opentofu, pulumi) used to re-implement the same
|
|
5
|
+
// `SKIP_DIRS` / `MAX_DEPTH` / `listDir` / recursive `walk` machinery — twelve
|
|
6
|
+
// near-identical copies (OpenTofu was a verbatim copy-paste of terraform.ts).
|
|
7
|
+
// This is the one walk: a depth-bounded, skip-dir-pruned, error-tolerant
|
|
8
|
+
// directory traversal that calls `onFile` for every file it reaches.
|
|
9
|
+
//
|
|
10
|
+
// The walk machinery is shared; the *policy* (which dirs to skip, how deep to
|
|
11
|
+
// go, which files to keep) stays with each adapter as call-site options, so
|
|
12
|
+
// migrating to this helper is a pure refactor with no behavior change — each
|
|
13
|
+
// adapter passes the exact `skipDirs`/`maxDepth` it always used.
|
|
14
|
+
import { readdirSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
/**
|
|
17
|
+
* The skip-set shared by the majority of adapters (cloudflare, supabase, fly,
|
|
18
|
+
* render). Adapters needing provider-specific extras (terraform → `.terraform`,
|
|
19
|
+
* vercel → `.vercel`/`out`, pulumi → `.pulumi`, railway → `.nixpacks`, the
|
|
20
|
+
* cloud adapters → `__pycache__`/`.venv`/`vendor`) pass their own `skipDirs`.
|
|
21
|
+
*/
|
|
22
|
+
export const DEFAULT_SKIP_DIRS = [
|
|
23
|
+
'node_modules',
|
|
24
|
+
'.git',
|
|
25
|
+
'dist',
|
|
26
|
+
'.wrangler',
|
|
27
|
+
'.next',
|
|
28
|
+
'build',
|
|
29
|
+
'coverage',
|
|
30
|
+
];
|
|
31
|
+
/** Default recursion bound — deep enough for monorepo nesting, cheap enough to stay bounded. */
|
|
32
|
+
const DEFAULT_MAX_DEPTH = 8;
|
|
33
|
+
/**
|
|
34
|
+
* Walk `repoDir` depth-first, pruning `skipDirs` and stopping past `maxDepth`,
|
|
35
|
+
* invoking `onFile(absPath, dirent)` for each file. Unreadable directories are
|
|
36
|
+
* skipped silently (a permission error on one subtree never aborts the walk).
|
|
37
|
+
*/
|
|
38
|
+
export function walkRepo(repoDir, opts) {
|
|
39
|
+
const skip = new Set(opts.skipDirs ?? DEFAULT_SKIP_DIRS);
|
|
40
|
+
const maxDepth = opts.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
41
|
+
const walk = (dir, depth) => {
|
|
42
|
+
if (depth > maxDepth)
|
|
43
|
+
return;
|
|
44
|
+
let entries;
|
|
45
|
+
try {
|
|
46
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
for (const e of entries) {
|
|
52
|
+
const abs = join(dir, e.name);
|
|
53
|
+
if (e.isDirectory()) {
|
|
54
|
+
if (!skip.has(e.name))
|
|
55
|
+
walk(abs, depth + 1);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
opts.onFile(abs, e);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
walk(repoDir, 0);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convenience over {@link walkRepo} for the common "collect every file matching
|
|
66
|
+
* a predicate" case. Returns absolute paths sorted lexicographically (the same
|
|
67
|
+
* `found.sort()` every adapter applied for deterministic output).
|
|
68
|
+
*
|
|
69
|
+
* `match` takes `(absPath, dirent)` — the SAME argument order as
|
|
70
|
+
* {@link WalkRepoOptions.onFile} — so a predicate can move between the two
|
|
71
|
+
* helpers without silently rebinding its parameters.
|
|
72
|
+
*/
|
|
73
|
+
export function findFiles(repoDir, match, opts) {
|
|
74
|
+
const found = [];
|
|
75
|
+
walkRepo(repoDir, {
|
|
76
|
+
skipDirs: opts?.skipDirs,
|
|
77
|
+
maxDepth: opts?.maxDepth,
|
|
78
|
+
onFile: (abs, e) => {
|
|
79
|
+
if (match(abs, e))
|
|
80
|
+
found.push(abs);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
return found.sort();
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/infra/walk.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,uEAAuE;AACvE,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,yEAAyE;AACzE,qEAAqE;AACrE,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,iEAAiE;AAEjE,OAAO,EAAE,WAAW,EAAe,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,cAAc;IACd,MAAM;IACN,MAAM;IACN,WAAW;IACX,OAAO;IACP,OAAO;IACP,UAAU;CACX,CAAC;AAEF,gGAAgG;AAChG,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAW5B;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAqB;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACpD,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,EAAE;QAC1C,IAAI,KAAK,GAAG,QAAQ;YAAE,OAAO;QAC7B,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,OAAe,EACf,KAAmD,EACnD,IAAyD;IAEzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,EAAE,IAAI,EAAE,QAAQ;QACxB,QAAQ,EAAE,IAAI,EAAE,QAAQ;QACxB,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACjB,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;KACF,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
package/dist/safety.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SafetyBudget {
|
|
2
|
+
maxFileBytes: number;
|
|
3
|
+
maxTotalBytes: number;
|
|
4
|
+
maxFiles: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const DEFAULT_BUDGET: SafetyBudget;
|
|
7
|
+
/**
|
|
8
|
+
* Walk the clone, enforcing the budget. Throws on the first violation. Symlinks
|
|
9
|
+
* are never followed and any symlink resolving OUTSIDE the clone root is
|
|
10
|
+
* rejected (path-traversal guard).
|
|
11
|
+
*/
|
|
12
|
+
export declare function enforceSourceBudget(root: string, budget?: SafetyBudget): void;
|
|
13
|
+
//# sourceMappingURL=safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,YAI5B,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,YAA6B,GAAG,IAAI,CA4C7F"}
|
package/dist/safety.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Source-tree safety budget (/370) — runs inside the ephemeral container
|
|
2
|
+
// before extraction. The extractor only READS source (ts-morph, install-free —
|
|
3
|
+
// it never eval/requires repo content), so the threat model is DoS/resource
|
|
4
|
+
// abuse (zip-bombs, giant files, symlink escapes), not RCE. This caps that.
|
|
5
|
+
//
|
|
6
|
+
// CPU/mem/disk caps come from the container instance type; wall-time from the
|
|
7
|
+
// exec timeout. This guard covers the content budgets the instance limits don't.
|
|
8
|
+
import { readdirSync, lstatSync, realpathSync } from 'node:fs';
|
|
9
|
+
import { join, resolve, sep } from 'node:path';
|
|
10
|
+
export const DEFAULT_BUDGET = {
|
|
11
|
+
maxFileBytes: 8 * 1024 * 1024, // 8 MB — a source file over this is pathological
|
|
12
|
+
maxTotalBytes: 512 * 1024 * 1024, // 512 MB total scanned
|
|
13
|
+
maxFiles: 50_000,
|
|
14
|
+
};
|
|
15
|
+
const SKIP_DIRS = new Set(['.git', 'node_modules', 'dist', 'build', '.next', 'coverage']);
|
|
16
|
+
/**
|
|
17
|
+
* Walk the clone, enforcing the budget. Throws on the first violation. Symlinks
|
|
18
|
+
* are never followed and any symlink resolving OUTSIDE the clone root is
|
|
19
|
+
* rejected (path-traversal guard).
|
|
20
|
+
*/
|
|
21
|
+
export function enforceSourceBudget(root, budget = DEFAULT_BUDGET) {
|
|
22
|
+
const rootReal = realpathSync(root);
|
|
23
|
+
let totalBytes = 0;
|
|
24
|
+
let fileCount = 0;
|
|
25
|
+
const walk = (dir) => {
|
|
26
|
+
for (const name of readdirSync(dir)) {
|
|
27
|
+
const p = join(dir, name);
|
|
28
|
+
const st = lstatSync(p); // lstat: do NOT follow symlinks
|
|
29
|
+
if (st.isSymbolicLink()) {
|
|
30
|
+
// Reject any symlink that escapes the clone root.
|
|
31
|
+
let target;
|
|
32
|
+
try {
|
|
33
|
+
target = realpathSync(p);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
continue; // dangling symlink — ignore
|
|
37
|
+
}
|
|
38
|
+
// Prefix match with the explicit separator — `target.startsWith(rootReal)`
|
|
39
|
+
// alone would let `/tmp/clone-12345-evil` pass as if inside `/tmp/clone-12345`.
|
|
40
|
+
if (target !== rootReal && !target.startsWith(rootReal + sep)) {
|
|
41
|
+
throw new Error(`safety: symlink escapes clone root: ${p}`);
|
|
42
|
+
}
|
|
43
|
+
continue; // don't traverse into symlinks
|
|
44
|
+
}
|
|
45
|
+
if (st.isDirectory()) {
|
|
46
|
+
if (SKIP_DIRS.has(name))
|
|
47
|
+
continue;
|
|
48
|
+
walk(p);
|
|
49
|
+
}
|
|
50
|
+
else if (st.isFile()) {
|
|
51
|
+
if (st.size > budget.maxFileBytes) {
|
|
52
|
+
throw new Error(`safety: file exceeds ${budget.maxFileBytes} bytes: ${p}`);
|
|
53
|
+
}
|
|
54
|
+
totalBytes += st.size;
|
|
55
|
+
fileCount += 1;
|
|
56
|
+
if (totalBytes > budget.maxTotalBytes) {
|
|
57
|
+
throw new Error(`safety: tree exceeds ${budget.maxTotalBytes} bytes (zip-bomb guard)`);
|
|
58
|
+
}
|
|
59
|
+
if (fileCount > budget.maxFiles) {
|
|
60
|
+
throw new Error(`safety: more than ${budget.maxFiles} files`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
walk(resolve(root));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type ShortSha = string & {
|
|
2
|
+
readonly __brand: 'ShortSha';
|
|
3
|
+
};
|
|
4
|
+
export type ModuleId = string & {
|
|
5
|
+
readonly __brand: 'ModuleId';
|
|
6
|
+
};
|
|
7
|
+
export declare const ShortSha: (s: string) => ShortSha;
|
|
8
|
+
export declare const ModuleId: (s: string) => ModuleId;
|
|
9
|
+
export type ModuleKind = 'frontend' | 'service' | 'gateway' | 'job' | 'worker' | 'static-site' | 'queue' | 'container' | 'datastore' | 'external-api' | 'secret-store' | 'cdn' | 'external';
|
|
10
|
+
export declare const INFRA_MODULE_KINDS: readonly ["worker", "static-site", "queue", "container", "datastore", "external-api", "secret-store", "cdn"];
|
|
11
|
+
export type InfraModuleKind = (typeof INFRA_MODULE_KINDS)[number];
|
|
12
|
+
export declare const MODULE_KINDS: readonly ["frontend", "service", "gateway", "job", "worker", "static-site", "queue", "container", "datastore", "external-api", "secret-store", "cdn"];
|
|
13
|
+
/**
|
|
14
|
+
* Producer-side: returns a strict, non-deprecated ModuleKind or throws.
|
|
15
|
+
* The deprecated `external` alias is REJECTED — producers must emit
|
|
16
|
+
* `external-api`. Readers tolerate legacy `external`; producers must not
|
|
17
|
+
* regenerate it, so we fail loud at the producer boundary.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseModuleKind(candidate: string): ModuleKind;
|
|
20
|
+
export type NodeProvenance = 'declared' | 'inferred' | 'llm-classified';
|
|
21
|
+
export type PackageRole = 'app' | 'lib' | 'tooling';
|
|
22
|
+
export declare const EDGE_KINDS: readonly ["calls", "reads", "writes", "publishes", "subscribes", "webhook-from", "deploys-to", "stores-in"];
|
|
23
|
+
export type EdgeKind = (typeof EDGE_KINDS)[number];
|
|
24
|
+
export declare const FORBIDDEN_EDGE_KINDS: readonly ["imports", "depends-on", "uses"];
|
|
25
|
+
export type ForbiddenEdgeKind = (typeof FORBIDDEN_EDGE_KINDS)[number];
|
|
26
|
+
/**
|
|
27
|
+
* Producer-side: returns a strict EdgeKind or throws. Use this at the extractor
|
|
28
|
+
* / enrichment / persist boundary. A throw means the classifier produced a
|
|
29
|
+
* substrate-only label that should never have left its layer — fix the
|
|
30
|
+
* classifier, not the type.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseEdgeKind(candidate: string): EdgeKind;
|
|
33
|
+
/**
|
|
34
|
+
* Reader-side: tolerant coercion of legacy / unknown values onto the closest
|
|
35
|
+
* 8-verb equivalent so old snapshots still render. New producers must NEVER
|
|
36
|
+
* call this — they call parseEdgeKind.
|
|
37
|
+
* - 'webhook' → 'webhook-from'
|
|
38
|
+
* - 'imports' | 'uses' | 'depends-on' → 'calls' (most-general structural verb)
|
|
39
|
+
* - anything else not in the 8 verbs → 'calls'
|
|
40
|
+
*/
|
|
41
|
+
export declare function coerceEdgeKind(candidate: string): EdgeKind;
|
|
42
|
+
export interface Edge {
|
|
43
|
+
source: ModuleId;
|
|
44
|
+
target: ModuleId;
|
|
45
|
+
kind: EdgeKind;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AACjE,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,KAAG,QAAyB,CAAC;AAC/D,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,KAAG,QAAyB,CAAC;AAkB/D,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,SAAS,GACT,SAAS,GACT,KAAK,GACL,QAAQ,GACR,aAAa,GACb,OAAO,GACP,WAAW,GACX,WAAW,GACX,cAAc,GACd,cAAc,GACd,KAAK,GACL,UAAU,CAAC;AAGf,eAAO,MAAM,kBAAkB,8GASrB,CAAC;AACX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAKlE,eAAO,MAAM,YAAY,uJAaf,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAa7D;AAKD,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAQxE,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AAYpD,eAAO,MAAM,UAAU,6GASb,CAAC;AACX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAGnD,eAAO,MAAM,oBAAoB,4CAA6C,CAAC;AAC/E,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAazD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAI1D;AAED,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Structural type vocabulary for the deterministic extractor.
|
|
2
|
+
//
|
|
3
|
+
// This is the shared type substrate the AST → cluster → framework → infra
|
|
4
|
+
// pipeline enforces: the 8-verb edge taxonomy, the 4 app-role + 8 infra Module
|
|
5
|
+
// kinds, and the branded primitives. The type system is law — a producer that
|
|
6
|
+
// emits an out-of-enum value is a bug in the classifier, never a reason to
|
|
7
|
+
// widen the enum (fail loud at the boundary instead of landing low-quality data).
|
|
8
|
+
//
|
|
9
|
+
// These definitions mirror the host application's domain types exactly (same
|
|
10
|
+
// literals, same brand strings) so a graph produced here is structurally
|
|
11
|
+
// interchangeable with one produced server-side. A drift-guard test keeps the
|
|
12
|
+
// two in lockstep.
|
|
13
|
+
export const ShortSha = (s) => s;
|
|
14
|
+
export const ModuleId = (s) => s;
|
|
15
|
+
// The 8 infra-altitude kinds, enumerated for runtime guards.
|
|
16
|
+
export const INFRA_MODULE_KINDS = [
|
|
17
|
+
'worker',
|
|
18
|
+
'static-site',
|
|
19
|
+
'queue',
|
|
20
|
+
'container',
|
|
21
|
+
'datastore',
|
|
22
|
+
'external-api',
|
|
23
|
+
'secret-store',
|
|
24
|
+
'cdn',
|
|
25
|
+
];
|
|
26
|
+
// Every NON-deprecated kind a producer may emit — ModuleKind minus the legacy
|
|
27
|
+
// `external` alias. Producer-side guard (parseModuleKind) validates against this;
|
|
28
|
+
// readers stay tolerant of `external` in already-seeded blobs.
|
|
29
|
+
export const MODULE_KINDS = [
|
|
30
|
+
'frontend',
|
|
31
|
+
'service',
|
|
32
|
+
'gateway',
|
|
33
|
+
'job',
|
|
34
|
+
'worker',
|
|
35
|
+
'static-site',
|
|
36
|
+
'queue',
|
|
37
|
+
'container',
|
|
38
|
+
'datastore',
|
|
39
|
+
'external-api',
|
|
40
|
+
'secret-store',
|
|
41
|
+
'cdn',
|
|
42
|
+
];
|
|
43
|
+
/**
|
|
44
|
+
* Producer-side: returns a strict, non-deprecated ModuleKind or throws.
|
|
45
|
+
* The deprecated `external` alias is REJECTED — producers must emit
|
|
46
|
+
* `external-api`. Readers tolerate legacy `external`; producers must not
|
|
47
|
+
* regenerate it, so we fail loud at the producer boundary.
|
|
48
|
+
*/
|
|
49
|
+
export function parseModuleKind(candidate) {
|
|
50
|
+
if (candidate === 'external') {
|
|
51
|
+
throw new Error(`deprecated module kind 'external' — emit 'external-api' instead. ` +
|
|
52
|
+
`Readers tolerate legacy 'external'; producers must not regenerate it.`);
|
|
53
|
+
}
|
|
54
|
+
if (!MODULE_KINDS.includes(candidate)) {
|
|
55
|
+
throw new Error(`unknown module kind '${candidate}'. Use one of: ${MODULE_KINDS.join(', ')}.`);
|
|
56
|
+
}
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
// --- Edge kind: the 8-verb taxonomy -----------------------------------------
|
|
60
|
+
// Every edge is a verb with a direction. Substrate-only labels
|
|
61
|
+
// (`imports / depends-on / uses`) are refused at the user-facing boundary.
|
|
62
|
+
//
|
|
63
|
+
// Producer-side discipline: `parseEdgeKind` returns an EdgeKind or throws — a
|
|
64
|
+
// classifier that emits `imports` fails loudly at the persist boundary.
|
|
65
|
+
// Reader-side discipline: `coerceEdgeKind` is tolerant; it maps legacy/unknown
|
|
66
|
+
// values onto an 8-verb fallback so old data still renders. Producers must
|
|
67
|
+
// NEVER call coerce — it exists for the renderer only.
|
|
68
|
+
export const EDGE_KINDS = [
|
|
69
|
+
'calls',
|
|
70
|
+
'reads',
|
|
71
|
+
'writes',
|
|
72
|
+
'publishes',
|
|
73
|
+
'subscribes',
|
|
74
|
+
'webhook-from',
|
|
75
|
+
'deploys-to',
|
|
76
|
+
'stores-in',
|
|
77
|
+
];
|
|
78
|
+
// Substrate-only edge labels — refused at the user-facing boundary.
|
|
79
|
+
export const FORBIDDEN_EDGE_KINDS = ['imports', 'depends-on', 'uses'];
|
|
80
|
+
/**
|
|
81
|
+
* Producer-side: returns a strict EdgeKind or throws. Use this at the extractor
|
|
82
|
+
* / enrichment / persist boundary. A throw means the classifier produced a
|
|
83
|
+
* substrate-only label that should never have left its layer — fix the
|
|
84
|
+
* classifier, not the type.
|
|
85
|
+
*/
|
|
86
|
+
export function parseEdgeKind(candidate) {
|
|
87
|
+
if (FORBIDDEN_EDGE_KINDS.includes(candidate)) {
|
|
88
|
+
throw new Error(`forbidden edge kind '${candidate}' — substrate-only, never user-facing. ` +
|
|
89
|
+
`Use one of: ${EDGE_KINDS.join(', ')}.`);
|
|
90
|
+
}
|
|
91
|
+
if (!EDGE_KINDS.includes(candidate)) {
|
|
92
|
+
throw new Error(`unknown edge kind '${candidate}'. Use one of: ${EDGE_KINDS.join(', ')}.`);
|
|
93
|
+
}
|
|
94
|
+
return candidate;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reader-side: tolerant coercion of legacy / unknown values onto the closest
|
|
98
|
+
* 8-verb equivalent so old snapshots still render. New producers must NEVER
|
|
99
|
+
* call this — they call parseEdgeKind.
|
|
100
|
+
* - 'webhook' → 'webhook-from'
|
|
101
|
+
* - 'imports' | 'uses' | 'depends-on' → 'calls' (most-general structural verb)
|
|
102
|
+
* - anything else not in the 8 verbs → 'calls'
|
|
103
|
+
*/
|
|
104
|
+
export function coerceEdgeKind(candidate) {
|
|
105
|
+
if (EDGE_KINDS.includes(candidate))
|
|
106
|
+
return candidate;
|
|
107
|
+
if (candidate === 'webhook')
|
|
108
|
+
return 'webhook-from';
|
|
109
|
+
return 'calls';
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,8EAA8E;AAC9E,2EAA2E;AAC3E,kFAAkF;AAClF,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,8EAA8E;AAC9E,mBAAmB;AAOnB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAY,EAAE,CAAC,CAAa,CAAC;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAY,EAAE,CAAC,CAAa,CAAC;AAiC/D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ;IACR,aAAa;IACb,OAAO;IACP,WAAW;IACX,WAAW;IACX,cAAc;IACd,cAAc;IACd,KAAK;CACG,CAAC;AAGX,8EAA8E;AAC9E,kFAAkF;AAClF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,UAAU;IACV,SAAS;IACT,SAAS;IACT,KAAK;IACL,QAAQ;IACR,aAAa;IACb,OAAO;IACP,WAAW;IACX,WAAW;IACX,cAAc;IACd,cAAc;IACd,KAAK;CACG,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,mEAAmE;YACjE,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,CAAE,YAAkC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,wBAAwB,SAAS,kBAAkB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,SAAuB,CAAC;AACjC,CAAC;AAeD,+EAA+E;AAC/E,+DAA+D;AAC/D,2EAA2E;AAC3E,EAAE;AACF,8EAA8E;AAC9E,wEAAwE;AACxE,+EAA+E;AAC/E,2EAA2E;AAC3E,uDAAuD;AAEvD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO;IACP,OAAO;IACP,QAAQ;IACR,WAAW;IACX,YAAY;IACZ,cAAc;IACd,YAAY;IACZ,WAAW;CACH,CAAC;AAGX,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,CAAU,CAAC;AAG/E;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,IAAK,oBAA0C,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CACb,wBAAwB,SAAS,yCAAyC;YACxE,eAAe,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC1C,CAAC;IACJ,CAAC;IACD,IAAI,CAAE,UAAgC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CACb,sBAAsB,SAAS,kBAAkB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,SAAqB,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,IAAK,UAAgC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAqB,CAAC;IACxF,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,cAAc,CAAC;IACnD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAwCA,eAAO,MAAM,yBAAyB,EAAE,MAA6B,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// The published package version, read from package.json at runtime. This is the
|
|
2
|
+
// SINGLE source of truth for the extractor version that both the CLI (local
|
|
3
|
+
// structure extraction) and the hosted container stamp on their output, so a
|
|
4
|
+
// version mismatch between the two — which would mean subtly different graphs —
|
|
5
|
+
// is detectable (the container↔CLI version-lockstep guard).
|
|
6
|
+
//
|
|
7
|
+
// NOTE: distinct from `EXTRACTOR_VERSION` in graph/file-graph.ts, which is the
|
|
8
|
+
// incremental-cache SCHEMA version (bumped to invalidate stale blob caches).
|
|
9
|
+
// This constant is the npm package version.
|
|
10
|
+
import { readFileSync } from 'node:fs';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
function readPackageVersion() {
|
|
14
|
+
// Preferred: a build-time injected version (survives bundling).
|
|
15
|
+
try {
|
|
16
|
+
if (typeof __EXTRACTOR_VERSION__ === 'string' && __EXTRACTOR_VERSION__) {
|
|
17
|
+
return __EXTRACTOR_VERSION__;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
/* not injected — fall through to the unbundled fs read */
|
|
22
|
+
}
|
|
23
|
+
// Fallback: read package.json (works when installed/unbundled).
|
|
24
|
+
try {
|
|
25
|
+
// dev: src/version.ts → ../package.json; built: dist/version.js → ../package.json.
|
|
26
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
27
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
28
|
+
return pkg.version ?? '0.0.0';
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return '0.0.0';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export const EXTRACTOR_PACKAGE_VERSION = readPackageVersion();
|
|
35
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,6EAA6E;AAC7E,gFAAgF;AAChF,4DAA4D;AAC5D,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,4CAA4C;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQ1C,SAAS,kBAAkB;IACzB,gEAAgE;IAChE,IAAI,CAAC;QACH,IAAI,OAAO,qBAAqB,KAAK,QAAQ,IAAI,qBAAqB,EAAE,CAAC;YACvE,OAAO,qBAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;IAC5D,CAAC;IACD,gEAAgE;IAChE,IAAI,CAAC;QACH,mFAAmF;QACnF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACpF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC9E,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAW,kBAAkB,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backthread/extractor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deterministic, install-free structural extraction for TypeScript and Python codebases — AST → communities → god-nodes → framework & infra adapters, zero LLM/DB/network.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Backthread",
|
|
8
|
+
"homepage": "https://github.com/backthread/backthread/tree/main/packages/extractor#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/backthread/backthread.git",
|
|
12
|
+
"directory": "packages/extractor"
|
|
13
|
+
},
|
|
14
|
+
"bugs": "https://github.com/backthread/backthread/issues",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ast",
|
|
17
|
+
"code-graph",
|
|
18
|
+
"static-analysis",
|
|
19
|
+
"typescript",
|
|
20
|
+
"python",
|
|
21
|
+
"louvain",
|
|
22
|
+
"architecture"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22.18"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
45
|
+
"build": "npm run clean && tsc -p tsconfig.json",
|
|
46
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
|
|
47
|
+
"test": "node --import tsx --test --test-force-exit \"src/**/*.test.ts\" && npm run build",
|
|
48
|
+
"prepack": "npm run build"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@zzzen/pyright-internal": "1.2.0-dev.20251207",
|
|
52
|
+
"graphology": "^0.25.4",
|
|
53
|
+
"graphology-communities-louvain": "^2.0.2",
|
|
54
|
+
"smol-toml": "^1.7.0",
|
|
55
|
+
"ts-morph": "^23.0.0",
|
|
56
|
+
"yaml": "^2.9.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^22.0.0",
|
|
60
|
+
"expect": "^29.7.0",
|
|
61
|
+
"jest-mock": "^29.7.0",
|
|
62
|
+
"tsx": "^4.22.3",
|
|
63
|
+
"typescript": "^5.6.0"
|
|
64
|
+
}
|
|
65
|
+
}
|