@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.
Files changed (195) hide show
  1. package/bin/aws-nx-mcp.js +12317 -10933
  2. package/docs/get_started/building-with-ai.mdx +116 -0
  3. package/docs/get_started/concepts.mdx +67 -0
  4. package/docs/get_started/existing-project.mdx +180 -0
  5. package/docs/get_started/graph-builder.mdx +39 -0
  6. package/docs/get_started/quick-start.mdx +277 -0
  7. package/docs/get_started/tutorials/contribute-generator.mdx +408 -0
  8. package/docs/get_started/tutorials/dungeon-game/1.mdx +1301 -0
  9. package/docs/get_started/tutorials/dungeon-game/2.mdx +237 -0
  10. package/docs/get_started/tutorials/dungeon-game/3.mdx +76 -0
  11. package/docs/get_started/tutorials/dungeon-game/4.mdx +164 -0
  12. package/docs/get_started/tutorials/dungeon-game/overview.mdx +145 -0
  13. package/docs/get_started/tutorials/dungeon-game/wrap-up.mdx +41 -0
  14. package/docs/get_started/tutorials/existing-project.mdx +4 -0
  15. package/docs/get_started/upgrading.mdx +147 -0
  16. package/docs/guides/agentcore-gateway.mdx +490 -0
  17. package/docs/guides/agentcore-harness.mdx +275 -0
  18. package/docs/guides/astro-docs.mdx +8 -0
  19. package/docs/guides/connection/agentcore-gateway-agent.mdx +222 -0
  20. package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
  21. package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
  22. package/docs/guides/connection/py-agent-a2a.mdx +48 -16
  23. package/docs/guides/connection/py-agent-dynamodb.mdx +116 -0
  24. package/docs/guides/connection/py-agent-gateway.mdx +178 -0
  25. package/docs/guides/connection/py-agent-mcp.mdx +43 -14
  26. package/docs/guides/connection/py-agent-rdb.mdx +178 -0
  27. package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
  28. package/docs/guides/connection/py-fast-api-rdb.mdx +184 -0
  29. package/docs/guides/connection/py-mcp-server-dynamodb.mdx +116 -0
  30. package/docs/guides/connection/py-mcp-server-rdb.mdx +187 -0
  31. package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
  32. package/docs/guides/connection/react-agui.mdx +13 -13
  33. package/docs/guides/connection/react-fastapi.mdx +38 -2
  34. package/docs/guides/connection/react-py-agent.mdx +9 -15
  35. package/docs/guides/connection/react-smithy.mdx +3 -3
  36. package/docs/guides/connection/react-trpc.mdx +1 -1
  37. package/docs/guides/connection/react-ts-agent.mdx +8 -8
  38. package/docs/guides/connection/smithy-dynamodb.mdx +5 -5
  39. package/docs/guides/connection/smithy-rdb.mdx +9 -9
  40. package/docs/guides/connection/trpc-dynamodb.mdx +5 -5
  41. package/docs/guides/connection/trpc-rdb.mdx +6 -6
  42. package/docs/guides/connection/ts-agent-a2a.mdx +14 -11
  43. package/docs/guides/connection/ts-agent-dynamodb.mdx +5 -5
  44. package/docs/guides/connection/ts-agent-gateway.mdx +143 -0
  45. package/docs/guides/connection/ts-agent-mcp.mdx +12 -9
  46. package/docs/guides/connection/ts-agent-rdb.mdx +70 -25
  47. package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +5 -5
  48. package/docs/guides/connection/ts-mcp-server-rdb.mdx +68 -18
  49. package/docs/guides/connection.mdx +122 -5
  50. package/docs/guides/docker-bundling.mdx +69 -12
  51. package/docs/guides/fastapi.mdx +249 -9
  52. package/docs/guides/local-development.mdx +87 -0
  53. package/docs/guides/nx-generator.mdx +4 -3
  54. package/docs/guides/nx-migration.mdx +165 -0
  55. package/docs/guides/py-agent.mdx +264 -49
  56. package/docs/guides/py-dynamodb.mdx +476 -0
  57. package/docs/guides/py-mcp-server.mdx +61 -2
  58. package/docs/guides/py-rdb.mdx +265 -0
  59. package/docs/guides/python-lambda-function.mdx +1 -1
  60. package/docs/guides/react-website-auth.mdx +65 -4
  61. package/docs/guides/react-website.mdx +149 -30
  62. package/docs/guides/runtime-config.mdx +1 -1
  63. package/docs/guides/security.mdx +75 -0
  64. package/docs/guides/smithy-project.mdx +167 -0
  65. package/docs/guides/terraform-project.mdx +2 -2
  66. package/docs/guides/trpc.mdx +53 -16
  67. package/docs/guides/ts-agent.mdx +183 -10
  68. package/docs/guides/ts-dcr-proxy.mdx +569 -0
  69. package/docs/guides/ts-dynamodb.mdx +66 -242
  70. package/docs/guides/ts-lambda-function.mdx +1 -1
  71. package/docs/guides/ts-mcp-server.mdx +109 -29
  72. package/docs/guides/ts-nx-plugin.mdx +3 -3
  73. package/docs/guides/ts-rdb.mdx +113 -467
  74. package/docs/guides/ts-smithy-api.mdx +258 -18
  75. package/docs/guides/typescript-infrastructure.mdx +46 -24
  76. package/docs/guides/typescript-project.mdx +134 -27
  77. package/docs/guides/workspace.mdx +10 -3
  78. package/docs/snippets/agent/architecture.mdx +1 -1
  79. package/docs/snippets/agent/bedrock-deployment.mdx +9 -5
  80. package/docs/snippets/agent/runtime-arn.mdx +23 -2
  81. package/docs/snippets/agent/securing-your-agent.mdx +39 -0
  82. package/docs/snippets/api/access-logging.mdx +33 -0
  83. package/docs/snippets/api/cors-configuration-cdk-note.mdx +1 -1
  84. package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
  85. package/docs/snippets/api/type-safe-api-integrations.mdx +33 -2
  86. package/docs/snippets/api/waf-configuration.mdx +3 -3
  87. package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
  88. package/docs/snippets/connection/dynamodb-local-development.mdx +2 -2
  89. package/docs/snippets/connection/lambda-dynamodb-access.mdx +1 -1
  90. package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
  91. package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
  92. package/docs/snippets/connection/rdb-api-infrastructure.mdx +51 -19
  93. package/docs/snippets/dynamodb/deploying-table.mdx +166 -0
  94. package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
  95. package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
  96. package/docs/snippets/dynamodb/local-dev-start.mdx +13 -0
  97. package/docs/snippets/dynamodb/local-dev-windows.mdx +15 -0
  98. package/docs/snippets/lambda-function/deploying-your-function.mdx +3 -3
  99. package/docs/snippets/mcp/architecture.mdx +1 -1
  100. package/docs/snippets/mcp/bedrock-deployment.mdx +9 -5
  101. package/docs/snippets/mcp/config.mdx +3 -2
  102. package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +7 -5
  103. package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +29 -10
  104. package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +4 -4
  105. package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +5 -111
  106. package/docs/snippets/prerequisites.mdx +1 -4
  107. package/docs/snippets/rdb/architecture.mdx +38 -0
  108. package/docs/snippets/rdb/cluster-instances.mdx +31 -0
  109. package/docs/snippets/rdb/deletion-protection.mdx +34 -0
  110. package/docs/snippets/rdb/deploying.mdx +187 -0
  111. package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
  112. package/docs/snippets/rdb/engine-version.mdx +63 -0
  113. package/docs/snippets/rdb/infrastructure.mdx +35 -0
  114. package/docs/snippets/rdb/logging-mysql.mdx +5 -0
  115. package/docs/snippets/rdb/logging-postgres.mdx +5 -0
  116. package/docs/snippets/rdb/performance-insights.mdx +34 -0
  117. package/docs/snippets/rdb/rds-proxy.mdx +50 -0
  118. package/docs/snippets/rdb/removal-policy.mdx +57 -0
  119. package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
  120. package/docs/snippets/recommended-prerequisites.mdx +10 -0
  121. package/docs/snippets/required-prerequisites.mdx +1 -4
  122. package/docs/snippets/runtime-config-app-id-note.mdx +8 -0
  123. package/docs/snippets/shared-constructs.mdx +1 -1
  124. package/docs/snippets/trivy-image-scan.mdx +37 -0
  125. package/generators.json +152 -10
  126. package/package.json +1 -1
  127. package/src/agentcore-gateway/agent-connection/schema.json +31 -0
  128. package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
  129. package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
  130. package/src/agentcore-gateway/react-connection/schema.json +31 -0
  131. package/src/agentcore-gateway/schema.json +72 -0
  132. package/src/agentcore-harness/schema.json +53 -0
  133. package/src/connection/schema.json +5 -0
  134. package/src/infra/app/schema.json +5 -0
  135. package/src/init/schema.json +35 -0
  136. package/src/internal/test-matrix/schema.json +21 -0
  137. package/src/license/schema.json +5 -0
  138. package/src/preset/schema.json +16 -5
  139. package/src/py/agent/a2a-connection/schema.json +5 -0
  140. package/src/py/agent/gateway-connection/schema.json +31 -0
  141. package/src/py/agent/mcp-connection/schema.json +5 -0
  142. package/src/py/agent/react-connection/schema.json +5 -0
  143. package/src/py/agent/schema.json +15 -1
  144. package/src/py/api/schema.json +5 -0
  145. package/src/py/dynamodb/agent-connection/schema.json +27 -0
  146. package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
  147. package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
  148. package/src/py/dynamodb/schema.json +76 -0
  149. package/src/py/fast-api/react/schema.json +5 -0
  150. package/src/py/fast-api/schema.json +6 -0
  151. package/src/py/lambda-function/schema.json +5 -0
  152. package/src/py/mcp-server/schema.json +6 -0
  153. package/src/py/project/schema.json +5 -0
  154. package/src/py/rdb/agent-connection/schema.json +27 -0
  155. package/src/py/rdb/fast-api-connection/schema.json +23 -0
  156. package/src/py/rdb/mcp-server-connection/schema.json +27 -0
  157. package/src/py/rdb/schema.json +78 -0
  158. package/src/smithy/project/schema.json +28 -1
  159. package/src/smithy/react-connection/schema.json +5 -0
  160. package/src/smithy/ts/api/schema.json +6 -0
  161. package/src/terraform/project/schema.json +5 -0
  162. package/src/trpc/backend/schema.json +6 -0
  163. package/src/trpc/react/schema.json +5 -0
  164. package/src/ts/agent/a2a-connection/schema.json +5 -0
  165. package/src/ts/agent/gateway-connection/schema.json +31 -0
  166. package/src/ts/agent/mcp-connection/schema.json +5 -0
  167. package/src/ts/agent/react-connection/schema.json +5 -0
  168. package/src/ts/agent/schema.json +14 -0
  169. package/src/ts/api/schema.json +5 -0
  170. package/src/ts/astro-docs/schema.json +3 -3
  171. package/src/ts/dcr-proxy/schema.json +44 -0
  172. package/src/ts/docs/schema.json +3 -3
  173. package/src/ts/dynamodb/agent-connection/schema.json +5 -0
  174. package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
  175. package/src/ts/dynamodb/schema.json +26 -2
  176. package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
  177. package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
  178. package/src/ts/lambda-function/schema.json +5 -0
  179. package/src/ts/lib/schema.json +5 -0
  180. package/src/ts/mcp-server/schema.json +6 -0
  181. package/src/ts/nx-generator/schema.json +5 -0
  182. package/src/ts/nx-migration/schema.json +63 -0
  183. package/src/ts/nx-plugin/schema.json +5 -0
  184. package/src/ts/rdb/agent-connection/schema.json +5 -0
  185. package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
  186. package/src/ts/rdb/schema.json +7 -1
  187. package/src/ts/rdb/smithy-connection/schema.json +5 -0
  188. package/src/ts/rdb/trpc-connection/schema.json +5 -0
  189. package/src/ts/react-website/app/schema.json +12 -6
  190. package/src/ts/react-website/cognito-auth/schema.json +5 -0
  191. package/src/ts/react-website/runtime-config/schema.json +5 -0
  192. package/src/ts/website/app/schema.json +11 -6
  193. package/src/ts/website/auth/schema.json +5 -0
  194. /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
  195. /package/docs/snippets/connection/{mcp-server-rdb-ssl-requirements.mdx → ts-mcp-server-rdb-ssl-requirements.mdx} +0 -0
