@aws/nx-plugin-mcp 1.0.0-rc.6 → 1.0.0-rc.60

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 (191) hide show
  1. package/bin/aws-nx-mcp.js +11731 -10471
  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 +266 -0
  7. package/docs/get_started/tutorials/contribute-generator.mdx +408 -0
  8. package/docs/get_started/tutorials/dungeon-game/1.mdx +1210 -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 +162 -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/connection/agentcore-gateway-agent.mdx +222 -0
  18. package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
  19. package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
  20. package/docs/guides/connection/py-agent-a2a.mdx +48 -16
  21. package/docs/guides/connection/py-agent-dynamodb.mdx +116 -0
  22. package/docs/guides/connection/py-agent-gateway.mdx +178 -0
  23. package/docs/guides/connection/py-agent-mcp.mdx +43 -14
  24. package/docs/guides/connection/py-agent-rdb.mdx +178 -0
  25. package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
  26. package/docs/guides/connection/py-fast-api-rdb.mdx +184 -0
  27. package/docs/guides/connection/py-mcp-server-dynamodb.mdx +116 -0
  28. package/docs/guides/connection/py-mcp-server-rdb.mdx +187 -0
  29. package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
  30. package/docs/guides/connection/react-agui.mdx +13 -13
  31. package/docs/guides/connection/react-fastapi.mdx +38 -2
  32. package/docs/guides/connection/react-py-agent.mdx +9 -15
  33. package/docs/guides/connection/react-smithy.mdx +3 -3
  34. package/docs/guides/connection/react-trpc.mdx +1 -1
  35. package/docs/guides/connection/react-ts-agent.mdx +8 -8
  36. package/docs/guides/connection/smithy-dynamodb.mdx +5 -5
  37. package/docs/guides/connection/smithy-rdb.mdx +9 -9
  38. package/docs/guides/connection/trpc-dynamodb.mdx +5 -5
  39. package/docs/guides/connection/trpc-rdb.mdx +6 -6
  40. package/docs/guides/connection/ts-agent-a2a.mdx +14 -11
  41. package/docs/guides/connection/ts-agent-dynamodb.mdx +5 -5
  42. package/docs/guides/connection/ts-agent-gateway.mdx +143 -0
  43. package/docs/guides/connection/ts-agent-mcp.mdx +12 -9
  44. package/docs/guides/connection/ts-agent-rdb.mdx +70 -25
  45. package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +5 -5
  46. package/docs/guides/connection/ts-mcp-server-rdb.mdx +68 -18
  47. package/docs/guides/connection.mdx +122 -5
  48. package/docs/guides/docker-bundling.mdx +68 -11
  49. package/docs/guides/fastapi.mdx +249 -9
  50. package/docs/guides/local-development.mdx +87 -0
  51. package/docs/guides/nx-generator.mdx +7 -2
  52. package/docs/guides/nx-migration.mdx +165 -0
  53. package/docs/guides/py-agent.mdx +264 -49
  54. package/docs/guides/py-dynamodb.mdx +476 -0
  55. package/docs/guides/py-mcp-server.mdx +61 -2
  56. package/docs/guides/py-rdb.mdx +265 -0
  57. package/docs/guides/python-lambda-function.mdx +1 -1
  58. package/docs/guides/react-website-auth.mdx +65 -4
  59. package/docs/guides/react-website.mdx +144 -25
  60. package/docs/guides/runtime-config.mdx +1 -1
  61. package/docs/guides/security.mdx +75 -0
  62. package/docs/guides/smithy-project.mdx +175 -0
  63. package/docs/guides/terraform-project.mdx +2 -2
  64. package/docs/guides/trpc.mdx +53 -16
  65. package/docs/guides/ts-agent.mdx +183 -10
  66. package/docs/guides/ts-dcr-proxy.mdx +569 -0
  67. package/docs/guides/ts-dynamodb.mdx +66 -242
  68. package/docs/guides/ts-lambda-function.mdx +1 -1
  69. package/docs/guides/ts-mcp-server.mdx +109 -29
  70. package/docs/guides/ts-nx-plugin.mdx +3 -3
  71. package/docs/guides/ts-rdb.mdx +113 -467
  72. package/docs/guides/ts-smithy-api.mdx +221 -16
  73. package/docs/guides/typescript-infrastructure.mdx +25 -15
  74. package/docs/guides/typescript-project.mdx +133 -26
  75. package/docs/guides/workspace.mdx +10 -3
  76. package/docs/snippets/agent/architecture.mdx +1 -1
  77. package/docs/snippets/agent/bedrock-deployment.mdx +9 -5
  78. package/docs/snippets/agent/runtime-arn.mdx +23 -2
  79. package/docs/snippets/agent/securing-your-agent.mdx +39 -0
  80. package/docs/snippets/api/access-logging.mdx +33 -0
  81. package/docs/snippets/api/cors-configuration-cdk-note.mdx +1 -1
  82. package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
  83. package/docs/snippets/api/type-safe-api-integrations.mdx +33 -2
  84. package/docs/snippets/api/waf-configuration.mdx +3 -3
  85. package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
  86. package/docs/snippets/connection/dynamodb-local-development.mdx +2 -2
  87. package/docs/snippets/connection/lambda-dynamodb-access.mdx +1 -1
  88. package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
  89. package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
  90. package/docs/snippets/connection/rdb-api-infrastructure.mdx +51 -19
  91. package/docs/snippets/dynamodb/deploying-table.mdx +166 -0
  92. package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
  93. package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
  94. package/docs/snippets/dynamodb/local-dev-start.mdx +13 -0
  95. package/docs/snippets/dynamodb/local-dev-windows.mdx +15 -0
  96. package/docs/snippets/lambda-function/deploying-your-function.mdx +3 -3
  97. package/docs/snippets/mcp/architecture.mdx +1 -1
  98. package/docs/snippets/mcp/bedrock-deployment.mdx +9 -5
  99. package/docs/snippets/mcp/config.mdx +3 -2
  100. package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +7 -5
  101. package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +29 -10
  102. package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +4 -4
  103. package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +5 -111
  104. package/docs/snippets/prerequisites.mdx +2 -1
  105. package/docs/snippets/rdb/architecture.mdx +38 -0
  106. package/docs/snippets/rdb/cluster-instances.mdx +31 -0
  107. package/docs/snippets/rdb/deletion-protection.mdx +34 -0
  108. package/docs/snippets/rdb/deploying.mdx +187 -0
  109. package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
  110. package/docs/snippets/rdb/engine-version.mdx +63 -0
  111. package/docs/snippets/rdb/infrastructure.mdx +35 -0
  112. package/docs/snippets/rdb/logging-mysql.mdx +5 -0
  113. package/docs/snippets/rdb/logging-postgres.mdx +5 -0
  114. package/docs/snippets/rdb/performance-insights.mdx +34 -0
  115. package/docs/snippets/rdb/rds-proxy.mdx +50 -0
  116. package/docs/snippets/rdb/removal-policy.mdx +57 -0
  117. package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
  118. package/docs/snippets/required-prerequisites.mdx +1 -2
  119. package/docs/snippets/runtime-config-app-id-note.mdx +8 -0
  120. package/docs/snippets/shared-constructs.mdx +1 -1
  121. package/docs/snippets/trivy-image-scan.mdx +37 -0
  122. package/generators.json +145 -10
  123. package/package.json +1 -1
  124. package/src/agentcore-gateway/agent-connection/schema.json +31 -0
  125. package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
  126. package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
  127. package/src/agentcore-gateway/react-connection/schema.json +31 -0
  128. package/src/agentcore-gateway/schema.json +72 -0
  129. package/src/connection/schema.json +5 -0
  130. package/src/infra/app/schema.json +5 -0
  131. package/src/init/schema.json +35 -0
  132. package/src/internal/test-matrix/schema.json +21 -0
  133. package/src/license/schema.json +5 -0
  134. package/src/preset/schema.json +16 -5
  135. package/src/py/agent/a2a-connection/schema.json +5 -0
  136. package/src/py/agent/gateway-connection/schema.json +31 -0
  137. package/src/py/agent/mcp-connection/schema.json +5 -0
  138. package/src/py/agent/react-connection/schema.json +5 -0
  139. package/src/py/agent/schema.json +15 -1
  140. package/src/py/api/schema.json +5 -0
  141. package/src/py/dynamodb/agent-connection/schema.json +27 -0
  142. package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
  143. package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
  144. package/src/py/dynamodb/schema.json +76 -0
  145. package/src/py/fast-api/react/schema.json +5 -0
  146. package/src/py/fast-api/schema.json +6 -0
  147. package/src/py/lambda-function/schema.json +5 -0
  148. package/src/py/mcp-server/schema.json +6 -0
  149. package/src/py/project/schema.json +5 -0
  150. package/src/py/rdb/agent-connection/schema.json +27 -0
  151. package/src/py/rdb/fast-api-connection/schema.json +23 -0
  152. package/src/py/rdb/mcp-server-connection/schema.json +27 -0
  153. package/src/py/rdb/schema.json +78 -0
  154. package/src/smithy/project/schema.json +28 -1
  155. package/src/smithy/react-connection/schema.json +5 -0
  156. package/src/smithy/ts/api/schema.json +6 -0
  157. package/src/terraform/project/schema.json +5 -0
  158. package/src/trpc/backend/schema.json +6 -0
  159. package/src/trpc/react/schema.json +5 -0
  160. package/src/ts/agent/a2a-connection/schema.json +5 -0
  161. package/src/ts/agent/gateway-connection/schema.json +31 -0
  162. package/src/ts/agent/mcp-connection/schema.json +5 -0
  163. package/src/ts/agent/react-connection/schema.json +5 -0
  164. package/src/ts/agent/schema.json +14 -0
  165. package/src/ts/api/schema.json +5 -0
  166. package/src/ts/astro-docs/schema.json +3 -3
  167. package/src/ts/dcr-proxy/schema.json +44 -0
  168. package/src/ts/docs/schema.json +3 -3
  169. package/src/ts/dynamodb/agent-connection/schema.json +5 -0
  170. package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
  171. package/src/ts/dynamodb/schema.json +26 -2
  172. package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
  173. package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
  174. package/src/ts/lambda-function/schema.json +5 -0
  175. package/src/ts/lib/schema.json +5 -0
  176. package/src/ts/mcp-server/schema.json +6 -0
  177. package/src/ts/nx-generator/schema.json +5 -0
  178. package/src/ts/nx-migration/schema.json +63 -0
  179. package/src/ts/nx-plugin/schema.json +5 -0
  180. package/src/ts/rdb/agent-connection/schema.json +5 -0
  181. package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
  182. package/src/ts/rdb/schema.json +7 -1
  183. package/src/ts/rdb/smithy-connection/schema.json +5 -0
  184. package/src/ts/rdb/trpc-connection/schema.json +5 -0
  185. package/src/ts/react-website/app/schema.json +12 -6
  186. package/src/ts/react-website/cognito-auth/schema.json +5 -0
  187. package/src/ts/react-website/runtime-config/schema.json +5 -0
  188. package/src/ts/website/app/schema.json +11 -6
  189. package/src/ts/website/auth/schema.json +5 -0
  190. /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
  191. /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,6 +46,7 @@ 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
