-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e2325f6
commit 0d4eb34
Showing
6 changed files
with
364 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
...in/java/software/amazon/smithy/typescript/codegen/integration/DefaultReadmeGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
package software.amazon.smithy.typescript.codegen.integration; | ||
|
||
import java.util.Arrays; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
import software.amazon.smithy.model.Model; | ||
import software.amazon.smithy.model.knowledge.TopDownIndex; | ||
import software.amazon.smithy.model.shapes.OperationShape; | ||
import software.amazon.smithy.model.shapes.ServiceShape; | ||
import software.amazon.smithy.model.traits.DocumentationTrait; | ||
import software.amazon.smithy.typescript.codegen.TypeScriptCodegenContext; | ||
import software.amazon.smithy.typescript.codegen.TypeScriptSettings; | ||
import software.amazon.smithy.utils.IoUtils; | ||
import software.amazon.smithy.utils.SmithyInternalApi; | ||
import software.amazon.smithy.utils.StringUtils; | ||
|
||
@SmithyInternalApi | ||
public final class DefaultReadmeGenerator implements TypeScriptIntegration { | ||
|
||
public static final String README_FILENAME = "README.md"; | ||
public static final String DEFAULT_CLIENT_README_TEMPLATE = "default_readme_client.md.template"; | ||
public static final String DEFAULT_SERVER_README_TEMPLATE = "default_readme_server.md.template"; | ||
|
||
@Override | ||
public void customize(TypeScriptCodegenContext codegenContext) { | ||
TypeScriptSettings settings = codegenContext.settings(); | ||
|
||
if (!settings.createDefaultReadme()) { | ||
return; | ||
} | ||
|
||
String file = settings.generateClient() ? DEFAULT_CLIENT_README_TEMPLATE : DEFAULT_SERVER_README_TEMPLATE; | ||
|
||
Model model = codegenContext.model(); | ||
|
||
codegenContext.writerDelegator().useFileWriter(README_FILENAME, "", writer -> { | ||
ServiceShape service = settings.getService(model); | ||
String resource = IoUtils.readUtf8Resource(getClass(), file); | ||
resource = resource.replaceAll(Pattern.quote("${packageName}"), settings.getPackageName()); | ||
|
||
String clientName = StringUtils.capitalize(service.getId().getName(service)); | ||
|
||
resource = resource.replaceAll(Pattern.quote("${serviceId}"), clientName); | ||
|
||
String rawDocumentation = service.getTrait(DocumentationTrait.class) | ||
.map(DocumentationTrait::getValue) | ||
.orElse(""); | ||
String documentation = Arrays.asList(rawDocumentation.split("\n")).stream() | ||
.map(StringUtils::trim) | ||
.collect(Collectors.joining("\n")); | ||
resource = resource.replaceAll(Pattern.quote("${documentation}"), Matcher.quoteReplacement(documentation)); | ||
|
||
TopDownIndex topDownIndex = TopDownIndex.of(model); | ||
OperationShape firstOperation = topDownIndex.getContainedOperations(service).iterator().next(); | ||
String operationName = firstOperation.getId().getName(service); | ||
resource = resource.replaceAll(Pattern.quote("${commandName}"), operationName); | ||
|
||
// The $ character is escaped using $$ | ||
writer.write(resource.replaceAll(Pattern.quote("$"), Matcher.quoteReplacement("$$"))); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
...s/software/amazon/smithy/typescript/codegen/integration/default_readme_client.md.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
<!-- generated file, do not edit directly --> | ||
|
||
# ${packageName} | ||
|
||
## Description | ||
|
||
SDK for JavaScript ${serviceId} Client for Node.js, Browser and React Native. | ||
|
||
${documentation} | ||
|
||
## Installing | ||
To install the this package, simply type add or install ${packageName} | ||
using your favorite package manager: | ||
- `npm install ${packageName}` | ||
- `yarn add ${packageName}` | ||
- `pnpm add ${packageName}` | ||
|
||
## Getting Started | ||
|
||
### Import | ||
|
||
To send a request, you only need to import the `${serviceId}Client` and | ||
the commands you need, for example `${commandName}Command`: | ||
|
||
```js | ||
// CJS example | ||
const { ${serviceId}Client, ${commandName}Command } = require("${packageName}"); | ||
``` | ||
|
||
```ts | ||
// ES6+ example | ||
import { ${serviceId}Client, ${commandName}Command } from "${packageName}"; | ||
``` | ||
|
||
### Usage | ||
|
||
To send a request, you: | ||
|
||
- Initiate client with configuration. | ||
- Initiate command with input parameters. | ||
- Call `send` operation on client with command object as input. | ||
- If you are using a custom http handler, you may call `destroy()` to close open connections. | ||
|
||
```js | ||
// a client can be shared by different commands. | ||
const client = new ${serviceId}Client(); | ||
|
||
const params = { /** input parameters */ }; | ||
const command = new ${commandName}Command(params); | ||
``` | ||
|
||
#### Async/await | ||
|
||
We recommend using [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) | ||
operator to wait for the promise returned by send operation as follows: | ||
|
||
```js | ||
// async/await. | ||
try { | ||
const data = await client.send(command); | ||
// process data. | ||
} catch (error) { | ||
// error handling. | ||
} finally { | ||
// finally. | ||
} | ||
``` | ||
|
||
Async-await is clean, concise, intuitive, easy to debug and has better error handling | ||
as compared to using Promise chains or callbacks. | ||
|
||
#### Promises | ||
|
||
You can also use [Promise chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#chaining) | ||
to execute send operation. | ||
|
||
```js | ||
client.send(command).then( | ||
(data) => { | ||
// process data. | ||
}, | ||
(error) => { | ||
// error handling. | ||
} | ||
); | ||
``` | ||
|
||
Promises can also be called using `.catch()` and `.finally()` as follows: | ||
|
||
```js | ||
client | ||
.send(command) | ||
.then((data) => { | ||
// process data. | ||
}) | ||
.catch((error) => { | ||
// error handling. | ||
}) | ||
.finally(() => { | ||
// finally. | ||
}); | ||
``` | ||
|
||
#### Callbacks | ||
|
||
We do not recommend using callbacks because of [callback hell](http://callbackhell.com/), | ||
but they are supported by the send operation. | ||
|
||
```js | ||
// callbacks. | ||
client.send(command, (err, data) => { | ||
// process err and data. | ||
}); | ||
``` | ||
|
||
### Troubleshooting | ||
|
||
When the service returns an exception, the error will include the exception information, | ||
as well as response metadata (e.g. request id). | ||
|
||
```js | ||
try { | ||
const data = await client.send(command); | ||
// process data. | ||
} catch (error) { | ||
const { requestId, httpStatusCode } = error.$$metadata; | ||
console.log({ requestId, httpStatusCode }); | ||
/** | ||
* The keys within exceptions are also parsed. | ||
* You can access them by specifying exception names: | ||
* if (error.name === 'SomeServiceException') { | ||
* const value = error.specialKeyInException; | ||
* } | ||
*/ | ||
} | ||
``` |
57 changes: 57 additions & 0 deletions
57
...s/software/amazon/smithy/typescript/codegen/integration/default_readme_server.md.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<!-- generated file, do not edit directly --> | ||
|
||
# ${packageName} | ||
|
||
## Description | ||
|
||
JavaScript Server SDK for ${serviceId} | ||
|
||
${documentation} | ||
|
||
## Installing | ||
To install this package, simply type add or install ${packageName} | ||
using your favorite package manager: | ||
- `npm install ${packageName}` | ||
- `yarn add ${packageName}` | ||
- `pnpm add ${packageName}` | ||
|
||
## Getting Started | ||
|
||
Below is an example service handler created for the ${commandName} operation. | ||
|
||
```ts | ||
import { createServer, IncomingMessage, ServerResponse } from "http"; | ||
import { HttpRequest } from "@aws-sdk/protocol-http"; | ||
import { | ||
${serviceId}Service as __${serviceId}Service, | ||
${commandName}Input, | ||
${commandName}Output, | ||
get${serviceId}ServiceHandler | ||
} from "${packageName}"; | ||
import { convertEvent, convertResponse } from "@aws-smithy/server-node"; | ||
|
||
class ${serviceId}Service implements __${serviceId}Service { | ||
${commandName}(input: ${commandName}Input, request: HttpRequest): ${commandName}Output { | ||
// Populate your business logic | ||
} | ||
} | ||
|
||
const serviceHandler = get${serviceId}ServiceHandler(new ${serviceId}Service()); | ||
|
||
const server = createServer(async function ( | ||
req: IncomingMessage, | ||
res: ServerResponse<IncomingMessage> & { req: IncomingMessage } | ||
) { | ||
// Convert NodeJS's http request to an HttpRequest. | ||
const httpRequest = convertRequest(req); | ||
|
||
// Call the service handler, which will route the request to the GreetingService | ||
// implementation and then serialize the response to an HttpResponse. | ||
const httpResponse = await serviceHandler.handle(httpRequest); | ||
|
||
// Write the HttpResponse to NodeJS http's response expected format. | ||
return writeResponse(httpResponse, res); | ||
}); | ||
|
||
server.listen(3000); | ||
``` |
Oops, something went wrong.