@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,200 @@
|
|
|
1
|
+
// Railway config parsers + env-ref extraction.
|
|
2
|
+
//
|
|
3
|
+
// Railway is convention-over-configuration: the canonical source of truth is
|
|
4
|
+
// railway.json / railway.toml (if present), nixpacks.toml (build config), and
|
|
5
|
+
// Procfile (legacy process declaration). package.json is used as a fallback
|
|
6
|
+
// signal for framework detection.
|
|
7
|
+
//
|
|
8
|
+
// This file provides PURE parsing functions — no fs IO, no side effects.
|
|
9
|
+
// railway.ts owns the IO layer; railway.test.ts / railway-parse.test.ts own
|
|
10
|
+
// the testing.
|
|
11
|
+
//
|
|
12
|
+
// Railway env-var template syntax for inter-resource references:
|
|
13
|
+
// ${{Postgres.DATABASE_URL}} → plugin named "Postgres"
|
|
14
|
+
// ${{Redis.URL}} → plugin named "Redis"
|
|
15
|
+
// ${{MongoDB.MONGODB_URL}} → plugin named "MongoDB"
|
|
16
|
+
// ${{api.RAILWAY_PRIVATE_URL}} → another service named "api"
|
|
17
|
+
//
|
|
18
|
+
// Plugins are managed datastores provisioned by Railway (Postgres, Redis,
|
|
19
|
+
// MongoDB, MySQL). Services are other containers in the same project.
|
|
20
|
+
//
|
|
21
|
+
// Env-ref detection regex: \$\{\{([^.}]+)\.([^}]+)\}\}
|
|
22
|
+
// group 1 = the referent name (plugin or service id, case-insensitive match
|
|
23
|
+
// against known plugin names)
|
|
24
|
+
// group 2 = the env var being interpolated
|
|
25
|
+
import { parseJsonc, parseTomlSubset } from '../cloudflare/wrangler-parse.js';
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Known Railway plugin names — these are managed datastores, not user services.
|
|
28
|
+
// Match case-insensitively.
|
|
29
|
+
const PLUGIN_NAMES = new Set(['postgres', 'redis', 'mongodb', 'mongo', 'mysql', 'mssql', 'rabbitmq']);
|
|
30
|
+
const ENV_REF_RE = /\$\{\{([^.}]+)\.([^}]+)\}\}/g;
|
|
31
|
+
/** Extract all `${{Name.VAR}}` references from a block of text. */
|
|
32
|
+
export function extractEnvRefs(text) {
|
|
33
|
+
const refs = [];
|
|
34
|
+
let m;
|
|
35
|
+
ENV_REF_RE.lastIndex = 0;
|
|
36
|
+
while ((m = ENV_REF_RE.exec(text)) !== null) {
|
|
37
|
+
const name = m[1];
|
|
38
|
+
const varKey = m[2];
|
|
39
|
+
const nameLower = name.toLowerCase();
|
|
40
|
+
refs.push({ name, nameLower, isPlugin: PLUGIN_NAMES.has(nameLower), varKey, raw: m[0] });
|
|
41
|
+
}
|
|
42
|
+
return refs;
|
|
43
|
+
}
|
|
44
|
+
/** Collect all env-var references from a config's services + project level. */
|
|
45
|
+
export function extractConfigRefs(config) {
|
|
46
|
+
const allText = [];
|
|
47
|
+
for (const svc of config.services) {
|
|
48
|
+
if (svc.envVars)
|
|
49
|
+
allText.push(JSON.stringify(svc.envVars));
|
|
50
|
+
}
|
|
51
|
+
if (config.projectEnvVars)
|
|
52
|
+
allText.push(JSON.stringify(config.projectEnvVars));
|
|
53
|
+
return extractEnvRefs(allText.join('\n'));
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// railway.json / railway.toml parser.
|
|
57
|
+
//
|
|
58
|
+
// Railway's JSON schema has two shapes:
|
|
59
|
+
// 1. Multi-service (monorepo): top-level `services` map/array
|
|
60
|
+
// 2. Single-service: top-level keys are the service config directly
|
|
61
|
+
//
|
|
62
|
+
// TOML shape mirrors the JSON shape (same key names under `[service]` tables).
|
|
63
|
+
function strOf(v) {
|
|
64
|
+
return typeof v === 'string' && v ? v : undefined;
|
|
65
|
+
}
|
|
66
|
+
function recordOf(v) {
|
|
67
|
+
if (!v || typeof v !== 'object' || Array.isArray(v))
|
|
68
|
+
return undefined;
|
|
69
|
+
const out = {};
|
|
70
|
+
for (const [k, val] of Object.entries(v)) {
|
|
71
|
+
if (typeof val === 'string')
|
|
72
|
+
out[k] = val;
|
|
73
|
+
// Railway env also supports integers/booleans — coerce to string
|
|
74
|
+
else if (typeof val === 'number' || typeof val === 'boolean')
|
|
75
|
+
out[k] = String(val);
|
|
76
|
+
}
|
|
77
|
+
return Object.keys(out).length ? out : undefined;
|
|
78
|
+
}
|
|
79
|
+
function parseServiceBlock(obj, fallbackName) {
|
|
80
|
+
// Build config may nest under a "build" or "deploy" sub-key in JSON, or be
|
|
81
|
+
// flat (toml). Try both shapes.
|
|
82
|
+
const build = (obj.build && typeof obj.build === 'object' ? obj.build : obj);
|
|
83
|
+
const deploy = (obj.deploy && typeof obj.deploy === 'object' ? obj.deploy : obj);
|
|
84
|
+
return {
|
|
85
|
+
name: strOf(obj.name) ?? strOf(obj.serviceName) ?? fallbackName,
|
|
86
|
+
builder: strOf(build.builder) ?? strOf(obj.builder),
|
|
87
|
+
buildCommand: strOf(build.buildCommand) ?? strOf(obj.buildCommand),
|
|
88
|
+
startCommand: strOf(deploy.startCommand) ?? strOf(obj.startCommand),
|
|
89
|
+
source: strOf(obj.source) ?? strOf(obj.sourceDir) ?? strOf(obj.rootDirectory),
|
|
90
|
+
healthcheck: strOf(deploy.healthcheckPath) ?? strOf(obj.healthcheckPath),
|
|
91
|
+
envVars: recordOf(obj.variables) ?? recordOf(obj.envVars) ?? recordOf(obj.env),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** Parse a railway.json or railway.toml (auto-detected by filename suffix). */
|
|
95
|
+
export function parseRailwayConfig(text, filename) {
|
|
96
|
+
const tree = /\.toml$/i.test(filename)
|
|
97
|
+
? parseTomlSubset(text)
|
|
98
|
+
: parseJsonc(text);
|
|
99
|
+
const services = [];
|
|
100
|
+
// Multi-service JSON: `{ "services": { "api": { ... }, "worker": { ... } } }`
|
|
101
|
+
// or `{ "services": [ { "name": "api", ... } ] }`
|
|
102
|
+
if (tree.services) {
|
|
103
|
+
if (Array.isArray(tree.services)) {
|
|
104
|
+
for (const s of tree.services) {
|
|
105
|
+
if (s && typeof s === 'object') {
|
|
106
|
+
services.push(parseServiceBlock(s, `service-${services.length + 1}`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (typeof tree.services === 'object') {
|
|
111
|
+
for (const [svcName, svcObj] of Object.entries(tree.services)) {
|
|
112
|
+
if (svcObj && typeof svcObj === 'object') {
|
|
113
|
+
const svc = parseServiceBlock(svcObj, svcName);
|
|
114
|
+
// If the block doesn't name itself, use the map key.
|
|
115
|
+
if (svc.name === svcName || !svc.name)
|
|
116
|
+
svc.name = svcName;
|
|
117
|
+
services.push(svc);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Single-service: the root IS the service config.
|
|
123
|
+
if (services.length === 0) {
|
|
124
|
+
const svc = parseServiceBlock(tree, 'app');
|
|
125
|
+
services.push(svc);
|
|
126
|
+
}
|
|
127
|
+
const projectEnvVars = recordOf(tree.variables) ?? recordOf(tree.envVars) ?? recordOf(tree.env);
|
|
128
|
+
return { services, projectEnvVars };
|
|
129
|
+
}
|
|
130
|
+
export function parseNixpacksConfig(text) {
|
|
131
|
+
const tree = parseTomlSubset(text);
|
|
132
|
+
// Phases: `[phases.build]` / `[phases.start]` in toml.
|
|
133
|
+
// After parseTomlSubset, these land as tree.phases.build / tree.phases.start.
|
|
134
|
+
const phases = tree.phases;
|
|
135
|
+
const buildPhase = phases?.build;
|
|
136
|
+
const startPhase = phases?.start;
|
|
137
|
+
const buildCmd = strOf(buildPhase?.cmd) ?? strOf(tree.buildCommand);
|
|
138
|
+
const startCmd = strOf(startPhase?.cmd) ?? strOf(tree.startCommand);
|
|
139
|
+
// Providers can be `providers = ["node"]` at top level.
|
|
140
|
+
const rawProviders = tree.providers;
|
|
141
|
+
const providers = Array.isArray(rawProviders)
|
|
142
|
+
? rawProviders.filter((p) => typeof p === 'string')
|
|
143
|
+
: undefined;
|
|
144
|
+
return { buildCmd, startCmd, providers };
|
|
145
|
+
}
|
|
146
|
+
export function parseProcfile(text) {
|
|
147
|
+
const entries = [];
|
|
148
|
+
for (const rawLine of text.split('\n')) {
|
|
149
|
+
const line = rawLine.trim();
|
|
150
|
+
if (!line || line.startsWith('#'))
|
|
151
|
+
continue;
|
|
152
|
+
const colon = line.indexOf(':');
|
|
153
|
+
if (colon < 1)
|
|
154
|
+
continue;
|
|
155
|
+
const process = line.slice(0, colon).trim();
|
|
156
|
+
const command = line.slice(colon + 1).trim();
|
|
157
|
+
if (process && command)
|
|
158
|
+
entries.push({ process, command });
|
|
159
|
+
}
|
|
160
|
+
return entries;
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// package.json framework detector (lightweight — no full parse needed).
|
|
164
|
+
// Returns a short label: 'next' | 'remix' | 'vite' | 'express' | etc.
|
|
165
|
+
const FRAMEWORK_DEPS = [
|
|
166
|
+
[/^next$/, 'next'],
|
|
167
|
+
[/^remix/, 'remix'],
|
|
168
|
+
[/^@remix-run\//, 'remix'],
|
|
169
|
+
[/^nuxt/, 'nuxt'],
|
|
170
|
+
[/^@nuxtjs\//, 'nuxt'],
|
|
171
|
+
[/^gatsby$/, 'gatsby'],
|
|
172
|
+
[/^astro$/, 'astro'],
|
|
173
|
+
[/^@sveltejs\/kit/, 'sveltekit'],
|
|
174
|
+
[/^svelte$/, 'svelte'],
|
|
175
|
+
[/^@angular\/core/, 'angular'],
|
|
176
|
+
[/^fastify$/, 'fastify'],
|
|
177
|
+
[/^express$/, 'express'],
|
|
178
|
+
[/^hono$/, 'hono'],
|
|
179
|
+
[/^koa$/, 'koa'],
|
|
180
|
+
[/^nestjs$|^@nestjs\/core/, 'nestjs'],
|
|
181
|
+
];
|
|
182
|
+
export function detectFramework(packageJsonText) {
|
|
183
|
+
let parsed;
|
|
184
|
+
try {
|
|
185
|
+
parsed = parseJsonc(packageJsonText);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
const deps = {
|
|
191
|
+
...(parsed.dependencies ?? {}),
|
|
192
|
+
...(parsed.devDependencies ?? {}),
|
|
193
|
+
};
|
|
194
|
+
for (const [re, label] of FRAMEWORK_DEPS) {
|
|
195
|
+
if (Object.keys(deps).some((k) => re.test(k)))
|
|
196
|
+
return label;
|
|
197
|
+
}
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=railway-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"railway-parse.js","sourceRoot":"","sources":["../../../src/infra/railway/railway-parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { InfraAdapter, InfraGraph } from '../types.js';
|
|
2
|
+
import { type RailwayConfig, type NixpacksConfig, type ProcfileEntry } from './railway-parse.js';
|
|
3
|
+
export interface RailwayInputs {
|
|
4
|
+
railwayConfig: RailwayConfig | null;
|
|
5
|
+
nixpacks: NixpacksConfig | null;
|
|
6
|
+
procfile: ProcfileEntry[];
|
|
7
|
+
framework: string | undefined;
|
|
8
|
+
/** Repo-relative path of the railway config file (for metadata). */
|
|
9
|
+
railwayConfigFile: string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* repo-relative dir the build runs from (the dir of the
|
|
12
|
+
* railway/nixpacks/Procfile config) — the source-root base. '' / undefined =
|
|
13
|
+
* repo root.
|
|
14
|
+
*/
|
|
15
|
+
buildContextDir?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function buildRailwayGraph(inputs: RailwayInputs, root: string): InfraGraph;
|
|
18
|
+
export declare const railwayAdapter: InfraAdapter;
|
|
19
|
+
//# sourceMappingURL=railway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"railway.d.ts","sourceRoot":"","sources":["../../../src/infra/railway/railway.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAa,UAAU,EAAa,MAAM,aAAa,CAAC;AAElF,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAkI5B,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CA4MjF;AAKD,eAAO,MAAM,cAAc,EAAE,YAsE5B,CAAC"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
// the Railway InfraAdapter (v0).
|
|
2
|
+
//
|
|
3
|
+
// Railway is a PaaS (Platform-as-a-Service) that deploys containerized services
|
|
4
|
+
// and managed plugins (Postgres, Redis, MongoDB, MySQL). This adapter reads the
|
|
5
|
+
// Railway project config files and emits the deployment topology entirely from
|
|
6
|
+
// declared configuration — no LLM, no inference.
|
|
7
|
+
//
|
|
8
|
+
// Sources (in priority order):
|
|
9
|
+
// 1. railway.json / railway.toml — canonical project + service config
|
|
10
|
+
// 2. nixpacks.toml — Nixpacks build config (provider / cmds)
|
|
11
|
+
// 3. Procfile — legacy Heroku-compat process declarations
|
|
12
|
+
// 4. package.json — framework detection fallback
|
|
13
|
+
//
|
|
14
|
+
// detect(): positive if railway.json OR railway.toml OR nixpacks.toml exists.
|
|
15
|
+
// Procfile alone is NOT sufficient (ambiguous with Heroku / bare Nixpacks).
|
|
16
|
+
//
|
|
17
|
+
// Emits:
|
|
18
|
+
// Nodes:
|
|
19
|
+
// - One `worker` node per service declared in railway.json/toml (or one per
|
|
20
|
+
// Procfile process type if no railway config exists but nixpacks.toml does)
|
|
21
|
+
// - One `datastore` node per Railway plugin referenced via ${{Plugin.*}} env
|
|
22
|
+
// vars (Postgres / Redis / MongoDB / MySQL)
|
|
23
|
+
// Edges:
|
|
24
|
+
// - service `stores-in` plugin (from ${{Plugin.*}} env refs)
|
|
25
|
+
// - service `calls` other-service (from ${{OtherService.*}} env refs)
|
|
26
|
+
//
|
|
27
|
+
// All nodes: provenance = 'declared', classificationsNeeded = [].
|
|
28
|
+
// metadata < ~500 bytes per node (no raw file content).
|
|
29
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
30
|
+
import { join, relative } from 'node:path';
|
|
31
|
+
import { walkRepo } from '../walk.js';
|
|
32
|
+
import { parseRailwayConfig, parseNixpacksConfig, parseProcfile, detectFramework, extractEnvRefs, } from './railway-parse.js';
|
|
33
|
+
const RAILWAY_SKIP_DIRS = ['node_modules', '.git', 'dist', '.next', 'build', 'coverage', '.nixpacks'];
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Source-root helpers. Repo-relative, normalized.
|
|
36
|
+
/** Normalize a repo-relative path: backslashes→/, collapse `.`/`./`, strip trailing `/`. */
|
|
37
|
+
function normalizeRoot(p) {
|
|
38
|
+
return p.replace(/\\/g, '/').replace(/^\.(?:\/|$)/, '').replace(/\/+$/, '');
|
|
39
|
+
}
|
|
40
|
+
/** Resolve `rel` (may contain `./`/`../`) against repo-relative `baseDir` → normalized. */
|
|
41
|
+
function resolveRel(baseDir, rel) {
|
|
42
|
+
const parts = (baseDir ? baseDir.split('/') : []).concat(rel.split('/'));
|
|
43
|
+
const out = [];
|
|
44
|
+
for (const p of parts) {
|
|
45
|
+
if (p === '' || p === '.')
|
|
46
|
+
continue;
|
|
47
|
+
if (p === '..')
|
|
48
|
+
out.pop();
|
|
49
|
+
else
|
|
50
|
+
out.push(p);
|
|
51
|
+
}
|
|
52
|
+
return out.join('/');
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* a Railway service's source root. A service's `source`/`rootDirectory`
|
|
56
|
+
* (monorepo sub-path) resolved against the build-context dir is the source root;
|
|
57
|
+
* otherwise the build-context dir itself (where railway.json / nixpacks.toml /
|
|
58
|
+
* Procfile lives = where Nixpacks/Dockerfile builds run). Returns '' (→ no source
|
|
59
|
+
* root) when that's the bare repo root, so a service never becomes a catch-all
|
|
60
|
+
* swallowing its siblings.
|
|
61
|
+
*/
|
|
62
|
+
function serviceSourceRoot(source, buildContextDir) {
|
|
63
|
+
const base = normalizeRoot(buildContextDir);
|
|
64
|
+
return source ? resolveRel(base, source) : base;
|
|
65
|
+
}
|
|
66
|
+
// Procfile process types that represent long-running services worth diagramming.
|
|
67
|
+
// One-shot types (release, postdeploy, etc.) are transient — they run once per
|
|
68
|
+
// deploy and must NOT appear as service nodes in the architecture diagram.
|
|
69
|
+
const LONG_RUNNING_PROCESS_TYPES = new Set(['web', 'worker']);
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// File finders.
|
|
72
|
+
function listDir(dir) {
|
|
73
|
+
try {
|
|
74
|
+
return readdirSync(dir, { withFileTypes: true });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const RAILWAY_CONFIG_NAMES = ['railway.json', 'railway.toml'];
|
|
81
|
+
const NIXPACKS_NAMES = ['nixpacks.toml'];
|
|
82
|
+
const PROCFILE_NAMES = ['Procfile'];
|
|
83
|
+
/** Shallow root-only scan — used by detect() which must be cheap. */
|
|
84
|
+
function findRailwayFilesShallow(repoDir) {
|
|
85
|
+
const result = {};
|
|
86
|
+
for (const e of listDir(repoDir)) {
|
|
87
|
+
if (!e.isFile())
|
|
88
|
+
continue;
|
|
89
|
+
if (!result.railwayConfig && RAILWAY_CONFIG_NAMES.includes(e.name)) {
|
|
90
|
+
result.railwayConfig = join(repoDir, e.name);
|
|
91
|
+
}
|
|
92
|
+
if (!result.nixpacksConfig && NIXPACKS_NAMES.includes(e.name)) {
|
|
93
|
+
result.nixpacksConfig = join(repoDir, e.name);
|
|
94
|
+
}
|
|
95
|
+
if (!result.procfile && PROCFILE_NAMES.includes(e.name)) {
|
|
96
|
+
result.procfile = join(repoDir, e.name);
|
|
97
|
+
}
|
|
98
|
+
if (!result.packageJson && e.name === 'package.json') {
|
|
99
|
+
result.packageJson = join(repoDir, e.name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
/** Full scan (root + bounded deep walk) — used by extract() only. */
|
|
105
|
+
function findRailwayFiles(repoDir) {
|
|
106
|
+
// Root-level scan first (most configs live at root).
|
|
107
|
+
const result = findRailwayFilesShallow(repoDir);
|
|
108
|
+
// If neither railway config nor nixpacks.toml found at root, do a bounded
|
|
109
|
+
// walk so monorepos with configs in sub-directories are still detected.
|
|
110
|
+
// nixpacks.toml is included here: a nested nixpacks.toml is a valid Railway
|
|
111
|
+
// signal for monorepos, same as a nested railway.json/toml.
|
|
112
|
+
if (!result.railwayConfig && !result.nixpacksConfig) {
|
|
113
|
+
walkRepo(repoDir, {
|
|
114
|
+
skipDirs: RAILWAY_SKIP_DIRS,
|
|
115
|
+
maxDepth: 5,
|
|
116
|
+
onFile: (abs, e) => {
|
|
117
|
+
if (!result.railwayConfig && RAILWAY_CONFIG_NAMES.includes(e.name)) {
|
|
118
|
+
result.railwayConfig = abs;
|
|
119
|
+
}
|
|
120
|
+
else if (!result.nixpacksConfig && NIXPACKS_NAMES.includes(e.name)) {
|
|
121
|
+
// nixpacks.toml alone is slightly fuzzy (Nixpacks is also used by
|
|
122
|
+
// Render, Netlify, and bare Nixpacks CLIs), but acceptable for v0
|
|
123
|
+
// because the Terraform adapter is the registered fallback for
|
|
124
|
+
// cloud-infra configs and will override this signal when present.
|
|
125
|
+
result.nixpacksConfig = abs;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Canonical display names for known plugins.
|
|
134
|
+
const PLUGIN_LABELS = {
|
|
135
|
+
postgres: 'Railway Postgres',
|
|
136
|
+
mysql: 'Railway MySQL',
|
|
137
|
+
mongodb: 'Railway MongoDB',
|
|
138
|
+
mongo: 'Railway MongoDB',
|
|
139
|
+
mssql: 'Railway MSSQL',
|
|
140
|
+
redis: 'Railway Redis',
|
|
141
|
+
rabbitmq: 'Railway RabbitMQ',
|
|
142
|
+
};
|
|
143
|
+
export function buildRailwayGraph(inputs, root) {
|
|
144
|
+
const { railwayConfig, nixpacks, procfile, framework, railwayConfigFile } = inputs;
|
|
145
|
+
const buildContextDir = inputs.buildContextDir ?? '';
|
|
146
|
+
const nodes = new Map();
|
|
147
|
+
const edges = [];
|
|
148
|
+
const addNode = (n) => {
|
|
149
|
+
if (!nodes.has(n.id))
|
|
150
|
+
nodes.set(n.id, n);
|
|
151
|
+
};
|
|
152
|
+
// -------------------------------------------------------------------------
|
|
153
|
+
// 1. Service nodes from railway config or Procfile fallback.
|
|
154
|
+
const serviceIds = []; // adapter-local ids, in declaration order
|
|
155
|
+
if (railwayConfig && railwayConfig.services.length > 0) {
|
|
156
|
+
for (const svc of railwayConfig.services) {
|
|
157
|
+
const id = `service:${svc.name}`;
|
|
158
|
+
serviceIds.push(id);
|
|
159
|
+
const meta = {
|
|
160
|
+
...(railwayConfigFile ? { config: railwayConfigFile } : {}),
|
|
161
|
+
...(svc.builder ? { builder: svc.builder } : {}),
|
|
162
|
+
...(svc.buildCommand ? { buildCommand: svc.buildCommand } : {}),
|
|
163
|
+
...(svc.startCommand ? { startCommand: svc.startCommand } : {}),
|
|
164
|
+
...(svc.source ? { source: svc.source } : {}),
|
|
165
|
+
...(framework ? { framework } : {}),
|
|
166
|
+
...(nixpacks?.providers?.length ? { nixpacksProviders: nixpacks.providers } : {}),
|
|
167
|
+
};
|
|
168
|
+
// per-service source root from its source/rootDirectory.
|
|
169
|
+
const srcRoot = serviceSourceRoot(svc.source, buildContextDir);
|
|
170
|
+
addNode({
|
|
171
|
+
id,
|
|
172
|
+
label: svc.name,
|
|
173
|
+
kind: 'worker',
|
|
174
|
+
provenance: 'declared',
|
|
175
|
+
metadata: meta,
|
|
176
|
+
...(srcRoot ? { sourceRoots: [srcRoot] } : {}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else if (procfile.length > 0) {
|
|
181
|
+
// No railway config, but nixpacks.toml confirmed Railway provenance.
|
|
182
|
+
// Only emit long-running process types (web, worker); one-shot types like
|
|
183
|
+
// release: (db migrations) and postdeploy: are transient and must not
|
|
184
|
+
// appear as service nodes in the architecture diagram.
|
|
185
|
+
for (const entry of procfile) {
|
|
186
|
+
if (!LONG_RUNNING_PROCESS_TYPES.has(entry.process))
|
|
187
|
+
continue;
|
|
188
|
+
const id = `service:${entry.process}`;
|
|
189
|
+
serviceIds.push(id);
|
|
190
|
+
// Procfile processes share the build-context dir (no per-process
|
|
191
|
+
// source field); drop the bare repo root.
|
|
192
|
+
const srcRoot = serviceSourceRoot(undefined, buildContextDir);
|
|
193
|
+
addNode({
|
|
194
|
+
id,
|
|
195
|
+
label: entry.process,
|
|
196
|
+
kind: 'worker',
|
|
197
|
+
provenance: 'declared',
|
|
198
|
+
metadata: {
|
|
199
|
+
startCommand: entry.command,
|
|
200
|
+
...(framework ? { framework } : {}),
|
|
201
|
+
...(nixpacks?.providers?.length ? { nixpacksProviders: nixpacks.providers } : {}),
|
|
202
|
+
},
|
|
203
|
+
...(srcRoot ? { sourceRoots: [srcRoot] } : {}),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// Minimal fallback: a single "app" service (nixpacks-only project with no
|
|
209
|
+
// Procfile — common for simple Next.js / Express apps).
|
|
210
|
+
const id = 'service:app';
|
|
211
|
+
serviceIds.push(id);
|
|
212
|
+
// the sole nixpacks/Procfile-less app builds from the build-context
|
|
213
|
+
// dir; drop the bare repo root (root project → honest "Other").
|
|
214
|
+
const srcRoot = serviceSourceRoot(undefined, buildContextDir);
|
|
215
|
+
addNode({
|
|
216
|
+
id,
|
|
217
|
+
label: 'app',
|
|
218
|
+
kind: 'worker',
|
|
219
|
+
provenance: 'declared',
|
|
220
|
+
metadata: {
|
|
221
|
+
...(nixpacks?.startCmd ? { startCommand: nixpacks.startCmd } : {}),
|
|
222
|
+
...(nixpacks?.buildCmd ? { buildCommand: nixpacks.buildCmd } : {}),
|
|
223
|
+
...(framework ? { framework } : {}),
|
|
224
|
+
...(nixpacks?.providers?.length ? { nixpacksProviders: nixpacks.providers } : {}),
|
|
225
|
+
},
|
|
226
|
+
...(srcRoot ? { sourceRoots: [srcRoot] } : {}),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// -------------------------------------------------------------------------
|
|
230
|
+
// 2. Plugin + inter-service edges from env-var references.
|
|
231
|
+
//
|
|
232
|
+
// We scan env vars from the railway config (per-service + project-level) and
|
|
233
|
+
// also any "sample env" strings present in nixpacks metadata.
|
|
234
|
+
// Collect all env-ref text from config.
|
|
235
|
+
let _allEnvText = '';
|
|
236
|
+
if (railwayConfig) {
|
|
237
|
+
for (const svc of railwayConfig.services) {
|
|
238
|
+
if (svc.envVars)
|
|
239
|
+
_allEnvText += JSON.stringify(svc.envVars) + '\n';
|
|
240
|
+
}
|
|
241
|
+
if (railwayConfig.projectEnvVars)
|
|
242
|
+
_allEnvText += JSON.stringify(railwayConfig.projectEnvVars);
|
|
243
|
+
}
|
|
244
|
+
// Build a set of known service names (lowercased) for service-ref detection.
|
|
245
|
+
const knownServiceNames = new Set((railwayConfig?.services ?? []).map((s) => s.name.toLowerCase()));
|
|
246
|
+
// For single-service fallback, serviceIds[0] is "service:app" — don't emit
|
|
247
|
+
// self-referencing edges.
|
|
248
|
+
// Map from plugin nameLower → plugin node id.
|
|
249
|
+
const pluginIdByName = new Map();
|
|
250
|
+
// Map from ref nameLower → source serviceId that owns the env.
|
|
251
|
+
// We model: if ANY service references a plugin/service, all services do
|
|
252
|
+
// (project-level env is project-wide; per-service env is that service's).
|
|
253
|
+
// For simplicity in v0, emit one edge per (referencing-service, target) pair
|
|
254
|
+
// if per-service data is available, or one edge per (first-service, target)
|
|
255
|
+
// if only project-level is available.
|
|
256
|
+
// Per-service env refs for fine-grained edges.
|
|
257
|
+
if (railwayConfig) {
|
|
258
|
+
for (let i = 0; i < railwayConfig.services.length; i++) {
|
|
259
|
+
const svc = railwayConfig.services[i];
|
|
260
|
+
const srcId = `service:${svc.name}`;
|
|
261
|
+
const svcEnvText = svc.envVars ? JSON.stringify(svc.envVars) : '';
|
|
262
|
+
const svcRefs = extractEnvRefs(svcEnvText);
|
|
263
|
+
for (const ref of svcRefs) {
|
|
264
|
+
if (ref.isPlugin) {
|
|
265
|
+
// Emit plugin datastore node.
|
|
266
|
+
const pluginId = `plugin:${ref.nameLower}`;
|
|
267
|
+
pluginIdByName.set(ref.nameLower, pluginId);
|
|
268
|
+
const label = PLUGIN_LABELS[ref.nameLower] ?? `Railway ${ref.name}`;
|
|
269
|
+
addNode({
|
|
270
|
+
id: pluginId,
|
|
271
|
+
label,
|
|
272
|
+
kind: 'datastore',
|
|
273
|
+
provenance: 'declared',
|
|
274
|
+
metadata: { provider: 'railway', plugin: ref.nameLower },
|
|
275
|
+
});
|
|
276
|
+
// Edge: service stores-in plugin.
|
|
277
|
+
edges.push({ source: srcId, target: pluginId, kind: 'stores-in', metadata: { via: 'env-ref', ref: ref.raw } });
|
|
278
|
+
}
|
|
279
|
+
else if (knownServiceNames.has(ref.nameLower)) {
|
|
280
|
+
// Inter-service ref: service calls another service.
|
|
281
|
+
const tgtId = `service:${ref.name}`;
|
|
282
|
+
// Don't self-reference.
|
|
283
|
+
if (tgtId !== srcId) {
|
|
284
|
+
edges.push({ source: srcId, target: tgtId, kind: 'calls', metadata: { via: 'env-ref', ref: ref.raw } });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Project-level env refs — attach to first service (or sole service).
|
|
291
|
+
if (railwayConfig?.projectEnvVars && serviceIds.length > 0) {
|
|
292
|
+
const projectText = JSON.stringify(railwayConfig.projectEnvVars);
|
|
293
|
+
const projectRefs = extractEnvRefs(projectText);
|
|
294
|
+
const defaultSrc = serviceIds[0];
|
|
295
|
+
for (const ref of projectRefs) {
|
|
296
|
+
if (ref.isPlugin) {
|
|
297
|
+
const pluginId = `plugin:${ref.nameLower}`;
|
|
298
|
+
if (!pluginIdByName.has(ref.nameLower)) {
|
|
299
|
+
pluginIdByName.set(ref.nameLower, pluginId);
|
|
300
|
+
const label = PLUGIN_LABELS[ref.nameLower] ?? `Railway ${ref.name}`;
|
|
301
|
+
addNode({
|
|
302
|
+
id: pluginId,
|
|
303
|
+
label,
|
|
304
|
+
kind: 'datastore',
|
|
305
|
+
provenance: 'declared',
|
|
306
|
+
metadata: { provider: 'railway', plugin: ref.nameLower },
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
// Only add edge if not already emitted from per-service scan.
|
|
310
|
+
const alreadyEmitted = edges.some((e) => e.source === defaultSrc && e.target === pluginId && e.kind === 'stores-in');
|
|
311
|
+
if (!alreadyEmitted) {
|
|
312
|
+
edges.push({ source: defaultSrc, target: pluginId, kind: 'stores-in', metadata: { via: 'env-ref', ref: ref.raw } });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Deduplicate edges (same source + target + kind).
|
|
318
|
+
const edgeKey = new Set();
|
|
319
|
+
const dedupedEdges = [];
|
|
320
|
+
for (const e of edges) {
|
|
321
|
+
const k = `${e.source}→${e.target}:${e.kind}`;
|
|
322
|
+
if (!edgeKey.has(k)) {
|
|
323
|
+
edgeKey.add(k);
|
|
324
|
+
dedupedEdges.push(e);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
root,
|
|
329
|
+
adapter: 'railway',
|
|
330
|
+
nodes: [...nodes.values()],
|
|
331
|
+
edges: dedupedEdges,
|
|
332
|
+
classificationsNeeded: [], // PaaS tight static model — no LLM needed
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
// The InfraAdapter.
|
|
337
|
+
export const railwayAdapter = {
|
|
338
|
+
name: 'railway',
|
|
339
|
+
async detect(repoDir) {
|
|
340
|
+
// Cheap root-only existence check — the InfraAdapter contract says detect()
|
|
341
|
+
// runs for every adapter on every repo, so no deep walk here.
|
|
342
|
+
// Positive if railway.json / railway.toml / nixpacks.toml exists at root.
|
|
343
|
+
// Procfile alone is ambiguous with Heroku and is NOT sufficient.
|
|
344
|
+
const files = findRailwayFilesShallow(repoDir);
|
|
345
|
+
return !!(files.railwayConfig || files.nixpacksConfig);
|
|
346
|
+
},
|
|
347
|
+
async extract(repoDir) {
|
|
348
|
+
const found = findRailwayFiles(repoDir);
|
|
349
|
+
let railwayConfig = null;
|
|
350
|
+
let nixpacks = null;
|
|
351
|
+
let procfile = [];
|
|
352
|
+
let framework;
|
|
353
|
+
let railwayConfigFile;
|
|
354
|
+
if (found.railwayConfig) {
|
|
355
|
+
railwayConfigFile = relative(repoDir, found.railwayConfig) || found.railwayConfig;
|
|
356
|
+
try {
|
|
357
|
+
railwayConfig = parseRailwayConfig(readFileSync(found.railwayConfig, 'utf8'), found.railwayConfig);
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
console.warn(` [railway] skipping unparseable ${railwayConfigFile}: ${err.message}`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (found.nixpacksConfig) {
|
|
364
|
+
try {
|
|
365
|
+
nixpacks = parseNixpacksConfig(readFileSync(found.nixpacksConfig, 'utf8'));
|
|
366
|
+
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
console.warn(` [railway] skipping unparseable nixpacks.toml: ${err.message}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (found.procfile) {
|
|
372
|
+
try {
|
|
373
|
+
procfile = parseProcfile(readFileSync(found.procfile, 'utf8'));
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// Non-fatal — Procfile is optional.
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (found.packageJson) {
|
|
380
|
+
try {
|
|
381
|
+
framework = detectFramework(readFileSync(found.packageJson, 'utf8'));
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
// Non-fatal.
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// the build runs from the dir of the primary config file (railway
|
|
388
|
+
// config > nixpacks > Procfile). For a monorepo with a nested config that's
|
|
389
|
+
// the sub-project dir; for a root-level project it's '' (→ no catch-all).
|
|
390
|
+
const primaryConfig = found.railwayConfig ?? found.nixpacksConfig ?? found.procfile;
|
|
391
|
+
const buildContextDir = primaryConfig
|
|
392
|
+
? (relative(repoDir, primaryConfig).replace(/\\/g, '/').split('/').slice(0, -1).join('/'))
|
|
393
|
+
: '';
|
|
394
|
+
return buildRailwayGraph({ railwayConfig, nixpacks, procfile, framework, railwayConfigFile, buildContextDir }, repoDir);
|
|
395
|
+
},
|
|
396
|
+
};
|
|
397
|
+
//# sourceMappingURL=railway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"railway.js","sourceRoot":"","sources":["../../../src/infra/railway/railway.ts"],"names":[],"mappings":"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"}
|