52
  - build.Dockerfile Docker configuration for building Smithy artifacts
@@ -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,6 +429,151 @@ 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
579
  The Smithy model project uses [Docker](https://www.docker.com/) to build the Smithy artifacts and generate the TypeScript Server SDK:
@@ -434,14 +607,14 @@ The local server will not only hot-reload when you make TypeScript changes to yo
434
607
 
435
608
  ## Deploying your Smithy API
436
609
 
437
- The generator creates CDK or Terraform infrastructure based on your selected `iacProvider`.
610
+ The generator creates CDK or Terraform infrastructure based on your selected `iac`.
438
611
 
439
612
  <Infrastructure>
440
613
  <Fragment slot="cdk">
441
614
  The CDK construct for deploying your API is in the `common/constructs` folder:
442
615
 
443
616
  ```ts {6-8}
444
- import { MyApi } from ':my-scope/common-constructs';
617
+ import { MyApi } from '@my-scope/common-constructs';
445
618
 
446
619
  export class ExampleStack extends Stack {
447
620
  constructor(scope: Construct, id: string) {
@@ -468,7 +641,7 @@ This sets up:
468
641
  If you selected `Cognito` authentication, you will need to supply the `identity` property to the API construct:
469
642
 
470
643
  ```ts {9}
471
- import { MyApi, UserIdentity } from ':my-scope/common-constructs';
644
+ import { MyApi, UserIdentity } from '@my-scope/common-constructs';
472
645
 
473
646
  export class ExampleStack extends Stack {
474
647
  constructor(scope: Construct, id: string) {
@@ -537,7 +710,7 @@ This sets up:
537
710
  :::note[Cognito Authentication]
538
711
  If you selected `Cognito` authentication, you will need to supply the Cognito configuration:
539
712
 
540
- ```hcl {3, 5-6}
713
+ ```hcl {6-7}
541
714
  module "my_api" {
542
715
  source = "../../common/terraform/src/app/apis/my-api"
543
716
 
@@ -583,6 +756,10 @@ output "lambda_function_name" {
583
756
 
584
757
  <Snippet name="api/waf-configuration" parentHeading="WAF" />
585
758
 
759
+ ### Access logging
760
+
761
+ <Snippet name="api/access-logging" parentHeading="Access logging" />
762
+
586
763
  ### Integrations
587
764
 
588
765
  <Snippet name="api/type-safe-api-integrations" parentHeading="Integrations" />
@@ -614,7 +791,7 @@ If you are actively working on both your CDK infrastructure and Smithy API toget
614
791
  </Fragment>
615
792
  <Fragment slot="terraform">
616
793
  :::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`.
794
+ 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
795
  :::
619
796
  </Fragment>
620
797
  </Infrastructure>
@@ -662,3 +839,31 @@ resource "aws_iam_role_policy_attachment" "api_invoke_access" {
662
839
  ## Invoking your Smithy API
663
840
 
664
841
  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.
842
+
843
+ ## Connections
844
+
845
+ Use the <Link path="guides/connection">`connection`</Link> generator to integrate this project with others in your workspace. The following connections involve this project:
846
+
847
+ <CardGrid>
848
+ <ConnectionCard
849
+ title="React to Smithy API"
850
+ description="Call a Smithy API from a React website"
851
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/react-smithy`}
852
+ source="react"
853
+ target="smithy"
854
+ />
855
+ <ConnectionCard
856
+ title="Smithy API to Relational Database"
857
+ description="Connect a Smithy API to an Aurora relational database"
858
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/smithy-rdb`}
859
+ source="smithy"
860
+ target="aurora"
861
+ />
862
+ <ConnectionCard
863
+ title="Smithy API to TypeScript DynamoDB"
864
+ description="Connect a Smithy API to a DynamoDB table"
865
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/smithy-dynamodb`}
866
+ source="smithy"
867
+ target="dynamodb"
868
+ />
869
+ </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
 
@@ -99,13 +100,14 @@ new ApplicationStage(app, 'my-app-sandbox', {
99
100
 
100
101
  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
102
 
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:
103
+ 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
104
 
104
- ```ts title="src/main.ts (with enableStageConfig)"
105
- import stagesConfig from ':my-scope/common-infra-config';
105
+ ```ts title="src/main.ts (with stageConfig)"
106
+ import { resolveStage } from '@my-scope/common-infra-config';
106
107
 
107
- const projectStages = stagesConfig.projects?.['packages/infra']?.stages ?? {};
108
- const sandboxConfig = projectStages['my-app-sandbox'];
108
+ // Looks up the stage under this project (packages/infra), falling back to
109
+ // shared stages. Returns undefined when no config exists for the stage.
110
+ const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
109
111
 
110
112
  new ApplicationStage(app, 'my-app-sandbox', {
111
113
  env: {
@@ -158,12 +160,12 @@ export class ApplicationStage extends Stage {
158
160
  ### Stage Credential Configuration
159
161
 
160
162
  :::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).
163
+ 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
164
  :::
163
165
 
164
166
  When you have multiple stages targeting different AWS accounts, managing credentials manually can be error-prone, especially as the number of stages grows.
165
167
 
166
- The `enableStageConfig` option solves this by generating two shared packages:
168
+ The `stageConfig` option solves this by generating two shared packages:
167
169
 
168
170
  - **`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
171
  - **`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 +244,7 @@ Each stage config includes a required `region` and an optional `account`:
242
244
  The generated `main.ts` reads these values from the config so that CDK synthesis and deployment use the same environment settings:
243
245
 
244
246
  ```ts title="src/main.ts"
245
- const sandboxConfig = projectStages['my-app-sandbox'];
247
+ const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
246
248
  new ApplicationStage(app, 'my-app-sandbox', {
247
249
  env: {
248
250
  account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
@@ -270,7 +272,7 @@ If, for example, you created a tRPC API called `my-api`, you can simply import a
270
272
  ```ts title="src/stacks/application-stack.ts" {3, 9-12}
271
273
  import { Stack, StackProps } from 'aws-cdk-lib';
272
274
  import { Construct } from 'constructs';
273
- import { MyApi } from ':my-scope/common-constructs';
275
+ import { MyApi } from '@my-scope/common-constructs';
274
276
 
275
277
  export class ApplicationStack extends Stack {
276
278
  constructor(scope: Construct, id: string, props?: StackProps) {
@@ -286,12 +288,12 @@ export class ApplicationStack extends Stack {
286
288
 
287
289
  ### Website Infrastructure
288
290
 
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:
291
+ 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
292
 
291
293
  ```ts title="src/stacks/application-stack.ts" {3, 9-10}
292
294
  import { Stack, StackProps } from 'aws-cdk-lib';
293
295
  import { Construct } from 'constructs';
294
- import { MyWebsite } from ':my-scope/common-constructs';
296
+ import { MyWebsite } from '@my-scope/common-constructs';
295
297
 
296
298
  export class ApplicationStack extends Stack {
297
299
  constructor(scope: Construct, id: string, props?: StackProps) {
@@ -338,7 +340,7 @@ There may be instances where you want to suppress certain rules on resources. Yo
338
340
  #### Supress a rule on a given construct
339
341
 
340
342
  ```typescript
341
- import { suppressRules } from ':my-scope/common-constructs';
343
+ import { suppressRules } from '@my-scope/common-constructs';
342
344
 
343
345
  // suppresses the CKV_AWS_XXX for the given construct.
344
346
  suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');
@@ -347,7 +349,7 @@ suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');
347
349
  #### Supress a rule on a descendant construct
348
350
 
349
351
  ```typescript
350
- import { suppressRules } from ':my-scope/common-constructs';
352
+ import { suppressRules } from '@my-scope/common-constructs';
351
353
 
352
354
  // Supresses the CKV_AWS_XXX for the construct or any of its descendants if it is an instance of Bucket
353
355
  suppressRules(construct, ['CKV_AWS_XXX'], 'Reason', (construct) => construct instanceof Bucket);
@@ -375,12 +377,20 @@ After a build, you can deploy your infrastructure to AWS using the `deploy` targ
375
377
  Use the `deploy-ci` target if deploying in a CI/CD pipeline. See below for more details.
376
378
  :::
377
379
 
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.
380
+ 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.
379
381
 
380
382
  Then run the deploy target:
381
383
 
382
384
  <NxCommands commands={['deploy <my-infra> <my-infra>-sandbox/*']} />
383
385
 
386
+ :::tip[Express Mode for Faster Deployments]
387
+ The `deploy` target waits 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:
388
+
389
+ <NxCommands commands={['deploy <my-infra> <my-infra>-sandbox/* --express']} />
390
+
391
+ 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.
392
+ :::
393
+
384
394
  :::tip[Selective Stack Deployment]
385
395
  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
396