Skip to content

Commit aad17d9

Browse files
authored
feat(type-safe-api): support documentation generation for websocket apis (#754)
Convert the OpenAPI spec to AsyncAPI, and use AsyncAPI's documentation generators for html and markdown documentation Fixes #742
1 parent 3beec6f commit aad17d9

32 files changed

+21309
-13678
lines changed

.projen/tasks.json

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/pdk/package.json

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/type-safe-api/docs/developer_guides/type-safe-api/websocket_getting_started.md

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The `TypeSafeWebSocketApiProject` projen project sets up the project structure f
1515
- `handlers` - Optionally select the `languages` in which you wish to write lambda handlers for operations in.
1616
- `runtime` - Optionally configure additional generated runtime projects. Include one or more `languages` you want to write your server-side code in. These projects contain generated types defined in your model, as well as type-safe lambda handler wrappers for implementing each operation, and server SDKs for sending messages to connected clients. You'll notice runtime packages are automatically generated for languages you picked for `infrastructure` and `handlers`.
1717
- `library` - Optionally specify additional `libraries` to generate, such as clients or React hooks for use in a React website.
18+
- `documentation` - Optionally specify `formats` to generate documentation in.
1819

1920
## Create your API project
2021

@@ -39,6 +40,7 @@ npx projen new --from @aws/pdk monorepo-ts --package-manager=pnpm
3940
ModelLanguage,
4041
TypeSafeWebSocketApiProject,
4142
WebSocketLibrary,
43+
WebSocketDocumentationFormat,
4244
} from "@aws/pdk/type-safe-api";
4345
import { InfrastructureTsProject } from "@aws/pdk/infrastructure";
4446
import { CloudscapeReactTsWebsiteProject } from "@aws/pdk/cloudscape-react-ts-website";
@@ -82,6 +84,12 @@ npx projen new --from @aws/pdk monorepo-ts --package-manager=pnpm
8284
library: {
8385
libraries: [WebSocketLibrary.TYPESCRIPT_WEBSOCKET_HOOKS],
8486
},
87+
// Generate HTML documentation
88+
documentation: {
89+
formats: [
90+
WebSocketDocumentationFormat.HTML,
91+
],
92+
},
8593
});
8694

8795
// Create a website project, which includes an API explorer which is useful for testing our API

packages/type-safe-api/docs/developer_guides/type-safe-api/websocket_lambda_handlers.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ As well as generating lambda handler stubs, when you use the `@handler` Smithy t
139139
=== "TS"
140140

