@aws/nx-plugin-mcp 1.0.0-rc.7 → 1.0.0-rc.71
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/bin/aws-nx-mcp.js +12317 -10933
- package/docs/get_started/building-with-ai.mdx +116 -0
- package/docs/get_started/concepts.mdx +67 -0
- package/docs/get_started/existing-project.mdx +180 -0
- package/docs/get_started/graph-builder.mdx +39 -0
- package/docs/get_started/quick-start.mdx +277 -0
- package/docs/get_started/tutorials/contribute-generator.mdx +408 -0
- package/docs/get_started/tutorials/dungeon-game/1.mdx +1301 -0
- package/docs/get_started/tutorials/dungeon-game/2.mdx +237 -0
- package/docs/get_started/tutorials/dungeon-game/3.mdx +76 -0
- package/docs/get_started/tutorials/dungeon-game/4.mdx +164 -0
- package/docs/get_started/tutorials/dungeon-game/overview.mdx +145 -0
- package/docs/get_started/tutorials/dungeon-game/wrap-up.mdx +41 -0
- package/docs/get_started/tutorials/existing-project.mdx +4 -0
- package/docs/get_started/upgrading.mdx +147 -0
- package/docs/guides/agentcore-gateway.mdx +490 -0
- package/docs/guides/agentcore-harness.mdx +275 -0
- package/docs/guides/astro-docs.mdx +8 -0
- package/docs/guides/connection/agentcore-gateway-agent.mdx +222 -0
- package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
- package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
- package/docs/guides/connection/py-agent-a2a.mdx +48 -16
- package/docs/guides/connection/py-agent-dynamodb.mdx +116 -0
- package/docs/guides/connection/py-agent-gateway.mdx +178 -0
- package/docs/guides/connection/py-agent-mcp.mdx +43 -14
- package/docs/guides/connection/py-agent-rdb.mdx +178 -0
- package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
- package/docs/guides/connection/py-fast-api-rdb.mdx +184 -0
- package/docs/guides/connection/py-mcp-server-dynamodb.mdx +116 -0
- package/docs/guides/connection/py-mcp-server-rdb.mdx +187 -0
- package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
- package/docs/guides/connection/react-agui.mdx +13 -13
- package/docs/guides/connection/react-fastapi.mdx +38 -2
- package/docs/guides/connection/react-py-agent.mdx +9 -15
- package/docs/guides/connection/react-smithy.mdx +3 -3
- package/docs/guides/connection/react-trpc.mdx +1 -1
- package/docs/guides/connection/react-ts-agent.mdx +8 -8
- package/docs/guides/connection/smithy-dynamodb.mdx +5 -5
- package/docs/guides/connection/smithy-rdb.mdx +9 -9
- package/docs/guides/connection/trpc-dynamodb.mdx +5 -5
- package/docs/guides/connection/trpc-rdb.mdx +6 -6
- package/docs/guides/connection/ts-agent-a2a.mdx +14 -11
- package/docs/guides/connection/ts-agent-dynamodb.mdx +5 -5
- package/docs/guides/connection/ts-agent-gateway.mdx +143 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +12 -9
- package/docs/guides/connection/ts-agent-rdb.mdx +70 -25
- package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +5 -5
- package/docs/guides/connection/ts-mcp-server-rdb.mdx +68 -18
- package/docs/guides/connection.mdx +122 -5
- package/docs/guides/docker-bundling.mdx +69 -12
- package/docs/guides/fastapi.mdx +249 -9
- package/docs/guides/local-development.mdx +87 -0
- package/docs/guides/nx-generator.mdx +4 -3
- package/docs/guides/nx-migration.mdx +165 -0
- package/docs/guides/py-agent.mdx +264 -49
- package/docs/guides/py-dynamodb.mdx +476 -0
- package/docs/guides/py-mcp-server.mdx +61 -2
- package/docs/guides/py-rdb.mdx +265 -0
- package/docs/guides/python-lambda-function.mdx +1 -1
- package/docs/guides/react-website-auth.mdx +65 -4
- package/docs/guides/react-website.mdx +149 -30
- package/docs/guides/runtime-config.mdx +1 -1
- package/docs/guides/security.mdx +75 -0
- package/docs/guides/smithy-project.mdx +167 -0
- package/docs/guides/terraform-project.mdx +2 -2
- package/docs/guides/trpc.mdx +53 -16
- package/docs/guides/ts-agent.mdx +183 -10
- package/docs/guides/ts-dcr-proxy.mdx +569 -0
- package/docs/guides/ts-dynamodb.mdx +66 -242
- package/docs/guides/ts-lambda-function.mdx +1 -1
- package/docs/guides/ts-mcp-server.mdx +109 -29
- package/docs/guides/ts-nx-plugin.mdx +3 -3
- package/docs/guides/ts-rdb.mdx +113 -467
- package/docs/guides/ts-smithy-api.mdx +258 -18
- package/docs/guides/typescript-infrastructure.mdx +46 -24
- package/docs/guides/typescript-project.mdx +134 -27
- package/docs/guides/workspace.mdx +10 -3
- package/docs/snippets/agent/architecture.mdx +1 -1
- package/docs/snippets/agent/bedrock-deployment.mdx +9 -5
- package/docs/snippets/agent/runtime-arn.mdx +23 -2
- package/docs/snippets/agent/securing-your-agent.mdx +39 -0
- package/docs/snippets/api/access-logging.mdx +33 -0
- package/docs/snippets/api/cors-configuration-cdk-note.mdx +1 -1
- package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
- package/docs/snippets/api/type-safe-api-integrations.mdx +33 -2
- package/docs/snippets/api/waf-configuration.mdx +3 -3
- package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
- package/docs/snippets/connection/dynamodb-local-development.mdx +2 -2
- package/docs/snippets/connection/lambda-dynamodb-access.mdx +1 -1
- package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
- package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
- package/docs/snippets/connection/rdb-api-infrastructure.mdx +51 -19
- package/docs/snippets/dynamodb/deploying-table.mdx +166 -0
- package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
- package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
- package/docs/snippets/dynamodb/local-dev-start.mdx +13 -0
- package/docs/snippets/dynamodb/local-dev-windows.mdx +15 -0
- package/docs/snippets/lambda-function/deploying-your-function.mdx +3 -3
- package/docs/snippets/mcp/architecture.mdx +1 -1
- package/docs/snippets/mcp/bedrock-deployment.mdx +9 -5
- package/docs/snippets/mcp/config.mdx +3 -2
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +7 -5
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +29 -10
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +4 -4
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +5 -111
- package/docs/snippets/prerequisites.mdx +1 -4
- package/docs/snippets/rdb/architecture.mdx +38 -0
- package/docs/snippets/rdb/cluster-instances.mdx +31 -0
- package/docs/snippets/rdb/deletion-protection.mdx +34 -0
- package/docs/snippets/rdb/deploying.mdx +187 -0
- package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
- package/docs/snippets/rdb/engine-version.mdx +63 -0
- package/docs/snippets/rdb/infrastructure.mdx +35 -0
- package/docs/snippets/rdb/logging-mysql.mdx +5 -0
- package/docs/snippets/rdb/logging-postgres.mdx +5 -0
- package/docs/snippets/rdb/performance-insights.mdx +34 -0
- package/docs/snippets/rdb/rds-proxy.mdx +50 -0
- package/docs/snippets/rdb/removal-policy.mdx +57 -0
- package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
- package/docs/snippets/recommended-prerequisites.mdx +10 -0
- package/docs/snippets/required-prerequisites.mdx +1 -4
- package/docs/snippets/runtime-config-app-id-note.mdx +8 -0
- package/docs/snippets/shared-constructs.mdx +1 -1
- package/docs/snippets/trivy-image-scan.mdx +37 -0
- package/generators.json +152 -10
- package/package.json +1 -1
- package/src/agentcore-gateway/agent-connection/schema.json +31 -0
- package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
- package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
- package/src/agentcore-gateway/react-connection/schema.json +31 -0
- package/src/agentcore-gateway/schema.json +72 -0
- package/src/agentcore-harness/schema.json +53 -0
- package/src/connection/schema.json +5 -0
- package/src/infra/app/schema.json +5 -0
- package/src/init/schema.json +35 -0
- package/src/internal/test-matrix/schema.json +21 -0
- package/src/license/schema.json +5 -0
- package/src/preset/schema.json +16 -5
- package/src/py/agent/a2a-connection/schema.json +5 -0
- package/src/py/agent/gateway-connection/schema.json +31 -0
- package/src/py/agent/mcp-connection/schema.json +5 -0
- package/src/py/agent/react-connection/schema.json +5 -0
- package/src/py/agent/schema.json +15 -1
- package/src/py/api/schema.json +5 -0
- package/src/py/dynamodb/agent-connection/schema.json +27 -0
- package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
- package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
- package/src/py/dynamodb/schema.json +76 -0
- package/src/py/fast-api/react/schema.json +5 -0
- package/src/py/fast-api/schema.json +6 -0
- package/src/py/lambda-function/schema.json +5 -0
- package/src/py/mcp-server/schema.json +6 -0
- package/src/py/project/schema.json +5 -0
- package/src/py/rdb/agent-connection/schema.json +27 -0
- package/src/py/rdb/fast-api-connection/schema.json +23 -0
- package/src/py/rdb/mcp-server-connection/schema.json +27 -0
- package/src/py/rdb/schema.json +78 -0
- package/src/smithy/project/schema.json +28 -1
- package/src/smithy/react-connection/schema.json +5 -0
- package/src/smithy/ts/api/schema.json +6 -0
- package/src/terraform/project/schema.json +5 -0
- package/src/trpc/backend/schema.json +6 -0
- package/src/trpc/react/schema.json +5 -0
- package/src/ts/agent/a2a-connection/schema.json +5 -0
- package/src/ts/agent/gateway-connection/schema.json +31 -0
- package/src/ts/agent/mcp-connection/schema.json +5 -0
- package/src/ts/agent/react-connection/schema.json +5 -0
- package/src/ts/agent/schema.json +14 -0
- package/src/ts/api/schema.json +5 -0
- package/src/ts/astro-docs/schema.json +3 -3
- package/src/ts/dcr-proxy/schema.json +44 -0
- package/src/ts/docs/schema.json +3 -3
- package/src/ts/dynamodb/agent-connection/schema.json +5 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
- package/src/ts/dynamodb/schema.json +26 -2
- package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
- package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
- package/src/ts/lambda-function/schema.json +5 -0
- package/src/ts/lib/schema.json +5 -0
- package/src/ts/mcp-server/schema.json +6 -0
- package/src/ts/nx-generator/schema.json +5 -0
- package/src/ts/nx-migration/schema.json +63 -0
- package/src/ts/nx-plugin/schema.json +5 -0
- package/src/ts/rdb/agent-connection/schema.json +5 -0
- package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
- package/src/ts/rdb/schema.json +7 -1
- package/src/ts/rdb/smithy-connection/schema.json +5 -0
- package/src/ts/rdb/trpc-connection/schema.json +5 -0
- package/src/ts/react-website/app/schema.json +12 -6
- package/src/ts/react-website/cognito-auth/schema.json +5 -0
- package/src/ts/react-website/runtime-config/schema.json +5 -0
- package/src/ts/website/app/schema.json +11 -6
- package/src/ts/website/auth/schema.json +5 -0
- /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
- /package/docs/snippets/connection/{mcp-server-rdb-ssl-requirements.mdx → ts-mcp-server-rdb-ssl-requirements.mdx} +0 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Quick Start Guide
|
|
3
|
+
description: "A quick start on how to use @aws/nx-plugin."
|
|
4
|
+
---
|
|
5
|
+
import { Steps } from '@astrojs/starlight/components';
|
|
6
|
+
import Link from '@components/link.astro';
|
|
7
|
+
import Snippet from '@components/snippet.astro';
|
|
8
|
+
import CreateNxWorkspaceCommand from '@components/create-nx-workspace-command.astro';
|
|
9
|
+
import PackageManagerShortCommand from '@components/package-manager-short-command.astro';
|
|
10
|
+
import InstallCommand from '@components/install-command.astro';
|
|
11
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
12
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
13
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
14
|
+
import EmbeddedGraph from '@components/embedded-graph.astro';
|
|
15
|
+
|
|
16
|
+
This guide walks you through the basics of installing and using `@aws/nx-plugin` to rapidly build projects on AWS.
|
|
17
|
+
|
|
18
|
+
:::tip[Full-Stack Tutorial]
|
|
19
|
+
For a more in-depth tutorial for building a full-stack application, check out the <Link path="get_started/tutorials/dungeon-game/overview">Dungeon Adventure Tutorial</Link>.
|
|
20
|
+
:::
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
The following global dependencies are needed before proceeding:
|
|
25
|
+
|
|
26
|
+
<Snippet name="prerequisites" />
|
|
27
|
+
|
|
28
|
+
## Step 1: Initialize a New Nx Workspace
|
|
29
|
+
|
|
30
|
+
Run the following command to create an <Link path="guides/workspace">Nx workspace</Link> with the package manager of your choice:
|
|
31
|
+
|
|
32
|
+
<CreateNxWorkspaceCommand workspace="my-project" />
|
|
33
|
+
|
|
34
|
+
:::tip[Choosing an IaC Provider]
|
|
35
|
+
You will be prompted for your preferred infrastructure as code (IaC) provider, either [CDK](https://docs.aws.amazon.com/cdk/) or [Terraform](https://developer.hashicorp.com/terraform). You can skip the prompt by running the command with `--iac`, ie:
|
|
36
|
+
|
|
37
|
+
<Infrastructure>
|
|
38
|
+
<Fragment slot="cdk">
|
|
39
|
+
<CreateNxWorkspaceCommand workspace="my-project" iac="cdk" />
|
|
40
|
+
</Fragment>
|
|
41
|
+
<Fragment slot="terraform">
|
|
42
|
+
<CreateNxWorkspaceCommand workspace="my-project" iac="terraform" />
|
|
43
|
+
</Fragment>
|
|
44
|
+
</Infrastructure>
|
|
45
|
+
:::
|
|
46
|
+
|
|
47
|
+
Once complete, navigate to the project directory:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
cd my-project
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Step 2: Use Generators to Scaffold your Project
|
|
54
|
+
|
|
55
|
+
We'll add a tRPC API, React Website, Cognito Authentication, and CDK or Terraform Infrastructure in this quick-start guide. Depending on the type of project you're building, you can choose any combination of generators to quickly bootstrap your project. Check out the __Generators__ in the navigation bar to the left to see the full list of options, or try the <Link path="get_started/graph-builder">graph builder</Link> to construct your workspace visually.
|
|
56
|
+
|
|
57
|
+
As a shortcut, you can use the button below to copy the commands to scaffold the full application.
|
|
58
|
+
|
|
59
|
+
<EmbeddedGraph preset="quick-start" workspace="my-project" iac="cdk" orientation="horizontal" skipWorkspace />
|
|
60
|
+
|
|
61
|
+
:::tip[Build with AI]
|
|
62
|
+
The <Link path="get_started/building-with-ai">Nx Plugin for AWS MCP Server</Link> is already configured in your workspace, so you can ask your favourite AI coding agent like Kiro or Claude to build these projects for you instead of typing the CLI commands yourself.
|
|
63
|
+
:::
|
|
64
|
+
|
|
65
|
+
Otherwise, follow the steps below to run each generator yourself.
|
|
66
|
+
|
|
67
|
+
### Add a tRPC API
|
|
68
|
+
|
|
69
|
+
<RunGenerator generator="ts#api" requiredParameters={{ name: 'demo-api', framework: 'trpc', auth: 'iam' }} noInteractive />
|
|
70
|
+
|
|
71
|
+
This will create the API inside the `packages/demo-api` folder.
|
|
72
|
+
|
|
73
|
+
### Add a React Website
|
|
74
|
+
|
|
75
|
+
<RunGenerator generator="ts#website" requiredParameters={{ name: 'demo-website' }} noInteractive />
|
|
76
|
+
|
|
77
|
+
This scaffolds a new React website in `packages/demo-website`.
|
|
78
|
+
|
|
79
|
+
### Add Cognito Authentication
|
|
80
|
+
|
|
81
|
+
<RunGenerator generator="ts#website#auth" requiredParameters={{ project: '@my-project/demo-website', cognitoDomain: 'my-demo' }} noInteractive />
|
|
82
|
+
|
|
83
|
+
This sets up the necessary infrastructure and React code to add Cognito Authentication to your website.
|
|
84
|
+
|
|
85
|
+
### Connect Frontend to Backend
|
|
86
|
+
|
|
87
|
+
<RunGenerator generator="connection" requiredParameters={{ sourceProject: '@my-project/demo-website', targetProject: '@my-project/demo-api' }} noInteractive />
|
|
88
|
+
|
|
89
|
+
This configures the necessary providers to ensure your website can call your tRPC API.
|
|
90
|
+
|
|
91
|
+
### Add Infrastructure
|
|
92
|
+
|
|
93
|
+
Add the infrastructure project based on your chosen IAC provider.
|
|
94
|
+
|
|
95
|
+
<Infrastructure>
|
|
96
|
+
<Fragment slot="cdk">
|
|
97
|
+
<RunGenerator generator="ts#infra" requiredParameters={{ name: 'infra' }} noInteractive />
|
|
98
|
+
|
|
99
|
+
This configures a CDK App which you can use to deploy your infrastructure on AWS.
|
|
100
|
+
</Fragment>
|
|
101
|
+
<Fragment slot="terraform">
|
|
102
|
+
<RunGenerator generator="terraform#project" requiredParameters={{ name: 'infra' }} noInteractive />
|
|
103
|
+
|
|
104
|
+
This configures a Terraform project which you can use to deploy your infrastructure on AWS.
|
|
105
|
+
</Fragment>
|
|
106
|
+
</Infrastructure>
|
|
107
|
+
|
|
108
|
+
## Step 3: Run your Website and API Locally
|
|
109
|
+
|
|
110
|
+
Use the following command to start local dev servers for your website and its connected APIs:
|
|
111
|
+
|
|
112
|
+
<PackageManagerShortCommand commands={["dev"]} />
|
|
113
|
+
|
|
114
|
+
Your website will be available at `http://localhost:4200`.
|
|
115
|
+
|
|
116
|
+
Changes to both your website and API will be reflected in real-time as both the local website and API servers will hot-reload.
|
|
117
|
+
|
|
118
|
+
## Step 4: Define Cloud Resources and Deploy to AWS
|
|
119
|
+
|
|
120
|
+
<Infrastructure>
|
|
121
|
+
<Fragment slot="cdk">
|
|
122
|
+
Open `packages/infra/src/stacks/application-stack.ts` and add the following code:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { Stack, StackProps } from 'aws-cdk-lib';
|
|
126
|
+
import { DemoApi, DemoWebsite, UserIdentity } from '@my-project/common-constructs';
|
|
127
|
+
import { Construct } from 'constructs';
|
|
128
|
+
|
|
129
|
+
export class ApplicationStack extends Stack {
|
|
130
|
+
constructor(scope: Construct, id: string, props?: StackProps) {
|
|
131
|
+
super(scope, id, props);
|
|
132
|
+
|
|
133
|
+
const identity = new UserIdentity(this, 'identity');
|
|
134
|
+
const api = new DemoApi(this, 'api', {
|
|
135
|
+
integrations: DemoApi.defaultIntegrations(this).build(),
|
|
136
|
+
});
|
|
137
|
+
api.grantInvokeAccess(identity.identityPool.authenticatedRole);
|
|
138
|
+
|
|
139
|
+
new DemoWebsite(this, 'website');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This is all the CDK we need to write to deploy our full stack application.
|
|
145
|
+
</Fragment>
|
|
146
|
+
<Fragment slot="terraform">
|
|
147
|
+
Open `packages/infra/src/main.tf` and add the following code:
|
|
148
|
+
|
|
149
|
+
```hcl
|
|
150
|
+
# Include metrics tracking for @aws/nx-plugin usage
|
|
151
|
+
module "metrics" {
|
|
152
|
+
source = "../../common/terraform/src/metrics"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Deploy user identity
|
|
156
|
+
module "user_identity" {
|
|
157
|
+
source = "../../common/terraform/src/core/user-identity"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# Shared asset bucket — stages Lambda deployment zips for every lambda / API module
|
|
161
|
+
module "asset_bucket" {
|
|
162
|
+
source = "../../common/terraform/src/core/asset-bucket"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# Deploy API
|
|
166
|
+
module "demo_api" {
|
|
167
|
+
source = "../../common/terraform/src/app/apis/demo-api"
|
|
168
|
+
|
|
169
|
+
asset_bucket_name = module.asset_bucket.bucket_name
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# Grant authenticated users access to invoke the API
|
|
173
|
+
resource "aws_iam_policy" "api_invoke_policy" {
|
|
174
|
+
name = "DemoApiInvokePolicy"
|
|
175
|
+
description = "Policy to allow authenticated users to invoke the API"
|
|
176
|
+
|
|
177
|
+
policy = jsonencode({
|
|
178
|
+
Version = "2012-10-17"
|
|
179
|
+
Statement = [
|
|
180
|
+
{
|
|
181
|
+
Effect = "Allow"
|
|
182
|
+
Action = "execute-api:Invoke"
|
|
183
|
+
Resource = "${module.demo_api.api_execution_arn}/*/*"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
resource "aws_iam_role_policy_attachment" "authenticated_api_access" {
|
|
190
|
+
role = module.user_identity.authenticated_role_name
|
|
191
|
+
policy_arn = aws_iam_policy.api_invoke_policy.arn
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# Deploy website
|
|
195
|
+
provider "aws" {
|
|
196
|
+
alias = "us_east_1"
|
|
197
|
+
region = "us-east-1"
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
module "demo_website" {
|
|
201
|
+
source = "../../common/terraform/src/app/static-websites/demo-website"
|
|
202
|
+
|
|
203
|
+
providers = {
|
|
204
|
+
aws.us_east_1 = aws.us_east_1
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
depends_on = [module.user_identity, module.demo_api]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
This is all the Terraform we need to write to deploy our full stack application.
|
|
212
|
+
</Fragment>
|
|
213
|
+
</Infrastructure>
|
|
214
|
+
|
|
215
|
+
### Build and Deploy the Infrastructure
|
|
216
|
+
|
|
217
|
+
Next, run the following command to build your project:
|
|
218
|
+
|
|
219
|
+
<PackageManagerShortCommand commands={["build"]} />
|
|
220
|
+
|
|
221
|
+
:::tip[Fixing Lint Errors]
|
|
222
|
+
If you encounter any lint errors, you can run the following command to automatically fix them.
|
|
223
|
+
|
|
224
|
+
<PackageManagerShortCommand commands={["lint"]} />
|
|
225
|
+
:::
|
|
226
|
+
|
|
227
|
+
Bootstrap your infrastructure:
|
|
228
|
+
|
|
229
|
+
<Infrastructure>
|
|
230
|
+
<Fragment slot="cdk">
|
|
231
|
+
<NxCommands commands={['bootstrap infra']} />
|
|
232
|
+
|
|
233
|
+
:::tip[Bootstrap Regions]
|
|
234
|
+
CDK bootstrapping is required for both your target deployment AWS region, and `us-east-1` to allow deployment of the AWS WAF WebACL for the website.
|
|
235
|
+
:::
|
|
236
|
+
</Fragment>
|
|
237
|
+
<Fragment slot="terraform">
|
|
238
|
+
<NxCommands commands={['bootstrap infra']} />
|
|
239
|
+
|
|
240
|
+
:::tip[One-Time Setup]
|
|
241
|
+
Terraform bootstrapping creates an S3 bucket to store your Terraform state files. This only needs to be done once per AWS account/region combination.
|
|
242
|
+
:::
|
|
243
|
+
</Fragment>
|
|
244
|
+
</Infrastructure>
|
|
245
|
+
|
|
246
|
+
Deploy your project:
|
|
247
|
+
|
|
248
|
+
<Infrastructure>
|
|
249
|
+
<Fragment slot="cdk">
|
|
250
|
+
<NxCommands commands={['deploy-sandbox infra']} />
|
|
251
|
+
</Fragment>
|
|
252
|
+
<Fragment slot="terraform">
|
|
253
|
+
<NxCommands commands={['apply infra']} />
|
|
254
|
+
|
|
255
|
+
:::tip[Plan Before Apply]
|
|
256
|
+
This command will first run `terraform plan` to show you what changes will be made, then apply those changes to deploy your infrastructure.
|
|
257
|
+
:::
|
|
258
|
+
</Fragment>
|
|
259
|
+
</Infrastructure>
|
|
260
|
+
|
|
261
|
+
## Step 5: Test the Website with Deployed Cloud Resources
|
|
262
|
+
|
|
263
|
+
<Steps>
|
|
264
|
+
1. Fetch the `runtime-config.json` file:
|
|
265
|
+
|
|
266
|
+
<NxCommands commands={['load-runtime-config demo-website']} />
|
|
267
|
+
|
|
268
|
+
2. Start the local website server
|
|
269
|
+
|
|
270
|
+
<NxCommands commands={['serve demo-website']} />
|
|
271
|
+
</Steps>
|
|
272
|
+
|
|
273
|
+
Your website will be available at `http://localhost:4200`, and will point to the resources you deployed for the API and authentication.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
Congratulations! 🎉 You have successfully built and deployed a full-stack application using `@aws/nx-plugin`!
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contribute a Generator
|
|
3
|
+
description: A walkthrough of how to build a generator using the @aws/nx-plugin.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
Aside,
|
|
8
|
+
Code,
|
|
9
|
+
FileTree,
|
|
10
|
+
Steps,
|
|
11
|
+
Tabs,
|
|
12
|
+
TabItem,
|
|
13
|
+
} from '@astrojs/starlight/components';
|
|
14
|
+
import { Image } from 'astro:assets';
|
|
15
|
+
import Drawer from '@components/drawer.astro';
|
|
16
|
+
import Link from '@components/link.astro';
|
|
17
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
18
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
19
|
+
import LinkCommand from '@components/link-command.astro';
|
|
20
|
+
import CreateNxWorkspaceCommand from '@components/create-nx-workspace-command.astro';
|
|
21
|
+
import InstallCommand from '@components/install-command.astro';
|
|
22
|
+
import dungeonAdventureArchitecturePng from '@assets/dungeon-game-architecture.png';
|
|
23
|
+
import baselineWebsitePng from '@assets/baseline-website.png';
|
|
24
|
+
import baselineGamePng from '@assets/baseline-game.png';
|
|
25
|
+
import nxGraphPng from '@assets/nx-graph.png';
|
|
26
|
+
import gameSelectPng from '@assets/game-select.png';
|
|
27
|
+
import gameConversationPng from '@assets/game-conversation.png';
|
|
28
|
+
|
|
29
|
+
:::tip[Learning By Example]
|
|
30
|
+
This tutorial guides you through contributing a generator to the Nx Plugin for AWS with a practical example. It can also serve as useful reference for ways to think about and test generators. You can skip to the general guidance section for some top tips for working on generators.
|
|
31
|
+
:::
|
|
32
|
+
|
|
33
|
+
Let's create a new generator to contribute to `@aws/nx-plugin`. Our objective will be to generate a new procedure for a tRPC API.
|
|
34
|
+
|
|
35
|
+
### Check Out the Plugin
|
|
36
|
+
|
|
37
|
+
First, let's clone the plugin:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone git@github.com:awslabs/nx-plugin-for-aws.git
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Next, install and build:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd nx-plugin-for-aws
|
|
47
|
+
pnpm i
|
|
48
|
+
pnpm nx run-many --target build --all
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Create an Empty Generator
|
|
52
|
+
|
|
53
|
+
Let's create the new generator in `packages/nx-plugin/src/trpc/procedure`.
|
|
54
|
+
|
|
55
|
+
We provide a generator for creating new generators so you can quickly scaffold your new generator! You can run this generator as follows:
|
|
56
|
+
|
|
57
|
+
<RunGenerator generator="ts#nx-generator" requiredParameters={{ pluginProject: '@aws/nx-plugin', name: 'ts#trpc-api#procedure', directory: 'trpc/procedure', description: 'Adds a procedure to a tRPC API' }} />
|
|
58
|
+
|
|
59
|
+
You will notice the following files have been generated for you:
|
|
60
|
+
|
|
61
|
+
<FileTree>
|
|
62
|
+
- packages/nx-plugin/src/trpc/procedure
|
|
63
|
+
- schema.json Defines the input for the generator
|
|
64
|
+
- schema.d.ts A typescript interface which matches the schema
|
|
65
|
+
- generator.ts Function which Nx runs as the generator
|
|
66
|
+
- generator.spec.ts Tests for the generator
|
|
67
|
+
- docs/src/content/docs/guides/
|
|
68
|
+
- trpc-procedure.mdx Documentation for the generator
|
|
69
|
+
- packages/nx-plugin/generators.json Updated to include the generator
|
|
70
|
+
</FileTree>
|
|
71
|
+
|
|
72
|
+
Let's update the schema to add the properties we'll need for the generator:
|
|
73
|
+
|
|
74
|
+
<Tabs>
|
|
75
|
+
<TabItem label="schema.json">
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"$schema": "https://json-schema.org/schema",
|
|
79
|
+
"$id": "tRPCProcedure",
|
|
80
|
+
"title": "Adds a procedure to a tRPC API",
|
|
81
|
+
"type": "object",
|
|
82
|
+
"properties": {
|
|
83
|
+
"project": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "tRPC API project",
|
|
86
|
+
"x-prompt": "Select the tRPC API project to add the procedure to",
|
|
87
|
+
"x-dropdown": "projects",
|
|
88
|
+
"x-priority": "important"
|
|
89
|
+
},
|
|
90
|
+
"procedure": {
|
|
91
|
+
"description": "The name of the new procedure",
|
|
92
|
+
"type": "string",
|
|
93
|
+
"x-prompt": "What would you like to call your new procedure?",
|
|
94
|
+
"x-priority": "important",
|
|
95
|
+
},
|
|
96
|
+
"type": {
|
|
97
|
+
"description": "The type of procedure to generate",
|
|
98
|
+
"type": "string",
|
|
99
|
+
"x-prompt": "What type of procedure would you like to generate?",
|
|
100
|
+
"x-priority": "important",
|
|
101
|
+
"default": "query",
|
|
102
|
+
"enum": ["query", "mutation"]
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"required": ["project", "procedure"]
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
</TabItem>
|
|
109
|
+
<TabItem label="schema.d.ts">
|
|
110
|
+
```ts
|
|
111
|
+
export interface TrpcProcedureSchema {
|
|
112
|
+
project: string;
|
|
113
|
+
procedure: string;
|
|
114
|
+
type: 'query' | 'mutation';
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
</TabItem>
|
|
118
|
+
</Tabs>
|
|
119
|
+
|
|
120
|
+
:::note[Virtual File System]
|
|
121
|
+
Notice the generator is given a `Tree` as input, as well as the options we defined in our schema. The `Tree` is essentially a virtual file system which we can read from and write to in order to create or update project files. We don't want to touch the filesystem directly, as we don't want to make any changes if users run the generator in "dry-run" mode.
|
|
122
|
+
:::
|
|
123
|
+
|
|
124
|
+
You will notice the generator has already been hooked up in `packages/nx-plugin/generators.json`:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
...
|
|
128
|
+
"generators": {
|
|
129
|
+
...
|
|
130
|
+
"ts#trpc-api#procedure": {
|
|
131
|
+
"factory": "./src/trpc/procedure/generator",
|
|
132
|
+
"schema": "./src/trpc/procedure/schema.json",
|
|
133
|
+
"description": "Adds a procedure to a tRPC API"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
...
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Implement the Generator
|
|
140
|
+
|
|
141
|
+
To add a procedure to a tRPC API, we need to do two things:
|
|
142
|
+
|
|
143
|
+
1. Create a TypeScript file for the new procedure
|
|
144
|
+
2. Add the procedure to the router
|
|
145
|
+
|
|
146
|
+
#### Create the new Procedure
|
|
147
|
+
|
|
148
|
+
To create the TypeScript file for the new procedure, we'll use a utility called `generateFiles`. Using this, we can define an [EJS](https://ejs.co/) template which we can render in our generator with variables based on the options selected by the user.
|
|
149
|
+
|
|
150
|
+
First, we'll define the template in `packages/nx-plugin/src/trpc/procedure/files/procedures/__procedureNameKebabCase__.ts.template`:
|
|
151
|
+
|
|
152
|
+
```ts title="files/procedures/__procedureNameKebabCase__.ts.template"
|
|
153
|
+
import { publicProcedure } from '../init.js';
|
|
154
|
+
import { z } from 'zod';
|
|
155
|
+
|
|
156
|
+
export const <%- procedureNameCamelCase %> = publicProcedure
|
|
157
|
+
.input(z.object({
|
|
158
|
+
// TODO: define input
|
|
159
|
+
}))
|
|
160
|
+
.output(z.object({
|
|
161
|
+
// TODO: define output
|
|
162
|
+
}))
|
|
163
|
+
.<%- procedureType %>(async ({ input, ctx }) => {
|
|
164
|
+
// TODO: implement!
|
|
165
|
+
return {};
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
:::tip[Template Substitutions]
|
|
170
|
+
When `generateFiles` consumes the template, it will replace references to `__<variable>__` in file/directory names with the values it's provided, as well as stripping the `.template` from the file name.
|
|
171
|
+
|
|
172
|
+
The template content is [EJS](https://ejs.co/), where variables are referenced using the `<% ... %>` syntax.
|
|
173
|
+
:::
|
|
174
|
+
|
|
175
|
+
In the template, we referenced three variables:
|
|
176
|
+
|
|
177
|
+
- `procedureNameCamelCase`
|
|
178
|
+
- `procedureNameKebabCase`
|
|
179
|
+
- `procedureType`
|
|
180
|
+
|
|
181
|
+
So we'll need to make sure we pass those to `generateFiles`, as well as the directory to generate files into, namely the location of source files (i.e. `sourceRoot`) for the tRPC project the user selected as input for the generator, which we can extract from the project configuration.
|
|
182
|
+
|
|
183
|
+
Let's update the generator to do that:
|
|
184
|
+
|
|
185
|
+
```ts title="procedure/generator.ts" {16-30}
|
|
186
|
+
import {
|
|
187
|
+
generateFiles,
|
|
188
|
+
joinPathFragments,
|
|
189
|
+
readProjectConfiguration,
|
|
190
|
+
type Tree,
|
|
191
|
+
} from '@nx/devkit';
|
|
192
|
+
import type { TrpcProcedureSchema } from './schema.js';
|
|
193
|
+
import { formatFilesInSubtree } from '../../utils/format';
|
|
194
|
+
import camelCase from 'lodash.camelcase';
|
|
195
|
+
import kebabCase from 'lodash.kebabcase';
|
|
196
|
+
|
|
197
|
+
export const trpcProcedureGenerator = async (
|
|
198
|
+
tree: Tree,
|
|
199
|
+
options: TrpcProcedureSchema,
|
|
200
|
+
) => {
|
|
201
|
+
const projectConfig = readProjectConfiguration(tree, options.project);
|
|
202
|
+
|
|
203
|
+
const procedureNameCamelCase = camelCase(options.procedure);
|
|
204
|
+
const procedureNameKebabCase = kebabCase(options.procedure);
|
|
205
|
+
|
|
206
|
+
generateFiles(
|
|
207
|
+
tree,
|
|
208
|
+
joinPathFragments(import.meta.dirname, 'files'),
|
|
209
|
+
projectConfig.sourceRoot,
|
|
210
|
+
{
|
|
211
|
+
procedureNameCamelCase,
|
|
212
|
+
procedureNameKebabCase,
|
|
213
|
+
procedureType: options.type,
|
|
214
|
+
},
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
await formatFilesInSubtree(tree);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export default trpcProcedureGenerator;
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
:::tip[File Formatting]
|
|
224
|
+
We also called `formatFilesInSubtree` at the end of the generator, which ensures that any files we create or modify are formatted according to the workspace's [Biome](https://biomejs.dev/) configuration.
|
|
225
|
+
:::
|
|
226
|
+
|
|
227
|
+
#### Add the Procedure to the Router
|
|
228
|
+
|
|
229
|
+
Next, we want the generator to hook up the new procedure to the router. This means reading and updating the user's source code!
|
|
230
|
+
|
|
231
|
+
We use [GritQL](https://docs.grit.io/) to declaratively search and transform source code. The `addDestructuredImport` helper adds named imports, and `applyGritQL` applies a GritQL pattern to add the procedure to the router's object literal.
|
|
232
|
+
|
|
233
|
+
```ts title="procedure/generator.ts" {11, 33-46}
|
|
234
|
+
import {
|
|
235
|
+
generateFiles,
|
|
236
|
+
joinPathFragments,
|
|
237
|
+
readProjectConfiguration,
|
|
238
|
+
type Tree,
|
|
239
|
+
} from '@nx/devkit';
|
|
240
|
+
import type { TrpcProcedureSchema } from './schema.js';
|
|
241
|
+
import { formatFilesInSubtree } from '../../utils/format';
|
|
242
|
+
import camelCase from 'lodash.camelcase';
|
|
243
|
+
import kebabCase from 'lodash.kebabcase';
|
|
244
|
+
import { addDestructuredImport, applyGritQL } from '../../utils/ast';
|
|
245
|
+
|
|
246
|
+
export const trpcProcedureGenerator = async (
|
|
247
|
+
tree: Tree,
|
|
248
|
+
options: TrpcProcedureSchema,
|
|
249
|
+
) => {
|
|
250
|
+
const projectConfig = readProjectConfiguration(tree, options.project);
|
|
251
|
+
|
|
252
|
+
const procedureNameCamelCase = camelCase(options.procedure);
|
|
253
|
+
const procedureNameKebabCase = kebabCase(options.procedure);
|
|
254
|
+
|
|
255
|
+
generateFiles(
|
|
256
|
+
tree,
|
|
257
|
+
joinPathFragments(import.meta.dirname, 'files'),
|
|
258
|
+
projectConfig.sourceRoot,
|
|
259
|
+
{
|
|
260
|
+
procedureNameCamelCase,
|
|
261
|
+
procedureNameKebabCase,
|
|
262
|
+
procedureType: options.type,
|
|
263
|
+
},
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
const routerPath = joinPathFragments(projectConfig.sourceRoot, 'router.ts');
|
|
267
|
+
|
|
268
|
+
await addDestructuredImport(
|
|
269
|
+
tree,
|
|
270
|
+
routerPath,
|
|
271
|
+
[procedureNameCamelCase],
|
|
272
|
+
`./procedures/${procedureNameKebabCase}.js`,
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
await applyGritQL(
|
|
276
|
+
tree,
|
|
277
|
+
routerPath,
|
|
278
|
+
`\`router({ $props })\` => \`router({ $props, ${procedureNameCamelCase} })\` where { $props <: not contains \`${procedureNameCamelCase}\` }`,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
await formatFilesInSubtree(tree);
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
export default trpcProcedureGenerator;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
:::tip[GritQL Patterns]
|
|
288
|
+
In the above code snippet, `applyGritQL` uses a [GritQL](https://docs.grit.io/) pattern to find the `router({ ... })` call and add the new procedure to its object literal. The `where` clause ensures idempotency — if the procedure is already present, no change is made.
|
|
289
|
+
|
|
290
|
+
You can try out GritQL patterns in the [GritQL Playground](https://docs.grit.io/playground), or install the GritQL CLI to test patterns locally:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npm install -g @getgrit/cli
|
|
294
|
+
grit apply '`router({ $props })` => `router({ $props, myProcedure })`' --dry-run
|
|
295
|
+
```
|
|
296
|
+
:::
|
|
297
|
+
|
|
298
|
+
Now that we've implemented the generator, let's compile it to make sure it's available for us to test it out in our dungeon adventure project.
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
pnpm nx compile @aws/nx-plugin
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Testing the Generator
|
|
305
|
+
|
|
306
|
+
To test the generator, we'll link our local Nx Plugin for AWS to an existing codebase.
|
|
307
|
+
|
|
308
|
+
#### Create a Test Project with a tRPC API
|
|
309
|
+
|
|
310
|
+
:::note[Using Your Own Project]
|
|
311
|
+
If you have completed the <Link path="get_started/tutorials/dungeon-game/overview">dungeon adventure tutorial</Link>, or already have another existing Nx workspace which uses a tRPC API, you can skip this step.
|
|
312
|
+
:::
|
|
313
|
+
|
|
314
|
+
In a separate directory, create a new test workspace:
|
|
315
|
+
|
|
316
|
+
<CreateNxWorkspaceCommand workspace="trpc-generator-test" />
|
|
317
|
+
|
|
318
|
+
Next, let's generate a tRPC API to add the procedure to:
|
|
319
|
+
|
|
320
|
+
<RunGenerator generator="ts#api" requiredParameters={{name:"test-api", framework:"trpc"}} noInteractive />
|
|
321
|
+
|
|
322
|
+
#### Link our local Nx Plugin for AWS
|
|
323
|
+
|
|
324
|
+
In your codebase, let's link our local `@aws/nx-plugin`:
|
|
325
|
+
|
|
326
|
+
<LinkCommand
|
|
327
|
+
dependency="@aws/nx-plugin"
|
|
328
|
+
dependencyPath="path/to/nx-plugin-for-aws/dist/packages/nx-plugin"
|
|
329
|
+
projectPath="path/to/trpc-generator-test"
|
|
330
|
+
/>
|
|
331
|
+
|
|
332
|
+
:::note[Compiled Plugin Path]
|
|
333
|
+
Notice above we linked to the compiled plugin in `dist/packages/nx-plugin` rather than the source code.
|
|
334
|
+
:::
|
|
335
|
+
|
|
336
|
+
#### Run the new Generator
|
|
337
|
+
|
|
338
|
+
Let's try the new generator:
|
|
339
|
+
|
|
340
|
+
<RunGenerator generator="ts#trpc-api#procedure" />
|
|
341
|
+
|
|
342
|
+
:::note[Generator Not Showing]
|
|
343
|
+
If you don't see the new generator in the list in VSCode, you might need to refresh the Nx workspace:
|
|
344
|
+
|
|
345
|
+
<NxCommands commands={['reset']} />
|
|
346
|
+
:::
|
|
347
|
+
|
|
348
|
+
If successful, we should have generated a new procedure and added the procedure to our router in `router.ts`.
|
|
349
|
+
|
|
350
|
+
### Exercises
|
|
351
|
+
|
|
352
|
+
If you've got this far and still have some time to experiment with Nx generators, here are some suggestions of features to add to the procedure generator:
|
|
353
|
+
|
|
354
|
+
#### 1. Nested Operations
|
|
355
|
+
|
|
356
|
+
Try updating the generator to support nested routers by:
|
|
357
|
+
|
|
358
|
+
- Accepting dot notation for the `procedure` input (e.g. `games.query`)
|
|
359
|
+
- Generating a procedure with a name based on reversed dot notation (e.g. `queryGames`)
|
|
360
|
+
- Adding the appropriate nested router (or updating it if it already exists!)
|
|
361
|
+
|
|
362
|
+
#### 2. Validation
|
|
363
|
+
|
|
364
|
+
Our generator should defend against potential issues, such as a user selecting a `project` which isn't a tRPC API. Take a look at the `connection` generator for an example of this.
|
|
365
|
+
|
|
366
|
+
#### 3. Unit Tests
|
|
367
|
+
|
|
368
|
+
Write some unit tests for the generator. These are quite straightforward to implement, and most follow the general flow:
|
|
369
|
+
|
|
370
|
+
1. Create an empty workspace tree using `createTreeUsingTsSolutionSetup()`
|
|
371
|
+
2. Add any files that should already exist in the tree (e.g. `project.json` and `src/router.ts` for a tRPC backend)
|
|
372
|
+
3. Run the generator under test
|
|
373
|
+
4. Validate the expected changes are made to the tree
|
|
374
|
+
|
|
375
|
+
#### 4. End to End Tests
|
|
376
|
+
|
|
377
|
+
We have a suite of "smoke tests" which run generators in a fresh workspace and make sure that everything builds. At a minimum, your new generator should be added to **both** generator matrices so that it's exercised by the smoke tests:
|
|
378
|
+
|
|
379
|
+
- `e2e/src/smoke-tests/generator-matrix.ts` — runs each generator through the CLI, one invocation at a time, exactly as a user would.
|
|
380
|
+
- `packages/nx-plugin/src/internal/test-matrix/generator.ts` — a hidden generator which composes all the others for testing migrations between versions.
|
|
381
|
+
|
|
382
|
+
Note that the generator matrix only runs the generators and builds the workspace — it does not instantiate any infrastructure. For generators which deploy infrastructure, consider extending the deployment e2e tests (`e2e/src/smoke-tests/cdk-deploy.spec.ts` and `terraform-deploy.spec.ts`) to actually deploy your resources (via `cdk deploy` / `terraform apply`), then add an assertion to `deploy-invocations.ts` that invokes the deployed resource and verifies it behaves as expected.
|
|
383
|
+
|
|
384
|
+
If your generator vends a local development server, consider adding it to the local development e2e test (`e2e/src/smoke-tests/local-dev.spec.ts`), which starts the `dev` target and exercises the running server.
|
|
385
|
+
|
|
386
|
+
### General Guidance to Accelerate Contributing
|
|
387
|
+
|
|
388
|
+
This section contains some general guidance which can help when working on the Nx Plugin for AWS.
|
|
389
|
+
|
|
390
|
+
#### Work backwards from a real project
|
|
391
|
+
|
|
392
|
+
A useful way to build new generators or add features/fixes to an existing generator is to _build it for real first_. This way you can validate your ideas and iterate quickly to achieve the functionality you need. After you've settled on the desired outcome, you can then update the generator.
|
|
393
|
+
|
|
394
|
+
In practice, this process might look like:
|
|
395
|
+
|
|
396
|
+
<Steps>
|
|
397
|
+
|
|
398
|
+
1. Create a new workspace
|
|
399
|
+
|
|
400
|
+
<CreateNxWorkspaceCommand workspace="my-project" />
|
|
401
|
+
|
|
402
|
+
1. Run any generators that may be prerequisites to your new generator/feature/fix
|
|
403
|
+
1. Commit your changes (`git commit`)
|
|
404
|
+
1. Make your desired changes and test them as needed
|
|
405
|
+
1. Use the `git diff` of your changes to inform what changes should be made to the Nx Plugin for AWS
|
|
406
|
+
1. Perform one final end to end test (linking your `@aws/nx-plugin`) to ensure your generator vends the changes you need
|
|
407
|
+
|
|
408
|
+
</Steps>
|