@@ -1,13 +1,15 @@
1
1
  ---
2
2
  title: Smithy TypeScript API
3
3
  description: Reference documentation for Smithy TypeScript API
4
- generator: ts#smithy-api
4
+ generator: ts#api
5
5
  when:
6
6
  framework: [smithy]
7
7
  infra: [rest-lambda]
8
8
  ---
9
9
 
10
- import { FileTree } from '@astrojs/starlight/components';
10
+ import { FileTree, CardGrid } from '@astrojs/starlight/components';
11
+ import Astro from '@astrojs/react';
12
+ import ConnectionCard from '@components/connection-card.astro';
11
13
  import Link from '@components/link.astro';
12
14
  import RunGenerator from '@components/run-generator.astro';
13
15
  import GeneratorParameters from '@components/generator-parameters.astro';
@@ -27,11 +29,11 @@ The Smithy TypeScript API generator creates a new API using Smithy for service d
27
29
 
28
30
  You can generate a new Smithy TypeScript API in two ways:
29
31
 
30
- <RunGenerator generator="ts#smithy-api" />
32
+ <RunGenerator generator="ts#api" requiredParameters={{ framework: 'smithy' }} />
31
33
 
32
34
  ### Options
33
35
 
34
- <GeneratorParameters generator="ts#smithy-api" />
36
+ <GeneratorParameters generator="ts#api" />
35
37
 
