Skip to content

Commit

Permalink
feat(type-safe-api): support documentation generation for websocket apis
Browse files Browse the repository at this point in the history
Convert the OpenAPI spec to AsyncAPI, and use AsyncAPI's documentation generators for html and
markdown documentation

Fixes #742
  • Loading branch information
cogwirrel committed Apr 9, 2024
1 parent 3beec6f commit fa325f3
Show file tree
Hide file tree
Showing 32 changed files with 21,916 additions and 14,709 deletions.
9 changes: 9 additions & 0 deletions .projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion packages/pdk/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The `TypeSafeWebSocketApiProject` projen project sets up the project structure f
- `handlers` - Optionally select the `languages` in which you wish to write lambda handlers for operations in.
- `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`.
- `library` - Optionally specify additional `libraries` to generate, such as clients or React hooks for use in a React website.
- `documentation` - Optionally specify `formats` to generate documentation in.

## Create your API project

Expand All @@ -39,6 +40,7 @@ npx projen new --from @aws/pdk monorepo-ts --package-manager=pnpm
ModelLanguage,
TypeSafeWebSocketApiProject,
WebSocketLibrary,
WebSocketDocumentationFormat,
} from "@aws/pdk/type-safe-api";
import { InfrastructureTsProject } from "@aws/pdk/infrastructure";
import { CloudscapeReactTsWebsiteProject } from "@aws/pdk/cloudscape-react-ts-website";
Expand Down Expand Up @@ -82,6 +84,12 @@ npx projen new --from @aws/pdk monorepo-ts --package-manager=pnpm
library: {
libraries: [WebSocketLibrary.TYPESCRIPT_WEBSOCKET_HOOKS],
},
// Generate HTML documentation
documentation: {
formats: [
WebSocketDocumentationFormat.HTML,
],
},
});

// Create a website project, which includes an API explorer which is useful for testing our API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ As well as generating lambda handler stubs, when you use the `@handler` Smithy t
=== "TS"

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

new WebSocketApi(this, id, {
authorizer: new WebSocketIamAuthorizer(),
Expand Down
8 changes: 7 additions & 1 deletion packages/type-safe-api/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 22 additions & 5 deletions packages/type-safe-api/scripts/type-safe-api/common/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ install_packages() {
[email protected] \
[email protected] \
@redocly/[email protected] \
@asyncapi/[email protected] \
@asyncapi/[email protected] \
@asyncapi/[email protected] \
[email protected] \
@faker-js/[email protected] \
@openapitools/[email protected] \
Expand All @@ -40,6 +43,22 @@ install_packages() {
[email protected]
}

##
# runs an install command to install the given packages
run_install_command() {
cmd="$@"

if [ "$pkg_manager" == "pnpm" ]; then
runner="$pkg_manager install --reporter=default"
else
runner="$pkg_manager install"
fi

log "running command $runner $cmd"

$runner $cmd
}

##
# installs the passed packages with the package manager in use
_install_packages() {
Expand All @@ -59,6 +78,8 @@ _install_packages() {

# The .committed file contains the identifier of the directory already installed to
_install_dir_identifier=$(cat $_install_packages_committed_file)

log "packages already installed to :: $_install_packages_pdk_base_dir/$_install_dir_identifier"
fi

_install_packages_pdk_dir="$_install_packages_pdk_base_dir/$_install_dir_identifier"
Expand All @@ -69,11 +90,7 @@ _install_packages() {
# Install if any packages are missing
if [ "$_install_packages_should_install" == "true" ]; then
npm init --yes
if [ "$pkg_manager" == "pnpm" ]; then
$pkg_manager install --reporter=default "$@"
else
$pkg_manager install "$@"
fi
run_install_command "$@"
fi

# Mark that we have installed the dependencies (if there's a race and we installed multiple times,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash

set -e

# Parse arguments
spec_path=''
output_path=''
while [[ "$#" -gt 0 ]]; do case $1 in
--spec-path) spec_path="$2"; shift;;
--output-path) output_path="$2"; shift;;
esac; shift; done

echo "Generating AsyncAPI HTML documentation..."

working_dir=$(pwd)
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 )";

# load common package manager helper functions
. "$script_dir/../../common/common.sh"

# Create a temporary directory
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp/}generate-docs-async-api-html.XXXXXXXXX")
cd $tmp_dir

log "async-api-html :: tmp_dir :: $tmp_dir"

# Install dependencies
install_packages

# Generate
run_command asyncapi generate fromTemplate "$working_dir/$spec_path" @asyncapi/[email protected] \
--param singleFile=true \
--param outFilename=index.html \
--force-write

# Copy html docs to output path
rm -f $working_dir/$output_path/index.html
cp index.html $working_dir/$output_path/index.html

echo "AsyncAPI HTML documentation generation done!"

# Clean up
cd $working_dir
rm -rf $tmp_dir
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

set -e

# Parse arguments
spec_path=''
output_path=''
while [[ "$#" -gt 0 ]]; do case $1 in
--spec-path) spec_path="$2"; shift;;
--output-path) output_path="$2"; shift;;
esac; shift; done

echo "Generating AsyncAPI Markdown documentation..."

working_dir=$(pwd)
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 )";

# load common package manager helper functions
. "$script_dir/../../common/common.sh"

# Create a temporary directory
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp/}generate-docs-async-api-markdown.XXXXXXXXX")
cd $tmp_dir

log "async-api-markdown :: tmp_dir :: $tmp_dir"

# Install dependencies
install_packages

# Generate
run_command asyncapi generate fromTemplate "$working_dir/$spec_path" @asyncapi/[email protected] \
--param outFilename=index.md \
--force-write

# Copy markdown docs to output path
rm -f $working_dir/$output_path/index.md
cp index.md $working_dir/$output_path/index.md

echo "AsyncAPI Markdown documentation generation done!"

# Clean up
cd $working_dir
rm -rf $tmp_dir
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash

set -e

# Parse arguments
spec_path=''
output_path=''
while [[ "$#" -gt 0 ]]; do case $1 in
--spec-path) spec_path="$2"; shift;;
--output-path) output_path="$2"; shift;;
esac; shift; done

working_dir=$(pwd)
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 )";

# load common package manager helper functions
. "$script_dir/../../common/common.sh"

# Create a temporary directory
tmp_dir=$(mktemp -d "${TMPDIR:-/tmp/}generate-asyncapi-spec.XXXXXXXXX")
cd $tmp_dir

log "generate-asyncapi-spec :: tmp_dir :: $tmp_dir"

# Copy the parse script into the temp directory
cp -r $script_dir/* .

# Install dependencies
install_packages

# Run the parse script
run_command ts-node generate-asyncapi-spec.ts \
--specPath="$working_dir/$spec_path" \
--outputPath="$working_dir/$output_path"

log "generate-asyncapi-spec :: done"

# Clean up
cd $working_dir
rm -rf $tmp_dir
Loading

0 comments on commit fa325f3

Please sign in to comment.