@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,19 @@
|
|
|
1
|
+
import type { DetectMatch, FrameworkAdapter } from '../types.js';
|
|
2
|
+
/** Canonical ORM families this adapter recognizes (PEP 503 normalized dep names). */
|
|
3
|
+
export type PyOrm = 'sqlalchemy' | 'sqlmodel' | 'tortoise-orm' | 'beanie' | 'peewee';
|
|
4
|
+
/** The deterministic Python-ORM signal set (declared dependency names only). */
|
|
5
|
+
export interface PyOrmSignals {
|
|
6
|
+
/** Detected ORM families, in ORM_ORDER. */
|
|
7
|
+
orms: PyOrm[];
|
|
8
|
+
}
|
|
9
|
+
/** Gather the signal set for a single root dir (reads manifests only). */
|
|
10
|
+
export declare function gatherPyOrmSignals(baseDir: string): PyOrmSignals;
|
|
11
|
+
/**
|
|
12
|
+
* Decide Python-ORM usage from the signal set. Any recognized ORM dep is
|
|
13
|
+
* sufficient; confidence rises when SQLAlchemy AND SQLModel are both declared
|
|
14
|
+
* (the canonical modern stack). Returns null → generic-Python fallthrough,
|
|
15
|
+
* byte-for-byte unchanged.
|
|
16
|
+
*/
|
|
17
|
+
export declare function scorePyOrm(s: PyOrmSignals, rootPath?: string): DetectMatch | null;
|
|
18
|
+
export declare const pythonOrmAdapter: FrameworkAdapter;
|
|
19
|
+
//# sourceMappingURL=python-orm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-orm.d.ts","sourceRoot":"","sources":["../../../src/framework/python-orm/python-orm.ts"],"names":[],"mappings":"AAiEA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAOjB,MAAM,aAAa,CAAC;AAMrB,qFAAqF;AACrF,MAAM,MAAM,KAAK,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAKrF,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,IAAI,EAAE,KAAK,EAAE,CAAC;CACf;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAGhE;AA6CD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,SAAK,GAAG,WAAW,GAAG,IAAI,CAU7E;AAiaD,eAAO,MAAM,gBAAgB,EAAE,gBA8C9B,CAAC"}
|
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
// the Python ORM entity FrameworkAdapter. The ORM *entity* surface,
|
|
2
|
+
// framework-independent: it works WITH or WITHOUT a web framework (co-fires with
|
|
3
|
+
// the FastAPI adapter on a FastAPI+SQLModel repo; runs alone on a plain
|
|
4
|
+
// SQLAlchemy service). Sibling of, NOT the same as, the TS `orm` adapter
|
|
5
|
+
// (Prisma/Drizzle/TypeORM/Mongoose) — this one reads Python via the shared
|
|
6
|
+
// pure-syntactic Pyright parse (scripts/ingest/framework/python/{py-ast,analyze}),
|
|
7
|
+
// install-free + never executes repo code.
|
|
8
|
+
//
|
|
9
|
+
// * detect() — a `sqlalchemy` / `sqlmodel` dependency (+ tortoise-orm /
|
|
10
|
+
// beanie / peewee widen the marker heuristic). PURE scorer.
|
|
11
|
+
// * roleTags — a module that DECLARES ORM entities → role 'model' on the
|
|
12
|
+
// LOCKED `service` Module-kind (roles are metadata; the
|
|
13
|
+
// module's `kind` is unchanged, and NEVER a new kind).
|
|
14
|
+
// * syntheticEdges — a `relationship()` / `Mapped["Other"]` / `ForeignKey(
|
|
15
|
+
// "other.id")` between entity classes in DIFFERENT modules
|
|
16
|
+
// → a 'calls' edge between the two model MODULES (a FK is a
|
|
17
|
+
// structural data relationship; 'calls' is the neutral
|
|
18
|
+
// 8-verb verb — 'reads'/'writes' would imply runtime data
|
|
19
|
+
// flow a schema relationship doesn't express). File-id
|
|
20
|
+
// endpoints; intra-file relationships collapse (self-edge).
|
|
21
|
+
// * groupingPrior — a `models/`-ish directory (or a cluster of ≥2 entity
|
|
22
|
+
// files, or a lone `models.py`) → a 'Data Model' subsystem.
|
|
23
|
+
//
|
|
24
|
+
// DESIGN NOTE (, NO schema change): entities are surfaced via role-tags +
|
|
25
|
+
// relationship EDGES between the EXISTING model modules — NOT as new entity
|
|
26
|
+
// sub-nodes (that would be a domain-model change beyond this issue). The moat
|
|
27
|
+
// (the *why*) is unaffected; this only makes the data layer legible.
|
|
28
|
+
//
|
|
29
|
+
// Entity detection (marker-base-class heuristic, gated by the detected ORM so a
|
|
30
|
+
// bare `class X(Model)` in a non-ORM repo never matches):
|
|
31
|
+
// * SQLAlchemy 2.0 — `class X(Base)` / a `DeclarativeBase` subclass carrying
|
|
32
|
+
// `Mapped[…]` / `mapped_column()` / `Column()` markers.
|
|
33
|
+
// * SQLModel — `class X(…, table=True)` (a non-table SQLModel is a schema,
|
|
34
|
+
// not a table — correctly excluded).
|
|
35
|
+
// * Tortoise/Peewee— `class X(Model)`. Beanie — `class X(Document)`.
|
|
36
|
+
//
|
|
37
|
+
// Unresolvable relationship / FK targets DEGRADE + LOG (no silent caps).
|
|
38
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
39
|
+
import { join } from 'node:path';
|
|
40
|
+
import { clampConfidence, resolveBase } from '../detect-util.js';
|
|
41
|
+
import { readPythonDeps } from '../../graph/python-manifest.js';
|
|
42
|
+
import { parsePythonScope } from '../python/analyze.js';
|
|
43
|
+
import { annotationChain, callCallee, classBaseChains, className, classKeywordArg, collectClassBody, isTrueConstant, keywordArg, nameValue, positionalArgs, stringValue, subscriptArgs, PN, } from '../python/py-ast.js';
|
|
44
|
+
// Canonical ordering — deterministic metadata order regardless of manifest order.
|
|
45
|
+
const ORM_ORDER = ['sqlalchemy', 'sqlmodel', 'tortoise-orm', 'beanie', 'peewee'];
|
|
46
|
+
/** Gather the signal set for a single root dir (reads manifests only). */
|
|
47
|
+
export function gatherPyOrmSignals(baseDir) {
|
|
48
|
+
const deps = readPythonDeps(baseDir);
|
|
49
|
+
return { orms: ORM_ORDER.filter((o) => deps.has(o)) };
|
|
50
|
+
}
|
|
51
|
+
// Non-source dirs the nested scan skips (cheap + can't hold a first-party manifest).
|
|
52
|
+
const NESTED_SKIP_DIRS = new Set([
|
|
53
|
+
'node_modules',
|
|
54
|
+
'dist',
|
|
55
|
+
'build',
|
|
56
|
+
'out',
|
|
57
|
+
'coverage',
|
|
58
|
+
'venv',
|
|
59
|
+
'.venv',
|
|
60
|
+
'__pycache__',
|
|
61
|
+
'site-packages',
|
|
62
|
+
]);
|
|
63
|
+
/** True if `dir` holds a Python manifest worth scanning for deps. */
|
|
64
|
+
function hasPythonManifest(dir) {
|
|
65
|
+
return (existsSync(join(dir, 'pyproject.toml')) ||
|
|
66
|
+
existsSync(join(dir, 'setup.py')) ||
|
|
67
|
+
existsSync(join(dir, 'setup.cfg')) ||
|
|
68
|
+
existsSync(join(dir, 'requirements.txt')));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Immediate subdirs (depth 1) that hold a Python manifest — the shallow search
|
|
72
|
+
* for a nested backend (`backend/` | `server/` | `api/`) where the ORM commonly
|
|
73
|
+
* lives in a frontend+backend monorepo. Sorted → deterministic first-match.
|
|
74
|
+
*/
|
|
75
|
+
function shallowManifestSubdirs(base) {
|
|
76
|
+
let entries;
|
|
77
|
+
try {
|
|
78
|
+
entries = readdirSync(base, { withFileTypes: true });
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const out = [];
|
|
84
|
+
for (const e of entries) {
|
|
85
|
+
if (!e.isDirectory() || e.name.startsWith('.') || NESTED_SKIP_DIRS.has(e.name))
|
|
86
|
+
continue;
|
|
87
|
+
if (hasPythonManifest(join(base, e.name)))
|
|
88
|
+
out.push(e.name);
|
|
89
|
+
}
|
|
90
|
+
return out.sort();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Decide Python-ORM usage from the signal set. Any recognized ORM dep is
|
|
94
|
+
* sufficient; confidence rises when SQLAlchemy AND SQLModel are both declared
|
|
95
|
+
* (the canonical modern stack). Returns null → generic-Python fallthrough,
|
|
96
|
+
* byte-for-byte unchanged.
|
|
97
|
+
*/
|
|
98
|
+
export function scorePyOrm(s, rootPath = '') {
|
|
99
|
+
if (s.orms.length === 0)
|
|
100
|
+
return null;
|
|
101
|
+
let confidence = 0.8;
|
|
102
|
+
if (s.orms.includes('sqlalchemy') && s.orms.includes('sqlmodel'))
|
|
103
|
+
confidence += 0.1;
|
|
104
|
+
return {
|
|
105
|
+
adapter: 'python-orm',
|
|
106
|
+
confidence: clampConfidence(confidence),
|
|
107
|
+
rootPath,
|
|
108
|
+
metadata: { orms: s.orms, variant: s.orms.join('+') },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Role vocabulary → locked MODULE_KINDS. A module that DECLARES ORM entities is a
|
|
113
|
+
// model/data-layer module → role 'model' on the LOCKED `service` kind (the same
|
|
114
|
+
// kind the TS `orm` adapter's 'repository' role maps onto — roles are metadata,
|
|
115
|
+
// NEVER a new Module-kind). Priority slots with the cross-adapter data-layer tier
|
|
116
|
+
// (below request-spine handlers, alongside the TS 'repository' role).
|
|
117
|
+
const MODEL_ROLE = 'model';
|
|
118
|
+
const MODEL_KIND = 'service';
|
|
119
|
+
const MODEL_PRIORITY = 2;
|
|
120
|
+
// SQLAlchemy field/relationship marker calls (a class body carrying any of these
|
|
121
|
+
// is a mapped entity even when its base was renamed away from `Base`).
|
|
122
|
+
const SQLA_FIELD_MARKERS = new Set(['mapped_column', 'Column', 'relationship']);
|
|
123
|
+
// The SQLAlchemy 2.0 typed-attribute wrapper — `Mapped[…]`.
|
|
124
|
+
const MAPPED = 'Mapped';
|
|
125
|
+
// The relationship constructor call names — SQLAlchemy `relationship()` +
|
|
126
|
+
// SQLModel `Relationship()`.
|
|
127
|
+
const RELATIONSHIP_CALLS = new Set(['relationship', 'Relationship']);
|
|
128
|
+
// The foreign-key markers — SQLAlchemy `ForeignKey("t.col")` (bare or nested in
|
|
129
|
+
// mapped_column/Column) + SQLModel `Field(foreign_key="t.col")`.
|
|
130
|
+
const FOREIGN_KEY = 'ForeignKey';
|
|
131
|
+
const FIELD = 'Field';
|
|
132
|
+
// Directory / file basenames that name a data-model home.
|
|
133
|
+
const MODELS_DIR_NAMES = new Set([
|
|
134
|
+
'models', 'model', 'entities', 'entity', 'schemas', 'schema', 'orm', 'db', 'database', 'domain', 'tables',
|
|
135
|
+
]);
|
|
136
|
+
// Alembic / migration files define HISTORICAL table snapshots, not the live
|
|
137
|
+
// domain model — never index them as entities (mirrors the TS `orm` adapter's
|
|
138
|
+
// MIGRATION_PATH_RE). Excluding them keeps edges pointing at the real model
|
|
139
|
+
// module and avoids mis-tagging a migration as a 'model'.
|
|
140
|
+
const MIGRATION_PATH_RE = /(^|\/)(migrations?|alembic|versions)(\/|$)/i;
|
|
141
|
+
// Memoized on the FrameworkContext OBJECT (not repoDir) so groupingPrior +
|
|
142
|
+
// syntheticEdges + roleTags share ONE parse, while the merge walk's per-checkpoint
|
|
143
|
+
// ctx gets a fresh analysis. Mirrors fastapi / nest / RN.
|
|
144
|
+
const ANALYSIS_CACHE = new WeakMap();
|
|
145
|
+
function chainLast(c) {
|
|
146
|
+
return c.path.length ? c.path[c.path.length - 1] : c.root;
|
|
147
|
+
}
|
|
148
|
+
function slugify(s) {
|
|
149
|
+
return s
|
|
150
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
151
|
+
.toLowerCase()
|
|
152
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
153
|
+
.replace(/^-+|-+$/g, '');
|
|
154
|
+
}
|
|
155
|
+
function humanize(s) {
|
|
156
|
+
const words = s
|
|
157
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
158
|
+
.replace(/[_\-.]+/g, ' ')
|
|
159
|
+
.trim()
|
|
160
|
+
.split(/\s+/)
|
|
161
|
+
.filter(Boolean);
|
|
162
|
+
if (words.length === 0)
|
|
163
|
+
return s;
|
|
164
|
+
return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
165
|
+
}
|
|
166
|
+
function dirOf(fileId) {
|
|
167
|
+
const i = fileId.lastIndexOf('/');
|
|
168
|
+
return i >= 0 ? fileId.slice(0, i) : '';
|
|
169
|
+
}
|
|
170
|
+
function dirBase(dir) {
|
|
171
|
+
if (dir === '')
|
|
172
|
+
return 'root';
|
|
173
|
+
const i = dir.lastIndexOf('/');
|
|
174
|
+
return i >= 0 ? dir.slice(i + 1) : dir;
|
|
175
|
+
}
|
|
176
|
+
function addEdge(edges, from, to, relation) {
|
|
177
|
+
if (from === to)
|
|
178
|
+
return; // intra-file relationship collapses; the step drops self-edges too
|
|
179
|
+
const key = `${from}→${to}:calls`;
|
|
180
|
+
if (!edges.has(key)) {
|
|
181
|
+
edges.set(key, {
|
|
182
|
+
source: from,
|
|
183
|
+
target: to,
|
|
184
|
+
kind: 'calls',
|
|
185
|
+
metadata: { framework: 'python-orm', relation },
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// A class body carries a SQLAlchemy mapping marker (a `mapped_column()`/`Column()`/
|
|
190
|
+
// `relationship()` call, or a `Mapped[…]` typed attribute) — the robust signal
|
|
191
|
+
// when the declarative base was renamed away from the literal `Base`.
|
|
192
|
+
function hasSqlaBodyMarker(body) {
|
|
193
|
+
for (const call of body.calls) {
|
|
194
|
+
const cc = callCallee(call);
|
|
195
|
+
if (cc && SQLA_FIELD_MARKERS.has(chainLast(cc)))
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
for (const ta of body.typeAnnotations) {
|
|
199
|
+
const head = annotationChain(ta.d.annotation);
|
|
200
|
+
if (head && chainLast(head) === MAPPED)
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
// Is this class a mapped ORM entity? Gated by the detected ORM family so a
|
|
206
|
+
// coincidental `class X(Model)` in a repo that doesn't use Tortoise/Peewee never
|
|
207
|
+
// matches. `table=True` alone (SQLModel) is authoritative regardless of base.
|
|
208
|
+
function isEntityClass(cls, body, detected) {
|
|
209
|
+
const bases = classBaseChains(cls).map(chainLast);
|
|
210
|
+
const hasBase = (n) => bases.includes(n);
|
|
211
|
+
// SQLModel — the `table=True` keyword is the table marker (a base-schema
|
|
212
|
+
// SQLModel without it is NOT a table). Independent of the exact base name so
|
|
213
|
+
// `class Hero(HeroBase, table=True)` still matches.
|
|
214
|
+
if (detected.has('sqlmodel') && isTrueConstant(classKeywordArg(cls, 'table')))
|
|
215
|
+
return true;
|
|
216
|
+
// SQLAlchemy declarative — the conventional `Base` user-base, or (renamed base /
|
|
217
|
+
// classic) any body mapping marker. A bare `class Base(DeclarativeBase): pass`
|
|
218
|
+
// (no `Base` in its OWN bases, no markers) is correctly NOT an entity.
|
|
219
|
+
if (detected.has('sqlalchemy') || detected.has('sqlmodel')) {
|
|
220
|
+
if (hasBase('Base'))
|
|
221
|
+
return true;
|
|
222
|
+
if (hasSqlaBodyMarker(body))
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
// Tortoise / Peewee active-record base, Beanie ODM document.
|
|
226
|
+
if ((detected.has('tortoise-orm') || detected.has('peewee')) && hasBase('Model'))
|
|
227
|
+
return true;
|
|
228
|
+
if (detected.has('beanie') && hasBase('Document'))
|
|
229
|
+
return true;
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
// The explicit `__tablename__ = "…"` of a class body, or undefined.
|
|
233
|
+
function explicitTableName(body) {
|
|
234
|
+
for (const a of body.assignments) {
|
|
235
|
+
if (nameValue(a.d.leftExpr) === '__tablename__') {
|
|
236
|
+
const v = stringValue(a.d.rightExpr);
|
|
237
|
+
if (v)
|
|
238
|
+
return v;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
// Recursively collect the class-name-ish leaves of a subscript's argument
|
|
244
|
+
// expressions: string forward-refs (`"Address"`), bare names (`Address`), and the
|
|
245
|
+
// inner refs of nested subscripts (`list["Address"]`, `Optional["Address"]`).
|
|
246
|
+
// Non-entity leaves (`int`, `str`, `list`) are harmless — they simply don't
|
|
247
|
+
// resolve against the entity map, so no edge is drawn.
|
|
248
|
+
function collectRefLeaves(exprs) {
|
|
249
|
+
const out = [];
|
|
250
|
+
for (const e of exprs) {
|
|
251
|
+
const s = stringValue(e);
|
|
252
|
+
if (s) {
|
|
253
|
+
out.push(s);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
const n = nameValue(e);
|
|
257
|
+
if (n) {
|
|
258
|
+
out.push(n);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (e.nodeType === PN.Index)
|
|
262
|
+
out.push(...collectRefLeaves(subscriptArgs(e)));
|
|
263
|
+
}
|
|
264
|
+
return out;
|
|
265
|
+
}
|
|
266
|
+
// Is `expr` a `relationship(...)` / `Relationship(...)` constructor call?
|
|
267
|
+
function isRelationshipCall(expr) {
|
|
268
|
+
if (!expr || expr.nodeType !== PN.Call)
|
|
269
|
+
return false;
|
|
270
|
+
const cc = callCallee(expr);
|
|
271
|
+
return !!cc && RELATIONSHIP_CALLS.has(chainLast(cc));
|
|
272
|
+
}
|
|
273
|
+
// The relationship / FK targets an entity class body references — covering BOTH
|
|
274
|
+
// the SQLAlchemy 2.0 and the SQLModel spellings:
|
|
275
|
+
// * `relationship("Other")` / `Relationship(...)` positional/`argument=` name.
|
|
276
|
+
// * `attr: Mapped["Other"] = relationship()` / `attr: "Other" = Relationship()`
|
|
277
|
+
// / `attr: list["Other"] = Relationship()` — refs from the LEFT annotation of
|
|
278
|
+
// any attribute assigned a relationship call (SQLModel drops the `Mapped[…]`).
|
|
279
|
+
// * bare `attr: Mapped["Other"]` typed relationships (gated on the `Mapped[…]`
|
|
280
|
+
// head so scalar `Mapped[int]` never counts).
|
|
281
|
+
// * `ForeignKey("other.id")` (bare or nested in mapped_column/Column) +
|
|
282
|
+
// SQLModel `Field(foreign_key="other.id")` → the referenced TABLE.
|
|
283
|
+
function relationshipTargets(body) {
|
|
284
|
+
const out = [];
|
|
285
|
+
const pushTable = (s) => {
|
|
286
|
+
const table = s?.split('.')[0];
|
|
287
|
+
if (table)
|
|
288
|
+
out.push({ kind: 'table', name: table });
|
|
289
|
+
};
|
|
290
|
+
// (1) calls — relationship/Relationship positional class ref; ForeignKey / Field
|
|
291
|
+
// foreign-key → the referenced table.
|
|
292
|
+
for (const call of body.calls) {
|
|
293
|
+
const cc = callCallee(call);
|
|
294
|
+
if (!cc)
|
|
295
|
+
continue;
|
|
296
|
+
const m = chainLast(cc);
|
|
297
|
+
if (RELATIONSHIP_CALLS.has(m)) {
|
|
298
|
+
const arg = positionalArgs(call)[0] ?? keywordArg(call, 'argument');
|
|
299
|
+
const nm = stringValue(arg) ?? nameValue(arg);
|
|
300
|
+
if (nm)
|
|
301
|
+
out.push({ kind: 'class', name: nm });
|
|
302
|
+
}
|
|
303
|
+
else if (m === FOREIGN_KEY) {
|
|
304
|
+
pushTable(stringValue(positionalArgs(call)[0]));
|
|
305
|
+
}
|
|
306
|
+
else if (m === FIELD) {
|
|
307
|
+
pushTable(stringValue(keywordArg(call, 'foreign_key')));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// (2) `attr: <annotation> = relationship()/Relationship()` — the target class(es)
|
|
311
|
+
// from the LEFT annotation (handles SQLModel's plain `"Other"`/`list["Other"]`
|
|
312
|
+
// as well as SQLAlchemy's `Mapped["Other"]`).
|
|
313
|
+
for (const a of body.assignments) {
|
|
314
|
+
const left = a.d.leftExpr;
|
|
315
|
+
if (left.nodeType !== PN.TypeAnnotation)
|
|
316
|
+
continue;
|
|
317
|
+
if (!isRelationshipCall(a.d.rightExpr))
|
|
318
|
+
continue;
|
|
319
|
+
for (const nm of collectRefLeaves([left.d.annotation])) {
|
|
320
|
+
out.push({ kind: 'class', name: nm });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// (3) bare `attr: Mapped["Other"]` (no assignment) — Mapped-gated so scalars skip.
|
|
324
|
+
for (const ta of body.typeAnnotations) {
|
|
325
|
+
const head = annotationChain(ta.d.annotation);
|
|
326
|
+
if (!head || chainLast(head) !== MAPPED)
|
|
327
|
+
continue;
|
|
328
|
+
for (const nm of collectRefLeaves(subscriptArgs(ta.d.annotation))) {
|
|
329
|
+
out.push({ kind: 'class', name: nm });
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return out;
|
|
333
|
+
}
|
|
334
|
+
// Deterministic, collision-free group ids ( discipline): sorted by dir, a
|
|
335
|
+
// bare slug goes to the first claimant; collisions take a `-<dirBase>` then `-<n>`
|
|
336
|
+
// suffix. Identical run-to-run (the snapshot grouping-stability invariant).
|
|
337
|
+
function assignGroups(seeds) {
|
|
338
|
+
const taken = new Set();
|
|
339
|
+
const byDir = [...seeds].sort((a, b) => (a.dir < b.dir ? -1 : a.dir > b.dir ? 1 : 0));
|
|
340
|
+
const groups = [];
|
|
341
|
+
for (const seed of byDir) {
|
|
342
|
+
let id = seed.baseSlug;
|
|
343
|
+
if (taken.has(id))
|
|
344
|
+
id = `${seed.baseSlug}-${slugify(dirBase(seed.dir)) || 'dir'}`;
|
|
345
|
+
let n = 2;
|
|
346
|
+
while (taken.has(id))
|
|
347
|
+
id = `${seed.baseSlug}-${n++}`;
|
|
348
|
+
taken.add(id);
|
|
349
|
+
groups.push({ id, label: seed.label, fileIds: [...seed.fileIds].sort() });
|
|
350
|
+
}
|
|
351
|
+
return groups.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
352
|
+
}
|
|
353
|
+
// Group entity files into 'Data Model' subsystem(s): one per directory that is
|
|
354
|
+
// models-ish-named OR holds a cluster of ≥2 entity files. A single scattered
|
|
355
|
+
// `models.py` (e.g. a per-domain `incident/models.py`) is deliberately LEFT to
|
|
356
|
+
// directory grouping — grouping it here would fragment a per-domain layout into
|
|
357
|
+
// dozens of identical 'Data Model' boxes and override the more informative
|
|
358
|
+
// domain subsystem ( review).
|
|
359
|
+
function buildGroups(entityFiles) {
|
|
360
|
+
const byDir = new Map();
|
|
361
|
+
for (const f of entityFiles) {
|
|
362
|
+
const dir = dirOf(f);
|
|
363
|
+
(byDir.get(dir) ?? byDir.set(dir, []).get(dir)).push(f);
|
|
364
|
+
}
|
|
365
|
+
const seeds = [];
|
|
366
|
+
for (const [dir, files] of byDir) {
|
|
367
|
+
const modelsDir = MODELS_DIR_NAMES.has(dirBase(dir).toLowerCase());
|
|
368
|
+
const cluster = files.length >= 2;
|
|
369
|
+
if (!(modelsDir || cluster))
|
|
370
|
+
continue;
|
|
371
|
+
const label = modelsDir ? 'Data Model' : humanize(dirBase(dir));
|
|
372
|
+
seeds.push({ dir, baseSlug: slugify(label) || 'data-model', label, fileIds: files });
|
|
373
|
+
}
|
|
374
|
+
return assignGroups(seeds);
|
|
375
|
+
}
|
|
376
|
+
function analyzePyOrm(ctx) {
|
|
377
|
+
const detected = new Set((ctx.match.metadata?.orms ?? []).filter(Boolean));
|
|
378
|
+
if (detected.size === 0)
|
|
379
|
+
return { groups: [], edges: [], roles: new Map() };
|
|
380
|
+
const scope = parsePythonScope(ctx);
|
|
381
|
+
const fileIds = [...scope.parsed.keys()].sort();
|
|
382
|
+
const diag = { unresolvedTargets: new Set(), duplicateClasses: new Set() };
|
|
383
|
+
const entities = [];
|
|
384
|
+
const entityFiles = new Set();
|
|
385
|
+
const classToFile = new Map(); // className → module (first/smallest fileId wins)
|
|
386
|
+
const tableToFile = new Map(); // tablename → module (first wins)
|
|
387
|
+
// Pass 1 — find entity classes; index them by class name + table name.
|
|
388
|
+
for (const fileId of fileIds) {
|
|
389
|
+
if (MIGRATION_PATH_RE.test(fileId))
|
|
390
|
+
continue; // historical snapshot, not the live model
|
|
391
|
+
const parsed = scope.parsed.get(fileId);
|
|
392
|
+
if (!parsed)
|
|
393
|
+
continue;
|
|
394
|
+
for (const cls of parsed.nodes.classes) {
|
|
395
|
+
const name = className(cls);
|
|
396
|
+
if (!name)
|
|
397
|
+
continue;
|
|
398
|
+
const body = collectClassBody(cls);
|
|
399
|
+
if (!isEntityClass(cls, body, detected))
|
|
400
|
+
continue;
|
|
401
|
+
entityFiles.add(fileId);
|
|
402
|
+
entities.push({ fileId, name, targets: relationshipTargets(body) });
|
|
403
|
+
if (classToFile.has(name))
|
|
404
|
+
diag.duplicateClasses.add(name);
|
|
405
|
+
else
|
|
406
|
+
classToFile.set(name, fileId);
|
|
407
|
+
const tables = new Set([name.toLowerCase()]);
|
|
408
|
+
const explicit = explicitTableName(body);
|
|
409
|
+
if (explicit) {
|
|
410
|
+
tables.add(explicit);
|
|
411
|
+
tables.add(explicit.toLowerCase());
|
|
412
|
+
}
|
|
413
|
+
for (const t of tables)
|
|
414
|
+
if (!tableToFile.has(t))
|
|
415
|
+
tableToFile.set(t, fileId);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
// Pass 2 — resolve relationship / FK targets to entity modules → 'calls' edges.
|
|
419
|
+
const edges = new Map();
|
|
420
|
+
for (const ent of entities) {
|
|
421
|
+
for (const t of ent.targets) {
|
|
422
|
+
let to;
|
|
423
|
+
if (t.kind === 'class')
|
|
424
|
+
to = classToFile.get(t.name);
|
|
425
|
+
else
|
|
426
|
+
to = tableToFile.get(t.name) ?? tableToFile.get(t.name.toLowerCase());
|
|
427
|
+
if (to)
|
|
428
|
+
addEdge(edges, ent.fileId, to, t.kind === 'table' ? 'foreign-key' : 'relationship');
|
|
429
|
+
else
|
|
430
|
+
diag.unresolvedTargets.add(`${ent.fileId}: ${ent.name} → ${t.kind}:${t.name}`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Roles — every entity module is a 'model' (service kind).
|
|
434
|
+
const roles = new Map();
|
|
435
|
+
for (const fileId of [...entityFiles].sort()) {
|
|
436
|
+
roles.set(fileId, {
|
|
437
|
+
role: MODEL_ROLE,
|
|
438
|
+
kind: MODEL_KIND,
|
|
439
|
+
priority: MODEL_PRIORITY,
|
|
440
|
+
metadata: { framework: 'python-orm' },
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
const groups = buildGroups([...entityFiles]);
|
|
444
|
+
const sortedEdges = [...edges.values()].sort((a, b) => a.source < b.source ? -1 : a.source > b.source ? 1 : a.target < b.target ? -1 : a.target > b.target ? 1 : 0);
|
|
445
|
+
// Positive signal for validation (mirrors fastapi/nest's log line).
|
|
446
|
+
if (roles.size > 0 || groups.length > 0 || sortedEdges.length > 0) {
|
|
447
|
+
console.log(` [python-orm] ${entityFiles.size} model module(s) · ${groups.length} data-model group(s) · ${sortedEdges.length} relationship edge(s)`);
|
|
448
|
+
}
|
|
449
|
+
// No silent caps (locked): log everything that degraded.
|
|
450
|
+
if (diag.unresolvedTargets.size > 0 || diag.duplicateClasses.size > 0) {
|
|
451
|
+
const parts = [];
|
|
452
|
+
if (diag.unresolvedTargets.size > 0) {
|
|
453
|
+
parts.push(`${diag.unresolvedTargets.size} unresolvable target(s): ${[...diag.unresolvedTargets].sort().slice(0, 10).join(' · ')}`);
|
|
454
|
+
}
|
|
455
|
+
if (diag.duplicateClasses.size > 0) {
|
|
456
|
+
parts.push(`${diag.duplicateClasses.size} duplicate class name(s): ${[...diag.duplicateClasses].sort().join(', ')}`);
|
|
457
|
+
}
|
|
458
|
+
console.log(` [python-orm] degraded: ${parts.join(' · ')} (logged, not silently dropped)`);
|
|
459
|
+
}
|
|
460
|
+
return { groups, edges: sortedEdges, roles };
|
|
461
|
+
}
|
|
462
|
+
function getAnalysis(ctx) {
|
|
463
|
+
let a = ANALYSIS_CACHE.get(ctx);
|
|
464
|
+
if (!a) {
|
|
465
|
+
a = analyzePyOrm(ctx);
|
|
466
|
+
ANALYSIS_CACHE.set(ctx, a);
|
|
467
|
+
}
|
|
468
|
+
return a;
|
|
469
|
+
}
|
|
470
|
+
// ---------------------------------------------------------------------------
|
|
471
|
+
// The adapter.
|
|
472
|
+
export const pythonOrmAdapter = {
|
|
473
|
+
name: 'python-orm',
|
|
474
|
+
async detect(ctx) {
|
|
475
|
+
const { base, rootPath } = resolveBase(ctx);
|
|
476
|
+
// Root scan first (a repo whose pyproject is at root reports rootPath '').
|
|
477
|
+
const rootMatch = scorePyOrm(gatherPyOrmSignals(base), rootPath);
|
|
478
|
+
if (rootMatch)
|
|
479
|
+
return rootMatch;
|
|
480
|
+
// Shallow-scan an immediate `backend/` | `server/` | `api/` package for a
|
|
481
|
+
// nested ORM manifest (a frontend+backend monorepo) — only when not already
|
|
482
|
+
// scoped to a workspace package (the per-package fan-out path).
|
|
483
|
+
if (!ctx.packageDir) {
|
|
484
|
+
for (const sub of shallowManifestSubdirs(base)) {
|
|
485
|
+
const m = scorePyOrm(gatherPyOrmSignals(join(base, sub)), sub);
|
|
486
|
+
if (m)
|
|
487
|
+
return m;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return null;
|
|
491
|
+
},
|
|
492
|
+
// A `models/`-ish directory / entity cluster → a 'Data Model' subsystem,
|
|
493
|
+
// authoritative over directory grouping (the fastapi/nest mechanism). Fully
|
|
494
|
+
// deterministic (path-derived) → no classificationsNeeded.
|
|
495
|
+
async groupingPrior(ctx) {
|
|
496
|
+
return { groups: getAnalysis(ctx).groups };
|
|
497
|
+
},
|
|
498
|
+
// relationship() / Mapped["Other"] / ForeignKey("other.id") between entity
|
|
499
|
+
// modules → 'calls' edges (file-id endpoints; the step resolves to modules,
|
|
500
|
+
// drops self-edges, dedupes, 8-verb-validates).
|
|
501
|
+
async syntheticEdges(ctx) {
|
|
502
|
+
return getAnalysis(ctx).edges;
|
|
503
|
+
},
|
|
504
|
+
// Each ORM-entity module → role 'model' on the LOCKED `service` kind. METADATA;
|
|
505
|
+
// the module's `kind` is unchanged.
|
|
506
|
+
async roleTags(ctx) {
|
|
507
|
+
return getAnalysis(ctx).roles;
|
|
508
|
+
},
|
|
509
|
+
// The hooks READ SOURCE (Python). Declare the paths the diff-driven hosted walk
|
|
510
|
+
// must treat as framework-relevant. Never-store-source holds: parse server-side,
|
|
511
|
+
// persist only the derived groups/edges/roles.
|
|
512
|
+
scansSourcePath(path) {
|
|
513
|
+
return path.endsWith('.py') || path.endsWith('.pyi');
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
//# sourceMappingURL=python-orm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-orm.js","sourceRoot":"","sources":["../../../src/framework/python-orm/python-orm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DetectMatch, FrameworkAdapter } from '../types.js';
|
|
2
|
+
/** The deterministic RN/Expo signal set read from a repo (or workspace package). */
|
|
3
|
+
export interface ReactNativeSignals {
|
|
4
|
+
hasReactNativeDep: boolean;
|
|
5
|
+
hasExpoDep: boolean;
|
|
6
|
+
hasAppJson: boolean;
|
|
7
|
+
hasAppConfig: boolean;
|
|
8
|
+
hasMetroConfig: boolean;
|
|
9
|
+
hasRnConfig: boolean;
|
|
10
|
+
hasIosDir: boolean;
|
|
11
|
+
hasAndroidDir: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Gather the signal set for a single root dir. */
|
|
14
|
+
export declare function gatherReactNativeSignals(baseDir: string): ReactNativeSignals;
|
|
15
|
+
/**
|
|
16
|
+
* Decide RN/Expo from the signal set. Returns a DetectMatch, or null if the
|
|
17
|
+
* signals are too weak/ambiguous to claim the stack (so the generic-TS
|
|
18
|
+
* fallthrough stays intact).
|
|
19
|
+
*
|
|
20
|
+
* A SUFFICIENT (match-on-its-own) signal is one of:
|
|
21
|
+
* * a `react-native` or `expo` dep — the authoritative signal
|
|
22
|
+
* * metro.config.* or react-native.config.* — RN-toolchain-specific
|
|
23
|
+
* * BOTH ios/ and android/ native dirs — a built RN project
|
|
24
|
+
*
|
|
25
|
+
* app.json / app.config / a single native dir are SUPPORTING signals (they
|
|
26
|
+
* raise confidence) but never sufficient alone — app.json in particular is too
|
|
27
|
+
* generic to claim a stack on its own.
|
|
28
|
+
*
|
|
29
|
+
* Variant: `expo` dep (or an `app.config.*` dynamic config) ⇒ 'expo', else
|
|
30
|
+
* 'bare'. Recorded in metadata + reflected in confidence.
|
|
31
|
+
*/
|
|
32
|
+
export declare function scoreReactNative(s: ReactNativeSignals, rootPath?: string): DetectMatch | null;
|
|
33
|
+
export type ReactNativeRole = 'navigator' | 'nativeModule' | 'screen' | 'hook' | 'component';
|
|
34
|
+
export declare const reactNativeAdapter: FrameworkAdapter;
|
|
35
|
+
//# sourceMappingURL=react-native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../../src/framework/react-native/react-native.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAOjB,MAAM,aAAa,CAAC;AAgCrB,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,mDAAmD;AACnD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAY5E;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,kBAAkB,EAAE,QAAQ,SAAK,GAAG,WAAW,GAAG,IAAI,CAuCzF;AAoCD,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAilC7F,eAAO,MAAM,kBAAkB,EAAE,gBAgDhC,CAAC"}
|