36
38
  :::tip[Integration Pattern]
37
39
  The `integrationPattern` option defaults to `isolated`, which creates one Lambda per Smithy operation. Select `shared` if you would prefer a single shared Lambda handler for the whole API, with optional per-operation overrides.
@@ -44,9 +46,10 @@ The generator creates two related projects in the `<directory>/<api-name>` direc
44
46
  <FileTree>
45
47
 
46
48
  - **model/** Smithy model project
49
+ - package.json Project manifest defining the project's package name and dependencies
47
50
  - project.json Project configuration and build targets
48
51
  - smithy-build.json Smithy build configuration
49
- - build.Dockerfile Docker configuration for building Smithy artifacts
52
+ - ssdk.rolldown.config.mjs Bundles the generated TypeScript Server SDK
50
53
  - src/
51
54
  - main.smithy Main service definition
52
55
  - operations/
@@ -67,7 +70,7 @@ The generator creates two related projects in the `<directory>/<api-name>` direc
67
70
 
68
71
  ### Infrastructure
69
72
 
70
- Since this generator creates infrastructure as code based on your chosen `iacProvider`, it will create a project in `packages/common` which includes the relevant CDK constructs or Terraform modules.
73
+ Since this generator creates infrastructure as code based on your chosen `iac`, it will create a project in `packages/common` which includes the relevant CDK constructs or Terraform modules.
71
74
 
72
75
  The common infrastructure as code project is structured as follows:
73
76
 
@@ -221,6 +224,31 @@ You can change the folder structure however you like - all `.smithy` files in th
221
224
  For more details on Smithy and its syntax, refer to the [Smithy specification](https://smithy.io/2.0/spec/index.html).
222
225
  :::
223
226
 
227
+ ### Adding a Shape Library
228
+
229
+ If you have several Smithy APIs which share the same data types, you can define those types once in a shape library rather than duplicating them in each model. A shape library is a Smithy project with no service — just reusable shapes — which any number of Smithy projects can depend on.
230
+
231
+ Generate one with the <Link path="guides/smithy-project">`smithy#project`</Link> generator:
232
+
233
+ <RunGenerator generator="smithy#project" requiredParameters={{ name: 'my-shapes', type: 'shapes' }} />
234
+
235
+ Your API's model can then reference its shapes with `use`:
236
+
237
+ ```smithy
238
+ $version: "2.0"
239
+
240
+ namespace com.example.api
241
+
242
+ use com.example.shared#Customer
243
+
244
+ structure GetCustomerOutput {
245
+ @required
246
+ customer: Customer
247
+ }
248
+ ```
249
+
250
+ See the <Link path="guides/smithy-project">Smithy project guide</Link> for how to create a shape library and wire it up as a dependency of your API's model.
251
+
224
252
  ### Implementing Operations in TypeScript
225
253
 
226
254
  Operation implementations are located in the backend project's `src/operations/` directory. Each operation is implemented using the generated types from the TypeScript Server SDK (generated at build time from your Smithy model).
@@ -280,7 +308,7 @@ You must construct the context yourself in both `handler.ts` (the Lambda functio
280
308
 
281
309
  The generator configures structured logging using AWS Lambda Powertools with automatic context injection via Middy middleware.
282
310
 
283
- ```typescript {4}
311
+ ```typescript {3}
284
312
  // handler.ts
285
313
  export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
286
314
  .use(captureLambdaHandler(tracer))
@@ -291,7 +319,7 @@ export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
291
319
 
292
320
  You can reference the logger from your operation implementations via the context:
293
321
 
294
- ```typescript {6}
322
+ ```typescript {5}
295
323
  // operations/echo.ts
296
324
  import { ServiceContext } from '../context.js';
297
325
  import { Echo as EchoOperation } from '../generated/ssdk/index.js';
@@ -306,7 +334,7 @@ export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
306
334
 
307
335
  AWS X-Ray tracing is configured automatically via the `captureLambdaHandler` middleware.
308
336
 
309
- ```typescript {3}
337
+ ```typescript {2}
310
338
  // handler.ts
311
339
  export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
312
340
  .use(captureLambdaHandler(tracer))
@@ -317,7 +345,7 @@ export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
317
345
 
318
346
  You can add custom subsegments to your traces in your operations:
319
347
 
320
- ```typescript {7, 11, 14}
348
+ ```typescript {6, 10, 13}
321
349
  // operations/echo.ts
322
350
  import { ServiceContext } from '../context.js';
323
351
  import { Echo as EchoOperation } from '../generated/ssdk/index.js';
@@ -340,7 +368,7 @@ export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
340
368
 
341
369
  CloudWatch metrics are collected automatically for each request via the `logMetrics` middleware.
342
370
 
343
- ```typescript {5}
371
+ ```typescript {4}
344
372
  // handler.ts
345
373
  export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
346
374
  .use(captureLambdaHandler(tracer))
@@ -351,7 +379,7 @@ export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
351
379
 
352
380
  You can add custom metrics in your operations:
353
381
 
354
- ```typescript {7}
382
+ ```typescript {6}
355
383
  // operations/echo.ts
356
384
  import { MetricUnit } from '@aws-lambda-powertools/metrics';
357
385
  import { ServiceContext } from '../context.js';
@@ -401,12 +429,159 @@ export const MyOperation: MyOperationHandler<ServiceContext> = async (input) =>
401
429
  };
402
430
  ```
403
431
 
432
+ ### Accessing the Calling User
433
+
434
+ When your API is protected by authentication, your operations often need to know who is calling. The recommended approach is to resolve the caller's identity once in the handler and pass it through the [service context](#service-context) for consumption by specific operations.
435
+
436
+ We'll model the unauthorized case as a Smithy error so it serializes to a proper `403` response. Add it to your model, for example in `model/src/operations/errors.smithy`, and reference it on any operation that requires identity:
437
+
438
+ ```smithy
439
+ $version: "2.0"
440
+
441
+ namespace your.namespace
442
+
443
+ /// Thrown when the calling user cannot be determined
444
+ @error("client")
445
+ @httpError(403)
446
+ structure UnauthorizedError {
447
+ @required
448
+ message: String
449
+ }
450
+ ```
451
+
452
+ First, expose the resolved identity on the service context in `src/context.ts`. We provide it as a function so that the `UnauthorizedError` is thrown from within an operation (where the Server SDK serializes it to a `403`), rather than from the handler:
453
+
454
+ ```ts {5-8,17} ins={5-8,17}
455
+ import { Logger } from '@aws-lambda-powertools/logger';
456
+ import { Metrics } from '@aws-lambda-powertools/metrics';
457
+ import { Tracer } from '@aws-lambda-powertools/tracer';
458
+
459
+ export interface Identity {
460
+ sub: string;
461
+ username: string;
462
+ }
463
+
464
+ /**
465
+ * Context provided to all operations.
466
+ */
467
+ export interface ServiceContext {
468
+ tracer: Tracer;
469
+ logger: Logger;
470
+ metrics: Metrics;
471
+ getIdentity: () => Promise<Identity>;
472
+ }
473
+ ```
474
+
475
+ Next, write the resolver in `src/identity.ts`. It throws `UnauthorizedError` when the caller cannot be determined. The implementation depends on your selected `auth` method:
476
+
477
+ <OptionFilter when={{ auth: 'iam' }} description="Identity resolution for IAM-authenticated APIs">
478
+ For `IAM` authentication, we look up the caller in Cognito using the sub extracted from the API Gateway event:
479
+
480
+ ```ts
481
+ import { CognitoIdentityProvider } from '@aws-sdk/client-cognito-identity-provider';
482
+ import type { APIGatewayProxyEvent } from 'aws-lambda';
483
+ import { Identity } from './context.js';
484
+ import { UnauthorizedError } from './generated/ssdk/index.js';
485
+
486
+ const cognito = new CognitoIdentityProvider();
487
+
488
+ export const getIdentity = async (
489
+ event: APIGatewayProxyEvent,
490
+ ): Promise<Identity> => {
491
+ const cognitoAuthenticationProvider =
492
+ event.requestContext?.identity?.cognitoAuthenticationProvider;
493
+
494
+ let sub: string | undefined = undefined;
495
+ if (cognitoAuthenticationProvider) {
496
+ const providerParts = cognitoAuthenticationProvider.split(':');
497
+ sub = providerParts[providerParts.length - 1];
498
+ }
499
+
500
+ if (!sub) {
501
+ throw new UnauthorizedError({ message: 'Unable to determine calling user' });
502
+ }
503
+
504
+ const { Users } = await cognito.listUsers({
505
+ // Assumes user pool id is configured in lambda environment
506
+ UserPoolId: process.env.USER_POOL_ID!,
507
+ Limit: 1,
508
+ Filter: `sub="${sub}"`,
509
+ });
510
+
511
+ if (!Users || Users.length !== 1) {
512
+ throw new UnauthorizedError({ message: `No user found with subjectId ${sub}` });
513
+ }
514
+
515
+ return { sub, username: Users[0].Username! };
516
+ };
517
+ ```
518
+ </OptionFilter>
519
+
520
+ <OptionFilter when={{ auth: 'cognito' }} description="Identity resolution for Cognito-authenticated APIs">
521
+ With `auth: 'cognito'`, the API Gateway Cognito User Pools authorizer verifies the JWT that the caller supplies in the `Authorization` header and places the verified claims on the event at `event.requestContext.authorizer.claims`:
522
+
523
+ ```ts
524
+ import type { APIGatewayProxyEvent } from 'aws-lambda';
525
+ import { Identity } from './context.js';
526
+ import { UnauthorizedError } from './generated/ssdk/index.js';
527
+
528
+ export const getIdentity = async (
529
+ event: APIGatewayProxyEvent,
530
+ ): Promise<Identity> => {
531
+ const claims = event.requestContext?.authorizer?.claims as
532
+ | Record<string, string>
533
+ | undefined;
534
+
535
+ const sub = claims?.sub;
536
+ const username = claims?.username;
537
+
538
+ if (!sub || !username) {
539
+ throw new UnauthorizedError({ message: 'Unable to determine calling user' });
540
+ }
541
+
542
+ return { sub, username };
543
+ };
544
+ ```
545
+
546
+ :::tip[No token verification required]
547
+ You don't need `aws-jwt-verify` or any other JWT-verification library here — the API Gateway Cognito User Pools authorizer has already verified the signature, issuer, scopes, and expiry by the time your Lambda runs. If any of those checks fail, API Gateway returns `401 Unauthorized` and your handler is never invoked.
548
+ :::
549
+ </OptionFilter>
550
+
551
+ Then wire the resolver into the context in `src/handler.ts`:
552
+
553
+ ```ts {2,8} ins={2,8}
554
+ import { Service } from './service.js';
555
+ import { getIdentity } from './identity.js';
556
+ // ...
557
+ const httpResponse = await serviceHandler.handle(httpRequest, {
558
+ tracer,
559
+ logger,
560
+ metrics,
561
+ getIdentity: () => getIdentity(event),
562
+ });
563
+ ```
564
+
565
+ We can now use the resolved identity in an operation, for example in `src/operations/echo.ts`:
566
+
567
+ ```ts
568
+ import { ServiceContext } from '../context.js';
569
+ import { Echo as EchoOperation } from '../generated/ssdk/index.js';
570
+
571
+ export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
572
+ const identity = await ctx.getIdentity();
573
+ return { message: `${identity.username} says ${input.message}` };
574
+ };
575
+ ```
576
+
404
577
  ## Building and Code Generation
405
578
 
406
- The Smithy model project uses [Docker](https://www.docker.com/) to build the Smithy artifacts and generate the TypeScript Server SDK:
579
+ The Smithy model project uses the [Smithy CLI](https://smithy.io/2.0/guides/smithy-cli/index.html) to build the Smithy artifacts and generate the TypeScript Server SDK:
407
580
 
408
581
  <NxCommands commands={['build <model-project>']} />
409
582
 
583
+ On macOS and Linux the CLI is resolved by [mise](https://mise.jdx.dev/), which the build fetches on demand, so there is nothing to install — it downloads and caches the pinned version the first time you build.
584
+
410
585
  This process:
411
586
 
412
587
  1. **Compiles the Smithy model** and validates it
@@ -418,6 +593,39 @@ The backend project automatically copies the generated SDK during compilation:
418
593
 
419
594
  <NxCommands commands={['copy-ssdk <backend-project>']} />
420
595
 
596
+ ### Building on Windows
597
+
598
+ `mise` publishes no Windows package to npm, so on Windows the Smithy CLI is a prerequisite you install yourself. Install it once following the [Smithy CLI installation guide](https://smithy.io/2.0/guides/smithy-cli/cli_installation.html) (for example `winget install smithy` or `scoop install smithy`), and make sure `smithy` is on your `PATH`. A Smithy project generated on Windows runs `smithy` directly rather than through `mise`.
599
+
600
+ :::caution[Upgrading the CLI]
601
+ Because the CLI is installed globally rather than pinned in your workspace, upgrading the workspace with `nx migrate` does **not** upgrade it. When a migration moves the Smithy dependencies forward, upgrade your global Smithy CLI to a matching version yourself.
602
+ :::
603
+
604
+ Alternatively, develop inside [WSL](https://learn.microsoft.com/en-us/windows/wsl/install), where the build runs the Linux path and `mise` resolves the CLI for you — nothing to install.
605
+
606
+ A project generated on Windows commits a `compile` target that invokes `smithy` directly, so anyone else working on it — including on macOS or Linux — needs the Smithy CLI on their `PATH` too. To have those machines resolve the CLI through `mise` instead, switch the target to the `mise` command as [described below](#choosing-how-the-cli-is-resolved).
607
+
608
+ ### Choosing how the CLI is resolved
609
+
610
+ macOS and Linux resolve the CLI through `mise` and Windows uses a globally installed CLI, but you can pick either on any platform by editing the `compile` target's command in the model project's `project.json`.
611
+
612
+ To use a globally installed Smithy CLI instead of `mise`, replace the `mise` prefix with a bare `smithy`:
613
+
614
+ ```json title="project.json" del={5} ins={6}
615
+ {
616
+ "targets": {
617
+ "compile": {
618
+ "options": {
619
+ "commands": ["... npx -y mise@<version> exec smithy@<version> -- smithy build ..."]
620
+ "commands": ["... smithy build ..."]
621
+ }
622
+ }
623
+ }
624
+ }
625
+ ```
626
+
627
+ To go back to `mise` resolving the CLI, restore the `npx -y mise@<version> exec smithy@<version> --` prefix.
628
+
421
629
  ### Bundle Target
422
630
 
423
631
  <Snippet name="ts-bundle" />
@@ -434,14 +642,14 @@ The local server will not only hot-reload when you make TypeScript changes to yo
434
642
 
435
643
  ## Deploying your Smithy API
436
644
 
437
- The generator creates CDK or Terraform infrastructure based on your selected `iacProvider`.
645
+ The generator creates CDK or Terraform infrastructure based on your selected `iac`.
438
646
 
439
647
  <Infrastructure>
440
648
  <Fragment slot="cdk">
441
649
  The CDK construct for deploying your API is in the `common/constructs` folder:
442
650
 
443
651
  ```ts {6-8}
