@aws/nx-plugin 1.0.0-rc.32 → 1.0.0-rc.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +75 -86
- package/generators.json +27 -0
- package/package.json +10 -10
- package/src/connection/generator.js +12 -1
- package/src/connection/generator.js.map +1 -1
- package/src/connection/supported-connections.d.ts +10 -1
- package/src/connection/supported-connections.js +13 -0
- package/src/connection/supported-connections.js.map +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +21 -21
- package/src/infra/app/files/app/src/main.ts.template +1 -1
- package/src/infra/app/files/app/src/stages/application-stage.ts.template +1 -1
- package/src/infra/app/generator.js +3 -1
- package/src/infra/app/generator.js.map +1 -1
- package/src/open-api/ts-client/__snapshots__/generator.complex-types.spec.ts.snap +12 -12
- package/src/open-api/ts-client/__snapshots__/generator.composite-types.spec.ts.snap +74 -10
- package/src/open-api/ts-client/__snapshots__/generator.content-type.spec.ts.snap +22 -4
- package/src/open-api/ts-client/__snapshots__/generator.duplicate-types.spec.ts.snap +53 -8
- package/src/open-api/ts-client/__snapshots__/generator.edge-cases.spec.ts.snap +32 -4
- package/src/open-api/ts-client/__snapshots__/generator.fast-api-gaps.spec.ts.snap +736 -0
- package/src/open-api/ts-client/__snapshots__/generator.fast-api.spec.ts.snap +86 -11
- package/src/open-api/ts-client/__snapshots__/generator.multipart.spec.ts.snap +21 -3
- package/src/open-api/ts-client/__snapshots__/generator.primitive-types.spec.ts.snap +2 -2
- package/src/open-api/ts-client/__snapshots__/generator.request.spec.ts.snap +6 -6
- package/src/open-api/ts-client/__snapshots__/generator.reserved-keywords.spec.ts.snap +2 -2
- package/src/open-api/ts-client/__snapshots__/generator.spec-compliance.spec.ts.snap +1883 -0
- package/src/open-api/ts-client/__snapshots__/generator.tags.spec.ts.snap +4 -4
- package/src/open-api/ts-client/files/client.gen.ts.template +196 -13
- package/src/open-api/ts-client/files/types.gen.ts.template +2 -0
- package/src/open-api/ts-client/generator.js +27 -2
- package/src/open-api/ts-client/generator.js.map +1 -1
- package/src/open-api/ts-hooks/files/options-proxy.gen.ts.template +2 -2
- package/src/open-api/ts-hooks/generator.js +5 -1
- package/src/open-api/ts-hooks/generator.js.map +1 -1
- package/src/open-api/utils/codegen-data/languages.js +6 -0
- package/src/open-api/utils/codegen-data/languages.js.map +1 -1
- package/src/open-api/utils/codegen-data/types.d.ts +16 -1
- package/src/open-api/utils/codegen-data/types.js.map +1 -1
- package/src/open-api/utils/codegen-data.js +71 -0
- package/src/open-api/utils/codegen-data.js.map +1 -1
- package/src/open-api/utils/normalise.js +53 -8
- package/src/open-api/utils/normalise.js.map +1 -1
- package/src/open-api/utils/parser.js +48 -15
- package/src/open-api/utils/parser.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +5 -3
- package/src/preset/generator.d.ts +1 -1
- package/src/preset/generator.js +5 -2
- package/src/preset/generator.js.map +1 -1
- package/src/preset/schema.d.js.map +1 -1
- package/src/preset/schema.d.ts +2 -0
- package/src/preset/schema.json +6 -0
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +7 -7
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +8 -8
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +89 -3
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +12 -12
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +91 -5
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2038 -0
- package/src/py/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +104 -0
- package/src/py/rdb/agent-connection/generator.d.ts +10 -0
- package/src/py/rdb/agent-connection/generator.js +46 -0
- package/src/py/rdb/agent-connection/generator.js.map +1 -0
- package/src/py/rdb/agent-connection/schema.d.js +8 -0
- package/src/py/rdb/agent-connection/schema.d.js.map +1 -0
- package/src/py/rdb/agent-connection/schema.d.ts +15 -0
- package/src/py/rdb/agent-connection/schema.json +27 -0
- package/src/py/rdb/fast-api-connection/__snapshots__/generator.spec.ts.snap +44 -0
- package/src/py/rdb/fast-api-connection/files/__apiModuleName__/dependencies/__rdbNameSnake__.py.template +14 -0
- package/src/py/rdb/fast-api-connection/generator.d.ts +10 -0
- package/src/py/rdb/fast-api-connection/generator.js +54 -0
- package/src/py/rdb/fast-api-connection/generator.js.map +1 -0
- package/src/py/rdb/fast-api-connection/schema.d.js +8 -0
- package/src/py/rdb/fast-api-connection/schema.d.js.map +1 -0
- package/src/py/rdb/fast-api-connection/schema.d.ts +13 -0
- package/src/py/rdb/fast-api-connection/schema.json +23 -0
- package/src/py/rdb/files/Dockerfile.create-db-user.template +10 -0
- package/src/py/rdb/files/Dockerfile.migration.template +10 -0
- package/src/py/rdb/files/__name__/__init__.py.template +3 -0
- package/src/py/rdb/files/__name__/connection.py.template +55 -0
- package/src/py/rdb/files/__name__/create_db_user_handler.py.template +97 -0
- package/src/py/rdb/files/__name__/migration_handler.py.template +36 -0
- package/src/py/rdb/files/__name__/models/__init__.py.template +3 -0
- package/src/py/rdb/files/__name__/models/example.py.template +8 -0
- package/src/py/rdb/files/__name__/utils.py.template +104 -0
- package/src/py/rdb/files/alembic.ini.template +38 -0
- package/src/py/rdb/files/config.json.template +14 -0
- package/src/py/rdb/files/migrations/env.py.template +80 -0
- package/src/py/rdb/files/migrations/script.py.mako.template +28 -0
- package/src/py/rdb/generator.d.ts +6 -0
- package/src/py/rdb/generator.js +263 -0
- package/src/py/rdb/generator.js.map +1 -0
- package/src/py/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +101 -0
- package/src/py/rdb/mcp-server-connection/generator.d.ts +10 -0
- package/src/py/rdb/mcp-server-connection/generator.js +46 -0
- package/src/py/rdb/mcp-server-connection/generator.js.map +1 -0
- package/src/py/rdb/mcp-server-connection/schema.d.js +8 -0
- package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -0
- package/src/py/rdb/mcp-server-connection/schema.d.ts +15 -0
- package/src/py/rdb/mcp-server-connection/schema.json +27 -0
- package/src/py/rdb/schema.d.js +6 -0
- package/src/py/rdb/schema.d.js.map +1 -0
- package/src/py/rdb/schema.d.ts +16 -0
- package/src/py/rdb/schema.json +77 -0
- package/src/py/rdb/utils.d.ts +6 -0
- package/src/py/rdb/utils.js +16 -0
- package/src/py/rdb/utils.js.map +1 -0
- package/src/sdk/py.d.ts +2 -0
- package/src/sdk/py.js +1 -0
- package/src/sdk/py.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +7 -7
- package/src/smithy/ts/api/files/handler.ts.template +2 -2
- package/src/smithy/ts/api/files/local-server.ts.template +2 -2
- package/src/smithy/ts/api/files/operations/echo.ts.template +2 -2
- package/src/smithy/ts/api/files/service.ts.template +3 -3
- package/src/smithy/ts/api/generator.js +3 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +12 -12
- package/src/trpc/backend/files/src/client/index.ts.template +1 -1
- package/src/trpc/backend/files/src/handler.ts.template +1 -1
- package/src/trpc/backend/files/src/index.ts.template +5 -5
- package/src/trpc/backend/files/src/init.ts.template +1 -1
- package/src/trpc/backend/files/src/local-server.ts.template +1 -1
- package/src/trpc/backend/files/src/middleware/index.ts.template +7 -7
- package/src/trpc/backend/files/src/procedures/echo.ts.template +2 -2
- package/src/trpc/backend/files/src/router.ts.template +2 -2
- package/src/trpc/backend/files/src/schema/index.ts.template +1 -1
- package/src/trpc/backend/generator.js +3 -1
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +89 -3
- package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client-strands.ts.template +2 -2
- package/src/ts/agent/a2a-connection/generator.js +3 -1
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/files/a2a/index.ts.template +1 -1
- package/src/ts/agent/files/ag-ui/index.ts.template +1 -1
- package/src/ts/agent/files/http/client.ts.template +2 -2
- package/src/ts/agent/files/http/index.ts.template +2 -2
- package/src/ts/agent/files/http/router.ts.template +3 -3
- package/src/ts/agent/gateway-connection/files/agent-connection/app/__gatewayKebabCase__-client-strands.ts.template +2 -2
- package/src/ts/agent/gateway-connection/generator.js +3 -1
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/generator.js +5 -2
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client-strands.ts.template +2 -2
- package/src/ts/agent/mcp-connection/generator.js +3 -1
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/astro-docs/files/translation/scripts/translate.ts.template +3 -2
- package/src/ts/astro-docs/generator.js +2 -0
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/dynamodb/files/src/client.ts.template +5 -2
- package/src/ts/dynamodb/files/src/entities/example.ts.template +1 -1
- package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -1
- package/src/ts/dynamodb/files/src/index.ts.template +2 -2
- package/src/ts/dynamodb/generator.js +3 -1
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/lib/generator.js +7 -1
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/ts-project-utils.js +19 -4
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/types.d.ts +6 -0
- package/src/ts/lib/types.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +94 -8
- package/src/ts/mcp-server/generator.js +3 -2
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/nx-generator/files/local/generator.ts.template +2 -2
- package/src/ts/nx-generator/files/nx-plugin-for-aws/generator/generator.ts.template +2 -2
- package/src/ts/nx-generator/generator.js +5 -2
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-plugin/files/mcp-server/server.ts.template +5 -5
- package/src/ts/nx-plugin/files/mcp-server/tools/create-workspace-command.ts.template +2 -2
- package/src/ts/nx-plugin/files/mcp-server/tools/general-guidance.ts.template +1 -1
- package/src/ts/nx-plugin/files/mcp-server/tools/generator-guide.ts.template +2 -2
- package/src/ts/nx-plugin/files/mcp-server/tools/list-generators.ts.template +2 -2
- package/src/ts/nx-plugin/files/mcp-server/utils.ts.template +3 -3
- package/src/ts/nx-plugin/generator.js +3 -1
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/nx-plugin/utils.js +7 -4
- package/src/ts/nx-plugin/utils.js.map +1 -1
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +149 -177
- package/src/ts/rdb/files/src/create-db-user-handler.ts.template +2 -2
- package/src/ts/rdb/files/src/index.ts.template +1 -1
- package/src/ts/rdb/files/src/migration-handler.ts.template +1 -1
- package/src/ts/rdb/files/src/prisma.ts.template +7 -4
- package/src/ts/rdb/generator.js +7 -4
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/rdb/schema.json +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +45 -45
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +2 -2
- package/src/utils/agent-chat/agent-chat.js +3 -1
- package/src/utils/agent-chat/agent-chat.js.map +1 -1
- package/src/utils/agent-chat/files/a2a/chat.ts.template +1 -1
- package/src/utils/agent-chat/files/ag-ui/chat.ts.template +1 -1
- package/src/utils/agent-chat/files/http-py/chat.ts.template +2 -2
- package/src/utils/agent-chat/files/http-ts/chat.ts.template +1 -1
- package/src/utils/agent-connection/agent-connection.js +4 -1
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +2 -2
- package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +1 -1
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +2 -2
- package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +2 -2
- package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/base/with-session-id-strands.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js +10 -3
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +3 -3
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +4 -4
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +1 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +27 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +60 -1
- package/src/utils/api-constructs/api-constructs.js +8 -2
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +8 -8
- package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +8 -8
- package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +3 -3
- package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account/index.js.template +32 -20
- package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account.ts.template +1 -1
- package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +4 -4
- package/src/utils/api-constructs/files/cdk/core/api/trpc/trpc-utils.ts.template +1 -1
- package/src/utils/ast.js +16 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/commands.d.ts +1 -1
- package/src/utils/commands.js +4 -1
- package/src/utils/commands.js.map +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js +9 -2
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
- package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +3 -3
- package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +1 -1
- package/src/utils/files/common/constructs/src/core/index.ts.template +4 -4
- package/src/utils/files/common/constructs/src/index.ts.template +2 -2
- package/src/utils/files/common/infra-config/src/index.ts.template +3 -3
- package/src/utils/files/common/infra-config/src/resolve-stage.ts.template +2 -2
- package/src/utils/files/common/infra-config/src/stages.config.ts.template +1 -1
- package/src/utils/files/common/scripts/src/infra/infra-deploy.ts.template +1 -1
- package/src/utils/files/common/scripts/src/infra/infra-destroy.ts.template +1 -1
- package/src/utils/files/common/scripts/src/infra/stage-credentials/run.ts.template +3 -3
- package/src/utils/files/common/shadcn/src/index.ts.template +2 -2
- package/src/utils/function-constructs/files/cdk/app/lambda-functions/__nameKebabCase__.ts.template +1 -1
- package/src/utils/function-constructs/function-constructs.js +3 -1
- package/src/utils/function-constructs/function-constructs.js.map +1 -1
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +2 -2
- package/src/utils/identity-constructs/identity-constructs.js +5 -1
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/module-format.d.ts +28 -0
- package/src/utils/module-format.js +28 -0
- package/src/utils/module-format.js.map +1 -0
- package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +61 -17
- package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +68 -78
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +88 -8
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +5 -32
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +11 -1
- package/src/utils/rdb-constructs/rdb-constructs.js +9 -2
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/shared-constructs.js +12 -22
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/shared-infra-config.js +3 -1
- package/src/utils/shared-infra-config.js.map +1 -1
- package/src/utils/shared-infra-scripts.js +3 -1
- package/src/utils/shared-infra-scripts.js.map +1 -1
- package/src/utils/shared-rdb-scripts.js +5 -1
- package/src/utils/shared-rdb-scripts.js.map +1 -1
- package/src/utils/shared-shadcn.js +3 -1
- package/src/utils/shared-shadcn.js.map +1 -1
- package/src/utils/test.d.ts +2 -0
- package/src/utils/test.js +7 -1
- package/src/utils/test.js.map +1 -1
- package/src/utils/versions.d.ts +73 -69
- package/src/utils/versions.js +71 -67
- package/src/utils/versions.js.map +1 -1
- package/src/utils/website-constructs/files/cdk/app/static-websites/__websiteNameKebabCase__.ts.template +2 -2
- package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +2 -2
- package/src/utils/website-constructs/website-constructs.js +9 -2
- package/src/utils/website-constructs/website-constructs.js.map +1 -1
- package/src/utils/files/terraform/scripts/reset-runtime-config.ts.template +0 -25
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`py#rdb agent-connection generator > should add RDS CA bundle to Dockerfile 1`] = `
|
|
4
|
+
"FROM public.ecr.aws/docker/library/python:3.14-slim
|
|
5
|
+
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
|
|
8
|
+
COPY . /app
|
|
9
|
+
|
|
10
|
+
ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /usr/local/share/ca-certificates/rds-global-bundle.crt
|
|
11
|
+
RUN update-ca-certificates
|
|
12
|
+
|
|
13
|
+
EXPOSE 8080
|
|
14
|
+
|
|
15
|
+
ENV PYTHONPATH=/app
|
|
16
|
+
ENV PATH="/app/bin:\${PATH}"
|
|
17
|
+
|
|
18
|
+
CMD ["python", "-m", "proj_my_agent.agent.main"]
|
|
19
|
+
"
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
exports[`py#rdb agent-connection generator > should add RDS CA bundle to sourceComponent Dockerfile 1`] = `
|
|
23
|
+
"FROM public.ecr.aws/docker/library/python:3.14-slim
|
|
24
|
+
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
|
|
27
|
+
COPY . /app
|
|
28
|
+
|
|
29
|
+
ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /usr/local/share/ca-certificates/rds-global-bundle.crt
|
|
30
|
+
RUN update-ca-certificates
|
|
31
|
+
|
|
32
|
+
EXPOSE 8080
|
|
33
|
+
|
|
34
|
+
ENV PYTHONPATH=/app
|
|
35
|
+
ENV PATH="/app/bin:\${PATH}"
|
|
36
|
+
|
|
37
|
+
CMD ["python", "-m", "proj_my_agent.custom_agent.main"]
|
|
38
|
+
"
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
exports[`py#rdb agent-connection generator > should add rdb dev dependency to agent dev 1`] = `
|
|
42
|
+
{
|
|
43
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
44
|
+
"name": "my-agent",
|
|
45
|
+
"root": "packages/my-agent",
|
|
46
|
+
"sourceRoot": "packages/my-agent/src/proj_my_agent",
|
|
47
|
+
"targets": {
|
|
48
|
+
"agent-dev": {
|
|
49
|
+
"continuous": true,
|
|
50
|
+
"dependsOn": [
|
|
51
|
+
{
|
|
52
|
+
"projects": [
|
|
53
|
+
"db",
|
|
54
|
+
],
|
|
55
|
+
"target": "dev",
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
"executor": "nx:run-commands",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
exports[`py#rdb agent-connection generator > should be idempotent for Dockerfile 1`] = `
|
|
65
|
+
"FROM public.ecr.aws/docker/library/python:3.14-slim
|
|
66
|
+
|
|
67
|
+
WORKDIR /app
|
|
68
|
+
|
|
69
|
+
COPY . /app
|
|
70
|
+
|
|
71
|
+
ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /usr/local/share/ca-certificates/rds-global-bundle.crt
|
|
72
|
+
RUN update-ca-certificates
|
|
73
|
+
|
|
74
|
+
EXPOSE 8080
|
|
75
|
+
|
|
76
|
+
ENV PYTHONPATH=/app
|
|
77
|
+
ENV PATH="/app/bin:\${PATH}"
|
|
78
|
+
|
|
79
|
+
CMD ["python", "-m", "proj_my_agent.agent.main"]
|
|
80
|
+
"
|
|
81
|
+
`;
|
|
82
|
+
|
|
83
|
+
exports[`py#rdb agent-connection generator > should use sourceComponent name when provided 1`] = `
|
|
84
|
+
{
|
|
85
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
86
|
+
"name": "my-agent",
|
|
87
|
+
"root": "packages/my-agent",
|
|
88
|
+
"sourceRoot": "packages/my-agent/src/proj_my_agent",
|
|
89
|
+
"targets": {
|
|
90
|
+
"custom-agent-dev": {
|
|
91
|
+
"continuous": true,
|
|
92
|
+
"dependsOn": [
|
|
93
|
+
{
|
|
94
|
+
"projects": [
|
|
95
|
+
"db",
|
|
96
|
+
],
|
|
97
|
+
"target": "dev",
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
"executor": "nx:run-commands",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
|
+
import { type NxGeneratorInfo } from '../../../utils/nx';
|
|
7
|
+
import type { PyRdbAgentConnectionGeneratorSchema } from './schema';
|
|
8
|
+
export declare const PY_RDB_AGENT_CONNECTION_GENERATOR_INFO: NxGeneratorInfo;
|
|
9
|
+
export declare const pyRdbAgentConnectionGenerator: (tree: Tree, options: PyRdbAgentConnectionGeneratorSchema) => Promise<GeneratorCallback>;
|
|
10
|
+
export default pyRdbAgentConnectionGenerator;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { joinPathFragments, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
6
|
+
import { installDependencies } from "../../../utils/install.js";
|
|
7
|
+
import { addGeneratorMetricsIfApplicable } from "../../../utils/metrics.js";
|
|
8
|
+
import { toSnakeCase } from "../../../utils/names.js";
|
|
9
|
+
import { addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
|
|
10
|
+
import { addWorkspaceDependencyToPyProject } from "../../../utils/py.js";
|
|
11
|
+
import { injectRdsCaBundleIntoDockerfile } from "../utils.js";
|
|
12
|
+
export const PY_RDB_AGENT_CONNECTION_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
13
|
+
export const pyRdbAgentConnectionGenerator = async (tree, options)=>{
|
|
14
|
+
const sourceProject = readProjectConfigurationUnqualified(tree, options.sourceProject);
|
|
15
|
+
const targetProject = readProjectConfigurationUnqualified(tree, options.targetProject);
|
|
16
|
+
addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);
|
|
17
|
+
const agentName = options.sourceComponent?.name ?? 'agent';
|
|
18
|
+
const devTarget = `${agentName}-dev`;
|
|
19
|
+
const agentSourceDir = options.sourceComponent?.path ? joinPathFragments(sourceProject.root, options.sourceComponent.path) : sourceProject.sourceRoot ? joinPathFragments(sourceProject.sourceRoot, toSnakeCase(agentName)) : undefined;
|
|
20
|
+
const dockerfilePath = agentSourceDir ? joinPathFragments(agentSourceDir, 'Dockerfile') : undefined;
|
|
21
|
+
if (dockerfilePath) {
|
|
22
|
+
injectRdsCaBundleIntoDockerfile(tree, dockerfilePath);
|
|
23
|
+
}
|
|
24
|
+
if (sourceProject.targets?.[devTarget]) {
|
|
25
|
+
addDependencyToTargetIfNotPresent(sourceProject, devTarget, {
|
|
26
|
+
projects: [
|
|
27
|
+
targetProject.name
|
|
28
|
+
],
|
|
29
|
+
target: 'dev'
|
|
30
|
+
});
|
|
31
|
+
updateProjectConfiguration(tree, sourceProject.name, sourceProject);
|
|
32
|
+
}
|
|
33
|
+
await addGeneratorMetricsIfApplicable(tree, [
|
|
34
|
+
PY_RDB_AGENT_CONNECTION_GENERATOR_INFO
|
|
35
|
+
]);
|
|
36
|
+
await formatFilesInSubtree(tree);
|
|
37
|
+
return ()=>installDependencies(tree, options.preferInstallDependencies, {
|
|
38
|
+
languages: [
|
|
39
|
+
'typescript',
|
|
40
|
+
'python'
|
|
41
|
+
]
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
export default pyRdbAgentConnectionGenerator;
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/agent-connection/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n joinPathFragments,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toSnakeCase } from '../../../utils/names';\nimport {\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { addWorkspaceDependencyToPyProject } from '../../../utils/py';\nimport { injectRdsCaBundleIntoDockerfile } from '../utils';\nimport type { PyRdbAgentConnectionGeneratorSchema } from './schema';\n\nexport const PY_RDB_AGENT_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyRdbAgentConnectionGenerator = async (\n tree: Tree,\n options: PyRdbAgentConnectionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const sourceProject = readProjectConfigurationUnqualified(\n tree,\n options.sourceProject,\n );\n const targetProject = readProjectConfigurationUnqualified(\n tree,\n options.targetProject,\n );\n\n addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);\n\n const agentName = options.sourceComponent?.name ?? 'agent';\n const devTarget = `${agentName}-dev`;\n const agentSourceDir = options.sourceComponent?.path\n ? joinPathFragments(sourceProject.root, options.sourceComponent.path)\n : sourceProject.sourceRoot\n ? joinPathFragments(sourceProject.sourceRoot, toSnakeCase(agentName))\n : undefined;\n const dockerfilePath = agentSourceDir\n ? joinPathFragments(agentSourceDir, 'Dockerfile')\n : undefined;\n\n if (dockerfilePath) {\n injectRdsCaBundleIntoDockerfile(tree, dockerfilePath);\n }\n\n if (sourceProject.targets?.[devTarget]) {\n addDependencyToTargetIfNotPresent(sourceProject, devTarget, {\n projects: [targetProject.name],\n target: 'dev',\n });\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_RDB_AGENT_CONNECTION_GENERATOR_INFO,\n ]);\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbAgentConnectionGenerator;\n"],"names":["joinPathFragments","updateProjectConfiguration","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toSnakeCase","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addWorkspaceDependencyToPyProject","injectRdsCaBundleIntoDockerfile","PY_RDB_AGENT_CONNECTION_GENERATOR_INFO","filename","pyRdbAgentConnectionGenerator","tree","options","sourceProject","targetProject","agentName","sourceComponent","name","devTarget","agentSourceDir","path","root","sourceRoot","undefined","dockerfilePath","targets","projects","target","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAEEA,iBAAiB,EAEjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,QAAQ,0BAAuB;AACnD,SACEC,iCAAiC,EACjCC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,iCAAiC,QAAQ,uBAAoB;AACtE,SAASC,+BAA+B,QAAQ,cAAW;AAG3D,OAAO,MAAMC,yCACXJ,iBAAiB,YAAYK,QAAQ,EAAE;AAEzC,OAAO,MAAMC,gCAAgC,OAC3CC,MACAC;IAEA,MAAMC,gBAAgBR,oCACpBM,MACAC,QAAQC,aAAa;IAEvB,MAAMC,gBAAgBT,oCACpBM,MACAC,QAAQE,aAAa;IAGvBR,kCAAkCK,MAAME,eAAeC;IAEvD,MAAMC,YAAYH,QAAQI,eAAe,EAAEC,QAAQ;IACnD,MAAMC,YAAY,GAAGH,UAAU,IAAI,CAAC;IACpC,MAAMI,iBAAiBP,QAAQI,eAAe,EAAEI,OAC5CvB,kBAAkBgB,cAAcQ,IAAI,EAAET,QAAQI,eAAe,CAACI,IAAI,IAClEP,cAAcS,UAAU,GACtBzB,kBAAkBgB,cAAcS,UAAU,EAAEpB,YAAYa,cACxDQ;IACN,MAAMC,iBAAiBL,iBACnBtB,kBAAkBsB,gBAAgB,gBAClCI;IAEJ,IAAIC,gBAAgB;QAClBjB,gCAAgCI,MAAMa;IACxC;IAEA,IAAIX,cAAcY,OAAO,EAAE,CAACP,UAAU,EAAE;QACtCf,kCAAkCU,eAAeK,WAAW;YAC1DQ,UAAU;gBAACZ,cAAcG,IAAI;aAAC;YAC9BU,QAAQ;QACV;QACA7B,2BAA2Ba,MAAME,cAAcI,IAAI,EAAEJ;IACvD;IAEA,MAAMZ,gCAAgCU,MAAM;QAC1CH;KACD;IACD,MAAMT,qBAAqBY;IAC3B,OAAO,IACLX,oBAAoBW,MAAMC,QAAQgB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;gBAAc;aAAS;QACrC;AACJ,EAAE;AAEF,eAAenB,8BAA8B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/agent-connection/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { ComponentMetadata } from '../../../utils/nx';\n\n/**\n * TypeScript types for options defined in schema.json\n */\nexport interface PyRdbAgentConnectionGeneratorSchema {\n sourceProject: string;\n targetProject: string;\n sourceComponent?: ComponentMetadata;\n preferInstallDependencies?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAGD;;CAEC,GACD,WAKC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { ComponentMetadata } from '../../../utils/nx';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* TypeScript types for options defined in schema.json
|
|
9
|
+
*/
|
|
10
|
+
export interface PyRdbAgentConnectionGeneratorSchema {
|
|
11
|
+
sourceProject: string;
|
|
12
|
+
targetProject: string;
|
|
13
|
+
sourceComponent?: ComponentMetadata;
|
|
14
|
+
preferInstallDependencies?: boolean;
|
|
15
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "py#rdb#agent-connection",
|
|
4
|
+
"title": "py#rdb#agent-connection",
|
|
5
|
+
"description": "Connect a py#agent to a py#rdb project",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"sourceProject": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The project containing the py#agent to connect from"
|
|
11
|
+
},
|
|
12
|
+
"targetProject": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "The py#rdb project to connect to"
|
|
15
|
+
},
|
|
16
|
+
"sourceComponent": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "The agent component name"
|
|
19
|
+
},
|
|
20
|
+
"preferInstallDependencies": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"description": "Whether to prefer installing dependencies after the generator runs. Set to false to defer installing when batching multiple generators (an install still runs if needed so subsequent generators can compute the Nx project graph); install once at the end.",
|
|
23
|
+
"default": true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": ["sourceProject", "targetProject"]
|
|
27
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`py#rdb fast-api-connection generator > should add rdb dev dependency to fast-api dev 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"apiName": "api",
|
|
8
|
+
},
|
|
9
|
+
"name": "api",
|
|
10
|
+
"root": "packages/api",
|
|
11
|
+
"targets": {
|
|
12
|
+
"dev": {
|
|
13
|
+
"continuous": true,
|
|
14
|
+
"dependsOn": [
|
|
15
|
+
{
|
|
16
|
+
"projects": [
|
|
17
|
+
"db",
|
|
18
|
+
],
|
|
19
|
+
"target": "dev",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
"executor": "nx:run-commands",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
exports[`py#rdb fast-api-connection generator > should generate the database session dependency file 1`] = `
|
|
29
|
+
"from collections.abc import AsyncGenerator
|
|
30
|
+
from typing import Annotated
|
|
31
|
+
|
|
32
|
+
from fastapi import Depends
|
|
33
|
+
from proj_db.connection import session_context
|
|
34
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async def get_session() -> AsyncGenerator[AsyncSession]:
|
|
38
|
+
async with session_context() as session:
|
|
39
|
+
yield session
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
DbSession = Annotated[AsyncSession, Depends(get_session)]
|
|
43
|
+
"
|
|
44
|
+
`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from collections.abc import AsyncGenerator
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
from fastapi import Depends
|
|
5
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
6
|
+
|
|
7
|
+
from <%= databasePackageAlias %>.connection import session_context
|
|
8
|
+
|
|
9
|
+
async def get_session() -> AsyncGenerator[AsyncSession]:
|
|
10
|
+
async with session_context() as session:
|
|
11
|
+
yield session
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<%= rdbNameClassName %>Session = Annotated[AsyncSession, Depends(get_session)]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
|
+
import { type NxGeneratorInfo } from '../../../utils/nx';
|
|
7
|
+
import type { PyRdbFastApiConnectionGeneratorSchema } from './schema';
|
|
8
|
+
export declare const PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO: NxGeneratorInfo;
|
|
9
|
+
export declare const pyRdbFastApiConnectionGenerator: (tree: Tree, options: PyRdbFastApiConnectionGeneratorSchema) => Promise<GeneratorCallback>;
|
|
10
|
+
export default pyRdbFastApiConnectionGenerator;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
6
|
+
import { installDependencies } from "../../../utils/install.js";
|
|
7
|
+
import { addGeneratorMetricsIfApplicable } from "../../../utils/metrics.js";
|
|
8
|
+
import { toClassName, toSnakeCase } from "../../../utils/names.js";
|
|
9
|
+
import { getNpmScope } from "../../../utils/npm-scope.js";
|
|
10
|
+
import { addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
|
|
11
|
+
import { addWorkspaceDependencyToPyProject } from "../../../utils/py.js";
|
|
12
|
+
export const PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
13
|
+
export const pyRdbFastApiConnectionGenerator = async (tree, options)=>{
|
|
14
|
+
const sourceProject = readProjectConfigurationUnqualified(tree, options.sourceProject);
|
|
15
|
+
const targetProject = readProjectConfigurationUnqualified(tree, options.targetProject);
|
|
16
|
+
addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);
|
|
17
|
+
if (sourceProject.targets?.['dev']) {
|
|
18
|
+
addDependencyToTargetIfNotPresent(sourceProject, 'dev', {
|
|
19
|
+
projects: [
|
|
20
|
+
targetProject.name
|
|
21
|
+
],
|
|
22
|
+
target: 'dev'
|
|
23
|
+
});
|
|
24
|
+
updateProjectConfiguration(tree, sourceProject.name, sourceProject);
|
|
25
|
+
}
|
|
26
|
+
const scope = toSnakeCase(getNpmScope(tree));
|
|
27
|
+
const rdbLocalName = targetProject.name.split('.').pop();
|
|
28
|
+
const databasePackageAlias = `${scope}_${rdbLocalName}`;
|
|
29
|
+
const rdbNameSnake = toSnakeCase(rdbLocalName);
|
|
30
|
+
const rdbNameClassName = toClassName(rdbLocalName);
|
|
31
|
+
const apiName = sourceProject.metadata?.apiName;
|
|
32
|
+
const apiModuleName = toSnakeCase(`${scope}_${toSnakeCase(apiName)}`);
|
|
33
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files'), sourceProject.root, {
|
|
34
|
+
databasePackageAlias,
|
|
35
|
+
rdbNameSnake,
|
|
36
|
+
rdbNameClassName,
|
|
37
|
+
apiModuleName
|
|
38
|
+
}, {
|
|
39
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
40
|
+
});
|
|
41
|
+
await addGeneratorMetricsIfApplicable(tree, [
|
|
42
|
+
PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO
|
|
43
|
+
]);
|
|
44
|
+
await formatFilesInSubtree(tree);
|
|
45
|
+
return ()=>installDependencies(tree, options.preferInstallDependencies, {
|
|
46
|
+
languages: [
|
|
47
|
+
'typescript',
|
|
48
|
+
'python'
|
|
49
|
+
]
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
export default pyRdbFastApiConnectionGenerator;
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/fast-api-connection/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { installDependencies } from '../../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics';\nimport { toClassName, toSnakeCase } from '../../../utils/names';\nimport { getNpmScope } from '../../../utils/npm-scope';\nimport {\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx';\nimport { addWorkspaceDependencyToPyProject } from '../../../utils/py';\nimport type { PyRdbFastApiConnectionGeneratorSchema } from './schema';\n\nexport const PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const pyRdbFastApiConnectionGenerator = async (\n tree: Tree,\n options: PyRdbFastApiConnectionGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const sourceProject = readProjectConfigurationUnqualified(\n tree,\n options.sourceProject,\n );\n const targetProject = readProjectConfigurationUnqualified(\n tree,\n options.targetProject,\n );\n\n addWorkspaceDependencyToPyProject(tree, sourceProject, targetProject);\n\n if (sourceProject.targets?.['dev']) {\n addDependencyToTargetIfNotPresent(sourceProject, 'dev', {\n projects: [targetProject.name],\n target: 'dev',\n });\n updateProjectConfiguration(tree, sourceProject.name, sourceProject);\n }\n\n const scope = toSnakeCase(getNpmScope(tree));\n const rdbLocalName = targetProject.name.split('.').pop()!;\n const databasePackageAlias = `${scope}_${rdbLocalName}`;\n const rdbNameSnake = toSnakeCase(rdbLocalName);\n const rdbNameClassName = toClassName(rdbLocalName);\n const apiName = (sourceProject.metadata as any)?.apiName as string;\n const apiModuleName = toSnakeCase(`${scope}_${toSnakeCase(apiName)}`);\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n sourceProject.root,\n { databasePackageAlias, rdbNameSnake, rdbNameClassName, apiModuleName },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n await addGeneratorMetricsIfApplicable(tree, [\n PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO,\n ]);\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbFastApiConnectionGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","formatFilesInSubtree","installDependencies","addGeneratorMetricsIfApplicable","toClassName","toSnakeCase","getNpmScope","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","addWorkspaceDependencyToPyProject","PY_RDB_FAST_API_CONNECTION_GENERATOR_INFO","filename","pyRdbFastApiConnectionGenerator","tree","options","sourceProject","targetProject","targets","projects","name","target","scope","rdbLocalName","split","pop","databasePackageAlias","rdbNameSnake","rdbNameClassName","apiName","metadata","apiModuleName","dirname","root","overwriteStrategy","KeepExisting","preferInstallDependencies","languages"],"mappings":"AAAA;;;CAGC,GACD,SAEEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAEjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,mBAAmB,QAAQ,4BAAyB;AAC7D,SAASC,+BAA+B,QAAQ,4BAAyB;AACzE,SAASC,WAAW,EAAEC,WAAW,QAAQ,0BAAuB;AAChE,SAASC,WAAW,QAAQ,8BAA2B;AACvD,SACEC,iCAAiC,EACjCC,gBAAgB,EAEhBC,mCAAmC,QAC9B,uBAAoB;AAC3B,SAASC,iCAAiC,QAAQ,uBAAoB;AAGtE,OAAO,MAAMC,4CACXH,iBAAiB,YAAYI,QAAQ,EAAE;AAEzC,OAAO,MAAMC,kCAAkC,OAC7CC,MACAC;IAEA,MAAMC,gBAAgBP,oCACpBK,MACAC,QAAQC,aAAa;IAEvB,MAAMC,gBAAgBR,oCACpBK,MACAC,QAAQE,aAAa;IAGvBP,kCAAkCI,MAAME,eAAeC;IAEvD,IAAID,cAAcE,OAAO,EAAE,CAAC,MAAM,EAAE;QAClCX,kCAAkCS,eAAe,OAAO;YACtDG,UAAU;gBAACF,cAAcG,IAAI;aAAC;YAC9BC,QAAQ;QACV;QACArB,2BAA2Bc,MAAME,cAAcI,IAAI,EAAEJ;IACvD;IAEA,MAAMM,QAAQjB,YAAYC,YAAYQ;IACtC,MAAMS,eAAeN,cAAcG,IAAI,CAACI,KAAK,CAAC,KAAKC,GAAG;IACtD,MAAMC,uBAAuB,GAAGJ,MAAM,CAAC,EAAEC,cAAc;IACvD,MAAMI,eAAetB,YAAYkB;IACjC,MAAMK,mBAAmBxB,YAAYmB;IACrC,MAAMM,UAAWb,cAAcc,QAAQ,EAAUD;IACjD,MAAME,gBAAgB1B,YAAY,GAAGiB,MAAM,CAAC,EAAEjB,YAAYwB,UAAU;IAEpEhC,cACEiB,MACAhB,kBAAkB,YAAYkC,OAAO,EAAE,UACvChB,cAAciB,IAAI,EAClB;QAAEP;QAAsBC;QAAcC;QAAkBG;IAAc,GACtE;QAAEG,mBAAmBnC,kBAAkBoC,YAAY;IAAC;IAGtD,MAAMhC,gCAAgCW,MAAM;QAC1CH;KACD;IACD,MAAMV,qBAAqBa;IAC3B,OAAO,IACLZ,oBAAoBY,MAAMC,QAAQqB,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;gBAAc;aAAS;QACrC;AACJ,EAAE;AAEF,eAAexB,gCAAgC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/py/rdb/fast-api-connection/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * TypeScript types for options defined in schema.json\n */\nexport interface PyRdbFastApiConnectionGeneratorSchema {\n sourceProject: string;\n targetProject: string;\n preferInstallDependencies?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAED;;CAEC,GACD,WAIC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* TypeScript types for options defined in schema.json
|
|
8
|
+
*/
|
|
9
|
+
export interface PyRdbFastApiConnectionGeneratorSchema {
|
|
10
|
+
sourceProject: string;
|
|
11
|
+
targetProject: string;
|
|
12
|
+
preferInstallDependencies?: boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "py#rdb#fast-api-connection",
|
|
4
|
+
"title": "py#rdb#fast-api-connection",
|
|
5
|
+
"description": "Connect a py#fast-api project to a py#rdb project",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"sourceProject": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The py#fast-api project to connect from"
|
|
11
|
+
},
|
|
12
|
+
"targetProject": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "The py#rdb project to connect to"
|
|
15
|
+
},
|
|
16
|
+
"preferInstallDependencies": {
|
|
17
|
+
"type": "boolean",
|
|
18
|
+
"description": "Whether to prefer installing dependencies after the generator runs. Set to false to defer installing when batching multiple generators (an install still runs if needed so subsequent generators can compute the Nx project graph); install once at the end.",
|
|
19
|
+
"default": true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"required": ["sourceProject", "targetProject"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
FROM public.ecr.aws/lambda/python:3.14
|
|
2
|
+
|
|
3
|
+
WORKDIR ${LAMBDA_TASK_ROOT}
|
|
4
|
+
|
|
5
|
+
COPY . .
|
|
6
|
+
|
|
7
|
+
ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
|
|
8
|
+
RUN update-ca-trust
|
|
9
|
+
|
|
10
|
+
CMD ["<%= name %>.create_db_user_handler.handler"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
FROM public.ecr.aws/lambda/python:3.14
|
|
2
|
+
|
|
3
|
+
WORKDIR ${LAMBDA_TASK_ROOT}
|
|
4
|
+
|
|
5
|
+
COPY . .
|
|
6
|
+
|
|
7
|
+
ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
|
|
8
|
+
RUN update-ca-trust
|
|
9
|
+
|
|
10
|
+
CMD ["<%= name %>.migration_handler.handler"]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from collections.abc import AsyncGenerator
|
|
2
|
+
from contextlib import asynccontextmanager
|
|
3
|
+
import ssl
|
|
4
|
+
|
|
5
|
+
import boto3
|
|
6
|
+
from sqlalchemy import event
|
|
7
|
+
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
8
|
+
|
|
9
|
+
from .utils import build_database_url, get_database_config, get_local_dev_config, is_local_dev
|
|
10
|
+
|
|
11
|
+
# Generated: must match runtimeConfigKey in config.json
|
|
12
|
+
_runtime_config_key = '<%= runtimeConfigKey %>'
|
|
13
|
+
|
|
14
|
+
_engine = None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_engine():
|
|
18
|
+
global _engine
|
|
19
|
+
if _engine is not None:
|
|
20
|
+
return _engine
|
|
21
|
+
if is_local_dev():
|
|
22
|
+
cfg = get_local_dev_config()
|
|
23
|
+
url = build_database_url(cfg['dbUser'], cfg['host'], cfg['port'], cfg['dbName'])
|
|
24
|
+
ssl_args: dict = {}
|
|
25
|
+
else:
|
|
26
|
+
config = get_database_config(_runtime_config_key)
|
|
27
|
+
url = build_database_url(
|
|
28
|
+
config['dbUser'], config['hostname'], config['port'], config['database'],
|
|
29
|
+
)
|
|
30
|
+
ssl_args = {'ssl': ssl.create_default_context()}
|
|
31
|
+
_engine = create_async_engine(url, connect_args=ssl_args)
|
|
32
|
+
|
|
33
|
+
@event.listens_for(_engine.sync_engine, 'do_connect')
|
|
34
|
+
def provide_password(_dialect, _connection_record, _cargs, connection_params):
|
|
35
|
+
if is_local_dev():
|
|
36
|
+
connection_params['password'] = get_local_dev_config()['dbPassword']
|
|
37
|
+
else:
|
|
38
|
+
config = get_database_config(_runtime_config_key)
|
|
39
|
+
connection_params['password'] = boto3.client(
|
|
40
|
+
'rds', region_name=config['region'],
|
|
41
|
+
).generate_db_auth_token(
|
|
42
|
+
DBHostname=config['hostname'],
|
|
43
|
+
Port=config['port'],
|
|
44
|
+
DBUsername=config['dbUser'],
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return _engine
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@asynccontextmanager
|
|
51
|
+
async def session_context() -> AsyncGenerator[AsyncSession]:
|
|
52
|
+
async with AsyncSession(get_engine()) as session:
|
|
53
|
+
yield session
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import secrets
|
|
3
|
+
import ssl
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
<%_ if (engine === 'mysql') { _%>
|
|
7
|
+
import aiomysql
|
|
8
|
+
<%_ } else { _%>
|
|
9
|
+
import asyncpg
|
|
10
|
+
<%_ } _%>
|
|
11
|
+
|
|
12
|
+
from .utils import get_database_secret, with_connection_retry
|
|
13
|
+
|
|
14
|
+
<%_ if (engine === 'mysql') { _%>
|
|
15
|
+
async def _ensure_database_user(db_user: str) -> None:
|
|
16
|
+
secret = get_database_secret()
|
|
17
|
+
conn = await aiomysql.connect(
|
|
18
|
+
host=secret['host'],
|
|
19
|
+
port=int(secret['port']),
|
|
20
|
+
db=secret['dbname'],
|
|
21
|
+
user=secret['username'],
|
|
22
|
+
password=secret['password'],
|
|
23
|
+
ssl=ssl.create_default_context(),
|
|
24
|
+
)
|
|
25
|
+
try:
|
|
26
|
+
async with conn.cursor() as cursor:
|
|
27
|
+
await cursor.execute(
|
|
28
|
+
"CREATE USER IF NOT EXISTS %s@'%%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'",
|
|
29
|
+
(db_user,),
|
|
30
|
+
)
|
|
31
|
+
await cursor.execute(
|
|
32
|
+
"ALTER USER %s@'%%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS' REQUIRE SSL",
|
|
33
|
+
(db_user,),
|
|
34
|
+
)
|
|
35
|
+
await cursor.execute(
|
|
36
|
+
f"GRANT SELECT, INSERT, UPDATE, DELETE ON `{secret['dbname']}`.* TO %s@'%%'",
|
|
37
|
+
(db_user,),
|
|
38
|
+
)
|
|
39
|
+
await conn.commit()
|
|
40
|
+
finally:
|
|
41
|
+
conn.close()
|
|
42
|
+
<%_ } else { _%>
|
|
43
|
+
async def _ensure_database_user(db_user: str) -> None:
|
|
44
|
+
secret = get_database_secret()
|
|
45
|
+
conn = await asyncpg.connect(
|
|
46
|
+
host=secret['host'],
|
|
47
|
+
port=int(secret['port']),
|
|
48
|
+
database=secret['dbname'],
|
|
49
|
+
user=secret['username'],
|
|
50
|
+
password=secret['password'],
|
|
51
|
+
ssl=ssl.create_default_context(),
|
|
52
|
+
)
|
|
53
|
+
try:
|
|
54
|
+
quoted = await conn.fetchrow(
|
|
55
|
+
'SELECT quote_ident($1) AS role_q, quote_ident($2) AS db_q',
|
|
56
|
+
db_user, secret['dbname'],
|
|
57
|
+
)
|
|
58
|
+
role_q, db_q = quoted['role_q'], quoted['db_q']
|
|
59
|
+
row = await conn.fetchrow('SELECT 1 FROM pg_roles WHERE rolname = $1', db_user)
|
|
60
|
+
if row is None:
|
|
61
|
+
await conn.execute(f'CREATE ROLE {role_q} WITH LOGIN')
|
|
62
|
+
await conn.execute(f'''
|
|
63
|
+
ALTER ROLE {role_q} WITH LOGIN;
|
|
64
|
+
GRANT CONNECT ON DATABASE {db_q} TO {role_q};
|
|
65
|
+
GRANT USAGE ON SCHEMA public TO {role_q};
|
|
66
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO {role_q};
|
|
67
|
+
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO {role_q};
|
|
68
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA public
|
|
69
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO {role_q};
|
|
70
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA public
|
|
71
|
+
GRANT USAGE, SELECT ON SEQUENCES TO {role_q};
|
|
72
|
+
GRANT rds_iam TO {role_q};
|
|
73
|
+
''')
|
|
74
|
+
finally:
|
|
75
|
+
await conn.close()
|
|
76
|
+
<%_ } _%>
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
_PHYSICAL_RESOURCE_ID_PREFIX = 'db-user:'
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _resolve_db_user(physical_resource_id: str | None) -> str:
|
|
83
|
+
if physical_resource_id and physical_resource_id.startswith(_PHYSICAL_RESOURCE_ID_PREFIX):
|
|
84
|
+
return physical_resource_id[len(_PHYSICAL_RESOURCE_ID_PREFIX):]
|
|
85
|
+
return f'db_{secrets.token_hex(8)}'
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def handler(event: dict[str, Any], _context: Any) -> dict[str, Any]:
|
|
89
|
+
db_user = _resolve_db_user(event.get('PhysicalResourceId'))
|
|
90
|
+
|
|
91
|
+
if event.get('RequestType') != 'Delete':
|
|
92
|
+
with_connection_retry(lambda: asyncio.run(_ensure_database_user(db_user)))
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
'PhysicalResourceId': f'{_PHYSICAL_RESOURCE_ID_PREFIX}{db_user}',
|
|
96
|
+
'Data': {'dbUser': db_user},
|
|
97
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import ssl
|
|
3
|
+
|
|
4
|
+
from alembic import command
|
|
5
|
+
from alembic.config import Config
|
|
6
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
7
|
+
from sqlalchemy.pool import NullPool
|
|
8
|
+
|
|
9
|
+
from .utils import build_database_url, get_database_secret, with_connection_retry
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _apply_migrations(sync_conn, alembic_cfg: Config) -> None:
|
|
13
|
+
alembic_cfg.attributes['connection'] = sync_conn
|
|
14
|
+
command.upgrade(alembic_cfg, 'head')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def _run_migrations() -> None:
|
|
18
|
+
secret = get_database_secret()
|
|
19
|
+
database_url = build_database_url(
|
|
20
|
+
secret['username'], secret['host'], secret['port'], secret['dbname'],
|
|
21
|
+
password=secret['password'],
|
|
22
|
+
)
|
|
23
|
+
alembic_cfg = Config('alembic.ini')
|
|
24
|
+
engine = create_async_engine(
|
|
25
|
+
database_url, poolclass=NullPool,
|
|
26
|
+
connect_args={'ssl': ssl.create_default_context()},
|
|
27
|
+
)
|
|
28
|
+
try:
|
|
29
|
+
async with engine.begin() as conn:
|
|
30
|
+
await conn.run_sync(lambda c: _apply_migrations(c, alembic_cfg))
|
|
31
|
+
finally:
|
|
32
|
+
await engine.dispose()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def handler(_event, _context):
|
|
36
|
+
with_connection_retry(lambda: asyncio.run(_run_migrations()))
|