@aws/nx-plugin 1.0.0-rc.79 → 1.0.0-rc.80
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/generators.json +10 -0
- package/migrations.json +1 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/agent-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/agent-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/agent-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/agent-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/attach-upstream.js.map +1 -1
- package/src/agentcore-gateway/gateway-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/gateway-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/gateway-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/generator.d.ts +3 -3
- package/src/agentcore-gateway/generator.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/react-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/react-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/react-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/react-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/schema.d.js.map +1 -1
- package/src/agentcore-gateway/schema.d.ts +1 -1
- package/src/agentcore-harness/generator.d.ts +4 -4
- package/src/agentcore-harness/generator.js.map +1 -1
- package/src/agentcore-harness/schema.d.js.map +1 -1
- package/src/agentcore-harness/schema.d.ts +1 -1
- package/src/connection/agent-local-dev.d.ts +1 -1
- package/src/connection/agent-local-dev.js.map +1 -1
- package/src/connection/agent-runtime-config.js.map +1 -1
- package/src/connection/gateway-runtime-config.js.map +1 -1
- package/src/connection/generator.d.ts +2 -2
- package/src/connection/generator.js.map +1 -1
- package/src/connection/local-dev.js.map +1 -1
- package/src/connection/scaffold-catalog.d.ts +1 -1
- package/src/connection/scaffold-catalog.js +6 -6
- package/src/connection/scaffold-catalog.js.map +1 -1
- package/src/connection/schema-resolver.d.ts +1 -1
- package/src/connection/schema-resolver.js.map +1 -1
- package/src/index.d.ts +1 -1
- package/src/index.js.map +1 -1
- package/src/infra/app/generator.d.ts +7 -7
- package/src/infra/app/generator.js.map +1 -1
- package/src/init/generator.d.ts +3 -3
- package/src/init/generator.js.map +1 -1
- package/src/init/schema.d.js.map +1 -1
- package/src/init/schema.d.ts +2 -2
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/license/config-types.d.ts +2 -2
- package/src/license/config-types.js.map +1 -1
- package/src/license/config.d.ts +2 -2
- package/src/license/config.js.map +1 -1
- package/src/license/dependency-check/check.d.ts +2 -2
- package/src/license/dependency-check/check.js.map +1 -1
- package/src/license/dependency-check/collectors/collector.js.map +1 -1
- package/src/license/dependency-check/collectors/python-collector.js.map +1 -1
- package/src/license/dependency-check/evaluator.d.ts +1 -1
- package/src/license/dependency-check/evaluator.js.map +1 -1
- package/src/license/dependency-check/executor.js.map +1 -1
- package/src/license/dependency-check/pre-approved.d.ts +1 -1
- package/src/license/dependency-check/pre-approved.js.map +1 -1
- package/src/license/dependency-check/types.d.ts +1 -1
- package/src/license/dependency-check/types.js.map +1 -1
- package/src/license/generator.d.ts +1 -1
- package/src/license/generator.js.map +1 -1
- package/src/license/index.d.ts +4 -4
- package/src/license/index.js.map +1 -1
- package/src/license/known-exceptions.d.ts +1 -1
- package/src/license/known-exceptions.js.map +1 -1
- package/src/license/sync/generator.js.map +1 -1
- package/src/license/sync/project-file-sync.d.ts +1 -1
- package/src/license/sync/project-file-sync.js.map +1 -1
- package/src/mcp-server/dev-server.js.map +1 -1
- package/src/mcp-server/generator-info.d.ts +3 -3
- package/src/mcp-server/generator-info.js.map +1 -1
- package/src/mcp-server/guide-pipeline.d.ts +1 -1
- package/src/mcp-server/guide-pipeline.js.map +1 -1
- package/src/mcp-server/guide-render.js.map +1 -1
- package/src/mcp-server/index.js.map +1 -1
- package/src/mcp-server/mdx-ast.js.map +1 -1
- package/src/mcp-server/server.js.map +1 -1
- package/src/mcp-server/tools/add-to-existing-project.d.ts +1 -1
- package/src/mcp-server/tools/add-to-existing-project.js.map +1 -1
- package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
- package/src/mcp-server/tools/general-guidance.d.ts +1 -1
- package/src/mcp-server/tools/general-guidance.js +1 -1
- package/src/mcp-server/tools/general-guidance.js.map +1 -1
- package/src/mcp-server/tools/generator-guide.d.ts +1 -1
- package/src/mcp-server/tools/generator-guide.js.map +1 -1
- package/src/mcp-server/tools/list-generators.d.ts +1 -1
- package/src/mcp-server/tools/list-generators.js.map +1 -1
- package/src/mcp-server/tools/upgrade-workspace.d.ts +1 -1
- package/src/mcp-server/tools/upgrade-workspace.js.map +1 -1
- package/src/migrations/latest/apt-security-updates-in-container-images/migration.js.map +1 -1
- package/src/migrations/latest/dynamodb-configurable-encryption/migration.js.map +1 -1
- package/src/migrations/latest/py-agent-ag-ui-hooks/migration.js.map +1 -1
- package/src/migrations/latest/py-agent-session-id-middleware-extraction/migration.js.map +1 -1
- package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js.map +1 -1
- package/src/migrations/latest/static-website-configurable-waf-encryption/migration.js.map +1 -1
- package/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.js.map +1 -1
- package/src/migrations/latest/user-identity-configurable-mfa/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.50/0001-modernize-function-props-cast/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.50/0002-restrict-cors-to-custom-domains/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.50/0003-terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.52/0001-user-identity-waf-allow-localhost-callback/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.54/0001-order-access-log-delivery-after-bucket-policy/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.d.ts +1 -1
- package/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.56/0001-dynamodb-local-remove-optimize-flag/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.57/0001-ts-agent-session-management-support/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.58/0001-smithy-ssdk-bundle-pins/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.59/0001-gateway-agent-targets/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.60/0001-gateway-cognito-passthrough/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.60/0002-waf-log-group-removal/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.60/0003-strip-pip-from-python-images/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.61/0001-py-agent-lifespan-construction/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.62/0001-rename-load-runtime-config-target/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.63/0001-add-deploy-sandbox-target/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.64/0001-smithy-build-without-docker/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.65/0001-vite-config-import-meta-dirname/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.65/0002-rolldown-code-splitting/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.67/0001-smithy-server-package-rename/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.68/0001-translate-script-whole-file-writes/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js.map +1 -1
- package/src/open-api/ts-client/generator.d.ts +1 -1
- package/src/open-api/ts-client/generator.js.map +1 -1
- package/src/open-api/ts-hooks/generator.d.ts +1 -1
- package/src/open-api/ts-hooks/generator.js.map +1 -1
- package/src/open-api/ts-hooks/generator.spec.tsx +6 -6
- package/src/open-api/ts-metadata/generator.d.ts +1 -1
- package/src/open-api/ts-metadata/generator.js.map +1 -1
- package/src/open-api/utils/codegen-data/languages.d.ts +1 -1
- package/src/open-api/utils/codegen-data/languages.js.map +1 -1
- package/src/open-api/utils/codegen-data.d.ts +2 -2
- package/src/open-api/utils/codegen-data.js.map +1 -1
- package/src/open-api/utils/normalise.d.ts +1 -1
- package/src/open-api/utils/normalise.js.map +1 -1
- package/src/open-api/utils/parse.d.ts +1 -1
- package/src/open-api/utils/parse.js.map +1 -1
- package/src/open-api/utils/parser.d.ts +2 -2
- package/src/open-api/utils/parser.js.map +1 -1
- package/src/open-api/utils/refs.d.ts +1 -1
- package/src/open-api/utils/refs.js.map +1 -1
- package/src/preset/generator.d.ts +3 -3
- package/src/preset/generator.js.map +1 -1
- package/src/preset/schema.d.js.map +1 -1
- package/src/preset/schema.d.ts +3 -3
- package/src/py/agent/a2a-connection/generator.d.ts +3 -3
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/a2a-connection/schema.d.js.map +1 -1
- package/src/py/agent/a2a-connection/schema.d.ts +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +3 -3
- package/src/py/agent/gateway-connection/generator.js.map +1 -1
- package/src/py/agent/gateway-connection/schema.d.js.map +1 -1
- package/src/py/agent/gateway-connection/schema.d.ts +1 -1
- package/src/py/agent/generator.d.ts +3 -3
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/generator.d.ts +3 -3
- package/src/py/agent/mcp-connection/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/schema.d.js.map +1 -1
- package/src/py/agent/mcp-connection/schema.d.ts +1 -1
- package/src/py/agent/react-connection/generator.d.ts +12 -12
- package/src/py/agent/react-connection/generator.js.map +1 -1
- package/src/py/agent/react-connection/local-dev.d.ts +1 -1
- package/src/py/agent/react-connection/local-dev.js.map +1 -1
- package/src/py/agent/react-connection/schema.d.js.map +1 -1
- package/src/py/agent/react-connection/schema.d.ts +1 -1
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +1 -1
- package/src/py/api/generator.d.ts +1 -1
- package/src/py/api/generator.js.map +1 -1
- package/src/py/api/schema.d.js.map +1 -1
- package/src/py/api/schema.d.ts +1 -1
- package/src/py/dynamodb/agent-connection/generator.d.ts +1 -1
- package/src/py/dynamodb/agent-connection/generator.js.map +1 -1
- package/src/py/dynamodb/agent-connection/schema.d.js.map +1 -1
- package/src/py/dynamodb/agent-connection/schema.d.ts +1 -1
- package/src/py/dynamodb/fast-api-connection/generator.d.ts +1 -1
- package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -1
- package/src/py/dynamodb/generator.d.ts +4 -4
- package/src/py/dynamodb/generator.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/generator.d.ts +1 -1
- package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/schema.d.ts +1 -1
- package/src/py/dynamodb/schema.d.js.map +1 -1
- package/src/py/dynamodb/schema.d.ts +1 -1
- package/src/py/fast-api/generator.d.ts +3 -3
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/fast-api/react/generator.d.ts +3 -3
- package/src/py/fast-api/react/generator.js.map +1 -1
- package/src/py/fast-api/react/open-api.js.map +1 -1
- package/src/py/fast-api/schema.d.js.map +1 -1
- package/src/py/fast-api/schema.d.ts +1 -1
- package/src/py/lambda-function/files/handler/__lambdaFunctionSnakeCase__.py.template +1 -1
- package/src/py/lambda-function/generator.d.ts +10 -4
- package/src/py/lambda-function/generator.js +8 -1
- package/src/py/lambda-function/generator.js.map +1 -1
- package/src/py/lambda-function/schema.d.js.map +1 -1
- package/src/py/lambda-function/schema.d.ts +2 -2
- package/src/py/lambda-function/schema.json +1 -1
- package/src/py/mcp-server/generator.d.ts +3 -3
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/mcp-server/schema.d.js.map +1 -1
- package/src/py/mcp-server/schema.d.ts +1 -1
- package/src/py/project/generator.d.ts +2 -2
- package/src/py/project/generator.js.map +1 -1
- package/src/py/project/schema.json +1 -0
- package/src/py/rdb/agent-connection/generator.d.ts +1 -1
- package/src/py/rdb/agent-connection/generator.js.map +1 -1
- package/src/py/rdb/agent-connection/schema.d.js.map +1 -1
- package/src/py/rdb/agent-connection/schema.d.ts +1 -1
- package/src/py/rdb/fast-api-connection/generator.d.ts +1 -1
- package/src/py/rdb/fast-api-connection/generator.js.map +1 -1
- package/src/py/rdb/generator.d.ts +3 -3
- package/src/py/rdb/generator.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/generator.d.ts +1 -1
- package/src/py/rdb/mcp-server-connection/generator.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/schema.d.ts +1 -1
- package/src/sdk/agentcore-gateway.d.ts +1 -1
- package/src/sdk/agentcore-gateway.js.map +1 -1
- package/src/sdk/agentcore-harness.d.ts +1 -1
- package/src/sdk/agentcore-harness.js.map +1 -1
- package/src/sdk/connection.d.ts +1 -1
- package/src/sdk/connection.js.map +1 -1
- package/src/sdk/license.d.ts +3 -3
- package/src/sdk/license.js.map +1 -1
- package/src/sdk/open-api.d.ts +3 -3
- package/src/sdk/open-api.js.map +1 -1
- package/src/sdk/py.d.ts +7 -7
- package/src/sdk/py.js.map +1 -1
- package/src/sdk/smithy.d.ts +1 -1
- package/src/sdk/smithy.js.map +1 -1
- package/src/sdk/terraform.d.ts +1 -1
- package/src/sdk/terraform.js.map +1 -1
- package/src/sdk/ts.d.ts +18 -18
- package/src/sdk/ts.js.map +1 -1
- package/src/sdk/utils/ast.d.ts +1 -1
- package/src/sdk/utils/ast.js.map +1 -1
- package/src/sdk/utils/format.d.ts +1 -1
- package/src/sdk/utils/format.js.map +1 -1
- package/src/sdk/utils/test.d.ts +1 -1
- package/src/sdk/utils/test.js.map +1 -1
- package/src/smithy/project/generator.d.ts +4 -4
- package/src/smithy/project/generator.js.map +1 -1
- package/src/smithy/react-connection/generator.d.ts +3 -3
- package/src/smithy/react-connection/generator.js.map +1 -1
- package/src/smithy/ts/api/generator.d.ts +3 -3
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/smithy/ts/api/schema.d.js.map +1 -1
- package/src/smithy/ts/api/schema.d.ts +1 -1
- package/src/terraform/project/generator.d.ts +5 -5
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/generator.d.ts +3 -3
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/backend/schema.d.js.map +1 -1
- package/src/trpc/backend/schema.d.ts +1 -1
- package/src/trpc/react/generator.d.ts +3 -3
- package/src/trpc/react/generator.js.map +1 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +3 -3
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/a2a-connection/schema.d.js.map +1 -1
- package/src/ts/agent/a2a-connection/schema.d.ts +1 -1
- package/src/ts/agent/gateway-connection/generator.d.ts +3 -3
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/gateway-connection/schema.d.js.map +1 -1
- package/src/ts/agent/gateway-connection/schema.d.ts +1 -1
- package/src/ts/agent/generator.d.ts +3 -3
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/generator.d.ts +3 -3
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/schema.d.js.map +1 -1
- package/src/ts/agent/mcp-connection/schema.d.ts +1 -1
- package/src/ts/agent/react-connection/generator.d.ts +11 -11
- package/src/ts/agent/react-connection/generator.js.map +1 -1
- package/src/ts/agent/react-connection/local-dev.d.ts +1 -1
- package/src/ts/agent/react-connection/local-dev.js.map +1 -1
- package/src/ts/agent/react-connection/schema.d.js.map +1 -1
- package/src/ts/agent/react-connection/schema.d.ts +1 -1
- package/src/ts/agent/schema.d.js.map +1 -1
- package/src/ts/agent/schema.d.ts +1 -1
- package/src/ts/api/generator.d.ts +1 -1
- package/src/ts/api/generator.js.map +1 -1
- package/src/ts/api/schema.d.js.map +1 -1
- package/src/ts/api/schema.d.ts +1 -1
- package/src/ts/astro-docs/generator.d.ts +3 -3
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/dcr-proxy/generator.d.ts +5 -5
- package/src/ts/dcr-proxy/generator.js.map +1 -1
- package/src/ts/dcr-proxy/schema.d.js.map +1 -1
- package/src/ts/dcr-proxy/schema.d.ts +1 -1
- package/src/ts/docs/generator.d.ts +1 -1
- package/src/ts/docs/generator.js.map +1 -1
- package/src/ts/dynamodb/agent-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/agent-connection/schema.d.js.map +1 -1
- package/src/ts/dynamodb/agent-connection/schema.d.ts +1 -1
- package/src/ts/dynamodb/generator.d.ts +5 -5
- package/src/ts/dynamodb/generator.js +1 -0
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +1 -1
- package/src/ts/dynamodb/schema.d.js.map +1 -1
- package/src/ts/dynamodb/schema.d.ts +1 -1
- package/src/ts/dynamodb/smithy-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/trpc-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
- package/src/ts/lambda-function/generator.d.ts +5 -5
- package/src/ts/lambda-function/generator.js.map +1 -1
- package/src/ts/lambda-function/schema.d.js.map +1 -1
- package/src/ts/lambda-function/schema.d.ts +1 -1
- package/src/ts/lib/biome.d.ts +1 -1
- package/src/ts/lib/biome.js.map +1 -1
- package/src/ts/lib/generator.d.ts +3 -3
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/ts-project-utils.d.ts +3 -3
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/vitest.d.ts +2 -2
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/ts/mcp-server/generator.d.ts +3 -3
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.d.js.map +1 -1
- package/src/ts/mcp-server/schema.d.ts +1 -1
- package/src/ts/nx-generator/generator.d.ts +2 -2
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-migration/generator.d.ts +3 -3
- package/src/ts/nx-migration/generator.js.map +1 -1
- package/src/ts/nx-plugin/generator.d.ts +3 -3
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/nx-plugin/utils.d.ts +1 -1
- package/src/ts/nx-plugin/utils.js.map +1 -1
- package/src/ts/rdb/agent-connection/generator.d.ts +1 -1
- package/src/ts/rdb/agent-connection/generator.js.map +1 -1
- package/src/ts/rdb/agent-connection/schema.d.js.map +1 -1
- package/src/ts/rdb/agent-connection/schema.d.ts +1 -1
- package/src/ts/rdb/generator.d.ts +4 -4
- package/src/ts/rdb/generator.js +1 -0
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/generator.d.ts +1 -1
- package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/schema.d.ts +1 -1
- package/src/ts/rdb/schema.d.js.map +1 -1
- package/src/ts/rdb/schema.d.ts +1 -1
- package/src/ts/rdb/smithy-connection/generator.d.ts +1 -1
- package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
- package/src/ts/rdb/trpc-connection/generator.d.ts +1 -1
- package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
- package/src/ts/react-website/agui/generator.d.ts +2 -2
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/ts/react-website/app/generator.d.ts +3 -3
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/app/schema.d.js.map +1 -1
- package/src/ts/react-website/app/schema.d.ts +2 -2
- package/src/ts/react-website/cognito-auth/generator.d.ts +5 -5
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/schema.d.js.map +1 -1
- package/src/ts/react-website/cognito-auth/schema.d.ts +1 -1
- package/src/ts/react-website/cognito-auth/utils.js.map +1 -1
- package/src/ts/react-website/runtime-config/generator.d.ts +1 -1
- package/src/ts/react-website/runtime-config/generator.js.map +1 -1
- package/src/ts/sync/generator.d.ts +1 -1
- package/src/ts/sync/generator.js.map +1 -1
- package/src/ts/website/app/generator.d.ts +1 -1
- package/src/ts/website/app/generator.js.map +1 -1
- package/src/ts/website/app/schema.d.js.map +1 -1
- package/src/ts/website/app/schema.d.ts +2 -2
- package/src/ts/website/auth/generator.d.ts +1 -1
- package/src/ts/website/auth/generator.js.map +1 -1
- package/src/ts/website/auth/schema.d.js.map +1 -1
- package/src/ts/website/auth/schema.d.ts +1 -1
- package/src/utils/add-dependencies.d.ts +1 -1
- package/src/utils/add-dependencies.js.map +1 -1
- package/src/utils/agent-chat/agent-chat.js.map +1 -1
- package/src/utils/agent-connection/agent-connection.d.ts +2 -2
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +4 -4
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/api-constructs/api-constructs.d.ts +3 -3
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/open-api-metadata.d.ts +1 -1
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/ast/website.js.map +1 -1
- package/src/utils/ast.js +6 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/bundle/bundle.d.ts +1 -1
- package/src/utils/bundle/bundle.js.map +1 -1
- package/src/utils/commands.d.ts +1 -1
- package/src/utils/commands.js.map +1 -1
- package/src/utils/config/index.d.ts +6 -6
- package/src/utils/config/index.js.map +1 -1
- package/src/utils/config/utils.d.ts +1 -1
- package/src/utils/config/utils.js.map +1 -1
- package/src/utils/connection/open-api/react.d.ts +1 -1
- package/src/utils/connection/open-api/react.js.map +1 -1
- package/src/utils/containers.js.map +1 -1
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.d.ts +1 -1
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -1
- package/src/utils/declared-dependencies.d.ts +1 -1
- package/src/utils/declared-dependencies.js.map +1 -1
- package/src/utils/dependencies.js.map +1 -1
- package/src/utils/docker.d.ts +1 -1
- package/src/utils/docker.js.map +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
- package/src/utils/format.js.map +1 -1
- package/src/utils/fs.d.ts +1 -1
- package/src/utils/fs.js.map +1 -1
- package/src/utils/function-constructs/function-constructs.d.ts +1 -1
- package/src/utils/function-constructs/function-constructs.js.map +1 -1
- package/src/utils/iac.d.ts +2 -2
- package/src/utils/iac.js.map +1 -1
- package/src/utils/identity-constructs/identity-constructs.d.ts +2 -2
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/init.d.ts +3 -3
- package/src/utils/init.js.map +1 -1
- package/src/utils/install.d.ts +1 -1
- package/src/utils/install.js.map +1 -1
- package/src/utils/mcp.js.map +1 -1
- package/src/utils/metrics.d.ts +1 -1
- package/src/utils/metrics.js.map +1 -1
- package/src/utils/migration-manifest.d.ts +1 -1
- package/src/utils/migration-manifest.js.map +1 -1
- package/src/utils/nx.d.ts +3 -3
- package/src/utils/nx.js.map +1 -1
- package/src/utils/paths.js.map +1 -1
- package/src/utils/pkg-manager.d.ts +1 -1
- package/src/utils/pkg-manager.js.map +1 -1
- package/src/utils/pnpm-workspace.js.map +1 -1
- package/src/utils/project-package-json.js.map +1 -1
- package/src/utils/py.d.ts +2 -2
- package/src/utils/py.js.map +1 -1
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +2 -2
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/shared-constructs.d.ts +3 -3
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/shared-dynamodb-scripts.d.ts +1 -1
- package/src/utils/shared-dynamodb-scripts.js.map +1 -1
- package/src/utils/shared-infra-config.js.map +1 -1
- package/src/utils/shared-infra-scripts.d.ts +2 -2
- package/src/utils/shared-infra-scripts.js.map +1 -1
- package/src/utils/shared-rdb-scripts.d.ts +1 -1
- package/src/utils/shared-rdb-scripts.js.map +1 -1
- package/src/utils/shared-scripts.js.map +1 -1
- package/src/utils/shared-shadcn.d.ts +1 -1
- package/src/utils/shared-shadcn.js.map +1 -1
- package/src/utils/smithy.js.map +1 -1
- package/src/utils/test.js.map +1 -1
- package/src/utils/version-upgrade-migration/migration.js.map +1 -1
- package/src/utils/version-upgrade-migration/nx-package-updates.js.map +1 -1
- package/src/utils/version-upgrade-migration/owned-dependencies.d.ts +1 -1
- package/src/utils/version-upgrade-migration/owned-dependencies.js.map +1 -1
- package/src/utils/version-upgrade-migration/register.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-embedded-versions.d.ts +1 -1
- package/src/utils/version-upgrade-migration/sync-embedded-versions.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-metrics-version.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js.map +1 -1
- package/src/utils/website-constructs/website-constructs.d.ts +2 -2
- package/src/utils/website-constructs/website-constructs.js.map +1 -1
package/src/migrations/v1.0.0-rc.50/0003-terraform-bootstrap-adopt-existing-bucket/migration.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.50/0003-terraform-bootstrap-adopt-existing-bucket/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { TERRAFORM_PROJECT_GENERATOR_INFO } from '../../../terraform/project/generator';\nimport {\n applyGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\n\n/**\n * Adopt an existing Terraform state bucket in the vended bootstrap script when its state object is missing\n *\n * The state bucket stores its own tfstate inside itself, so if that object is\n * deleted while the bucket survives, `bootstrap` reads the 404 as a first run\n * and asks terraform to create a bucket that already exists — failing with\n * `BucketAlreadyOwnedByYou` on every subsequent run, with no retry that clears\n * it. The vended script now imports the existing bucket instead.\n *\n * Every edit is expressed as a GritQL rewrite so the script is matched on its\n * AST rather than its formatting.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * your generators produce and report them via `nextSteps`, or consider a\n * hybrid migration, rather than clobbering the user's changes.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree` so the files your\n * migration wrote are formatted correctly.\n */\n\n// Guards the whole migration: present only once the import step exists.\nconst MIGRATED_PATTERN = '`bucketExists($_, $_)`';\n\n// Every edit site, matched structurally so formatting and argument layout\n// don't affect whether the script is recognised.\nconst STATE_FETCH_TRY_PATTERN =\n 'try_statement() as $try where { $try <: contains `GetObjectCommand` }';\nconst STATE_FLAG_SET_PATTERN = '`if (out.Body) { $body }`';\nconst HELPER_PATTERN = '`const main = async () => { $body }`';\nconst INIT_PATTERN = \"`execFileSync('terraform', ['init'], $opts)`\";\nconst S3_IMPORT_PATTERN =\n \"`import { $before, GetObjectCommand, $after } from '@aws-sdk/client-s3'`\";\nconst HEADER_COMMENT_PATTERN =\n 'comment() as $c where { $c <: includes \"state back to S3.\" }';\n\n// GritQL snippets are parsed as backtick-quoted patterns, so any backtick in\n// the inserted source has to survive that layer escaped.\nconst BUCKET_EXISTS_HELPER = `// S3 answers 404 only when the name is genuinely free; 403 means it exists\n// but is not readable with these credentials.\nconst bucketExists = async (s3: S3Client, bucket: string) => {\n try {\n await s3.send(new HeadBucketCommand({ Bucket: bucket }));\n return true;\n } catch (err: any) {\n const status = err?.$metadata?.httpStatusCode;\n if (status === 404) return false;\n if (status === 403) return true;\n throw err;\n }\n};`;\n\nconst IMPORT_STEP = `// The bucket holds its own state, so losing the state object while the\n // bucket survives would otherwise wedge bootstrap on a permanent\n // \\`BucketAlreadyOwnedByYou\\`. Adopt the existing bucket instead.\n if (!haveState && (await bucketExists(s3, bucket))) {\n console.log(\n \\`State bucket \\${bucket} already exists but its bootstrap state is missing — importing it.\\`,\n );\n execFileSync(\n 'terraform',\n [\n 'import',\n \\`-state=\\${tfStatePath}\\`,\n \\`-var=aws_region=\\${region}\\`,\n 'aws_s3_bucket.terraform_state',\n bucket,\n ],\n { cwd: bootstrapDir, stdio: 'inherit' },\n );\n }`;\n\n// Rewritten wholesale rather than appended to, since the summary sentence\n// changes rather than gaining a clause.\nconst NEW_HEADER_COMMENT = `/**\n * Bootstraps the remote Terraform state bucket.\n *\n * Equivalent to \\\\\\`cdk bootstrap\\\\\\` — resolves account + region from the AWS\n * SDK credential chain, pulls any existing bootstrap tfstate from S3,\n * runs \\\\\\`terraform apply\\\\\\` in the \\\\\\`bootstrap\\\\\\` dir, then pushes the new\n * state back to S3. Adopts an already-existing state bucket when its\n * state object is missing.\n */`;\n\nconst DIVERGED_NEXT_STEP = (filePath: string) =>\n `${filePath}: the bootstrap script has diverged from the generated shape - left untouched. Manually \\`terraform import aws_s3_bucket.terraform_state <bucket>\\` before \\`terraform apply\\` when the state bucket exists but its \\`bootstrap.tfstate\\` object does not, otherwise bootstrap fails with BucketAlreadyOwnedByYou.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n // Terraform application projects are the only ones that vend bootstrap.ts.\n const bootstrapScripts = [...getProjects(tree).values()]\n .filter(\n (project) =>\n (project.metadata as any)?.generator ===\n TERRAFORM_PROJECT_GENERATOR_INFO.id,\n )\n .map((project) => joinPathFragments(project.root, 'scripts/bootstrap.ts'))\n .filter((filePath) => tree.exists(filePath));\n\n for (const filePath of bootstrapScripts) {\n if (await matchGritQL(tree, filePath, MIGRATED_PATTERN)) {\n // Already migrated - silent skip keeps re-runs a no-op.\n continue;\n }\n\n // Confirm every edit site is present before writing any of them, so a\n // script that only partly matches is left whole rather than half-edited.\n const allSitesPresent = (\n await Promise.all(\n [\n STATE_FETCH_TRY_PATTERN,\n STATE_FLAG_SET_PATTERN,\n HELPER_PATTERN,\n INIT_PATTERN,\n S3_IMPORT_PATTERN,\n HEADER_COMMENT_PATTERN,\n ].map((pattern) => matchGritQL(tree, filePath, pattern)),\n )\n ).every(Boolean);\n\n if (!allSitesPresent) {\n nextSteps.push(DIVERGED_NEXT_STEP(filePath));\n continue;\n }\n\n // `haveState` distinguishes \"no remote state\" from \"no bucket\", so the\n // import only runs when terraform has no prior knowledge of the bucket.\n await insertViaGritQL(\n tree,\n filePath,\n `${STATE_FETCH_TRY_PATTERN} => \\`${GRIT_INSERT_PLACEHOLDER}\\n $try\\``,\n 'let haveState = false;',\n );\n await applyGritQL(\n tree,\n filePath,\n `${STATE_FLAG_SET_PATTERN} => \\`if (out.Body) {\\n $body\\n haveState = true;\\n }\\``,\n );\n await insertViaGritQL(\n tree,\n filePath,\n `${HELPER_PATTERN} => \\`${GRIT_INSERT_PLACEHOLDER}\\n\\nconst main = async () => { $body }\\``,\n BUCKET_EXISTS_HELPER,\n );\n await insertViaGritQL(\n tree,\n filePath,\n `${INIT_PATTERN} => \\`execFileSync('terraform', ['init'], $opts);\\n\\n ${GRIT_INSERT_PLACEHOLDER}\\n\\``,\n IMPORT_STEP,\n );\n\n // Placed in the generator's import position rather than appended, so a\n // migrated workspace matches a freshly generated one.\n await applyGritQL(\n tree,\n filePath,\n `${S3_IMPORT_PATTERN} => \\`import { $before, GetObjectCommand, HeadBucketCommand, $after } from '@aws-sdk/client-s3'\\``,\n );\n\n await applyGritQL(\n tree,\n filePath,\n `${HEADER_COMMENT_PATTERN} => \\`${NEW_HEADER_COMMENT}\\``,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","TERRAFORM_PROJECT_GENERATOR_INFO","applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","MIGRATED_PATTERN","STATE_FETCH_TRY_PATTERN","STATE_FLAG_SET_PATTERN","HELPER_PATTERN","INIT_PATTERN","S3_IMPORT_PATTERN","HEADER_COMMENT_PATTERN","BUCKET_EXISTS_HELPER","IMPORT_STEP","NEW_HEADER_COMMENT","DIVERGED_NEXT_STEP","filePath","migration","tree","nextSteps","bootstrapScripts","values","filter","project","metadata","generator","id","map","root","exists","allSitesPresent","Promise","all","pattern","every","Boolean","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAGZ,aAAa;AACpB,SAASC,gCAAgC,QAAQ,0CAAuC;AACxF,SACEC,WAAW,EACXC,uBAAuB,EACvBC,eAAe,EACfC,WAAW,QACN,wBAAqB;AAC5B,SAASC,oBAAoB,QAAQ,2BAAwB;AAE7D;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GAED,wEAAwE;AACxE,MAAMC,mBAAmB;AAEzB,0EAA0E;AAC1E,iDAAiD;AACjD,MAAMC,0BACJ;AACF,MAAMC,yBAAyB;AAC/B,MAAMC,iBAAiB;AACvB,MAAMC,eAAe;AACrB,MAAMC,oBACJ;AACF,MAAMC,yBACJ;AAEF,6EAA6E;AAC7E,yDAAyD;AACzD,MAAMC,uBAAuB,CAAC;;;;;;;;;;;;EAY5B,CAAC;AAEH,MAAMC,cAAc,CAAC;;;;;;;;;;;;;;;;;;GAkBlB,CAAC;AAEJ,0EAA0E;AAC1E,wCAAwC;AACxC,MAAMC,qBAAqB,CAAC;;;;;;;;GAQzB,CAAC;AAEJ,MAAMC,qBAAqB,CAACC,WAC1B,GAAGA,SAAS,kTAAkT,CAAC;AAEjU,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,2EAA2E;IAC3E,MAAMC,mBAAmB;WAAIvB,YAAYqB,MAAMG,MAAM;KAAG,CACrDC,MAAM,CACL,CAACC,UACC,AAACA,QAAQC,QAAQ,EAAUC,cAC3B1B,iCAAiC2B,EAAE,EAEtCC,GAAG,CAAC,CAACJ,UAAYzB,kBAAkByB,QAAQK,IAAI,EAAE,yBACjDN,MAAM,CAAC,CAACN,WAAaE,KAAKW,MAAM,CAACb;IAEpC,KAAK,MAAMA,YAAYI,iBAAkB;QACvC,IAAI,MAAMjB,YAAYe,MAAMF,UAAUX,mBAAmB;YAEvD;QACF;QAEA,sEAAsE;QACtE,yEAAyE;QACzE,MAAMyB,kBAAkB,AACtB,CAAA,MAAMC,QAAQC,GAAG,CACf;YACE1B;YACAC;YACAC;YACAC;YACAC;YACAC;SACD,CAACgB,GAAG,CAAC,CAACM,UAAY9B,YAAYe,MAAMF,UAAUiB,UACjD,EACAC,KAAK,CAACC;QAER,IAAI,CAACL,iBAAiB;YACpBX,UAAUiB,IAAI,CAACrB,mBAAmBC;YAClC;QACF;QAEA,uEAAuE;QACvE,wEAAwE;QACxE,MAAMd,gBACJgB,MACAF,UACA,GAAGV,wBAAwB,MAAM,EAAEL,wBAAwB,UAAU,CAAC,EACtE;QAEF,MAAMD,YACJkB,MACAF,UACA,GAAGT,uBAAuB,oEAAoE,CAAC;QAEjG,MAAML,gBACJgB,MACAF,UACA,GAAGR,eAAe,MAAM,EAAEP,wBAAwB,wCAAwC,CAAC,EAC3FW;QAEF,MAAMV,gBACJgB,MACAF,UACA,GAAGP,aAAa,uDAAuD,EAAER,wBAAwB,IAAI,CAAC,EACtGY;QAGF,uEAAuE;QACvE,sDAAsD;QACtD,MAAMb,YACJkB,MACAF,UACA,GAAGN,kBAAkB,iGAAiG,CAAC;QAGzH,MAAMV,YACJkB,MACAF,UACA,GAAGL,uBAAuB,MAAM,EAAEG,mBAAmB,EAAE,CAAC;IAE5D;IAEA,MAAMV,qBAAqBc;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.50/0003-terraform-bootstrap-adopt-existing-bucket/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { TERRAFORM_PROJECT_GENERATOR_INFO } from '../../../terraform/project/generator.js';\nimport {\n applyGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\n\n/**\n * Adopt an existing Terraform state bucket in the vended bootstrap script when its state object is missing\n *\n * The state bucket stores its own tfstate inside itself, so if that object is\n * deleted while the bucket survives, `bootstrap` reads the 404 as a first run\n * and asks terraform to create a bucket that already exists — failing with\n * `BucketAlreadyOwnedByYou` on every subsequent run, with no retry that clears\n * it. The vended script now imports the existing bucket instead.\n *\n * Every edit is expressed as a GritQL rewrite so the script is matched on its\n * AST rather than its formatting.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * your generators produce and report them via `nextSteps`, or consider a\n * hybrid migration, rather than clobbering the user's changes.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree` so the files your\n * migration wrote are formatted correctly.\n */\n\n// Guards the whole migration: present only once the import step exists.\nconst MIGRATED_PATTERN = '`bucketExists($_, $_)`';\n\n// Every edit site, matched structurally so formatting and argument layout\n// don't affect whether the script is recognised.\nconst STATE_FETCH_TRY_PATTERN =\n 'try_statement() as $try where { $try <: contains `GetObjectCommand` }';\nconst STATE_FLAG_SET_PATTERN = '`if (out.Body) { $body }`';\nconst HELPER_PATTERN = '`const main = async () => { $body }`';\nconst INIT_PATTERN = \"`execFileSync('terraform', ['init'], $opts)`\";\nconst S3_IMPORT_PATTERN =\n \"`import { $before, GetObjectCommand, $after } from '@aws-sdk/client-s3'`\";\nconst HEADER_COMMENT_PATTERN =\n 'comment() as $c where { $c <: includes \"state back to S3.\" }';\n\n// GritQL snippets are parsed as backtick-quoted patterns, so any backtick in\n// the inserted source has to survive that layer escaped.\nconst BUCKET_EXISTS_HELPER = `// S3 answers 404 only when the name is genuinely free; 403 means it exists\n// but is not readable with these credentials.\nconst bucketExists = async (s3: S3Client, bucket: string) => {\n try {\n await s3.send(new HeadBucketCommand({ Bucket: bucket }));\n return true;\n } catch (err: any) {\n const status = err?.$metadata?.httpStatusCode;\n if (status === 404) return false;\n if (status === 403) return true;\n throw err;\n }\n};`;\n\nconst IMPORT_STEP = `// The bucket holds its own state, so losing the state object while the\n // bucket survives would otherwise wedge bootstrap on a permanent\n // \\`BucketAlreadyOwnedByYou\\`. Adopt the existing bucket instead.\n if (!haveState && (await bucketExists(s3, bucket))) {\n console.log(\n \\`State bucket \\${bucket} already exists but its bootstrap state is missing — importing it.\\`,\n );\n execFileSync(\n 'terraform',\n [\n 'import',\n \\`-state=\\${tfStatePath}\\`,\n \\`-var=aws_region=\\${region}\\`,\n 'aws_s3_bucket.terraform_state',\n bucket,\n ],\n { cwd: bootstrapDir, stdio: 'inherit' },\n );\n }`;\n\n// Rewritten wholesale rather than appended to, since the summary sentence\n// changes rather than gaining a clause.\nconst NEW_HEADER_COMMENT = `/**\n * Bootstraps the remote Terraform state bucket.\n *\n * Equivalent to \\\\\\`cdk bootstrap\\\\\\` — resolves account + region from the AWS\n * SDK credential chain, pulls any existing bootstrap tfstate from S3,\n * runs \\\\\\`terraform apply\\\\\\` in the \\\\\\`bootstrap\\\\\\` dir, then pushes the new\n * state back to S3. Adopts an already-existing state bucket when its\n * state object is missing.\n */`;\n\nconst DIVERGED_NEXT_STEP = (filePath: string) =>\n `${filePath}: the bootstrap script has diverged from the generated shape - left untouched. Manually \\`terraform import aws_s3_bucket.terraform_state <bucket>\\` before \\`terraform apply\\` when the state bucket exists but its \\`bootstrap.tfstate\\` object does not, otherwise bootstrap fails with BucketAlreadyOwnedByYou.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n // Terraform application projects are the only ones that vend bootstrap.ts.\n const bootstrapScripts = [...getProjects(tree).values()]\n .filter(\n (project) =>\n (project.metadata as any)?.generator ===\n TERRAFORM_PROJECT_GENERATOR_INFO.id,\n )\n .map((project) => joinPathFragments(project.root, 'scripts/bootstrap.ts'))\n .filter((filePath) => tree.exists(filePath));\n\n for (const filePath of bootstrapScripts) {\n if (await matchGritQL(tree, filePath, MIGRATED_PATTERN)) {\n // Already migrated - silent skip keeps re-runs a no-op.\n continue;\n }\n\n // Confirm every edit site is present before writing any of them, so a\n // script that only partly matches is left whole rather than half-edited.\n const allSitesPresent = (\n await Promise.all(\n [\n STATE_FETCH_TRY_PATTERN,\n STATE_FLAG_SET_PATTERN,\n HELPER_PATTERN,\n INIT_PATTERN,\n S3_IMPORT_PATTERN,\n HEADER_COMMENT_PATTERN,\n ].map((pattern) => matchGritQL(tree, filePath, pattern)),\n )\n ).every(Boolean);\n\n if (!allSitesPresent) {\n nextSteps.push(DIVERGED_NEXT_STEP(filePath));\n continue;\n }\n\n // `haveState` distinguishes \"no remote state\" from \"no bucket\", so the\n // import only runs when terraform has no prior knowledge of the bucket.\n await insertViaGritQL(\n tree,\n filePath,\n `${STATE_FETCH_TRY_PATTERN} => \\`${GRIT_INSERT_PLACEHOLDER}\\n $try\\``,\n 'let haveState = false;',\n );\n await applyGritQL(\n tree,\n filePath,\n `${STATE_FLAG_SET_PATTERN} => \\`if (out.Body) {\\n $body\\n haveState = true;\\n }\\``,\n );\n await insertViaGritQL(\n tree,\n filePath,\n `${HELPER_PATTERN} => \\`${GRIT_INSERT_PLACEHOLDER}\\n\\nconst main = async () => { $body }\\``,\n BUCKET_EXISTS_HELPER,\n );\n await insertViaGritQL(\n tree,\n filePath,\n `${INIT_PATTERN} => \\`execFileSync('terraform', ['init'], $opts);\\n\\n ${GRIT_INSERT_PLACEHOLDER}\\n\\``,\n IMPORT_STEP,\n );\n\n // Placed in the generator's import position rather than appended, so a\n // migrated workspace matches a freshly generated one.\n await applyGritQL(\n tree,\n filePath,\n `${S3_IMPORT_PATTERN} => \\`import { $before, GetObjectCommand, HeadBucketCommand, $after } from '@aws-sdk/client-s3'\\``,\n );\n\n await applyGritQL(\n tree,\n filePath,\n `${HEADER_COMMENT_PATTERN} => \\`${NEW_HEADER_COMMENT}\\``,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","TERRAFORM_PROJECT_GENERATOR_INFO","applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","MIGRATED_PATTERN","STATE_FETCH_TRY_PATTERN","STATE_FLAG_SET_PATTERN","HELPER_PATTERN","INIT_PATTERN","S3_IMPORT_PATTERN","HEADER_COMMENT_PATTERN","BUCKET_EXISTS_HELPER","IMPORT_STEP","NEW_HEADER_COMMENT","DIVERGED_NEXT_STEP","filePath","migration","tree","nextSteps","bootstrapScripts","values","filter","project","metadata","generator","id","map","root","exists","allSitesPresent","Promise","all","pattern","every","Boolean","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAGZ,aAAa;AACpB,SAASC,gCAAgC,QAAQ,0CAA0C;AAC3F,SACEC,WAAW,EACXC,uBAAuB,EACvBC,eAAe,EACfC,WAAW,QACN,wBAAwB;AAC/B,SAASC,oBAAoB,QAAQ,2BAA2B;AAEhE;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GAED,wEAAwE;AACxE,MAAMC,mBAAmB;AAEzB,0EAA0E;AAC1E,iDAAiD;AACjD,MAAMC,0BACJ;AACF,MAAMC,yBAAyB;AAC/B,MAAMC,iBAAiB;AACvB,MAAMC,eAAe;AACrB,MAAMC,oBACJ;AACF,MAAMC,yBACJ;AAEF,6EAA6E;AAC7E,yDAAyD;AACzD,MAAMC,uBAAuB,CAAC;;;;;;;;;;;;EAY5B,CAAC;AAEH,MAAMC,cAAc,CAAC;;;;;;;;;;;;;;;;;;GAkBlB,CAAC;AAEJ,0EAA0E;AAC1E,wCAAwC;AACxC,MAAMC,qBAAqB,CAAC;;;;;;;;GAQzB,CAAC;AAEJ,MAAMC,qBAAqB,CAACC,WAC1B,GAAGA,SAAS,kTAAkT,CAAC;AAEjU,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,2EAA2E;IAC3E,MAAMC,mBAAmB;WAAIvB,YAAYqB,MAAMG,MAAM;KAAG,CACrDC,MAAM,CACL,CAACC,UACC,AAACA,QAAQC,QAAQ,EAAUC,cAC3B1B,iCAAiC2B,EAAE,EAEtCC,GAAG,CAAC,CAACJ,UAAYzB,kBAAkByB,QAAQK,IAAI,EAAE,yBACjDN,MAAM,CAAC,CAACN,WAAaE,KAAKW,MAAM,CAACb;IAEpC,KAAK,MAAMA,YAAYI,iBAAkB;QACvC,IAAI,MAAMjB,YAAYe,MAAMF,UAAUX,mBAAmB;YAEvD;QACF;QAEA,sEAAsE;QACtE,yEAAyE;QACzE,MAAMyB,kBAAkB,AACtB,CAAA,MAAMC,QAAQC,GAAG,CACf;YACE1B;YACAC;YACAC;YACAC;YACAC;YACAC;SACD,CAACgB,GAAG,CAAC,CAACM,UAAY9B,YAAYe,MAAMF,UAAUiB,UACjD,EACAC,KAAK,CAACC;QAER,IAAI,CAACL,iBAAiB;YACpBX,UAAUiB,IAAI,CAACrB,mBAAmBC;YAClC;QACF;QAEA,uEAAuE;QACvE,wEAAwE;QACxE,MAAMd,gBACJgB,MACAF,UACA,GAAGV,wBAAwB,MAAM,EAAEL,wBAAwB,UAAU,CAAC,EACtE;QAEF,MAAMD,YACJkB,MACAF,UACA,GAAGT,uBAAuB,oEAAoE,CAAC;QAEjG,MAAML,gBACJgB,MACAF,UACA,GAAGR,eAAe,MAAM,EAAEP,wBAAwB,wCAAwC,CAAC,EAC3FW;QAEF,MAAMV,gBACJgB,MACAF,UACA,GAAGP,aAAa,uDAAuD,EAAER,wBAAwB,IAAI,CAAC,EACtGY;QAGF,uEAAuE;QACvE,sDAAsD;QACtD,MAAMb,YACJkB,MACAF,UACA,GAAGN,kBAAkB,iGAAiG,CAAC;QAGzH,MAAMV,YACJkB,MACAF,UACA,GAAGL,uBAAuB,MAAM,EAAEG,mBAAmB,EAAE,CAAC;IAE5D;IAEA,MAAMV,qBAAqBc;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
|
package/src/migrations/v1.0.0-rc.52/0001-user-identity-waf-allow-localhost-callback/migration.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.52/0001-user-identity-waf-allow-localhost-callback/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport { applyGritQL, matchGritQL } from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Count the EC2MetaDataSSRF_QUERYARGUMENTS WAF rule on the UserIdentity Web ACL\n *\n * `AWSManagedRulesCommonRuleSet` treats the loopback `redirect_uri` the Cognito\n * Hosted UI receives during local sign-in as an SSRF attempt, so sign-in against\n * a local dev server fails with an opaque 403 before the login page renders. The\n * rule is overridden to Count while a local callback URL is allowed; every other\n * rule in the group still blocks.\n *\n * The local callback URLs are lifted into a named constant so the override can be\n * derived from them rather than restating the condition.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * your generators produce and report them via `nextSteps`, rather than\n * clobbering the user's changes.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree` so the files your\n * migration wrote are formatted correctly.\n */\n\nconst CDK_USER_IDENTITY_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/user-identity.ts`;\nconst TERRAFORM_IDENTITY_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/user-identity/identity/identity.tf`;\n\nconst SSRF_RULE_NAME = 'EC2MetaDataSSRF_QUERYARGUMENTS';\n\n// Guards each file: present only once the override has been added.\nconst CDK_MIGRATED_PATTERN = `\\`ruleActionOverrides: allowsLocalCallback ? $_ : undefined\\``;\nconst TERRAFORM_MIGRATED_PATTERN = `language hcl\\n\\`name = \"${SSRF_RULE_NAME}\"\\``;\n\n// Every CDK edit site, matched structurally so formatting doesn't affect whether\n// the construct is recognised.\nconst CDK_CONSTANT_ANCHOR_PATTERN = \"`const WEB_CLIENT_ID = 'WebClient'`\";\n// Scoped to the `.concat` callsite so it can't also rewrite the array literal\n// inside the constant this migration inserts.\nconst CDK_LOCAL_URLS_PATTERN =\n \"`['http://localhost:4200', 'http://localhost:4300'].concat($rest)`\";\nconst CDK_CALL_PATTERN = '`this.createWebAcl($id, this.userPool)`';\nconst CDK_SIGNATURE_PATTERN =\n '`private createWebAcl = ($id: string, $pool: UserPool) => $body`';\nconst CDK_STATEMENT_PATTERN =\n \"`managedRuleGroupStatement: { name: 'AWSManagedRulesCommonRuleSet', vendorName: 'AWS' }`\";\n\nconst CDK_EDITS: Array<[string, string]> = [\n // Local callback URLs become a named constant the override can key off.\n [\n CDK_CONSTANT_ANCHOR_PATTERN,\n `${CDK_CONSTANT_ANCHOR_PATTERN} => \\`const WEB_CLIENT_ID = 'WebClient';\n\n/** Local dev server origins permitted to complete the sign-in redirect */\nconst LOCAL_CALLBACK_URLS = ['http://localhost:4200', 'http://localhost:4300']\\``,\n ],\n [\n CDK_LOCAL_URLS_PATTERN,\n `${CDK_LOCAL_URLS_PATTERN} => \\`LOCAL_CALLBACK_URLS.concat($rest)\\``,\n ],\n [\n CDK_CALL_PATTERN,\n `${CDK_CALL_PATTERN} => \\`this.createWebAcl($id, this.userPool, LOCAL_CALLBACK_URLS.length > 0)\\``,\n ],\n [\n CDK_SIGNATURE_PATTERN,\n `${CDK_SIGNATURE_PATTERN} => \\`private createWebAcl = (\n $id: string,\n $pool: UserPool,\n allowsLocalCallback: boolean\n ) => $body\\``,\n ],\n [\n CDK_STATEMENT_PATTERN,\n `${CDK_STATEMENT_PATTERN} => \\`managedRuleGroupStatement: {\n name: 'AWSManagedRulesCommonRuleSet',\n vendorName: 'AWS',\n // ${SSRF_RULE_NAME} treats the loopback redirect_uri the\n // Hosted UI receives during local sign-in as an SSRF attempt. Counted\n // only while a local callback URL is allowed; every other rule blocks.\n ruleActionOverrides: allowsLocalCallback\n ? [\n {\n name: '${SSRF_RULE_NAME}',\n actionToUse: { count: {} },\n },\n ]\n : undefined,\n }\\``,\n ],\n];\n\nconst TERRAFORM_DATA_SOURCES_PATTERN = [\n 'language hcl',\n '`data \"aws_region\" \"current\" {}`',\n].join('\\n');\n\nconst TERRAFORM_EDITS: Array<[string, string]> = [\n // Local callback URLs become a local the override can key off.\n [\n TERRAFORM_DATA_SOURCES_PATTERN,\n [\n 'language hcl',\n '`data \"aws_region\" \"current\" {}` => `data \"aws_region\" \"current\" {}',\n '',\n 'locals {',\n ' # Local dev server origins permitted to complete the sign-in redirect',\n ' local_callback_urls = [',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ]',\n '}`',\n ].join('\\n'),\n ],\n [\n [\n 'language hcl',\n '`callback_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.callback_urls)`',\n ].join('\\n'),\n [\n 'language hcl',\n '`callback_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.callback_urls)` => `callback_urls = concat(local.local_callback_urls, var.callback_urls)`',\n ].join('\\n'),\n ],\n [\n [\n 'language hcl',\n '`logout_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.logout_urls)`',\n ].join('\\n'),\n [\n 'language hcl',\n '`logout_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.logout_urls)` => `logout_urls = concat(local.local_callback_urls, var.logout_urls)`',\n ].join('\\n'),\n ],\n [\n [\n 'language hcl',\n '`managed_rule_group_statement {',\n ' name = \"AWSManagedRulesCommonRuleSet\"',\n ' vendor_name = \"AWS\"',\n ' }`',\n ].join('\\n'),\n [\n 'language hcl',\n '`managed_rule_group_statement {',\n ' name = \"AWSManagedRulesCommonRuleSet\"',\n ' vendor_name = \"AWS\"',\n ' }` => `managed_rule_group_statement {',\n ' name = \"AWSManagedRulesCommonRuleSet\"',\n ' vendor_name = \"AWS\"',\n '',\n ` # ${SSRF_RULE_NAME} treats the loopback redirect_uri the`,\n ' # Hosted UI receives during local sign-in as an SSRF attempt. Counted',\n ' # only while a local callback URL is allowed; every other rule blocks.',\n ' dynamic \"rule_action_override\" {',\n ' for_each = length(local.local_callback_urls) > 0 ? [1] : []',\n '',\n ' content {',\n ` name = \"${SSRF_RULE_NAME}\"`,\n '',\n ' action_to_use {',\n ' count {}',\n ' }',\n ' }',\n ' }',\n ' }`',\n ].join('\\n'),\n ],\n];\n\nconst divergedNextStep = (filePath: string) =>\n `${filePath}: the UserIdentity Web ACL has diverged from the generated shape - left untouched. To sign in against a local dev server, override ${SSRF_RULE_NAME} in the AWSManagedRulesCommonRuleSet rule group to Count, otherwise the Cognito Hosted UI returns 403 for localhost redirect URIs.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const [filePath, migratedPattern, edits] of [\n [CDK_USER_IDENTITY_FILE, CDK_MIGRATED_PATTERN, CDK_EDITS],\n [TERRAFORM_IDENTITY_FILE, TERRAFORM_MIGRATED_PATTERN, TERRAFORM_EDITS],\n ] as const) {\n if (!tree.exists(filePath)) {\n // This workspace doesn't use this IaC provider, or has no UserIdentity.\n continue;\n }\n\n if (await matchGritQL(tree, filePath, migratedPattern)) {\n // Already migrated - silent skip keeps re-runs a no-op.\n continue;\n }\n\n // Confirm every edit site is present before writing any of them, so a file\n // that only partly matches is left whole rather than half-edited.\n const allSitesPresent = (\n await Promise.all(\n edits.map(([match]) => matchGritQL(tree, filePath, match)),\n )\n ).every(Boolean);\n\n if (!allSitesPresent) {\n nextSteps.push(divergedNextStep(filePath));\n continue;\n }\n\n for (const [, rewrite] of edits) {\n await applyGritQL(tree, filePath, rewrite);\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","CDK_USER_IDENTITY_FILE","TERRAFORM_IDENTITY_FILE","SSRF_RULE_NAME","CDK_MIGRATED_PATTERN","TERRAFORM_MIGRATED_PATTERN","CDK_CONSTANT_ANCHOR_PATTERN","CDK_LOCAL_URLS_PATTERN","CDK_CALL_PATTERN","CDK_SIGNATURE_PATTERN","CDK_STATEMENT_PATTERN","CDK_EDITS","TERRAFORM_DATA_SOURCES_PATTERN","join","TERRAFORM_EDITS","divergedNextStep","filePath","migration","tree","nextSteps","migratedPattern","edits","exists","allSitesPresent","Promise","all","map","match","every","Boolean","push","rewrite"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.52/0001-user-identity-waf-allow-localhost-callback/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport { applyGritQL, matchGritQL } from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Count the EC2MetaDataSSRF_QUERYARGUMENTS WAF rule on the UserIdentity Web ACL\n *\n * `AWSManagedRulesCommonRuleSet` treats the loopback `redirect_uri` the Cognito\n * Hosted UI receives during local sign-in as an SSRF attempt, so sign-in against\n * a local dev server fails with an opaque 403 before the login page renders. The\n * rule is overridden to Count while a local callback URL is allowed; every other\n * rule in the group still blocks.\n *\n * The local callback URLs are lifted into a named constant so the override can be\n * derived from them rather than restating the condition.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * your generators produce and report them via `nextSteps`, rather than\n * clobbering the user's changes.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree` so the files your\n * migration wrote are formatted correctly.\n */\n\nconst CDK_USER_IDENTITY_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/user-identity.ts`;\nconst TERRAFORM_IDENTITY_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/user-identity/identity/identity.tf`;\n\nconst SSRF_RULE_NAME = 'EC2MetaDataSSRF_QUERYARGUMENTS';\n\n// Guards each file: present only once the override has been added.\nconst CDK_MIGRATED_PATTERN = `\\`ruleActionOverrides: allowsLocalCallback ? $_ : undefined\\``;\nconst TERRAFORM_MIGRATED_PATTERN = `language hcl\\n\\`name = \"${SSRF_RULE_NAME}\"\\``;\n\n// Every CDK edit site, matched structurally so formatting doesn't affect whether\n// the construct is recognised.\nconst CDK_CONSTANT_ANCHOR_PATTERN = \"`const WEB_CLIENT_ID = 'WebClient'`\";\n// Scoped to the `.concat` callsite so it can't also rewrite the array literal\n// inside the constant this migration inserts.\nconst CDK_LOCAL_URLS_PATTERN =\n \"`['http://localhost:4200', 'http://localhost:4300'].concat($rest)`\";\nconst CDK_CALL_PATTERN = '`this.createWebAcl($id, this.userPool)`';\nconst CDK_SIGNATURE_PATTERN =\n '`private createWebAcl = ($id: string, $pool: UserPool) => $body`';\nconst CDK_STATEMENT_PATTERN =\n \"`managedRuleGroupStatement: { name: 'AWSManagedRulesCommonRuleSet', vendorName: 'AWS' }`\";\n\nconst CDK_EDITS: Array<[string, string]> = [\n // Local callback URLs become a named constant the override can key off.\n [\n CDK_CONSTANT_ANCHOR_PATTERN,\n `${CDK_CONSTANT_ANCHOR_PATTERN} => \\`const WEB_CLIENT_ID = 'WebClient';\n\n/** Local dev server origins permitted to complete the sign-in redirect */\nconst LOCAL_CALLBACK_URLS = ['http://localhost:4200', 'http://localhost:4300']\\``,\n ],\n [\n CDK_LOCAL_URLS_PATTERN,\n `${CDK_LOCAL_URLS_PATTERN} => \\`LOCAL_CALLBACK_URLS.concat($rest)\\``,\n ],\n [\n CDK_CALL_PATTERN,\n `${CDK_CALL_PATTERN} => \\`this.createWebAcl($id, this.userPool, LOCAL_CALLBACK_URLS.length > 0)\\``,\n ],\n [\n CDK_SIGNATURE_PATTERN,\n `${CDK_SIGNATURE_PATTERN} => \\`private createWebAcl = (\n $id: string,\n $pool: UserPool,\n allowsLocalCallback: boolean\n ) => $body\\``,\n ],\n [\n CDK_STATEMENT_PATTERN,\n `${CDK_STATEMENT_PATTERN} => \\`managedRuleGroupStatement: {\n name: 'AWSManagedRulesCommonRuleSet',\n vendorName: 'AWS',\n // ${SSRF_RULE_NAME} treats the loopback redirect_uri the\n // Hosted UI receives during local sign-in as an SSRF attempt. Counted\n // only while a local callback URL is allowed; every other rule blocks.\n ruleActionOverrides: allowsLocalCallback\n ? [\n {\n name: '${SSRF_RULE_NAME}',\n actionToUse: { count: {} },\n },\n ]\n : undefined,\n }\\``,\n ],\n];\n\nconst TERRAFORM_DATA_SOURCES_PATTERN = [\n 'language hcl',\n '`data \"aws_region\" \"current\" {}`',\n].join('\\n');\n\nconst TERRAFORM_EDITS: Array<[string, string]> = [\n // Local callback URLs become a local the override can key off.\n [\n TERRAFORM_DATA_SOURCES_PATTERN,\n [\n 'language hcl',\n '`data \"aws_region\" \"current\" {}` => `data \"aws_region\" \"current\" {}',\n '',\n 'locals {',\n ' # Local dev server origins permitted to complete the sign-in redirect',\n ' local_callback_urls = [',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ]',\n '}`',\n ].join('\\n'),\n ],\n [\n [\n 'language hcl',\n '`callback_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.callback_urls)`',\n ].join('\\n'),\n [\n 'language hcl',\n '`callback_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.callback_urls)` => `callback_urls = concat(local.local_callback_urls, var.callback_urls)`',\n ].join('\\n'),\n ],\n [\n [\n 'language hcl',\n '`logout_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.logout_urls)`',\n ].join('\\n'),\n [\n 'language hcl',\n '`logout_urls = concat([',\n ' \"http://localhost:4200\",',\n ' \"http://localhost:4300\"',\n ' ], var.logout_urls)` => `logout_urls = concat(local.local_callback_urls, var.logout_urls)`',\n ].join('\\n'),\n ],\n [\n [\n 'language hcl',\n '`managed_rule_group_statement {',\n ' name = \"AWSManagedRulesCommonRuleSet\"',\n ' vendor_name = \"AWS\"',\n ' }`',\n ].join('\\n'),\n [\n 'language hcl',\n '`managed_rule_group_statement {',\n ' name = \"AWSManagedRulesCommonRuleSet\"',\n ' vendor_name = \"AWS\"',\n ' }` => `managed_rule_group_statement {',\n ' name = \"AWSManagedRulesCommonRuleSet\"',\n ' vendor_name = \"AWS\"',\n '',\n ` # ${SSRF_RULE_NAME} treats the loopback redirect_uri the`,\n ' # Hosted UI receives during local sign-in as an SSRF attempt. Counted',\n ' # only while a local callback URL is allowed; every other rule blocks.',\n ' dynamic \"rule_action_override\" {',\n ' for_each = length(local.local_callback_urls) > 0 ? [1] : []',\n '',\n ' content {',\n ` name = \"${SSRF_RULE_NAME}\"`,\n '',\n ' action_to_use {',\n ' count {}',\n ' }',\n ' }',\n ' }',\n ' }`',\n ].join('\\n'),\n ],\n];\n\nconst divergedNextStep = (filePath: string) =>\n `${filePath}: the UserIdentity Web ACL has diverged from the generated shape - left untouched. To sign in against a local dev server, override ${SSRF_RULE_NAME} in the AWSManagedRulesCommonRuleSet rule group to Count, otherwise the Cognito Hosted UI returns 403 for localhost redirect URIs.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const [filePath, migratedPattern, edits] of [\n [CDK_USER_IDENTITY_FILE, CDK_MIGRATED_PATTERN, CDK_EDITS],\n [TERRAFORM_IDENTITY_FILE, TERRAFORM_MIGRATED_PATTERN, TERRAFORM_EDITS],\n ] as const) {\n if (!tree.exists(filePath)) {\n // This workspace doesn't use this IaC provider, or has no UserIdentity.\n continue;\n }\n\n if (await matchGritQL(tree, filePath, migratedPattern)) {\n // Already migrated - silent skip keeps re-runs a no-op.\n continue;\n }\n\n // Confirm every edit site is present before writing any of them, so a file\n // that only partly matches is left whole rather than half-edited.\n const allSitesPresent = (\n await Promise.all(\n edits.map(([match]) => matchGritQL(tree, filePath, match)),\n )\n ).every(Boolean);\n\n if (!allSitesPresent) {\n nextSteps.push(divergedNextStep(filePath));\n continue;\n }\n\n for (const [, rewrite] of edits) {\n await applyGritQL(tree, filePath, rewrite);\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","CDK_USER_IDENTITY_FILE","TERRAFORM_IDENTITY_FILE","SSRF_RULE_NAME","CDK_MIGRATED_PATTERN","TERRAFORM_MIGRATED_PATTERN","CDK_CONSTANT_ANCHOR_PATTERN","CDK_LOCAL_URLS_PATTERN","CDK_CALL_PATTERN","CDK_SIGNATURE_PATTERN","CDK_STATEMENT_PATTERN","CDK_EDITS","TERRAFORM_DATA_SOURCES_PATTERN","join","TERRAFORM_EDITS","divergedNextStep","filePath","migration","tree","nextSteps","migratedPattern","edits","exists","allSitesPresent","Promise","all","map","match","every","Boolean","push","rewrite"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.54/0001-order-access-log-delivery-after-bucket-policy/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\n addDestructuredImport,\n applyGritQL,\n captureGritQL,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Order the S3 server access log delivery source after the bucket policy.\n *\n * S3 rejects concurrent configuration writes against the same bucket with a 409\n * (OperationAborted). The generated StaticWebsite construct left the delivery\n * source and the bucket policy unordered, so CloudFormation could submit both at\n * once and fail the stack.\n */\n\nconst STATIC_WEBSITE_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/static-website.ts`;\n\nconst BUCKET_ARN_SUFFIX = '.bucketArn';\n\n/**\n * The bucket whose policy the delivery source must be ordered after is the one\n * the delivery source itself targets, so read it off `resourceArn` rather than\n * assuming the generated parameter name. Returns undefined unless exactly one\n * simple identifier is found, so a diverged helper is left alone.\n */\nconst findDeliverySourceBucket = async (\n tree: Tree,\n filePath: string,\n): Promise<string | undefined> => {\n const captured = await captureGritQL(\n tree,\n filePath,\n '`resourceArn: $bucket.bucketArn`',\n );\n if (!captured) return undefined;\n\n const bucket = captured\n .slice(captured.indexOf(':') + 1)\n .replace(BUCKET_ARN_SUFFIX, '')\n .trim();\n\n // Only a plain identifier can be cast and dereferenced safely in the\n // statement this migration writes.\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(bucket) ? bucket : undefined;\n};\n\n/**\n * Confirm the bucket the delivery source targets is declared as a parameter of\n * the enclosing helper, so the statement this migration writes references a\n * variable that is actually in scope.\n */\nconst isBucketDeclaredParameter = async (\n tree: Tree,\n filePath: string,\n bucket: string,\n): Promise<boolean> =>\n await matchGritQL(\n tree,\n filePath,\n `\\`private deliverAccessLogsToCloudWatch($params) { $_ }\\` where {\n $params <: contains \\`${bucket}: $bucketType\\`,\n $bucketType <: or { \\`IBucket\\`, \\`Bucket\\` }\n }`,\n );\n\n// Inserts the bucket policy dependency between the delivery source and the\n// delivery destination, matching the shape generators produced prior to this\n// fix. Anchored on the destination declaration so the source's own (multi-line,\n// Lazy-valued) arguments don't need to be matched.\nconst addDependencyPattern = (bucket: string) =>\n `\\`const $dest: CfnDeliveryDestination = new CfnDeliveryDestination($destArgs)\\` as $decl where {\n $dest <: \\`destination\\`\n} => \\`const bucketPolicy = (${bucket} as Bucket).policy;\n if (bucketPolicy) {\n source.node.addDependency(bucketPolicy);\n }\n $decl\\``;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(STATIC_WEBSITE_FILE)) {\n // No vended StaticWebsite construct in this workspace - nothing to migrate.\n return { nextSteps };\n }\n\n const contents = tree.read(STATIC_WEBSITE_FILE, 'utf-8') ?? '';\n if (contents.includes('source.node.addDependency(bucketPolicy)')) {\n // Already migrated.\n return { nextSteps };\n }\n\n const divergedMessage = `${STATIC_WEBSITE_FILE}: deliverAccessLogsToCloudWatch has diverged from the generated shape - left untouched. Manually order the S3 server access log delivery source after the bucket policy of the bucket it targets (\\`source.node.addDependency(bucketPolicy)\\`), avoiding a 409 (OperationAborted) from concurrent bucket configuration writes.`;\n\n // The rewrite is anchored on the delivery destination but references the\n // `source` variable, so only apply it when the delivery source still has the\n // generated shape.\n const hasGeneratedSource = await matchGritQL(\n tree,\n STATIC_WEBSITE_FILE,\n '`const source: CfnDeliverySource = new CfnDeliverySource($_)`',\n );\n\n const bucket = hasGeneratedSource\n ? await findDeliverySourceBucket(tree, STATIC_WEBSITE_FILE)\n : undefined;\n\n if (\n !bucket ||\n !(await isBucketDeclaredParameter(tree, STATIC_WEBSITE_FILE, bucket))\n ) {\n nextSteps.push(divergedMessage);\n return { nextSteps };\n }\n\n const rewrote = await applyGritQL(\n tree,\n STATIC_WEBSITE_FILE,\n addDependencyPattern(bucket),\n );\n\n if (!rewrote) {\n nextSteps.push(divergedMessage);\n return { nextSteps };\n }\n\n // The inserted statement casts to the concrete Bucket to reach its policy,\n // which the helper's own `IBucket` parameter type does not expose.\n await addDestructuredImport(\n tree,\n STATIC_WEBSITE_FILE,\n ['Bucket'],\n 'aws-cdk-lib/aws-s3',\n );\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["addDestructuredImport","applyGritQL","captureGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","STATIC_WEBSITE_FILE","BUCKET_ARN_SUFFIX","findDeliverySourceBucket","tree","filePath","captured","undefined","bucket","slice","indexOf","replace","trim","test","isBucketDeclaredParameter","addDependencyPattern","migration","nextSteps","exists","contents","read","includes","divergedMessage","hasGeneratedSource","push","rewrote"],"mappings":"AAAA;;;CAGC,GAED,SACEA,qBAAqB,EACrBC,WAAW,EACXC,aAAa,EACbC,WAAW,QACN,
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.54/0001-order-access-log-delivery-after-bucket-policy/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\n addDestructuredImport,\n applyGritQL,\n captureGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Order the S3 server access log delivery source after the bucket policy.\n *\n * S3 rejects concurrent configuration writes against the same bucket with a 409\n * (OperationAborted). The generated StaticWebsite construct left the delivery\n * source and the bucket policy unordered, so CloudFormation could submit both at\n * once and fail the stack.\n */\n\nconst STATIC_WEBSITE_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/static-website.ts`;\n\nconst BUCKET_ARN_SUFFIX = '.bucketArn';\n\n/**\n * The bucket whose policy the delivery source must be ordered after is the one\n * the delivery source itself targets, so read it off `resourceArn` rather than\n * assuming the generated parameter name. Returns undefined unless exactly one\n * simple identifier is found, so a diverged helper is left alone.\n */\nconst findDeliverySourceBucket = async (\n tree: Tree,\n filePath: string,\n): Promise<string | undefined> => {\n const captured = await captureGritQL(\n tree,\n filePath,\n '`resourceArn: $bucket.bucketArn`',\n );\n if (!captured) return undefined;\n\n const bucket = captured\n .slice(captured.indexOf(':') + 1)\n .replace(BUCKET_ARN_SUFFIX, '')\n .trim();\n\n // Only a plain identifier can be cast and dereferenced safely in the\n // statement this migration writes.\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(bucket) ? bucket : undefined;\n};\n\n/**\n * Confirm the bucket the delivery source targets is declared as a parameter of\n * the enclosing helper, so the statement this migration writes references a\n * variable that is actually in scope.\n */\nconst isBucketDeclaredParameter = async (\n tree: Tree,\n filePath: string,\n bucket: string,\n): Promise<boolean> =>\n await matchGritQL(\n tree,\n filePath,\n `\\`private deliverAccessLogsToCloudWatch($params) { $_ }\\` where {\n $params <: contains \\`${bucket}: $bucketType\\`,\n $bucketType <: or { \\`IBucket\\`, \\`Bucket\\` }\n }`,\n );\n\n// Inserts the bucket policy dependency between the delivery source and the\n// delivery destination, matching the shape generators produced prior to this\n// fix. Anchored on the destination declaration so the source's own (multi-line,\n// Lazy-valued) arguments don't need to be matched.\nconst addDependencyPattern = (bucket: string) =>\n `\\`const $dest: CfnDeliveryDestination = new CfnDeliveryDestination($destArgs)\\` as $decl where {\n $dest <: \\`destination\\`\n} => \\`const bucketPolicy = (${bucket} as Bucket).policy;\n if (bucketPolicy) {\n source.node.addDependency(bucketPolicy);\n }\n $decl\\``;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(STATIC_WEBSITE_FILE)) {\n // No vended StaticWebsite construct in this workspace - nothing to migrate.\n return { nextSteps };\n }\n\n const contents = tree.read(STATIC_WEBSITE_FILE, 'utf-8') ?? '';\n if (contents.includes('source.node.addDependency(bucketPolicy)')) {\n // Already migrated.\n return { nextSteps };\n }\n\n const divergedMessage = `${STATIC_WEBSITE_FILE}: deliverAccessLogsToCloudWatch has diverged from the generated shape - left untouched. Manually order the S3 server access log delivery source after the bucket policy of the bucket it targets (\\`source.node.addDependency(bucketPolicy)\\`), avoiding a 409 (OperationAborted) from concurrent bucket configuration writes.`;\n\n // The rewrite is anchored on the delivery destination but references the\n // `source` variable, so only apply it when the delivery source still has the\n // generated shape.\n const hasGeneratedSource = await matchGritQL(\n tree,\n STATIC_WEBSITE_FILE,\n '`const source: CfnDeliverySource = new CfnDeliverySource($_)`',\n );\n\n const bucket = hasGeneratedSource\n ? await findDeliverySourceBucket(tree, STATIC_WEBSITE_FILE)\n : undefined;\n\n if (\n !bucket ||\n !(await isBucketDeclaredParameter(tree, STATIC_WEBSITE_FILE, bucket))\n ) {\n nextSteps.push(divergedMessage);\n return { nextSteps };\n }\n\n const rewrote = await applyGritQL(\n tree,\n STATIC_WEBSITE_FILE,\n addDependencyPattern(bucket),\n );\n\n if (!rewrote) {\n nextSteps.push(divergedMessage);\n return { nextSteps };\n }\n\n // The inserted statement casts to the concrete Bucket to reach its policy,\n // which the helper's own `IBucket` parameter type does not expose.\n await addDestructuredImport(\n tree,\n STATIC_WEBSITE_FILE,\n ['Bucket'],\n 'aws-cdk-lib/aws-s3',\n );\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["addDestructuredImport","applyGritQL","captureGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","STATIC_WEBSITE_FILE","BUCKET_ARN_SUFFIX","findDeliverySourceBucket","tree","filePath","captured","undefined","bucket","slice","indexOf","replace","trim","test","isBucketDeclaredParameter","addDependencyPattern","migration","nextSteps","exists","contents","read","includes","divergedMessage","hasGeneratedSource","push","rewrote"],"mappings":"AAAA;;;CAGC,GAED,SACEA,qBAAqB,EACrBC,WAAW,EACXC,aAAa,EACbC,WAAW,QACN,wBAAwB;AAC/B,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,qBAAqB,QAChB,gDAAgD;AAEvD;;;;;;;CAOC,GAED,MAAMC,sBAAsB,GAAGF,aAAa,CAAC,EAAEC,sBAAsB,2BAA2B,CAAC;AAEjG,MAAME,oBAAoB;AAE1B;;;;;CAKC,GACD,MAAMC,2BAA2B,OAC/BC,MACAC;IAEA,MAAMC,WAAW,MAAMV,cACrBQ,MACAC,UACA;IAEF,IAAI,CAACC,UAAU,OAAOC;IAEtB,MAAMC,SAASF,SACZG,KAAK,CAACH,SAASI,OAAO,CAAC,OAAO,GAC9BC,OAAO,CAACT,mBAAmB,IAC3BU,IAAI;IAEP,qEAAqE;IACrE,mCAAmC;IACnC,OAAO,6BAA6BC,IAAI,CAACL,UAAUA,SAASD;AAC9D;AAEA;;;;CAIC,GACD,MAAMO,4BAA4B,OAChCV,MACAC,UACAG,SAEA,MAAMX,YACJO,MACAC,UACA,CAAC;4BACuB,EAAEG,OAAO;;KAEhC,CAAC;AAGN,2EAA2E;AAC3E,6EAA6E;AAC7E,gFAAgF;AAChF,mDAAmD;AACnD,MAAMO,uBAAuB,CAACP,SAC5B,CAAC;;6BAE0B,EAAEA,OAAO;;;;WAI3B,CAAC;AAEZ,eAAe,eAAeQ,UAC5BZ,IAAU;IAEV,MAAMa,YAAsB,EAAE;IAE9B,IAAI,CAACb,KAAKc,MAAM,CAACjB,sBAAsB;QACrC,4EAA4E;QAC5E,OAAO;YAAEgB;QAAU;IACrB;IAEA,MAAME,WAAWf,KAAKgB,IAAI,CAACnB,qBAAqB,YAAY;IAC5D,IAAIkB,SAASE,QAAQ,CAAC,4CAA4C;QAChE,oBAAoB;QACpB,OAAO;YAAEJ;QAAU;IACrB;IAEA,MAAMK,kBAAkB,GAAGrB,oBAAoB,8TAA8T,CAAC;IAE9W,yEAAyE;IACzE,6EAA6E;IAC7E,mBAAmB;IACnB,MAAMsB,qBAAqB,MAAM1B,YAC/BO,MACAH,qBACA;IAGF,MAAMO,SAASe,qBACX,MAAMpB,yBAAyBC,MAAMH,uBACrCM;IAEJ,IACE,CAACC,UACD,CAAE,MAAMM,0BAA0BV,MAAMH,qBAAqBO,SAC7D;QACAS,UAAUO,IAAI,CAACF;QACf,OAAO;YAAEL;QAAU;IACrB;IAEA,MAAMQ,UAAU,MAAM9B,YACpBS,MACAH,qBACAc,qBAAqBP;IAGvB,IAAI,CAACiB,SAAS;QACZR,UAAUO,IAAI,CAACF;QACf,OAAO;YAAEL;QAAU;IACrB;IAEA,2EAA2E;IAC3E,mEAAmE;IACnE,MAAMvB,sBACJU,MACAH,qBACA;QAAC;KAAS,EACV;IAGF,MAAMH,qBAAqBM;IAE3B,OAAO;QAAEa;IAAU;AACrB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { type MigrationReturnObject, type ProjectConfiguration, type Tree } from '@nx/devkit';
|
|
6
|
-
import type { ComponentMetadata } from '../../../utils/nx';
|
|
6
|
+
import type { ComponentMetadata } from '../../../utils/nx.js';
|
|
7
7
|
/** Metadata as a project records it, over the fields this backfill reads. */
|
|
8
8
|
interface ProjectMetadata {
|
|
9
9
|
generator?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { relative } from 'node:path';\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type ProjectConfiguration,\n readJson,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { AGENTCORE_GATEWAY_GATEWAY_CONNECTION_GENERATOR_INFO } from '../../../agentcore-gateway/gateway-connection/generator';\nimport { AGENTCORE_GATEWAY_GENERATOR_INFO } from '../../../agentcore-gateway/generator';\nimport { AGENTCORE_GATEWAY_MCP_CONNECTION_GENERATOR_INFO } from '../../../agentcore-gateway/mcp-connection/generator';\nimport { PY_AGENT_A2A_CONNECTION_GENERATOR_INFO } from '../../../py/agent/a2a-connection/generator';\nimport { PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO } from '../../../py/agent/gateway-connection/generator';\nimport { PY_AGENT_GENERATOR_INFO } from '../../../py/agent/generator';\nimport { PY_AGENT_MCP_CONNECTION_GENERATOR_INFO } from '../../../py/agent/mcp-connection/generator';\nimport { PY_AGENT_REACT_CONNECTION_GENERATOR_INFO } from '../../../py/agent/react-connection/generator';\nimport { PY_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../py/dynamodb/agent-connection/generator';\nimport { PY_DYNAMODB_FAST_API_CONNECTION_GENERATOR_INFO } from '../../../py/dynamodb/fast-api-connection/generator';\nimport { PY_DYNAMODB_GENERATOR_INFO } from '../../../py/dynamodb/generator';\nimport { PY_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../py/dynamodb/mcp-server-connection/generator';\nimport { FAST_API_GENERATOR_INFO } from '../../../py/fast-api/generator';\nimport { FAST_API_REACT_GENERATOR_INFO } from '../../../py/fast-api/react/generator';\nimport { LAMBDA_FUNCTION_GENERATOR_INFO as PY_LAMBDA_FUNCTION_GENERATOR_INFO } from '../../../py/lambda-function/generator';\nimport { PY_MCP_SERVER_GENERATOR_INFO } from '../../../py/mcp-server/generator';\nimport { PY_RDB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../py/rdb/agent-connection/generator';\nimport { PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO } from '../../../py/rdb/fast-api-connection/generator';\nimport { PY_RDB_GENERATOR_INFO } from '../../../py/rdb/generator';\nimport { PY_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../py/rdb/mcp-server-connection/generator';\nimport { SMITHY_PROJECT_GENERATOR_INFO } from '../../../smithy/project/generator';\nimport { SMITHY_REACT_CONNECTION_GENERATOR_INFO } from '../../../smithy/react-connection/generator';\nimport { TS_SMITHY_API_GENERATOR_INFO } from '../../../smithy/ts/api/generator';\nimport { TRPC_BACKEND_GENERATOR_INFO } from '../../../trpc/backend/generator';\nimport { TRPC_REACT_GENERATOR_INFO } from '../../../trpc/react/generator';\nimport { TS_AGENT_A2A_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/a2a-connection/generator';\nimport { TS_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/gateway-connection/generator';\nimport { TS_AGENT_GENERATOR_INFO } from '../../../ts/agent/generator';\nimport { TS_AGENT_MCP_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/mcp-connection/generator';\nimport { TS_AGENT_REACT_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/react-connection/generator';\nimport { TS_DCR_PROXY_GENERATOR_INFO } from '../../../ts/dcr-proxy/generator';\nimport { TS_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/agent-connection/generator';\nimport { TS_DYNAMODB_GENERATOR_INFO } from '../../../ts/dynamodb/generator';\nimport { TS_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/mcp-server-connection/generator';\nimport { TS_DYNAMODB_SMITHY_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/smithy-connection/generator';\nimport { TS_DYNAMODB_TRPC_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/trpc-connection/generator';\nimport { TS_LAMBDA_FUNCTION_GENERATOR_INFO } from '../../../ts/lambda-function/generator';\nimport { TS_LIB_GENERATOR_INFO } from '../../../ts/lib/generator';\nimport { TS_MCP_SERVER_GENERATOR_INFO } from '../../../ts/mcp-server/generator';\nimport { TS_RDB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/agent-connection/generator';\nimport { TS_RDB_GENERATOR_INFO } from '../../../ts/rdb/generator';\nimport { TS_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/mcp-server-connection/generator';\nimport { TS_RDB_SMITHY_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/smithy-connection/generator';\nimport { TS_RDB_TRPC_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/trpc-connection/generator';\nimport { REACT_WEBSITE_APP_GENERATOR_INFO } from '../../../ts/react-website/app/generator';\nimport { COGNITO_AUTH_GENERATOR_INFO } from '../../../ts/react-website/cognito-auth/generator';\nimport {\n PY_CLIENT_NAMING,\n resolveAgentFramework,\n} from '../../../utils/agent-connection/agent-connection';\nimport { matchGritQL } from '../../../utils/ast';\nimport { DCR_PROXY_HANDLERS } from '../../../utils/dcr-proxy-constructs/dcr-proxy-constructs';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n camelCase,\n kebabCase,\n pascalCase,\n toClassName,\n toSnakeCase,\n} from '../../../utils/names';\nimport type { ComponentMetadata } from '../../../utils/nx';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Backfill the project metadata the version sync reads.\n *\n * The sync owns a generator's dependencies only for the runs it can see, and it\n * sees a run through the metadata that generator recorded — narrowing each run to\n * the branch it took by replaying the declaration's `when` predicates against that\n * metadata. Workspaces generated before this release recorded less, in three ways\n * that each cost ownership:\n *\n * - No connection generator recorded anything at all, so the packages they add\n * (the agent Layer-2 clients, AG-UI, the tRPC and OpenAPI react clients) are\n * invisible to the sync and their versions would never move again.\n * - `ts#dcr-proxy` was attributed to the `ts#project` that creates its project.\n * - No project recorded an `iac`, and a predicate reading absent metadata counts\n * as not applying, so the infrastructure helpers' packages go unowned.\n *\n * Every connection is recorded, including those that add no dependencies today.\n * The sync reads the recorded metadata rather than the generators, so a connection\n * recorded now is picked up the moment its generator starts owning packages —\n * otherwise a later release needs a second backfill for the workspaces this one\n * already ran on.\n *\n * Every field is recovered from evidence the generators left behind — the files\n * they wrote, the clients they imported, the dev chains and build dependencies they\n * registered — rather than guessed, and anything that can't be established is left\n * alone. A wrong value is worse than a missing one: it has the sync claim packages\n * a project never received.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n */\n\ntype Iac = 'cdk' | 'terraform';\n\n/** Metadata as a project records it, over the fields this backfill reads. */\ninterface ProjectMetadata {\n generator?: string;\n components?: ComponentMetadata[];\n iac?: string;\n smithyType?: string;\n namespace?: string;\n tailwind?: boolean;\n tanstackRouter?: boolean;\n [key: string]: unknown;\n}\n\n/** The shared project each provider generates its infrastructure into. */\nconst SHARED_INFRA_ROOT: Record<Iac, string> = {\n cdk: joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR),\n terraform: joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR),\n};\n\n/**\n * The provider each project's infrastructure was generated with.\n *\n * Every infra helper registers `<project>:build` on the build target of the shared\n * project belonging to the provider it ran with, so those lists name exactly the\n * projects that received infrastructure, and which provider gave it to them.\n *\n * Read per project rather than per workspace because `iac` is a per-generator\n * option: one workspace can hold both providers.\n */\nconst infrastructureProviders = (tree: Tree): Map<string, Iac> => {\n const providers = new Map<string, Iac>();\n for (const iac of ['cdk', 'terraform'] as const) {\n const configPath = joinPathFragments(\n SHARED_INFRA_ROOT[iac],\n 'project.json',\n );\n if (!tree.exists(configPath)) {\n continue;\n }\n const config = readJson<ProjectConfiguration>(tree, configPath);\n for (const dependency of config.targets?.build?.dependsOn ?? []) {\n // Registered as `<project>:build`, either as that string or as an object.\n const name =\n typeof dependency === 'string'\n ? dependency.split(':')[0]\n : (dependency.projects as string | undefined);\n if (name) {\n providers.set(name, iac);\n }\n }\n }\n return providers;\n};\n\n/**\n * Where a component's infrastructure lives under a provider's shared project,\n * keyed by the generator that created it.\n *\n * These components belong to a project rather than being one, and each records its\n * own `iac` — a project can hold a CDK-deployed agent alongside one generated with\n * `infra: 'none'` — so the project-level build dependency isn't precise enough.\n * Each component gets its own entry under the app directory below, which is.\n *\n * `paths` lists the candidates because the two providers don't lay out every\n * component the same way: a Lambda function is one CDK file but a Terraform\n * directory.\n */\nconst COMPONENT_INFRA: Record<\n string,\n { readonly appDirectory: string; readonly paths: (name: string) => string[] }\n> = {\n ...Object.fromEntries(\n (\n [\n [TS_AGENT_GENERATOR_INFO.id, 'agents'],\n [PY_AGENT_GENERATOR_INFO.id, 'agents'],\n [TS_MCP_SERVER_GENERATOR_INFO.id, 'mcp-servers'],\n [PY_MCP_SERVER_GENERATOR_INFO.id, 'mcp-servers'],\n ] as const\n ).map(([id, appDirectory]) => [\n id,\n { appDirectory, paths: (name: string) => [name] },\n ]),\n ),\n ...Object.fromEntries(\n [\n TS_LAMBDA_FUNCTION_GENERATOR_INFO.id,\n PY_LAMBDA_FUNCTION_GENERATOR_INFO.id,\n ].map((id) => [\n id,\n {\n appDirectory: 'lambda-functions',\n // CDK vends `<name>.ts`; Terraform vends `<name>/<name>.tf`.\n paths: (name: string) => [`${name}.ts`, name],\n },\n ]),\n ),\n};\n\n/**\n * The provider a component's own infrastructure was generated with, from the entry\n * the infra helper created for it under one provider's shared project.\n *\n * That entry is named after the component, which for these generators is the name\n * the component records.\n */\nconst componentInfrastructureProvider = (\n tree: Tree,\n component: ComponentMetadata,\n): Iac | undefined => {\n const layout = component.generator\n ? COMPONENT_INFRA[component.generator]\n : undefined;\n if (!layout || !component.name) {\n return undefined;\n }\n for (const iac of ['cdk', 'terraform'] as const) {\n for (const entry of layout.paths(component.name)) {\n if (\n tree.exists(\n joinPathFragments(\n SHARED_INFRA_ROOT[iac],\n 'src',\n 'app',\n layout.appDirectory,\n entry,\n ),\n )\n ) {\n return iac;\n }\n }\n }\n return undefined;\n};\n\n/**\n * `ts#dcr-proxy` creates its handler project through `ts#project`, which recorded\n * its own id — so an existing workspace attributes the project to `ts#project` and\n * owns none of the proxy's dependencies. The six vended handlers are its\n * signature; a project carrying every one of them is a DCR proxy.\n */\nconst isDcrProxyProject = (tree: Tree, projectRoot: string): boolean =>\n DCR_PROXY_HANDLERS.every((handler) =>\n tree.exists(\n joinPathFragments(projectRoot, 'src', 'handlers', `${handler}.ts`),\n ),\n );\n\n/**\n * What a Smithy project models, from the `smithy-build.json` each kind gets: a\n * service builds an OpenAPI spec and a TypeScript SSDK from its model, so it has\n * the plugins to do so, while a shape library only shares shapes and has none.\n */\nconst smithyProjectType = (\n tree: Tree,\n projectRoot: string,\n): 'service' | 'shapes' | undefined => {\n const buildPath = joinPathFragments(projectRoot, 'smithy-build.json');\n if (!tree.exists(buildPath)) {\n return undefined;\n }\n const build = readJson<{ plugins?: Record<string, unknown> }>(\n tree,\n buildPath,\n );\n return build.plugins && Object.keys(build.plugins).length > 0\n ? 'service'\n : 'shapes';\n};\n\n/**\n * The Smithy namespace a project's shapes are declared in, read from the model\n * rather than derived from the npm scope: the generator takes it as an option, so\n * a project may not carry the default.\n */\nconst smithyNamespace = (\n tree: Tree,\n project: ProjectConfiguration,\n): string | undefined => {\n const modelPath = joinPathFragments(\n project.sourceRoot ?? joinPathFragments(project.root, 'src'),\n 'main.smithy',\n );\n if (!tree.exists(modelPath)) {\n return undefined;\n }\n // Smithy is not a language GritQL parses, and `namespace <x>` is a single\n // declaration on its own line rather than a structure worth an AST for.\n return /^namespace\\s+(\\S+)\\s*$/m\n .exec(tree.read(modelPath, 'utf-8') ?? '')\n ?.at(1);\n};\n\n/**\n * Whether a website's vite config registers the given plugin, which is how\n * `tailwind` and `tanstackRouter` show up in a generated workspace: both default\n * to true, so only the config proves one was turned off.\n *\n * Matched on the AST rather than the text so the plugin's arguments, and any\n * reformatting since, don't hide it.\n */\nconst usesVitePlugin = (\n tree: Tree,\n projectRoot: string,\n plugin: string,\n): Promise<boolean> =>\n matchGritQL(\n tree,\n joinPathFragments(projectRoot, 'vite.config.mts'),\n `\\`${plugin}\\``,\n );\n\n/**\n * A connection generator, and how to recognise a run of it.\n *\n * A connection is found from the source component it was made from and the target\n * it reaches: `evidence` is a check that only passes if that exact pair was wired\n * up — a client import named after the target, a vended file named after it, or\n * the dev-target dependency on its project. So `name` and `sourcePath` are\n * recovered facts rather than guesses.\n *\n * Every connection generator is listed, including those that add no dependencies\n * today. The sync reads the metadata rather than the generator, so recording a\n * connection now is what lets it be picked up the moment its generator starts\n * owning packages — a later release would otherwise need another backfill.\n */\ninterface ConnectionKind {\n /** The generator id to record. */\n readonly id: string;\n /**\n * The generator that created a source component of this connection, or\n * undefined when the connection is made from the project as a whole.\n */\n readonly sourceGenerator?: string;\n /** The generators that could have created its target. */\n readonly targetGenerators: readonly string[];\n /**\n * Whether this connection was made from `source` to `target`, and what to record\n * as the component's `path` if so. Undefined means it was not.\n */\n readonly evidence: (\n context: ConnectionContext,\n ) => string | undefined | Promise<string | undefined>;\n /**\n * The `name` this connection records, when it is not the target's class name.\n * Matched to what each generator writes so a re-run recognises its own entry.\n */\n readonly recordedName?: (context: ConnectionContext) => string;\n /** What this connection records beyond the path, which its predicates read. */\n readonly metadata?: (\n context: ConnectionContext,\n ) => Record<string, unknown> | undefined;\n}\n\n/** `<sourceComponent>-<target>`, the name the database connections record. */\nconst sourceQualifiedName =\n (target: (context: ConnectionContext) => string, fallback: string) =>\n (context: ConnectionContext) =>\n `${context.source.name ?? fallback}-${target(context)}`;\n\n/** The database name as each language's connections case it. */\nconst camelDatabase = ({ target }: ConnectionContext) =>\n camelCase(target.databaseName);\nconst targetProjectName = ({ target }: ConnectionContext) => target.projectName;\n\n/** What a connection's evidence check has to work from. */\ninterface ConnectionContext {\n readonly tree: Tree;\n /** The project the connection lives on — the source side. */\n readonly project: ProjectConfiguration;\n /**\n * The source component, or the project's own metadata standing in for it when\n * the connection is made from the project as a whole.\n */\n readonly source: ComponentMetadata;\n /** The target being connected to. */\n readonly target: ConnectionTarget;\n}\n\n/** Prefix a GritQL pattern to match against Python rather than TypeScript. */\nconst py = (pattern: string) => `language python\\n${pattern}`;\n\n/**\n * Whether the source project's `dev` chain runs the target project's, which every\n * connection wires up so `nx run <source>:dev` starts what it depends on.\n *\n * This is the only trace left by the connections that vend no code (the DynamoDB\n * ones grant IAM in the target's infrastructure instead). It identifies the pair\n * because the dependency names the target project.\n */\nconst dependsOnTargetDev = (\n project: ProjectConfiguration,\n target: ConnectionTarget,\n devTarget: string,\n): boolean =>\n (project.targets?.[devTarget]?.dependsOn ?? []).some((dependency) => {\n const projects =\n typeof dependency === 'string'\n ? dependency.split(':')[0]\n : (dependency.projects as string | string[] | undefined);\n return Array.isArray(projects)\n ? projects.includes(target.projectName)\n : projects === target.projectName;\n });\n\n/**\n * An agent-to-service connection, which imports a Layer-2 client named after the\n * target into the source agent's entry point.\n */\nconst agentClientConnection = (\n id: string,\n language: 'ts' | 'py',\n targetGenerators: readonly string[],\n): ConnectionKind => ({\n id,\n sourceGenerator:\n language === 'ts' ? TS_AGENT_GENERATOR_INFO.id : PY_AGENT_GENERATOR_INFO.id,\n targetGenerators,\n evidence: async ({ tree, project, source, target }) => {\n const path = joinPathFragments(\n source.path ?? 'src',\n language === 'ts' ? 'agent.ts' : 'agent.py',\n );\n // The Python client's class suffix follows the source agent's framework, read\n // from the same naming table the generators use.\n const client =\n language === 'ts'\n ? `${target.className}ClientStrands`\n : `${target.className}Client${\n PY_CLIENT_NAMING[resolveAgentFramework(source.framework)]\n .clientClassSuffix\n }`;\n const pattern = `\\`${client}\\``;\n return (await matchGritQL(\n tree,\n joinPathFragments(project.root, path),\n language === 'ts' ? pattern : py(pattern),\n ))\n ? path\n : undefined;\n },\n ...(language === 'py'\n ? {\n metadata: ({ source }) => ({\n framework: resolveAgentFramework(source.framework),\n }),\n }\n : {}),\n});\n\n/**\n * A database-to-component connection, which imports the database's client getter\n * into the component it connects to and aliases it after the database.\n */\nconst rdbConnection = (\n id: string,\n options: {\n readonly sourceGenerator?: string;\n readonly targetGenerator: string;\n readonly entryPoint: (source: ComponentMetadata) => string;\n readonly recordedName?: ConnectionKind['recordedName'];\n },\n): ConnectionKind => ({\n id,\n sourceGenerator: options.sourceGenerator,\n targetGenerators: [options.targetGenerator],\n recordedName: options.recordedName,\n evidence: async ({ tree, project, source, target }) => {\n const path = options.entryPoint(source);\n return (await matchGritQL(\n tree,\n joinPathFragments(project.root, path),\n // Aliased to `get<Database>` on import, so the alias names the target.\n `\\`get${pascalCase(target.databaseName)}\\``,\n ))\n ? path\n : undefined;\n },\n});\n\n/**\n * A connection that vends no code, recognised by the dev chain it wires from the\n * source component to the target project.\n */\nconst devChainConnection = (\n id: string,\n options: {\n readonly sourceGenerator?: string;\n readonly targetGenerator: string;\n /** The source project's target whose chain this connection extends. */\n readonly devTarget?: (source: ComponentMetadata) => string;\n readonly recordedName?: ConnectionKind['recordedName'];\n },\n): ConnectionKind => ({\n id,\n sourceGenerator: options.sourceGenerator,\n targetGenerators: [options.targetGenerator],\n recordedName: options.recordedName,\n evidence: ({ project, source, target }) =>\n dependsOnTargetDev(project, target, options.devTarget?.(source) ?? 'dev')\n ? target.projectRoot\n : undefined,\n});\n\n/** The `<component>-dev` target a component generator authors for itself. */\nconst componentDevTarget = (source: ComponentMetadata) =>\n `${source.name ?? 'agent'}-dev`;\n\n/** The tRPC-over-HTTP integration patterns, whose extra client packages differ. */\nconst REST_API_INFRA = new Set(['rest-lambda', 'serverlessapigatewayrestapi']);\n\n/**\n * A website connection, recognised by the provider component it vends for its\n * target under the website's source root.\n */\nconst websiteConnection = (\n id: string,\n options: {\n readonly targetGenerator: string;\n readonly provider: (targetClassName: string) => string;\n readonly metadata?: ConnectionKind['metadata'];\n },\n): ConnectionKind => ({\n id,\n sourceGenerator: REACT_WEBSITE_APP_GENERATOR_INFO.id,\n targetGenerators: [options.targetGenerator],\n evidence: ({ tree, project, target }) => {\n const sourceRoot =\n project.sourceRoot ?? joinPathFragments(project.root, 'src');\n const provider = joinPathFragments(\n 'components',\n options.provider(target.className),\n );\n return tree.exists(joinPathFragments(sourceRoot, `${provider}.tsx`))\n ? joinPathFragments(relative(project.root, sourceRoot), provider)\n : undefined;\n },\n metadata: options.metadata,\n});\n\n/**\n * Every connection generator, and the trace each leaves on the project it connects\n * from.\n *\n * Grouped by how a run is recognised, since that follows what the generator does\n * rather than which pair it joins.\n */\nexport const CONNECTION_KINDS: readonly ConnectionKind[] = [\n // Agent to service: imports a Layer-2 client named after the target.\n agentClientConnection(TS_AGENT_MCP_CONNECTION_GENERATOR_INFO.id, 'ts', [\n TS_MCP_SERVER_GENERATOR_INFO.id,\n PY_MCP_SERVER_GENERATOR_INFO.id,\n ]),\n agentClientConnection(TS_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO.id, 'ts', [\n AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n ]),\n agentClientConnection(TS_AGENT_A2A_CONNECTION_GENERATOR_INFO.id, 'ts', [\n TS_AGENT_GENERATOR_INFO.id,\n PY_AGENT_GENERATOR_INFO.id,\n ]),\n agentClientConnection(PY_AGENT_MCP_CONNECTION_GENERATOR_INFO.id, 'py', [\n TS_MCP_SERVER_GENERATOR_INFO.id,\n PY_MCP_SERVER_GENERATOR_INFO.id,\n ]),\n agentClientConnection(PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO.id, 'py', [\n AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n ]),\n agentClientConnection(PY_AGENT_A2A_CONNECTION_GENERATOR_INFO.id, 'py', [\n TS_AGENT_GENERATOR_INFO.id,\n PY_AGENT_GENERATOR_INFO.id,\n ]),\n\n // Website to backend: vends a provider component named after the target.\n websiteConnection(TRPC_REACT_GENERATOR_INFO.id, {\n targetGenerator: TRPC_BACKEND_GENERATOR_INFO.id,\n provider: (className) => `${className}ClientProvider`,\n metadata: ({ target }) => ({\n auth: String(target.project.auth ?? 'iam').toLowerCase(),\n isRestApi: REST_API_INFRA.has(\n String(\n target.project.infra ?? target.project.computeType ?? '',\n ).toLowerCase(),\n ),\n }),\n }),\n // Both OpenAPI react clients vend the same provider shape.\n websiteConnection(SMITHY_REACT_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: TS_SMITHY_API_GENERATOR_INFO.id,\n provider: (className) => `${className}Provider`,\n }),\n websiteConnection(FAST_API_REACT_GENERATOR_INFO.id, {\n targetGenerator: FAST_API_GENERATOR_INFO.id,\n provider: (className) => `${className}Provider`,\n }),\n websiteConnection(TS_AGENT_REACT_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: TS_AGENT_GENERATOR_INFO.id,\n provider: (className) => `${className}AgentClientProvider`,\n }),\n websiteConnection(PY_AGENT_REACT_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: PY_AGENT_GENERATOR_INFO.id,\n provider: (className) => `${className}AgentClientProvider`,\n }),\n\n // Database to component: imports the database's `get<Database>` client getter.\n rdbConnection(TS_RDB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n sourceGenerator: TS_AGENT_GENERATOR_INFO.id,\n targetGenerator: TS_RDB_GENERATOR_INFO.id,\n entryPoint: (source) =>\n joinPathFragments('src', source.name ?? 'agent', 'agent.ts'),\n recordedName: sourceQualifiedName(camelDatabase, 'agent'),\n }),\n rdbConnection(TS_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n sourceGenerator: TS_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: TS_RDB_GENERATOR_INFO.id,\n entryPoint: (source) =>\n joinPathFragments('src', source.name ?? 'mcp-server', 'server.ts'),\n recordedName: sourceQualifiedName(camelDatabase, 'mcp-server'),\n }),\n rdbConnection(TS_RDB_SMITHY_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: TS_RDB_GENERATOR_INFO.id,\n entryPoint: () => joinPathFragments('src', 'context.ts'),\n recordedName: camelDatabase,\n }),\n\n // Vends a middleware or dependency module named after the database.\n {\n id: TS_RDB_TRPC_CONNECTION_GENERATOR_INFO.id,\n targetGenerators: [TS_RDB_GENERATOR_INFO.id],\n recordedName: camelDatabase,\n evidence: ({ tree, project, target }) => {\n const path = joinPathFragments(\n 'src',\n 'middleware',\n `${kebabCase(target.databaseName)}.ts`,\n );\n return tree.exists(joinPathFragments(project.root, path))\n ? path\n : undefined;\n },\n },\n {\n id: PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO.id,\n targetGenerators: [PY_RDB_GENERATOR_INFO.id],\n recordedName: ({ target }) => toSnakeCase(target.databaseName),\n evidence: ({ tree, project, target }) => {\n const dependencies = pythonDependenciesDir(tree, project);\n if (!dependencies) {\n return undefined;\n }\n const path = joinPathFragments(\n dependencies,\n `${toSnakeCase(target.databaseName)}.py`,\n );\n return tree.exists(joinPathFragments(project.root, path))\n ? path\n : undefined;\n },\n },\n\n // Python database connections vend no code into the source, so the dev chain and\n // the workspace dependency on the database project are the trace.\n devChainConnection(PY_RDB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'agent'),\n sourceGenerator: PY_AGENT_GENERATOR_INFO.id,\n targetGenerator: PY_RDB_GENERATOR_INFO.id,\n devTarget: componentDevTarget,\n }),\n devChainConnection(PY_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'mcp-server'),\n sourceGenerator: PY_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: PY_RDB_GENERATOR_INFO.id,\n devTarget: (source) => `${source.name ?? 'mcp-server'}-dev`,\n }),\n\n // DynamoDB connections grant IAM in the target's infrastructure rather than\n // vending code, so the dev chain is all they leave behind.\n devChainConnection(TS_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'agent'),\n sourceGenerator: TS_AGENT_GENERATOR_INFO.id,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n devTarget: componentDevTarget,\n }),\n devChainConnection(TS_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'mcp-server'),\n sourceGenerator: TS_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n devTarget: (source) => `${source.name ?? 'mcp-server'}-dev`,\n }),\n devChainConnection(TS_DYNAMODB_TRPC_CONNECTION_GENERATOR_INFO.id, {\n recordedName: targetProjectName,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n }),\n devChainConnection(TS_DYNAMODB_SMITHY_CONNECTION_GENERATOR_INFO.id, {\n recordedName: targetProjectName,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n }),\n devChainConnection(PY_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'agent'),\n sourceGenerator: PY_AGENT_GENERATOR_INFO.id,\n targetGenerator: PY_DYNAMODB_GENERATOR_INFO.id,\n devTarget: componentDevTarget,\n }),\n devChainConnection(PY_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'mcp-server'),\n sourceGenerator: PY_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: PY_DYNAMODB_GENERATOR_INFO.id,\n devTarget: (source) => `${source.name ?? 'mcp-server'}-dev`,\n }),\n devChainConnection(PY_DYNAMODB_FAST_API_CONNECTION_GENERATOR_INFO.id, {\n recordedName: targetProjectName,\n targetGenerator: PY_DYNAMODB_GENERATOR_INFO.id,\n }),\n\n // Gateway to upstream: registers the upstream in the gateway's local-dev.ts,\n // under the kebab-cased class name the deployed gateway also uses.\n ...(\n [\n [\n AGENTCORE_GATEWAY_MCP_CONNECTION_GENERATOR_INFO.id,\n [TS_MCP_SERVER_GENERATOR_INFO.id, PY_MCP_SERVER_GENERATOR_INFO.id],\n ],\n [\n AGENTCORE_GATEWAY_GATEWAY_CONNECTION_GENERATOR_INFO.id,\n [AGENTCORE_GATEWAY_GENERATOR_INFO.id],\n ],\n ] as const\n ).map(([id, targetGenerators]) => ({\n id,\n sourceGenerator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n targetGenerators,\n recordedName: ({ target }: ConnectionContext) =>\n kebabCase(target.className),\n evidence: async ({ tree, project, target }: ConnectionContext) =>\n (await matchGritQL(\n tree,\n joinPathFragments(project.root, 'local-dev.ts'),\n `\\`'${kebabCase(target.className)}'\\``,\n ))\n ? target.projectRoot\n : undefined,\n })),\n];\n\n/**\n * A thing in the workspace a connection could have been made to, by the names its\n * generated code is derived from.\n */\ninterface ConnectionTarget {\n /** The class name a client or provider for this target is named after. */\n readonly className: string;\n /**\n * The last segment of the target project's name, which the database connections\n * derive their identifiers from.\n */\n readonly databaseName: string;\n /** The target project's name, which a dev-target dependency names. */\n readonly projectName: string;\n /** The target project's root, recorded as `path` by the connections that vend no file. */\n readonly projectRoot: string;\n /** The target project's metadata, which a connection's own fields come from. */\n readonly project: ProjectMetadata;\n}\n\n/**\n * Every connection target in the workspace, keyed by the generator that created it.\n *\n * A target may be a component of a project (an agent, an MCP server) or a whole\n * project (a gateway, an API, a database), so both are indexed. Agents, MCP servers\n * and gateways record the class name directly as `rc`; an API's is derived from its\n * `apiName` the same way its connection generator derives it.\n */\nconst connectionTargets = (tree: Tree): Map<string, ConnectionTarget[]> => {\n const targets = new Map<string, ConnectionTarget[]>();\n for (const [projectName, project] of getProjects(tree)) {\n const metadata = project.metadata as ProjectMetadata | undefined;\n if (!metadata) {\n continue;\n }\n const shared = {\n // The database generators split on `/` for TypeScript and `.` for Python.\n databaseName: projectName.split(/[/.]/).pop() ?? projectName,\n projectName,\n projectRoot: project.root,\n project: metadata,\n };\n const add = (generator: string | undefined, className: unknown) => {\n if (!generator || typeof className !== 'string') {\n return;\n }\n targets.set(generator, [\n ...(targets.get(generator) ?? []),\n { ...shared, className },\n ]);\n };\n add(\n metadata.generator,\n metadata.rc ??\n (typeof metadata.apiName === 'string'\n ? toClassName(metadata.apiName)\n : // A database is named by its project, not a recorded class name.\n shared.databaseName),\n );\n for (const component of metadata.components ?? []) {\n add(component.generator, component.rc);\n }\n }\n return targets;\n};\n\n/**\n * The Python module a FastAPI project's sources live in, found by looking for the\n * `dependencies` directory the connections vend into.\n *\n * The module name mixes the workspace's npm scope with the API name, so it is read\n * off the tree rather than derived — a scope that has since changed would make a\n * derived name wrong.\n */\nconst pythonDependenciesDir = (\n tree: Tree,\n project: ProjectConfiguration,\n): string | undefined =>\n tree\n .children(project.root)\n .map((child) => joinPathFragments(child, 'dependencies'))\n .find((dir) => tree.exists(joinPathFragments(project.root, dir)));\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const providers = infrastructureProviders(tree);\n const targets = connectionTargets(tree);\n\n for (const [projectName, project] of getProjects(tree)) {\n const metadata = project.metadata as ProjectMetadata | undefined;\n if (!metadata?.generator && !metadata?.components?.length) {\n // Not a project this plugin generated, so none of this is ours to record.\n continue;\n }\n\n const next: ProjectMetadata = { ...metadata };\n let changed = false;\n\n if (\n next.generator === TS_LIB_GENERATOR_INFO.id &&\n isDcrProxyProject(tree, project.root)\n ) {\n next.generator = TS_DCR_PROXY_GENERATOR_INFO.id;\n changed = true;\n }\n\n // The provider this project's infrastructure was generated with. Left unset\n // where the project received none, matching what the generators record: the\n // sync reads a set `iac` as \"infrastructure was generated\", and would claim\n // the helpers' packages for a project that never got them.\n const iac = providers.get(projectName);\n if (iac && next.iac === undefined) {\n next.iac = iac;\n changed = true;\n }\n\n // What a Smithy project models, and the namespace it declares. Neither gates a\n // dependency yet, but recording them now means a future gate reads them in a\n // workspace this backfill has already run on.\n if (next.generator === SMITHY_PROJECT_GENERATOR_INFO.id) {\n if (next.smithyType === undefined) {\n const smithyType = smithyProjectType(tree, project.root);\n if (smithyType) {\n next.smithyType = smithyType;\n changed = true;\n }\n }\n if (next.namespace === undefined) {\n const namespace = smithyNamespace(tree, project);\n if (namespace) {\n next.namespace = namespace;\n changed = true;\n }\n }\n }\n\n if (next.generator === REACT_WEBSITE_APP_GENERATOR_INFO.id) {\n if (next.tailwind === undefined) {\n next.tailwind = await usesVitePlugin(tree, project.root, 'tailwindcss');\n changed = true;\n }\n if (next.tanstackRouter === undefined) {\n next.tanstackRouter = await usesVitePlugin(\n tree,\n project.root,\n 'tanstackRouter',\n );\n changed = true;\n }\n }\n\n // The provider each of this project's components generated with. Recorded on\n // the component because that is where these generators record it — an agent\n // and an MCP server each choose their own provider.\n //\n // Left absent rather than set to an empty list where the project has no\n // components, so a project this backfill has nothing to add to is untouched.\n next.components = next.components?.map((component) => {\n if (component.iac !== undefined) {\n return component;\n }\n const componentIac =\n // The auth component vends no infrastructure of its own; it always\n // generates the shared constructs, so it took the project's provider.\n component.generator === COGNITO_AUTH_GENERATOR_INFO.id\n ? iac\n : componentInfrastructureProvider(tree, component);\n if (!componentIac) {\n return component;\n }\n changed = true;\n return { ...component, iac: componentIac };\n });\n\n // A connection already recorded is left as it is: re-recording it would\n // duplicate the entry, and the sync counts entries.\n const recorded = new Set(\n (next.components ?? []).map(\n (component) => `${component.generator}:${component.name}`,\n ),\n );\n const record = (component: ComponentMetadata) => {\n next.components = [...(next.components ?? []), component];\n recorded.add(`${component.generator}:${component.name}`);\n changed = true;\n };\n // The connections made from this project, each found by the trace its\n // generator left for the exact pair it wired up.\n for (const kind of CONNECTION_KINDS) {\n // A connection made from a component starts at each matching component. One\n // made from the project as a whole — a website, a tRPC API — starts at the\n // project's own metadata, which stands in for the source.\n const componentSources = (next.components ?? []).filter(\n (component) => component.generator === kind.sourceGenerator,\n );\n const sources: ComponentMetadata[] = componentSources.length\n ? componentSources\n : (kind.sourceGenerator === undefined ||\n kind.sourceGenerator === next.generator) &&\n next.generator\n ? [{ ...next, generator: next.generator }]\n : [];\n const candidates = kind.targetGenerators.flatMap(\n (generator) => targets.get(generator) ?? [],\n );\n for (const source of sources) {\n for (const target of candidates) {\n // A connection from a component to itself is not one any generator makes.\n if (\n target.projectName === projectName &&\n target.className === source.rc\n ) {\n continue;\n }\n const context: ConnectionContext = { tree, project, source, target };\n const name = kind.recordedName?.(context) ?? target.className;\n if (recorded.has(`${kind.id}:${name}`)) {\n continue;\n }\n const path = await kind.evidence(context);\n if (path === undefined) {\n continue;\n }\n record({\n generator: kind.id,\n path,\n name,\n ...(kind.sourceGenerator && source.path\n ? { sourcePath: source.path }\n : {}),\n ...kind.metadata?.(context),\n });\n }\n }\n }\n\n if (changed) {\n // Keep metadata before targets so the serialized key order matches what the\n // generators write, leaving this a pure metadata edit.\n const { targets: projectTargets, ...rest } = project;\n updateProjectConfiguration(tree, projectName, {\n ...rest,\n metadata: next as ProjectConfiguration['metadata'],\n ...(projectTargets ? { targets: projectTargets } : {}),\n });\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps: [] };\n}\n"],"names":["relative","getProjects","joinPathFragments","readJson","updateProjectConfiguration","AGENTCORE_GATEWAY_GATEWAY_CONNECTION_GENERATOR_INFO","AGENTCORE_GATEWAY_GENERATOR_INFO","AGENTCORE_GATEWAY_MCP_CONNECTION_GENERATOR_INFO","PY_AGENT_A2A_CONNECTION_GENERATOR_INFO","PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO","PY_AGENT_GENERATOR_INFO","PY_AGENT_MCP_CONNECTION_GENERATOR_INFO","PY_AGENT_REACT_CONNECTION_GENERATOR_INFO","PY_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO","PY_DYNAMODB_FAST_API_CONNECTION_GENERATOR_INFO","PY_DYNAMODB_GENERATOR_INFO","PY_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO","FAST_API_GENERATOR_INFO","FAST_API_REACT_GENERATOR_INFO","LAMBDA_FUNCTION_GENERATOR_INFO","PY_LAMBDA_FUNCTION_GENERATOR_INFO","PY_MCP_SERVER_GENERATOR_INFO","PY_RDB_AGENT_CONNECTION_GENERATOR_INFO","PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO","PY_RDB_GENERATOR_INFO","PY_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO","SMITHY_PROJECT_GENERATOR_INFO","SMITHY_REACT_CONNECTION_GENERATOR_INFO","TS_SMITHY_API_GENERATOR_INFO","TRPC_BACKEND_GENERATOR_INFO","TRPC_REACT_GENERATOR_INFO","TS_AGENT_A2A_CONNECTION_GENERATOR_INFO","TS_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO","TS_AGENT_GENERATOR_INFO","TS_AGENT_MCP_CONNECTION_GENERATOR_INFO","TS_AGENT_REACT_CONNECTION_GENERATOR_INFO","TS_DCR_PROXY_GENERATOR_INFO","TS_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO","TS_DYNAMODB_GENERATOR_INFO","TS_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO","TS_DYNAMODB_SMITHY_CONNECTION_GENERATOR_INFO","TS_DYNAMODB_TRPC_CONNECTION_GENERATOR_INFO","TS_LAMBDA_FUNCTION_GENERATOR_INFO","TS_LIB_GENERATOR_INFO","TS_MCP_SERVER_GENERATOR_INFO","TS_RDB_AGENT_CONNECTION_GENERATOR_INFO","TS_RDB_GENERATOR_INFO","TS_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO","TS_RDB_SMITHY_CONNECTION_GENERATOR_INFO","TS_RDB_TRPC_CONNECTION_GENERATOR_INFO","REACT_WEBSITE_APP_GENERATOR_INFO","COGNITO_AUTH_GENERATOR_INFO","PY_CLIENT_NAMING","resolveAgentFramework","matchGritQL","DCR_PROXY_HANDLERS","formatFilesInSubtree","camelCase","kebabCase","pascalCase","toClassName","toSnakeCase","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","SHARED_INFRA_ROOT","cdk","terraform","infrastructureProviders","tree","providers","Map","iac","configPath","exists","config","dependency","targets","build","dependsOn","name","split","projects","set","COMPONENT_INFRA","Object","fromEntries","id","map","appDirectory","paths","componentInfrastructureProvider","component","layout","generator","undefined","entry","isDcrProxyProject","projectRoot","every","handler","smithyProjectType","buildPath","plugins","keys","length","smithyNamespace","project","modelPath","sourceRoot","root","exec","read","at","usesVitePlugin","plugin","sourceQualifiedName","target","fallback","context","source","camelDatabase","databaseName","targetProjectName","projectName","py","pattern","dependsOnTargetDev","devTarget","some","Array","isArray","includes","agentClientConnection","language","targetGenerators","sourceGenerator","evidence","path","client","className","framework","clientClassSuffix","metadata","rdbConnection","options","targetGenerator","recordedName","entryPoint","devChainConnection","componentDevTarget","REST_API_INFRA","Set","websiteConnection","provider","CONNECTION_KINDS","auth","String","toLowerCase","isRestApi","has","infra","computeType","dependencies","pythonDependenciesDir","connectionTargets","shared","pop","add","get","rc","apiName","components","children","child","find","dir","migration","next","changed","smithyType","namespace","tailwind","tanstackRouter","componentIac","recorded","record","kind","componentSources","filter","sources","candidates","flatMap","sourcePath","projectTargets","rest","nextSteps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { relative } from 'node:path';\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type ProjectConfiguration,\n readJson,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { AGENTCORE_GATEWAY_GATEWAY_CONNECTION_GENERATOR_INFO } from '../../../agentcore-gateway/gateway-connection/generator.js';\nimport { AGENTCORE_GATEWAY_GENERATOR_INFO } from '../../../agentcore-gateway/generator.js';\nimport { AGENTCORE_GATEWAY_MCP_CONNECTION_GENERATOR_INFO } from '../../../agentcore-gateway/mcp-connection/generator.js';\nimport { PY_AGENT_A2A_CONNECTION_GENERATOR_INFO } from '../../../py/agent/a2a-connection/generator.js';\nimport { PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO } from '../../../py/agent/gateway-connection/generator.js';\nimport { PY_AGENT_GENERATOR_INFO } from '../../../py/agent/generator.js';\nimport { PY_AGENT_MCP_CONNECTION_GENERATOR_INFO } from '../../../py/agent/mcp-connection/generator.js';\nimport { PY_AGENT_REACT_CONNECTION_GENERATOR_INFO } from '../../../py/agent/react-connection/generator.js';\nimport { PY_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../py/dynamodb/agent-connection/generator.js';\nimport { PY_DYNAMODB_FAST_API_CONNECTION_GENERATOR_INFO } from '../../../py/dynamodb/fast-api-connection/generator.js';\nimport { PY_DYNAMODB_GENERATOR_INFO } from '../../../py/dynamodb/generator.js';\nimport { PY_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../py/dynamodb/mcp-server-connection/generator.js';\nimport { FAST_API_GENERATOR_INFO } from '../../../py/fast-api/generator.js';\nimport { FAST_API_REACT_GENERATOR_INFO } from '../../../py/fast-api/react/generator.js';\nimport { LAMBDA_FUNCTION_GENERATOR_INFO as PY_LAMBDA_FUNCTION_GENERATOR_INFO } from '../../../py/lambda-function/generator.js';\nimport { PY_MCP_SERVER_GENERATOR_INFO } from '../../../py/mcp-server/generator.js';\nimport { PY_RDB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../py/rdb/agent-connection/generator.js';\nimport { PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO } from '../../../py/rdb/fast-api-connection/generator.js';\nimport { PY_RDB_GENERATOR_INFO } from '../../../py/rdb/generator.js';\nimport { PY_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../py/rdb/mcp-server-connection/generator.js';\nimport { SMITHY_PROJECT_GENERATOR_INFO } from '../../../smithy/project/generator.js';\nimport { SMITHY_REACT_CONNECTION_GENERATOR_INFO } from '../../../smithy/react-connection/generator.js';\nimport { TS_SMITHY_API_GENERATOR_INFO } from '../../../smithy/ts/api/generator.js';\nimport { TRPC_BACKEND_GENERATOR_INFO } from '../../../trpc/backend/generator.js';\nimport { TRPC_REACT_GENERATOR_INFO } from '../../../trpc/react/generator.js';\nimport { TS_AGENT_A2A_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/a2a-connection/generator.js';\nimport { TS_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/gateway-connection/generator.js';\nimport { TS_AGENT_GENERATOR_INFO } from '../../../ts/agent/generator.js';\nimport { TS_AGENT_MCP_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/mcp-connection/generator.js';\nimport { TS_AGENT_REACT_CONNECTION_GENERATOR_INFO } from '../../../ts/agent/react-connection/generator.js';\nimport { TS_DCR_PROXY_GENERATOR_INFO } from '../../../ts/dcr-proxy/generator.js';\nimport { TS_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/agent-connection/generator.js';\nimport { TS_DYNAMODB_GENERATOR_INFO } from '../../../ts/dynamodb/generator.js';\nimport { TS_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/mcp-server-connection/generator.js';\nimport { TS_DYNAMODB_SMITHY_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/smithy-connection/generator.js';\nimport { TS_DYNAMODB_TRPC_CONNECTION_GENERATOR_INFO } from '../../../ts/dynamodb/trpc-connection/generator.js';\nimport { TS_LAMBDA_FUNCTION_GENERATOR_INFO } from '../../../ts/lambda-function/generator.js';\nimport { TS_LIB_GENERATOR_INFO } from '../../../ts/lib/generator.js';\nimport { TS_MCP_SERVER_GENERATOR_INFO } from '../../../ts/mcp-server/generator.js';\nimport { TS_RDB_AGENT_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/agent-connection/generator.js';\nimport { TS_RDB_GENERATOR_INFO } from '../../../ts/rdb/generator.js';\nimport { TS_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/mcp-server-connection/generator.js';\nimport { TS_RDB_SMITHY_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/smithy-connection/generator.js';\nimport { TS_RDB_TRPC_CONNECTION_GENERATOR_INFO } from '../../../ts/rdb/trpc-connection/generator.js';\nimport { REACT_WEBSITE_APP_GENERATOR_INFO } from '../../../ts/react-website/app/generator.js';\nimport { COGNITO_AUTH_GENERATOR_INFO } from '../../../ts/react-website/cognito-auth/generator.js';\nimport {\n PY_CLIENT_NAMING,\n resolveAgentFramework,\n} from '../../../utils/agent-connection/agent-connection.js';\nimport { matchGritQL } from '../../../utils/ast.js';\nimport { DCR_PROXY_HANDLERS } from '../../../utils/dcr-proxy-constructs/dcr-proxy-constructs.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n camelCase,\n kebabCase,\n pascalCase,\n toClassName,\n toSnakeCase,\n} from '../../../utils/names.js';\nimport type { ComponentMetadata } from '../../../utils/nx.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Backfill the project metadata the version sync reads.\n *\n * The sync owns a generator's dependencies only for the runs it can see, and it\n * sees a run through the metadata that generator recorded — narrowing each run to\n * the branch it took by replaying the declaration's `when` predicates against that\n * metadata. Workspaces generated before this release recorded less, in three ways\n * that each cost ownership:\n *\n * - No connection generator recorded anything at all, so the packages they add\n * (the agent Layer-2 clients, AG-UI, the tRPC and OpenAPI react clients) are\n * invisible to the sync and their versions would never move again.\n * - `ts#dcr-proxy` was attributed to the `ts#project` that creates its project.\n * - No project recorded an `iac`, and a predicate reading absent metadata counts\n * as not applying, so the infrastructure helpers' packages go unowned.\n *\n * Every connection is recorded, including those that add no dependencies today.\n * The sync reads the recorded metadata rather than the generators, so a connection\n * recorded now is picked up the moment its generator starts owning packages —\n * otherwise a later release needs a second backfill for the workspaces this one\n * already ran on.\n *\n * Every field is recovered from evidence the generators left behind — the files\n * they wrote, the clients they imported, the dev chains and build dependencies they\n * registered — rather than guessed, and anything that can't be established is left\n * alone. A wrong value is worse than a missing one: it has the sync claim packages\n * a project never received.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n */\n\ntype Iac = 'cdk' | 'terraform';\n\n/** Metadata as a project records it, over the fields this backfill reads. */\ninterface ProjectMetadata {\n generator?: string;\n components?: ComponentMetadata[];\n iac?: string;\n smithyType?: string;\n namespace?: string;\n tailwind?: boolean;\n tanstackRouter?: boolean;\n [key: string]: unknown;\n}\n\n/** The shared project each provider generates its infrastructure into. */\nconst SHARED_INFRA_ROOT: Record<Iac, string> = {\n cdk: joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR),\n terraform: joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR),\n};\n\n/**\n * The provider each project's infrastructure was generated with.\n *\n * Every infra helper registers `<project>:build` on the build target of the shared\n * project belonging to the provider it ran with, so those lists name exactly the\n * projects that received infrastructure, and which provider gave it to them.\n *\n * Read per project rather than per workspace because `iac` is a per-generator\n * option: one workspace can hold both providers.\n */\nconst infrastructureProviders = (tree: Tree): Map<string, Iac> => {\n const providers = new Map<string, Iac>();\n for (const iac of ['cdk', 'terraform'] as const) {\n const configPath = joinPathFragments(\n SHARED_INFRA_ROOT[iac],\n 'project.json',\n );\n if (!tree.exists(configPath)) {\n continue;\n }\n const config = readJson<ProjectConfiguration>(tree, configPath);\n for (const dependency of config.targets?.build?.dependsOn ?? []) {\n // Registered as `<project>:build`, either as that string or as an object.\n const name =\n typeof dependency === 'string'\n ? dependency.split(':')[0]\n : (dependency.projects as string | undefined);\n if (name) {\n providers.set(name, iac);\n }\n }\n }\n return providers;\n};\n\n/**\n * Where a component's infrastructure lives under a provider's shared project,\n * keyed by the generator that created it.\n *\n * These components belong to a project rather than being one, and each records its\n * own `iac` — a project can hold a CDK-deployed agent alongside one generated with\n * `infra: 'none'` — so the project-level build dependency isn't precise enough.\n * Each component gets its own entry under the app directory below, which is.\n *\n * `paths` lists the candidates because the two providers don't lay out every\n * component the same way: a Lambda function is one CDK file but a Terraform\n * directory.\n */\nconst COMPONENT_INFRA: Record<\n string,\n { readonly appDirectory: string; readonly paths: (name: string) => string[] }\n> = {\n ...Object.fromEntries(\n (\n [\n [TS_AGENT_GENERATOR_INFO.id, 'agents'],\n [PY_AGENT_GENERATOR_INFO.id, 'agents'],\n [TS_MCP_SERVER_GENERATOR_INFO.id, 'mcp-servers'],\n [PY_MCP_SERVER_GENERATOR_INFO.id, 'mcp-servers'],\n ] as const\n ).map(([id, appDirectory]) => [\n id,\n { appDirectory, paths: (name: string) => [name] },\n ]),\n ),\n ...Object.fromEntries(\n [\n TS_LAMBDA_FUNCTION_GENERATOR_INFO.id,\n PY_LAMBDA_FUNCTION_GENERATOR_INFO.id,\n ].map((id) => [\n id,\n {\n appDirectory: 'lambda-functions',\n // CDK vends `<name>.ts`; Terraform vends `<name>/<name>.tf`.\n paths: (name: string) => [`${name}.ts`, name],\n },\n ]),\n ),\n};\n\n/**\n * The provider a component's own infrastructure was generated with, from the entry\n * the infra helper created for it under one provider's shared project.\n *\n * That entry is named after the component, which for these generators is the name\n * the component records.\n */\nconst componentInfrastructureProvider = (\n tree: Tree,\n component: ComponentMetadata,\n): Iac | undefined => {\n const layout = component.generator\n ? COMPONENT_INFRA[component.generator]\n : undefined;\n if (!layout || !component.name) {\n return undefined;\n }\n for (const iac of ['cdk', 'terraform'] as const) {\n for (const entry of layout.paths(component.name)) {\n if (\n tree.exists(\n joinPathFragments(\n SHARED_INFRA_ROOT[iac],\n 'src',\n 'app',\n layout.appDirectory,\n entry,\n ),\n )\n ) {\n return iac;\n }\n }\n }\n return undefined;\n};\n\n/**\n * `ts#dcr-proxy` creates its handler project through `ts#project`, which recorded\n * its own id — so an existing workspace attributes the project to `ts#project` and\n * owns none of the proxy's dependencies. The six vended handlers are its\n * signature; a project carrying every one of them is a DCR proxy.\n */\nconst isDcrProxyProject = (tree: Tree, projectRoot: string): boolean =>\n DCR_PROXY_HANDLERS.every((handler) =>\n tree.exists(\n joinPathFragments(projectRoot, 'src', 'handlers', `${handler}.ts`),\n ),\n );\n\n/**\n * What a Smithy project models, from the `smithy-build.json` each kind gets: a\n * service builds an OpenAPI spec and a TypeScript SSDK from its model, so it has\n * the plugins to do so, while a shape library only shares shapes and has none.\n */\nconst smithyProjectType = (\n tree: Tree,\n projectRoot: string,\n): 'service' | 'shapes' | undefined => {\n const buildPath = joinPathFragments(projectRoot, 'smithy-build.json');\n if (!tree.exists(buildPath)) {\n return undefined;\n }\n const build = readJson<{ plugins?: Record<string, unknown> }>(\n tree,\n buildPath,\n );\n return build.plugins && Object.keys(build.plugins).length > 0\n ? 'service'\n : 'shapes';\n};\n\n/**\n * The Smithy namespace a project's shapes are declared in, read from the model\n * rather than derived from the npm scope: the generator takes it as an option, so\n * a project may not carry the default.\n */\nconst smithyNamespace = (\n tree: Tree,\n project: ProjectConfiguration,\n): string | undefined => {\n const modelPath = joinPathFragments(\n project.sourceRoot ?? joinPathFragments(project.root, 'src'),\n 'main.smithy',\n );\n if (!tree.exists(modelPath)) {\n return undefined;\n }\n // Smithy is not a language GritQL parses, and `namespace <x>` is a single\n // declaration on its own line rather than a structure worth an AST for.\n return /^namespace\\s+(\\S+)\\s*$/m\n .exec(tree.read(modelPath, 'utf-8') ?? '')\n ?.at(1);\n};\n\n/**\n * Whether a website's vite config registers the given plugin, which is how\n * `tailwind` and `tanstackRouter` show up in a generated workspace: both default\n * to true, so only the config proves one was turned off.\n *\n * Matched on the AST rather than the text so the plugin's arguments, and any\n * reformatting since, don't hide it.\n */\nconst usesVitePlugin = (\n tree: Tree,\n projectRoot: string,\n plugin: string,\n): Promise<boolean> =>\n matchGritQL(\n tree,\n joinPathFragments(projectRoot, 'vite.config.mts'),\n `\\`${plugin}\\``,\n );\n\n/**\n * A connection generator, and how to recognise a run of it.\n *\n * A connection is found from the source component it was made from and the target\n * it reaches: `evidence` is a check that only passes if that exact pair was wired\n * up — a client import named after the target, a vended file named after it, or\n * the dev-target dependency on its project. So `name` and `sourcePath` are\n * recovered facts rather than guesses.\n *\n * Every connection generator is listed, including those that add no dependencies\n * today. The sync reads the metadata rather than the generator, so recording a\n * connection now is what lets it be picked up the moment its generator starts\n * owning packages — a later release would otherwise need another backfill.\n */\ninterface ConnectionKind {\n /** The generator id to record. */\n readonly id: string;\n /**\n * The generator that created a source component of this connection, or\n * undefined when the connection is made from the project as a whole.\n */\n readonly sourceGenerator?: string;\n /** The generators that could have created its target. */\n readonly targetGenerators: readonly string[];\n /**\n * Whether this connection was made from `source` to `target`, and what to record\n * as the component's `path` if so. Undefined means it was not.\n */\n readonly evidence: (\n context: ConnectionContext,\n ) => string | undefined | Promise<string | undefined>;\n /**\n * The `name` this connection records, when it is not the target's class name.\n * Matched to what each generator writes so a re-run recognises its own entry.\n */\n readonly recordedName?: (context: ConnectionContext) => string;\n /** What this connection records beyond the path, which its predicates read. */\n readonly metadata?: (\n context: ConnectionContext,\n ) => Record<string, unknown> | undefined;\n}\n\n/** `<sourceComponent>-<target>`, the name the database connections record. */\nconst sourceQualifiedName =\n (target: (context: ConnectionContext) => string, fallback: string) =>\n (context: ConnectionContext) =>\n `${context.source.name ?? fallback}-${target(context)}`;\n\n/** The database name as each language's connections case it. */\nconst camelDatabase = ({ target }: ConnectionContext) =>\n camelCase(target.databaseName);\nconst targetProjectName = ({ target }: ConnectionContext) => target.projectName;\n\n/** What a connection's evidence check has to work from. */\ninterface ConnectionContext {\n readonly tree: Tree;\n /** The project the connection lives on — the source side. */\n readonly project: ProjectConfiguration;\n /**\n * The source component, or the project's own metadata standing in for it when\n * the connection is made from the project as a whole.\n */\n readonly source: ComponentMetadata;\n /** The target being connected to. */\n readonly target: ConnectionTarget;\n}\n\n/** Prefix a GritQL pattern to match against Python rather than TypeScript. */\nconst py = (pattern: string) => `language python\\n${pattern}`;\n\n/**\n * Whether the source project's `dev` chain runs the target project's, which every\n * connection wires up so `nx run <source>:dev` starts what it depends on.\n *\n * This is the only trace left by the connections that vend no code (the DynamoDB\n * ones grant IAM in the target's infrastructure instead). It identifies the pair\n * because the dependency names the target project.\n */\nconst dependsOnTargetDev = (\n project: ProjectConfiguration,\n target: ConnectionTarget,\n devTarget: string,\n): boolean =>\n (project.targets?.[devTarget]?.dependsOn ?? []).some((dependency) => {\n const projects =\n typeof dependency === 'string'\n ? dependency.split(':')[0]\n : (dependency.projects as string | string[] | undefined);\n return Array.isArray(projects)\n ? projects.includes(target.projectName)\n : projects === target.projectName;\n });\n\n/**\n * An agent-to-service connection, which imports a Layer-2 client named after the\n * target into the source agent's entry point.\n */\nconst agentClientConnection = (\n id: string,\n language: 'ts' | 'py',\n targetGenerators: readonly string[],\n): ConnectionKind => ({\n id,\n sourceGenerator:\n language === 'ts' ? TS_AGENT_GENERATOR_INFO.id : PY_AGENT_GENERATOR_INFO.id,\n targetGenerators,\n evidence: async ({ tree, project, source, target }) => {\n const path = joinPathFragments(\n source.path ?? 'src',\n language === 'ts' ? 'agent.ts' : 'agent.py',\n );\n // The Python client's class suffix follows the source agent's framework, read\n // from the same naming table the generators use.\n const client =\n language === 'ts'\n ? `${target.className}ClientStrands`\n : `${target.className}Client${\n PY_CLIENT_NAMING[resolveAgentFramework(source.framework)]\n .clientClassSuffix\n }`;\n const pattern = `\\`${client}\\``;\n return (await matchGritQL(\n tree,\n joinPathFragments(project.root, path),\n language === 'ts' ? pattern : py(pattern),\n ))\n ? path\n : undefined;\n },\n ...(language === 'py'\n ? {\n metadata: ({ source }) => ({\n framework: resolveAgentFramework(source.framework),\n }),\n }\n : {}),\n});\n\n/**\n * A database-to-component connection, which imports the database's client getter\n * into the component it connects to and aliases it after the database.\n */\nconst rdbConnection = (\n id: string,\n options: {\n readonly sourceGenerator?: string;\n readonly targetGenerator: string;\n readonly entryPoint: (source: ComponentMetadata) => string;\n readonly recordedName?: ConnectionKind['recordedName'];\n },\n): ConnectionKind => ({\n id,\n sourceGenerator: options.sourceGenerator,\n targetGenerators: [options.targetGenerator],\n recordedName: options.recordedName,\n evidence: async ({ tree, project, source, target }) => {\n const path = options.entryPoint(source);\n return (await matchGritQL(\n tree,\n joinPathFragments(project.root, path),\n // Aliased to `get<Database>` on import, so the alias names the target.\n `\\`get${pascalCase(target.databaseName)}\\``,\n ))\n ? path\n : undefined;\n },\n});\n\n/**\n * A connection that vends no code, recognised by the dev chain it wires from the\n * source component to the target project.\n */\nconst devChainConnection = (\n id: string,\n options: {\n readonly sourceGenerator?: string;\n readonly targetGenerator: string;\n /** The source project's target whose chain this connection extends. */\n readonly devTarget?: (source: ComponentMetadata) => string;\n readonly recordedName?: ConnectionKind['recordedName'];\n },\n): ConnectionKind => ({\n id,\n sourceGenerator: options.sourceGenerator,\n targetGenerators: [options.targetGenerator],\n recordedName: options.recordedName,\n evidence: ({ project, source, target }) =>\n dependsOnTargetDev(project, target, options.devTarget?.(source) ?? 'dev')\n ? target.projectRoot\n : undefined,\n});\n\n/** The `<component>-dev` target a component generator authors for itself. */\nconst componentDevTarget = (source: ComponentMetadata) =>\n `${source.name ?? 'agent'}-dev`;\n\n/** The tRPC-over-HTTP integration patterns, whose extra client packages differ. */\nconst REST_API_INFRA = new Set(['rest-lambda', 'serverlessapigatewayrestapi']);\n\n/**\n * A website connection, recognised by the provider component it vends for its\n * target under the website's source root.\n */\nconst websiteConnection = (\n id: string,\n options: {\n readonly targetGenerator: string;\n readonly provider: (targetClassName: string) => string;\n readonly metadata?: ConnectionKind['metadata'];\n },\n): ConnectionKind => ({\n id,\n sourceGenerator: REACT_WEBSITE_APP_GENERATOR_INFO.id,\n targetGenerators: [options.targetGenerator],\n evidence: ({ tree, project, target }) => {\n const sourceRoot =\n project.sourceRoot ?? joinPathFragments(project.root, 'src');\n const provider = joinPathFragments(\n 'components',\n options.provider(target.className),\n );\n return tree.exists(joinPathFragments(sourceRoot, `${provider}.tsx`))\n ? joinPathFragments(relative(project.root, sourceRoot), provider)\n : undefined;\n },\n metadata: options.metadata,\n});\n\n/**\n * Every connection generator, and the trace each leaves on the project it connects\n * from.\n *\n * Grouped by how a run is recognised, since that follows what the generator does\n * rather than which pair it joins.\n */\nexport const CONNECTION_KINDS: readonly ConnectionKind[] = [\n // Agent to service: imports a Layer-2 client named after the target.\n agentClientConnection(TS_AGENT_MCP_CONNECTION_GENERATOR_INFO.id, 'ts', [\n TS_MCP_SERVER_GENERATOR_INFO.id,\n PY_MCP_SERVER_GENERATOR_INFO.id,\n ]),\n agentClientConnection(TS_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO.id, 'ts', [\n AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n ]),\n agentClientConnection(TS_AGENT_A2A_CONNECTION_GENERATOR_INFO.id, 'ts', [\n TS_AGENT_GENERATOR_INFO.id,\n PY_AGENT_GENERATOR_INFO.id,\n ]),\n agentClientConnection(PY_AGENT_MCP_CONNECTION_GENERATOR_INFO.id, 'py', [\n TS_MCP_SERVER_GENERATOR_INFO.id,\n PY_MCP_SERVER_GENERATOR_INFO.id,\n ]),\n agentClientConnection(PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO.id, 'py', [\n AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n ]),\n agentClientConnection(PY_AGENT_A2A_CONNECTION_GENERATOR_INFO.id, 'py', [\n TS_AGENT_GENERATOR_INFO.id,\n PY_AGENT_GENERATOR_INFO.id,\n ]),\n\n // Website to backend: vends a provider component named after the target.\n websiteConnection(TRPC_REACT_GENERATOR_INFO.id, {\n targetGenerator: TRPC_BACKEND_GENERATOR_INFO.id,\n provider: (className) => `${className}ClientProvider`,\n metadata: ({ target }) => ({\n auth: String(target.project.auth ?? 'iam').toLowerCase(),\n isRestApi: REST_API_INFRA.has(\n String(\n target.project.infra ?? target.project.computeType ?? '',\n ).toLowerCase(),\n ),\n }),\n }),\n // Both OpenAPI react clients vend the same provider shape.\n websiteConnection(SMITHY_REACT_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: TS_SMITHY_API_GENERATOR_INFO.id,\n provider: (className) => `${className}Provider`,\n }),\n websiteConnection(FAST_API_REACT_GENERATOR_INFO.id, {\n targetGenerator: FAST_API_GENERATOR_INFO.id,\n provider: (className) => `${className}Provider`,\n }),\n websiteConnection(TS_AGENT_REACT_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: TS_AGENT_GENERATOR_INFO.id,\n provider: (className) => `${className}AgentClientProvider`,\n }),\n websiteConnection(PY_AGENT_REACT_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: PY_AGENT_GENERATOR_INFO.id,\n provider: (className) => `${className}AgentClientProvider`,\n }),\n\n // Database to component: imports the database's `get<Database>` client getter.\n rdbConnection(TS_RDB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n sourceGenerator: TS_AGENT_GENERATOR_INFO.id,\n targetGenerator: TS_RDB_GENERATOR_INFO.id,\n entryPoint: (source) =>\n joinPathFragments('src', source.name ?? 'agent', 'agent.ts'),\n recordedName: sourceQualifiedName(camelDatabase, 'agent'),\n }),\n rdbConnection(TS_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n sourceGenerator: TS_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: TS_RDB_GENERATOR_INFO.id,\n entryPoint: (source) =>\n joinPathFragments('src', source.name ?? 'mcp-server', 'server.ts'),\n recordedName: sourceQualifiedName(camelDatabase, 'mcp-server'),\n }),\n rdbConnection(TS_RDB_SMITHY_CONNECTION_GENERATOR_INFO.id, {\n targetGenerator: TS_RDB_GENERATOR_INFO.id,\n entryPoint: () => joinPathFragments('src', 'context.ts'),\n recordedName: camelDatabase,\n }),\n\n // Vends a middleware or dependency module named after the database.\n {\n id: TS_RDB_TRPC_CONNECTION_GENERATOR_INFO.id,\n targetGenerators: [TS_RDB_GENERATOR_INFO.id],\n recordedName: camelDatabase,\n evidence: ({ tree, project, target }) => {\n const path = joinPathFragments(\n 'src',\n 'middleware',\n `${kebabCase(target.databaseName)}.ts`,\n );\n return tree.exists(joinPathFragments(project.root, path))\n ? path\n : undefined;\n },\n },\n {\n id: PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO.id,\n targetGenerators: [PY_RDB_GENERATOR_INFO.id],\n recordedName: ({ target }) => toSnakeCase(target.databaseName),\n evidence: ({ tree, project, target }) => {\n const dependencies = pythonDependenciesDir(tree, project);\n if (!dependencies) {\n return undefined;\n }\n const path = joinPathFragments(\n dependencies,\n `${toSnakeCase(target.databaseName)}.py`,\n );\n return tree.exists(joinPathFragments(project.root, path))\n ? path\n : undefined;\n },\n },\n\n // Python database connections vend no code into the source, so the dev chain and\n // the workspace dependency on the database project are the trace.\n devChainConnection(PY_RDB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'agent'),\n sourceGenerator: PY_AGENT_GENERATOR_INFO.id,\n targetGenerator: PY_RDB_GENERATOR_INFO.id,\n devTarget: componentDevTarget,\n }),\n devChainConnection(PY_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'mcp-server'),\n sourceGenerator: PY_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: PY_RDB_GENERATOR_INFO.id,\n devTarget: (source) => `${source.name ?? 'mcp-server'}-dev`,\n }),\n\n // DynamoDB connections grant IAM in the target's infrastructure rather than\n // vending code, so the dev chain is all they leave behind.\n devChainConnection(TS_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'agent'),\n sourceGenerator: TS_AGENT_GENERATOR_INFO.id,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n devTarget: componentDevTarget,\n }),\n devChainConnection(TS_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'mcp-server'),\n sourceGenerator: TS_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n devTarget: (source) => `${source.name ?? 'mcp-server'}-dev`,\n }),\n devChainConnection(TS_DYNAMODB_TRPC_CONNECTION_GENERATOR_INFO.id, {\n recordedName: targetProjectName,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n }),\n devChainConnection(TS_DYNAMODB_SMITHY_CONNECTION_GENERATOR_INFO.id, {\n recordedName: targetProjectName,\n targetGenerator: TS_DYNAMODB_GENERATOR_INFO.id,\n }),\n devChainConnection(PY_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'agent'),\n sourceGenerator: PY_AGENT_GENERATOR_INFO.id,\n targetGenerator: PY_DYNAMODB_GENERATOR_INFO.id,\n devTarget: componentDevTarget,\n }),\n devChainConnection(PY_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO.id, {\n recordedName: sourceQualifiedName(targetProjectName, 'mcp-server'),\n sourceGenerator: PY_MCP_SERVER_GENERATOR_INFO.id,\n targetGenerator: PY_DYNAMODB_GENERATOR_INFO.id,\n devTarget: (source) => `${source.name ?? 'mcp-server'}-dev`,\n }),\n devChainConnection(PY_DYNAMODB_FAST_API_CONNECTION_GENERATOR_INFO.id, {\n recordedName: targetProjectName,\n targetGenerator: PY_DYNAMODB_GENERATOR_INFO.id,\n }),\n\n // Gateway to upstream: registers the upstream in the gateway's local-dev.ts,\n // under the kebab-cased class name the deployed gateway also uses.\n ...(\n [\n [\n AGENTCORE_GATEWAY_MCP_CONNECTION_GENERATOR_INFO.id,\n [TS_MCP_SERVER_GENERATOR_INFO.id, PY_MCP_SERVER_GENERATOR_INFO.id],\n ],\n [\n AGENTCORE_GATEWAY_GATEWAY_CONNECTION_GENERATOR_INFO.id,\n [AGENTCORE_GATEWAY_GENERATOR_INFO.id],\n ],\n ] as const\n ).map(([id, targetGenerators]) => ({\n id,\n sourceGenerator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n targetGenerators,\n recordedName: ({ target }: ConnectionContext) =>\n kebabCase(target.className),\n evidence: async ({ tree, project, target }: ConnectionContext) =>\n (await matchGritQL(\n tree,\n joinPathFragments(project.root, 'local-dev.ts'),\n `\\`'${kebabCase(target.className)}'\\``,\n ))\n ? target.projectRoot\n : undefined,\n })),\n];\n\n/**\n * A thing in the workspace a connection could have been made to, by the names its\n * generated code is derived from.\n */\ninterface ConnectionTarget {\n /** The class name a client or provider for this target is named after. */\n readonly className: string;\n /**\n * The last segment of the target project's name, which the database connections\n * derive their identifiers from.\n */\n readonly databaseName: string;\n /** The target project's name, which a dev-target dependency names. */\n readonly projectName: string;\n /** The target project's root, recorded as `path` by the connections that vend no file. */\n readonly projectRoot: string;\n /** The target project's metadata, which a connection's own fields come from. */\n readonly project: ProjectMetadata;\n}\n\n/**\n * Every connection target in the workspace, keyed by the generator that created it.\n *\n * A target may be a component of a project (an agent, an MCP server) or a whole\n * project (a gateway, an API, a database), so both are indexed. Agents, MCP servers\n * and gateways record the class name directly as `rc`; an API's is derived from its\n * `apiName` the same way its connection generator derives it.\n */\nconst connectionTargets = (tree: Tree): Map<string, ConnectionTarget[]> => {\n const targets = new Map<string, ConnectionTarget[]>();\n for (const [projectName, project] of getProjects(tree)) {\n const metadata = project.metadata as ProjectMetadata | undefined;\n if (!metadata) {\n continue;\n }\n const shared = {\n // The database generators split on `/` for TypeScript and `.` for Python.\n databaseName: projectName.split(/[/.]/).pop() ?? projectName,\n projectName,\n projectRoot: project.root,\n project: metadata,\n };\n const add = (generator: string | undefined, className: unknown) => {\n if (!generator || typeof className !== 'string') {\n return;\n }\n targets.set(generator, [\n ...(targets.get(generator) ?? []),\n { ...shared, className },\n ]);\n };\n add(\n metadata.generator,\n metadata.rc ??\n (typeof metadata.apiName === 'string'\n ? toClassName(metadata.apiName)\n : // A database is named by its project, not a recorded class name.\n shared.databaseName),\n );\n for (const component of metadata.components ?? []) {\n add(component.generator, component.rc);\n }\n }\n return targets;\n};\n\n/**\n * The Python module a FastAPI project's sources live in, found by looking for the\n * `dependencies` directory the connections vend into.\n *\n * The module name mixes the workspace's npm scope with the API name, so it is read\n * off the tree rather than derived — a scope that has since changed would make a\n * derived name wrong.\n */\nconst pythonDependenciesDir = (\n tree: Tree,\n project: ProjectConfiguration,\n): string | undefined =>\n tree\n .children(project.root)\n .map((child) => joinPathFragments(child, 'dependencies'))\n .find((dir) => tree.exists(joinPathFragments(project.root, dir)));\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const providers = infrastructureProviders(tree);\n const targets = connectionTargets(tree);\n\n for (const [projectName, project] of getProjects(tree)) {\n const metadata = project.metadata as ProjectMetadata | undefined;\n if (!metadata?.generator && !metadata?.components?.length) {\n // Not a project this plugin generated, so none of this is ours to record.\n continue;\n }\n\n const next: ProjectMetadata = { ...metadata };\n let changed = false;\n\n if (\n next.generator === TS_LIB_GENERATOR_INFO.id &&\n isDcrProxyProject(tree, project.root)\n ) {\n next.generator = TS_DCR_PROXY_GENERATOR_INFO.id;\n changed = true;\n }\n\n // The provider this project's infrastructure was generated with. Left unset\n // where the project received none, matching what the generators record: the\n // sync reads a set `iac` as \"infrastructure was generated\", and would claim\n // the helpers' packages for a project that never got them.\n const iac = providers.get(projectName);\n if (iac && next.iac === undefined) {\n next.iac = iac;\n changed = true;\n }\n\n // What a Smithy project models, and the namespace it declares. Neither gates a\n // dependency yet, but recording them now means a future gate reads them in a\n // workspace this backfill has already run on.\n if (next.generator === SMITHY_PROJECT_GENERATOR_INFO.id) {\n if (next.smithyType === undefined) {\n const smithyType = smithyProjectType(tree, project.root);\n if (smithyType) {\n next.smithyType = smithyType;\n changed = true;\n }\n }\n if (next.namespace === undefined) {\n const namespace = smithyNamespace(tree, project);\n if (namespace) {\n next.namespace = namespace;\n changed = true;\n }\n }\n }\n\n if (next.generator === REACT_WEBSITE_APP_GENERATOR_INFO.id) {\n if (next.tailwind === undefined) {\n next.tailwind = await usesVitePlugin(tree, project.root, 'tailwindcss');\n changed = true;\n }\n if (next.tanstackRouter === undefined) {\n next.tanstackRouter = await usesVitePlugin(\n tree,\n project.root,\n 'tanstackRouter',\n );\n changed = true;\n }\n }\n\n // The provider each of this project's components generated with. Recorded on\n // the component because that is where these generators record it — an agent\n // and an MCP server each choose their own provider.\n //\n // Left absent rather than set to an empty list where the project has no\n // components, so a project this backfill has nothing to add to is untouched.\n next.components = next.components?.map((component) => {\n if (component.iac !== undefined) {\n return component;\n }\n const componentIac =\n // The auth component vends no infrastructure of its own; it always\n // generates the shared constructs, so it took the project's provider.\n component.generator === COGNITO_AUTH_GENERATOR_INFO.id\n ? iac\n : componentInfrastructureProvider(tree, component);\n if (!componentIac) {\n return component;\n }\n changed = true;\n return { ...component, iac: componentIac };\n });\n\n // A connection already recorded is left as it is: re-recording it would\n // duplicate the entry, and the sync counts entries.\n const recorded = new Set(\n (next.components ?? []).map(\n (component) => `${component.generator}:${component.name}`,\n ),\n );\n const record = (component: ComponentMetadata) => {\n next.components = [...(next.components ?? []), component];\n recorded.add(`${component.generator}:${component.name}`);\n changed = true;\n };\n // The connections made from this project, each found by the trace its\n // generator left for the exact pair it wired up.\n for (const kind of CONNECTION_KINDS) {\n // A connection made from a component starts at each matching component. One\n // made from the project as a whole — a website, a tRPC API — starts at the\n // project's own metadata, which stands in for the source.\n const componentSources = (next.components ?? []).filter(\n (component) => component.generator === kind.sourceGenerator,\n );\n const sources: ComponentMetadata[] = componentSources.length\n ? componentSources\n : (kind.sourceGenerator === undefined ||\n kind.sourceGenerator === next.generator) &&\n next.generator\n ? [{ ...next, generator: next.generator }]\n : [];\n const candidates = kind.targetGenerators.flatMap(\n (generator) => targets.get(generator) ?? [],\n );\n for (const source of sources) {\n for (const target of candidates) {\n // A connection from a component to itself is not one any generator makes.\n if (\n target.projectName === projectName &&\n target.className === source.rc\n ) {\n continue;\n }\n const context: ConnectionContext = { tree, project, source, target };\n const name = kind.recordedName?.(context) ?? target.className;\n if (recorded.has(`${kind.id}:${name}`)) {\n continue;\n }\n const path = await kind.evidence(context);\n if (path === undefined) {\n continue;\n }\n record({\n generator: kind.id,\n path,\n name,\n ...(kind.sourceGenerator && source.path\n ? { sourcePath: source.path }\n : {}),\n ...kind.metadata?.(context),\n });\n }\n }\n }\n\n if (changed) {\n // Keep metadata before targets so the serialized key order matches what the\n // generators write, leaving this a pure metadata edit.\n const { targets: projectTargets, ...rest } = project;\n updateProjectConfiguration(tree, projectName, {\n ...rest,\n metadata: next as ProjectConfiguration['metadata'],\n ...(projectTargets ? { targets: projectTargets } : {}),\n });\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps: [] };\n}\n"],"names":["relative","getProjects","joinPathFragments","readJson","updateProjectConfiguration","AGENTCORE_GATEWAY_GATEWAY_CONNECTION_GENERATOR_INFO","AGENTCORE_GATEWAY_GENERATOR_INFO","AGENTCORE_GATEWAY_MCP_CONNECTION_GENERATOR_INFO","PY_AGENT_A2A_CONNECTION_GENERATOR_INFO","PY_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO","PY_AGENT_GENERATOR_INFO","PY_AGENT_MCP_CONNECTION_GENERATOR_INFO","PY_AGENT_REACT_CONNECTION_GENERATOR_INFO","PY_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO","PY_DYNAMODB_FAST_API_CONNECTION_GENERATOR_INFO","PY_DYNAMODB_GENERATOR_INFO","PY_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO","FAST_API_GENERATOR_INFO","FAST_API_REACT_GENERATOR_INFO","LAMBDA_FUNCTION_GENERATOR_INFO","PY_LAMBDA_FUNCTION_GENERATOR_INFO","PY_MCP_SERVER_GENERATOR_INFO","PY_RDB_AGENT_CONNECTION_GENERATOR_INFO","PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO","PY_RDB_GENERATOR_INFO","PY_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO","SMITHY_PROJECT_GENERATOR_INFO","SMITHY_REACT_CONNECTION_GENERATOR_INFO","TS_SMITHY_API_GENERATOR_INFO","TRPC_BACKEND_GENERATOR_INFO","TRPC_REACT_GENERATOR_INFO","TS_AGENT_A2A_CONNECTION_GENERATOR_INFO","TS_AGENT_GATEWAY_CONNECTION_GENERATOR_INFO","TS_AGENT_GENERATOR_INFO","TS_AGENT_MCP_CONNECTION_GENERATOR_INFO","TS_AGENT_REACT_CONNECTION_GENERATOR_INFO","TS_DCR_PROXY_GENERATOR_INFO","TS_DYNAMODB_AGENT_CONNECTION_GENERATOR_INFO","TS_DYNAMODB_GENERATOR_INFO","TS_DYNAMODB_MCP_SERVER_CONNECTION_GENERATOR_INFO","TS_DYNAMODB_SMITHY_CONNECTION_GENERATOR_INFO","TS_DYNAMODB_TRPC_CONNECTION_GENERATOR_INFO","TS_LAMBDA_FUNCTION_GENERATOR_INFO","TS_LIB_GENERATOR_INFO","TS_MCP_SERVER_GENERATOR_INFO","TS_RDB_AGENT_CONNECTION_GENERATOR_INFO","TS_RDB_GENERATOR_INFO","TS_RDB_MCP_SERVER_CONNECTION_GENERATOR_INFO","TS_RDB_SMITHY_CONNECTION_GENERATOR_INFO","TS_RDB_TRPC_CONNECTION_GENERATOR_INFO","REACT_WEBSITE_APP_GENERATOR_INFO","COGNITO_AUTH_GENERATOR_INFO","PY_CLIENT_NAMING","resolveAgentFramework","matchGritQL","DCR_PROXY_HANDLERS","formatFilesInSubtree","camelCase","kebabCase","pascalCase","toClassName","toSnakeCase","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","SHARED_INFRA_ROOT","cdk","terraform","infrastructureProviders","tree","providers","Map","iac","configPath","exists","config","dependency","targets","build","dependsOn","name","split","projects","set","COMPONENT_INFRA","Object","fromEntries","id","map","appDirectory","paths","componentInfrastructureProvider","component","layout","generator","undefined","entry","isDcrProxyProject","projectRoot","every","handler","smithyProjectType","buildPath","plugins","keys","length","smithyNamespace","project","modelPath","sourceRoot","root","exec","read","at","usesVitePlugin","plugin","sourceQualifiedName","target","fallback","context","source","camelDatabase","databaseName","targetProjectName","projectName","py","pattern","dependsOnTargetDev","devTarget","some","Array","isArray","includes","agentClientConnection","language","targetGenerators","sourceGenerator","evidence","path","client","className","framework","clientClassSuffix","metadata","rdbConnection","options","targetGenerator","recordedName","entryPoint","devChainConnection","componentDevTarget","REST_API_INFRA","Set","websiteConnection","provider","CONNECTION_KINDS","auth","String","toLowerCase","isRestApi","has","infra","computeType","dependencies","pythonDependenciesDir","connectionTargets","shared","pop","add","get","rc","apiName","components","children","child","find","dir","migration","next","changed","smithyType","namespace","tailwind","tanstackRouter","componentIac","recorded","record","kind","componentSources","filter","sources","candidates","flatMap","sourcePath","projectTargets","rest","nextSteps"],"mappings":"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"}
|
package/src/migrations/v1.0.0-rc.56/0001-dynamodb-local-remove-optimize-flag/migration.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.56/0001-dynamodb-local-remove-optimize-flag/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport { applyGritQL } from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n PACKAGES_DIR,\n SHARED_SCRIPTS_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Drop -optimizeDbBeforeStartup from the vended DynamoDB Local container script\n *\n * DynamoDB Local's startup vacuum drops primary key / GSI uniqueness on the\n * underlying sqlite file, letting PutItem/UpdateItem write duplicate rows for\n * the same key.\n *\n * The edit is expressed as a GritQL rewrite so the script is matched on its\n * AST rather than its formatting. The rewrite matches the whole `runArgs`\n * array rather than just the flag, because this GritQL/tree-sitter grammar\n * can't match a partial slice of array elements, and a literal backtick\n * template string breaks matching anywhere it appears alongside other\n * elements - so every templated element (the port/volume args) is matched via\n * a metavariable instead of being spelled out.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * the generator produces and report them via `nextSteps`.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree`.\n */\n\nconst START_CONTAINER_FILE = `${PACKAGES_DIR}/${SHARED_SCRIPTS_DIR}/src/dynamodb/start-container.ts`;\n\nconst FLAG = \"'-optimizeDbBeforeStartup'\";\n\nconst REMOVE_FLAG_PATTERN = `\\`[\n 'run',\n ...(containerEngine === 'docker' ? ['--rm'] : []),\n '--name', containerName,\n '-u', 'root',\n '-w', '/home/dynamodblocal',\n $flagP, $portColonPort,\n '-v', $volume,\n '-d', image,\n '-jar', 'DynamoDBLocal.jar',\n '-sharedDb',\n '-dbPath', './data',\n '-port', $portArg,\n ${FLAG},\n ]\\` => \\`[\n 'run',\n ...(containerEngine === 'docker' ? ['--rm'] : []),\n '--name', containerName,\n '-u', 'root',\n '-w', '/home/dynamodblocal',\n $flagP, $portColonPort,\n '-v', $volume,\n '-d', image,\n '-jar', 'DynamoDBLocal.jar',\n '-sharedDb',\n '-dbPath', './data',\n '-port', $portArg,\n ]\\``;\n\nconst divergedNextStep = `${START_CONTAINER_FILE}: the container script has diverged from the generated shape - left untouched. Manually drop ${FLAG} from the DynamoDB Local container run args - its startup vacuum can drop primary key / GSI uniqueness on the sqlite file, letting PutItem/UpdateItem write duplicate rows for the same key.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(START_CONTAINER_FILE)) {\n return { nextSteps };\n }\n\n const contents = tree.read(START_CONTAINER_FILE, 'utf-8') ?? '';\n if (!contents.includes(FLAG)) {\n // Already migrated, or doesn't use this shape.\n return { nextSteps };\n }\n\n const rewrote = await applyGritQL(\n tree,\n START_CONTAINER_FILE,\n REMOVE_FLAG_PATTERN,\n );\n\n if (!rewrote) {\n nextSteps.push(divergedNextStep);\n return { nextSteps };\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_SCRIPTS_DIR","START_CONTAINER_FILE","FLAG","REMOVE_FLAG_PATTERN","divergedNextStep","migration","tree","nextSteps","exists","contents","read","includes","rewrote","push"],"mappings":"AAAA;;;CAGC,GAED,SAASA,WAAW,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.56/0001-dynamodb-local-remove-optimize-flag/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport { applyGritQL } from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_SCRIPTS_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Drop -optimizeDbBeforeStartup from the vended DynamoDB Local container script\n *\n * DynamoDB Local's startup vacuum drops primary key / GSI uniqueness on the\n * underlying sqlite file, letting PutItem/UpdateItem write duplicate rows for\n * the same key.\n *\n * The edit is expressed as a GritQL rewrite so the script is matched on its\n * AST rather than its formatting. The rewrite matches the whole `runArgs`\n * array rather than just the flag, because this GritQL/tree-sitter grammar\n * can't match a partial slice of array elements, and a literal backtick\n * template string breaks matching anywhere it appears alongside other\n * elements - so every templated element (the port/volume args) is matched via\n * a metavariable instead of being spelled out.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * the generator produces and report them via `nextSteps`.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree`.\n */\n\nconst START_CONTAINER_FILE = `${PACKAGES_DIR}/${SHARED_SCRIPTS_DIR}/src/dynamodb/start-container.ts`;\n\nconst FLAG = \"'-optimizeDbBeforeStartup'\";\n\nconst REMOVE_FLAG_PATTERN = `\\`[\n 'run',\n ...(containerEngine === 'docker' ? ['--rm'] : []),\n '--name', containerName,\n '-u', 'root',\n '-w', '/home/dynamodblocal',\n $flagP, $portColonPort,\n '-v', $volume,\n '-d', image,\n '-jar', 'DynamoDBLocal.jar',\n '-sharedDb',\n '-dbPath', './data',\n '-port', $portArg,\n ${FLAG},\n ]\\` => \\`[\n 'run',\n ...(containerEngine === 'docker' ? ['--rm'] : []),\n '--name', containerName,\n '-u', 'root',\n '-w', '/home/dynamodblocal',\n $flagP, $portColonPort,\n '-v', $volume,\n '-d', image,\n '-jar', 'DynamoDBLocal.jar',\n '-sharedDb',\n '-dbPath', './data',\n '-port', $portArg,\n ]\\``;\n\nconst divergedNextStep = `${START_CONTAINER_FILE}: the container script has diverged from the generated shape - left untouched. Manually drop ${FLAG} from the DynamoDB Local container run args - its startup vacuum can drop primary key / GSI uniqueness on the sqlite file, letting PutItem/UpdateItem write duplicate rows for the same key.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(START_CONTAINER_FILE)) {\n return { nextSteps };\n }\n\n const contents = tree.read(START_CONTAINER_FILE, 'utf-8') ?? '';\n if (!contents.includes(FLAG)) {\n // Already migrated, or doesn't use this shape.\n return { nextSteps };\n }\n\n const rewrote = await applyGritQL(\n tree,\n START_CONTAINER_FILE,\n REMOVE_FLAG_PATTERN,\n );\n\n if (!rewrote) {\n nextSteps.push(divergedNextStep);\n return { nextSteps };\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_SCRIPTS_DIR","START_CONTAINER_FILE","FLAG","REMOVE_FLAG_PATTERN","divergedNextStep","migration","tree","nextSteps","exists","contents","read","includes","rewrote","push"],"mappings":"AAAA;;;CAGC,GAED,SAASA,WAAW,QAAQ,wBAAwB;AACpD,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,kBAAkB,QACb,gDAAgD;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;CAwBC,GAED,MAAMC,uBAAuB,GAAGF,aAAa,CAAC,EAAEC,mBAAmB,gCAAgC,CAAC;AAEpG,MAAME,OAAO;AAEb,MAAMC,sBAAsB,CAAC;;;;;;;;;;;;;IAazB,EAAED,KAAK;;;;;;;;;;;;;;KAcN,CAAC;AAEN,MAAME,mBAAmB,GAAGH,qBAAqB,6FAA6F,EAAEC,KAAK,4LAA4L,CAAC;AAElV,eAAe,eAAeG,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,IAAI,CAACD,KAAKE,MAAM,CAACP,uBAAuB;QACtC,OAAO;YAAEM;QAAU;IACrB;IAEA,MAAME,WAAWH,KAAKI,IAAI,CAACT,sBAAsB,YAAY;IAC7D,IAAI,CAACQ,SAASE,QAAQ,CAACT,OAAO;QAC5B,+CAA+C;QAC/C,OAAO;YAAEK;QAAU;IACrB;IAEA,MAAMK,UAAU,MAAMf,YACpBS,MACAL,sBACAE;IAGF,IAAI,CAACS,SAAS;QACZL,UAAUM,IAAI,CAACT;QACf,OAAO;YAAEG;QAAU;IACrB;IAEA,MAAMT,qBAAqBQ;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
|