444
- import { MyApi } from ':my-scope/common-constructs';
652
+ import { MyApi } from '@my-scope/common-constructs';
445
653
 
446
654
  export class ExampleStack extends Stack {
447
655
  constructor(scope: Construct, id: string) {
@@ -468,7 +676,7 @@ This sets up:
468
676
  If you selected `Cognito` authentication, you will need to supply the `identity` property to the API construct:
469
677
 
470
678
  ```ts {9}
471
- import { MyApi, UserIdentity } from ':my-scope/common-constructs';
679
+ import { MyApi, UserIdentity } from '@my-scope/common-constructs';
472
680
 
473
681
  export class ExampleStack extends Stack {
474
682
  constructor(scope: Construct, id: string) {
@@ -537,7 +745,7 @@ This sets up:
537
745
  :::note[Cognito Authentication]
538
746
  If you selected `Cognito` authentication, you will need to supply the Cognito configuration:
539
747
 
540
- ```hcl {3, 5-6}
748
+ ```hcl {6-7}
541
749
  module "my_api" {
542
750
  source = "../../common/terraform/src/app/apis/my-api"
543
751
 
@@ -583,6 +791,10 @@ output "lambda_function_name" {
583
791
 
584
792
  <Snippet name="api/waf-configuration" parentHeading="WAF" />
585
793
 
794
+ ### Access logging
795
+
796
+ <Snippet name="api/access-logging" parentHeading="Access logging" />
797
+
586
798
  ### Integrations
587
799
 
588
800
  <Snippet name="api/type-safe-api-integrations" parentHeading="Integrations" />
@@ -614,7 +826,7 @@ If you are actively working on both your CDK infrastructure and Smithy API toget
614
826
  </Fragment>
615
827
  <Fragment slot="terraform">
616
828
  :::note[Terraform Limitations]
617
- We do not support type-safe integrations for Terraform, and therefore no code generation targets are configured if you selected Terraform for your `iacProvider`.
829
+ We do not support type-safe integrations for Terraform, and therefore no code generation targets are configured if you selected Terraform for your `iac`.
618
830
  :::
619
831
  </Fragment>
620
832
  </Infrastructure>
@@ -662,3 +874,31 @@ resource "aws_iam_role_policy_attachment" "api_invoke_access" {
662
874
  ## Invoking your Smithy API
663
875
 
664
876
  To invoke your API from a React website, you can use the <Link path="guides/connection/react-smithy">`connection`</Link> generator, which provides type-safe client generation from your Smithy model.
877
+
878
+ ## Connections
879
+
880
+ Use the <Link path="guides/connection">`connection`</Link> generator to integrate this project with others in your workspace. The following connections involve this project:
881
+
882
+ <CardGrid>
883
+ <ConnectionCard
884
+ title="React to Smithy API"
885
+ description="Call a Smithy API from a React website"
886
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/react-smithy`}
887
+ source="react"
888
+ target="smithy"
889
+ />
890
+ <ConnectionCard
891
+ title="Smithy API to Relational Database"
892
+ description="Connect a Smithy API to an Aurora relational database"
893
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/smithy-rdb`}
894
+ source="smithy"
895
+ target="aurora"
896
+ />
897
+ <ConnectionCard
898
+ title="Smithy API to TypeScript DynamoDB"
899
+ description="Connect a Smithy API to a DynamoDB table"
900
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/smithy-dynamodb`}
901
+ source="smithy"
902
+ target="dynamodb"
903
+ />
904
+ </CardGrid>
@@ -38,12 +38,13 @@ The generator will create the following project structure in the `<directory>/<n
38
38
  - stacks CDK Stack definitions
39
39
  - application-stack.ts Main application stack
40
40
  - cdk.json CDK configuration
41
+ - package.json Project manifest defining the project's package name and dependencies
41
42
  - project.json Project configuration and build targets
42
43
  - checkov.yml Checkov configuration file
43
44
 
44
45
  </FileTree>
45
46
 
46
- If you set the `enableStageConfig` option, the generator also creates two shared packages for centralized credential management (if they don't already exist):
47
+ If you set the `stageConfig` option, the generator also creates two shared packages for centralized credential management (if they don't already exist):
47
48
 
48
49
  <FileTree>
49
50
 
@@ -95,17 +96,22 @@ new ApplicationStage(app, 'my-app-sandbox', {
95
96
  region: process.env.CDK_DEFAULT_REGION,
96
97
  },
97
98
  });
99
+
100
+ // Define other instances of stages, such as beta and prod, below
98
101
  ```