141141
```ts hl_lines="1 11"
142-
import { Api, SayHelloFunction } from "myapi-typescript-infra";
142+
import { WebSocketApi, SayHelloFunction } from "myapi-typescript-infra";
143143

144144
new WebSocketApi(this, id, {
145145
authorizer: new WebSocketIamAuthorizer(),

packages/type-safe-api/package.json

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/type-safe-api/scripts/type-safe-api/common/common.sh

+22-5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ install_packages() {
3030
3131
3232
@redocly/[email protected] \
33+
@asyncapi/[email protected] \
34+
@asyncapi/[email protected] \
35+
@asyncapi/[email protected] \
3336
3437
@faker-js/[email protected] \
3538
@openapitools/[email protected] \
@@ -40,6 +43,22 @@ install_packages() {
4043
4144
}
4245

46+
##
47+
# runs an install command to install the given packages
48+
run_install_command() {
49+
cmd="$@"
50+
51+
if [ "$pkg_manager" == "pnpm" ]; then
52+
runner="$pkg_manager install --reporter=default"
53+
else
54+
runner="$pkg_manager install"
55+
fi
56+
57+
log "running command $runner $cmd"
58+
59+
$runner $cmd
60+
}
61+
4362
##
4463
# installs the passed packages with the package manager in use
4564
_install_packages() {
@@ -59,6 +78,8 @@ _install_packages() {
5978

6079
# The .committed file contains the identifier of the directory already installed to
6180
_install_dir_identifier=$(cat $_install_packages_committed_file)
81+
82+
log "packages already installed to :: $_install_packages_pdk_base_dir/$_install_dir_identifier"
6283
fi
6384

6485
_install_packages_pdk_dir="$_install_packages_pdk_base_dir/$_install_dir_identifier"
@@ -69,11 +90,7 @@ _install_packages() {
6990
# Install if any packages are missing
7091
if [ "$_install_packages_should_install" == "true" ]; then
7192
npm init --yes
72-
if [ "$pkg_manager" == "pnpm" ]; then
73-
$pkg_manager install --reporter=default "$@"
74-
else
75-
$pkg_manager install "$@"
76-
fi
93+
run_install_command "$@"
7794
fi
7895

7996
# Mark that we have installed the dependencies (if there's a race and we installed multiple times,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Parse arguments
6+
spec_path=''
7+
output_path=''
8+
while [[ "$#" -gt 0 ]]; do case $1 in
9+
--spec-path) spec_path="$2"; shift;;
10+
--output-path) output_path="$2"; shift;;
11+
esac; shift; done
12+
13+
echo "Generating AsyncAPI HTML documentation..."
14+
15+
working_dir=$(pwd)
16+
script_dir="$( cd -- "$(dirname $([ -L "${BASH_SOURCE[0]:-$0}" ] && readlink -f "${BASH_SOURCE[0]:-$0}" || echo "${BASH_SOURCE[0]:-$0}"))" >/dev/null 2>&1 ; pwd -P )";
17+
18+
# load common package manager helper functions
19+
. "$script_dir/../../common/common.sh"
20+
21+
# Create a temporary directory
22+
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp/}generate-docs-async-api-html.XXXXXXXXX")
23+
cd $tmp_dir
24+
25+
log "async-api-html :: tmp_dir :: $tmp_dir"
26+
27+
# Install dependencies
28+
install_packages
29+
30+
# Generate
31+
run_command asyncapi generate fromTemplate "$working_dir/$spec_path" @asyncapi/[email protected] \
32+
--param singleFile=true \
33+
--param outFilename=index.html \
34+
--force-write
35+
36+
# Copy html docs to output path
37+
rm -f $working_dir/$output_path/index.html
38+
cp index.html $working_dir/$output_path/index.html
39+
40+
echo "AsyncAPI HTML documentation generation done!"
41+
42+
# Clean up
43+
cd $working_dir
44+
rm -rf $tmp_dir
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Parse arguments
6+
spec_path=''
7+
output_path=''
8+
while [[ "$#" -gt 0 ]]; do case $1 in
9+
--spec-path) spec_path="$2"; shift;;
10+
--output-path) output_path="$2"; shift;;
11+
esac; shift; done
12+
13+
echo "Generating AsyncAPI Markdown documentation..."
14+
15+
working_dir=$(pwd)
16+
script_dir="$( cd -- "$(dirname $([ -L "${BASH_SOURCE[0]:-$0}" ] && readlink -f "${BASH_SOURCE[0]:-$0}" || echo "${BASH_SOURCE[0]:-$0}"))" >/dev/null 2>&1 ; pwd -P )";
17+
18+
# load common package manager helper functions
19+
. "$script_dir/../../common/common.sh"
20+
21+
# Create a temporary directory
22+
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp/}generate-docs-async-api-markdown.XXXXXXXXX")
23+
cd $tmp_dir
24+
25+
log "async-api-markdown :: tmp_dir :: $tmp_dir"
26+
27+
# Install dependencies
28+
install_packages
29+
30+
# Generate
31+
run_command asyncapi generate fromTemplate "$working_dir/$spec_path" @asyncapi/[email protected] \
32+
--param outFilename=index.md \
33+
--force-write
34+
35+
# Copy markdown docs to output path
36+
rm -f $working_dir/$output_path/index.md
37+
cp index.md $working_dir/$output_path/index.md
38+
39+
echo "AsyncAPI Markdown documentation generation done!"
40+
41+
# Clean up
42+
cd $working_dir
43+
rm -rf $tmp_dir
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Parse arguments
6+
spec_path=''
7+
output_path=''
8+
while [[ "$#" -gt 0 ]]; do case $1 in
9+
--spec-path) spec_path="$2"; shift;;
10+
--output-path) output_path="$2"; shift;;
11+
esac; shift; done
12+
13+
working_dir=$(pwd)
14+
script_dir="$( cd -- "$(dirname $([ -L "${BASH_SOURCE[0]:-$0}" ] && readlink -f "${BASH_SOURCE[0]:-$0}" || echo "${BASH_SOURCE[0]:-$0}"))" >/dev/null 2>&1 ; pwd -P )";
15+
16+
# load common package manager helper functions
17+
. "$script_dir/../../common/common.sh"
18+
19+
# Create a temporary directory
20+
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp/}generate-asyncapi-spec.XXXXXXXXX")
21+
cd $tmp_dir
22+
23+
log "generate-asyncapi-spec :: tmp_dir :: $tmp_dir"
24+
25+
# Copy the parse script into the temp directory
26+
cp -r $script_dir/* .
27+
28+
# Install dependencies
29+
install_packages
30+
31+
# Run the parse script
32+
run_command ts-node generate-asyncapi-spec.ts \
33+
--specPath="$working_dir/$spec_path" \
34+
--outputPath="$working_dir/$output_path"
35+
36+
log "generate-asyncapi-spec :: done"
37+
38+
# Clean up
39+
cd $working_dir
40+
rm -rf $tmp_dir

0 commit comments

Comments
 (0)