From 696d2e1632b25c6c6523041141d28698c27754a4 Mon Sep 17 00:00:00 2001 From: Jack Stevenson Date: Thu, 28 Mar 2024 15:20:09 +1100 Subject: [PATCH] fix(type-safe-api): fix websocket api issues (#738) * fix(type-safe-api): use service namespace in prelude and fix docs * fix(type-safe-api): ensure smithy async transformer jar is included in cache Addresses a bug where the smithy async transformer was not published as part of the release build, since build artifacts were loaded from the cache which didn't include the jar --- .../type-safe-api/getting_started.md | 4 +- .../websocket_getting_started.md | 18 ++-- packages/type-safe-api/project.json | 3 +- .../smithy-aws-pdk-async-prelude.ts | 12 ++- ...pe-safe-websocket-api-project.test.ts.snap | 96 +++++++++---------- ...e-websocket-api-model-project.test.ts.snap | 16 ++-- projenrc/projects/type-safe-api-project.ts | 4 + 7 files changed, 84 insertions(+), 69 deletions(-) diff --git a/packages/type-safe-api/docs/developer_guides/type-safe-api/getting_started.md b/packages/type-safe-api/docs/developer_guides/type-safe-api/getting_started.md index 1bf5f6be3..d4c3a2dc4 100644 --- a/packages/type-safe-api/docs/developer_guides/type-safe-api/getting_started.md +++ b/packages/type-safe-api/docs/developer_guides/type-safe-api/getting_started.md @@ -26,7 +26,7 @@ The `TypeSafeApiProject` projen project sets up the project structure for you. C 1.) To start an empty `monorepo` project, use this command: ```bash -pdk new monorepo-ts +pdk new monorepo-ts --package-manager=pnpm ``` 2.) Edit your `.projenrc` and configure `TypeSafeApiProject`. @@ -47,6 +47,7 @@ pdk new monorepo-ts TypeSafeApiProject, } from "@aws/pdk/type-safe-api"; import { InfrastructureTsProject } from "@aws/pdk/infrastructure"; + import { NodePackageManager } from "projen/lib/javascript"; // Create the monorepo const monorepo = new MonorepoTsProject({ @@ -54,6 +55,7 @@ pdk new monorepo-ts devDeps: [ "@aws/pdk", ], + packageManager: NodePackageManager.PNPM, }); // Create the API project diff --git a/packages/type-safe-api/docs/developer_guides/type-safe-api/websocket_getting_started.md b/packages/type-safe-api/docs/developer_guides/type-safe-api/websocket_getting_started.md index 3bb10a375..6c725c067 100644 --- a/packages/type-safe-api/docs/developer_guides/type-safe-api/websocket_getting_started.md +++ b/packages/type-safe-api/docs/developer_guides/type-safe-api/websocket_getting_started.md @@ -25,7 +25,7 @@ The `TypeSafeWebSocketApiProject` projen project sets up the project structure f 1.) To start an empty `monorepo` project, use this command: ```bash -pdk new monorepo-ts +pdk new monorepo-ts --package-manager=pnpm ``` 2.) Edit your `.projenrc` and configure `TypeSafeWebSocketApiProject`. @@ -35,13 +35,13 @@ pdk new monorepo-ts ```ts import { MonorepoTsProject } from "@aws/pdk/monorepo"; import { - DocumentationFormat, Language, - Library, ModelLanguage, TypeSafeWebSocketApiProject, + WebSocketLibrary, } from "@aws/pdk/type-safe-api"; import { InfrastructureTsProject } from "@aws/pdk/infrastructure"; + import { CloudscapeReactTsWebsiteProject } from "@aws/pdk/cloudscape-react-ts-website"; // Create the monorepo const monorepo = new MonorepoTsProject({ @@ -75,10 +75,10 @@ pdk new monorepo-ts // Lambda handlers in TypeScript handlers: { languages: [Language.TYPESCRIPT], - } + }, // Generate react hooks to interact with the API from a React website library: { - libraries: [Library.TYPESCRIPT_WEBSOCKET_HOOKS], + libraries: [WebSocketLibrary.TYPESCRIPT_WEBSOCKET_HOOKS], }, }); @@ -124,9 +124,11 @@ The generated runtime projects include lambda handler wrappers which provide typ === "SMITHY" + Use the `@async` trait to select the operation direction. Choose between `client_to_server`, `server_to_client` or `bidirectional` + Use the `@handler` trait, and specify the language you wish to implement this operation in. - ```smithy hl_lines="2" + ```smithy hl_lines="1-2" @async(direction: "client_to_server") @handler(language: "typescript") operation SubscribeToNotifications { @@ -143,9 +145,11 @@ The generated runtime projects include lambda handler wrappers which provide typ === "OPENAPI" + Use the `x-async` vendor extension to select the operation direction. Choose between `client_to_server`, `server_to_client` or `bidirectional` + Use the `x-handler` vendor extension, specifying the language you wish to implement this operation in. - ```yaml hl_lines="4-5" + ```yaml hl_lines="4-7" /SubscribeToNotifications: post: operationId: SubscribeToNotifications diff --git a/packages/type-safe-api/project.json b/packages/type-safe-api/project.json index 617b472e8..4f3a09516 100644 --- a/packages/type-safe-api/project.json +++ b/packages/type-safe-api/project.json @@ -19,7 +19,8 @@ "{projectRoot}/dist", "{projectRoot}/coverage", "{projectRoot}/test-reports", - "{projectRoot}/docs/api" + "{projectRoot}/docs/api", + "{projectRoot}/scripts/type-safe-api/custom/smithy-async-transformer/aws-pdk-smithy-async-transformer.jar" ], "dependsOn": [ "^build" diff --git a/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-async-prelude.ts b/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-async-prelude.ts index bf559957b..b04b738b0 100644 --- a/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-async-prelude.ts +++ b/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-async-prelude.ts @@ -54,7 +54,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|${this.options.serviceNamespace}#async]) """ } } @@ -65,7 +65,9 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|${ + this.options.serviceNamespace + }#websocketJson]) """ } } @@ -99,8 +101,10 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|${ + this.options.serviceNamespace + }#async: @{direction} = server_to_client] + [trait|${this.options.serviceNamespace}#handler] """ } } diff --git a/packages/type-safe-api/test/project/__snapshots__/type-safe-websocket-api-project.test.ts.snap b/packages/type-safe-api/test/project/__snapshots__/type-safe-websocket-api-project.test.ts.snap index 968e6d97f..722303bf7 100644 --- a/packages/type-safe-api/test/project/__snapshots__/type-safe-websocket-api-project.test.ts.snap +++ b/packages/type-safe-api/test/project/__snapshots__/type-safe-websocket-api-project.test.ts.snap @@ -7914,7 +7914,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -7925,7 +7925,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -7959,8 +7959,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -11171,7 +11171,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -11182,7 +11182,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -11216,8 +11216,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -13150,7 +13150,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -13161,7 +13161,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -13195,8 +13195,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -16545,7 +16545,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -16556,7 +16556,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -16590,8 +16590,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -18724,7 +18724,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -18735,7 +18735,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -18769,8 +18769,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -22136,7 +22136,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -22147,7 +22147,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -22181,8 +22181,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -24321,7 +24321,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -24332,7 +24332,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -24366,8 +24366,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -27717,7 +27717,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -27728,7 +27728,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -27762,8 +27762,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -29908,7 +29908,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -29919,7 +29919,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -29953,8 +29953,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -33363,7 +33363,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -33374,7 +33374,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -33408,8 +33408,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -35535,7 +35535,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -35546,7 +35546,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -35580,8 +35580,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -38931,7 +38931,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -38942,7 +38942,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -38976,8 +38976,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } diff --git a/packages/type-safe-api/test/project/model/__snapshots__/type-safe-websocket-api-model-project.test.ts.snap b/packages/type-safe-api/test/project/model/__snapshots__/type-safe-websocket-api-model-project.test.ts.snap index 924c80bae..6a942794b 100644 --- a/packages/type-safe-api/test/project/model/__snapshots__/type-safe-websocket-api-model-project.test.ts.snap +++ b/packages/type-safe-api/test/project/model/__snapshots__/type-safe-websocket-api-model-project.test.ts.snap @@ -795,7 +795,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -806,7 +806,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -840,8 +840,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } @@ -1304,7 +1304,7 @@ metadata validators = [ message: "Operation is missing @async trait" configuration: { selector: """ - operation :not([trait|com.aws#async]) + operation :not([trait|com.test#async]) """ } } @@ -1315,7 +1315,7 @@ metadata validators = [ message: "Service is missing @websocketJson trait" configuration: { selector: """ - service :not([trait|com.aws#websocketJson]) + service :not([trait|com.test#websocketJson]) """ } } @@ -1349,8 +1349,8 @@ metadata validators = [ configuration: { selector: """ operation - [@trait|com.aws#async: @{direction} = server_to_client] - [trait|com.aws#handler] + [@trait|com.test#async: @{direction} = server_to_client] + [trait|com.test#handler] """ } } diff --git a/projenrc/projects/type-safe-api-project.ts b/projenrc/projects/type-safe-api-project.ts index 9c066f05e..b94f62198 100644 --- a/projenrc/projects/type-safe-api-project.ts +++ b/projenrc/projects/type-safe-api-project.ts @@ -117,6 +117,10 @@ export class TypeSafeApiProject extends PDKProject { ] )} ${smithyAsyncTransformerJar}` ); + NxProject.of(this)?.addBuildTargetFiles( + [], + [`{projectRoot}/${smithyAsyncTransformerJar}`] + ); this.gitignore.addPatterns(smithyAsyncTransformerJar); this.generateInterfaces();