99
102
 
100
103
  The `env` property tells CDK which AWS account and region to deploy to. `CDK_DEFAULT_ACCOUNT` and `CDK_DEFAULT_REGION` are resolved automatically by the CDK CLI from your active AWS credentials. See the [CDK environments documentation](https://docs.aws.amazon.com/cdk/v2/guide/environments.html) for more details.
101
104
 
102
- If you generated with `enableStageConfig`, the `main.ts` reads account and region from a centralized config file instead, falling back to environment variables when no config is set:
105
+ The sandbox stage is the one the <Link path="guides/typescript-infrastructure#deploying-your-sandbox-stage">`deploy-sandbox` target</Link> deploys.
106
+
107
+ If you generated with `stageConfig`, the `main.ts` reads account and region from a centralized config file instead, falling back to environment variables when no config is set:
103
108
 
104
- ```ts title="src/main.ts (with enableStageConfig)"
105
- import stagesConfig from ':my-scope/common-infra-config';
109
+ ```ts title="src/main.ts (with stageConfig)"
110
+ import { resolveStage } from '@my-scope/common-infra-config';
106
111
 
107
- const projectStages = stagesConfig.projects?.['packages/infra']?.stages ?? {};
108
- const sandboxConfig = projectStages['my-app-sandbox'];
112
+ // Looks up the stage under this project (packages/infra), falling back to
113
+ // shared stages. Returns undefined when no config exists for the stage.
114
+ const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
109
115
 
110
116
  new ApplicationStage(app, 'my-app-sandbox', {
111
117
  env: {
@@ -158,12 +164,12 @@ export class ApplicationStage extends Stage {
158
164
  ### Stage Credential Configuration
159
165
 
160
166
  :::note[Staged Configuration]
161
- This section applies when you generate with `enableStageConfig`. Without it, the generator produces a simpler setup where you manage AWS credentials yourself (e.g., by exporting `AWS_PROFILE` before deploying).
167
+ This section applies when you generate with `stageConfig`. Without it, the generator produces a simpler setup where you manage AWS credentials yourself (e.g., by exporting `AWS_PROFILE` before deploying).
162
168
  :::
163
169
 
164
170
  When you have multiple stages targeting different AWS accounts, managing credentials manually can be error-prone, especially as the number of stages grows.
165
171
 
166
- The `enableStageConfig` option solves this by generating two shared packages:
172
+ The `stageConfig` option solves this by generating two shared packages:
167
173
 
168
174
  - **`packages/common/infra-config`** — A single config file where you map each stage to its AWS credentials, account, and region. This is importable from any package in your workspace, so your CDK `main.ts` can read account and region from the same source of truth.
169
175
  - **`packages/common/scripts`** — `infra-deploy` and `infra-destroy` commands that wrap CDK with automatic credential resolution. When you run `deploy`, the script reads the config, sets the right AWS environment variables for the CDK child process, and runs `cdk deploy`. Your shell environment is never modified.
@@ -242,7 +248,7 @@ Each stage config includes a required `region` and an optional `account`:
242
248
  The generated `main.ts` reads these values from the config so that CDK synthesis and deployment use the same environment settings:
243
249
 
244
250
  ```ts title="src/main.ts"
245
- const sandboxConfig = projectStages['my-app-sandbox'];
251
+ const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
246
252
  new ApplicationStage(app, 'my-app-sandbox', {
247
253
  env: {
248
254
  account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
@@ -270,7 +276,7 @@ If, for example, you created a tRPC API called `my-api`, you can simply import a
270
276
  ```ts title="src/stacks/application-stack.ts" {3, 9-12}
271
277
  import { Stack, StackProps } from 'aws-cdk-lib';
272
278
  import { Construct } from 'constructs';
273
- import { MyApi } from ':my-scope/common-constructs';
279
+ import { MyApi } from '@my-scope/common-constructs';
274
280
 
275
281
  export class ApplicationStack extends Stack {
276
282
  constructor(scope: Construct, id: string, props?: StackProps) {
@@ -286,12 +292,12 @@ export class ApplicationStack extends Stack {
286
292
 
287
293
  ### Website Infrastructure
288
294
 
289
- If you have used the <Link path="guides/react-website">CloudScape website</Link> generator, you will notice you already have a construct in `packages/common/constructs` to deploy it. For example:
295
+ If you have used the <Link path="guides/react-website">React Website</Link> generator, you will notice you already have a construct in `packages/common/constructs` to deploy it. For example:
290
296
 
291
297
  ```ts title="src/stacks/application-stack.ts" {3, 9-10}
292
298
  import { Stack, StackProps } from 'aws-cdk-lib';
293
299
  import { Construct } from 'constructs';
294
- import { MyWebsite } from ':my-scope/common-constructs';
300
+ import { MyWebsite } from '@my-scope/common-constructs';
295
301
 
296
302
  export class ApplicationStack extends Stack {
297
303
  constructor(scope: Construct, id: string, props?: StackProps) {
@@ -338,7 +344,7 @@ There may be instances where you want to suppress certain rules on resources. Yo
338
344
  #### Supress a rule on a given construct
339
345
 
340
346
  ```typescript
341
- import { suppressRules } from ':my-scope/common-constructs';
347
+ import { suppressRules } from '@my-scope/common-constructs';
342
348
 
343
349
  // suppresses the CKV_AWS_XXX for the given construct.
344
350
  suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');
@@ -347,7 +353,7 @@ suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');
347
353
  #### Supress a rule on a descendant construct
348
354
 
349
355
  ```typescript
350
- import { suppressRules } from ':my-scope/common-constructs';
356
+ import { suppressRules } from '@my-scope/common-constructs';
351
357
 
352
358
  // Supresses the CKV_AWS_XXX for the construct or any of its descendants if it is an instance of Bucket
353
359
  suppressRules(construct, ['CKV_AWS_XXX'], 'Reason', (construct) => construct instanceof Bucket);
@@ -369,25 +375,41 @@ For more details, please refer to the [CDK bootstrapping documentation](https://
369
375
 
370
376
  ## Deploying to AWS
371
377
 
372
- After a build, you can deploy your infrastructure to AWS using the `deploy` target.
378
+ Your project has three deploy targets, each suited to a different situation:
379
+
380
+ | Target | Use it for |
381
+ | ---------------- | -------------------------------------------------------------------------------- |
382
+ | `deploy-sandbox` | Deploying your own sandbox stage during development. No stage argument needed. |
383
+ | `deploy` | Deploying any stage, by naming the stage or stacks you want. |
384
+ | `deploy-ci` | Deploying from a CI/CD pipeline, using a pre-synthesized cloud assembly. |
385
+
386
+ First, make sure you have AWS credentials configured. If you generated with `stageConfig` and have configured stage credentials in `packages/common/infra-config/src/stages.config.ts`, the deploy command will automatically resolve and apply the correct credentials for the target stage. Otherwise, ensure your AWS credentials are set in your environment (e.g., via `AWS_PROFILE` or environment variables). See the [AWS credentials documentation](https://docs.aws.amazon.com/sdkref/latest/guide/access.html) for the available options.
387
+
388
+ ### Deploying your Sandbox Stage
389
+
390
+ The `deploy-sandbox` target deploys the sandbox stage that `main.ts` declares, so you don't need to remember its stage name:
373
391
 
374
- :::caution[CI Deployment]
375
- Use the `deploy-ci` target if deploying in a CI/CD pipeline. See below for more details.
392
+ <NxCommands commands={['deploy-sandbox <my-infra>']} />
393
+
394
+ This is the quickest way to get your own copy of the application running in AWS while you develop.
395
+
396
+ :::tip[Express Mode for Faster Deployments]
397
+ The deploy targets wait for full resource stabilization by default, favouring consistency over speed. To speed up iteration during development, opt into [CloudFormation express mode](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-express-mode.html) by passing CDK's `--express` flag:
398
+
399
+ <NxCommands commands={['deploy-sandbox <my-infra> --express']} />
400
+
401
+ Express mode finishes once resource configuration is confirmed applied rather than waiting for full stabilization, with propagation continuing in the background, for significantly faster iteration cycles. It is intended for development and iteration.
376
402
  :::
377
403
 
378
- First, make sure you have AWS credentials configured. If you generated with `enableStageConfig` and have configured stage credentials in `packages/common/infra-config/src/stages.config.ts`, the deploy command will automatically resolve and apply the correct credentials for the target stage. Otherwise, ensure your AWS credentials are set in your environment (e.g., via `AWS_PROFILE` or environment variables). See the [AWS credentials documentation](https://docs.aws.amazon.com/sdkref/latest/guide/access.html) for the available options.
404
+ ### Deploying a Specific Stage
379
405
 
380
- Then run the deploy target:
406
+ The `deploy` target deploys whichever stage or stacks you name. Use it for stages other than your sandbox, or to deploy a single stack:
381
407
 
382
408
  <NxCommands commands={['deploy <my-infra> <my-infra>-sandbox/*']} />
383
409
 
384
- :::tip[Selective Stack Deployment]
385
- The above command deploys _all_ stacks for the `<my-infra>-sandbox` stage. You can specify other stages so long as they are defined in `main.ts`.
386
-
387
- You can also deploy individual stacks by specifying the full stack name, for example:
410
+ You can specify any stage so long as it is defined in `main.ts`. To deploy an individual stack, give the full stack name:
388
411
 
389
412
  <NxCommands commands={['deploy <my-infra> <my-infra>-sandbox/Application']} />
390
- :::
391
413
 
392
414
  ## Deploying to AWS in a CI/CD Pipeline
393
415