From 16633b60c1f9789439663465eebd94d5e8aaf8aa Mon Sep 17 00:00:00 2001 From: Jack Stevenson Date: Thu, 17 Aug 2023 08:36:55 +1000 Subject: [PATCH] feat(type-safe-api): generate lambda handler stubs based on model trait (#537) This change adds a new configuration option `handlers` which allows users to opt in to generating lambda handler projects for java, python, and/or typescript, ready-configured with packaging tasks for use in a lambda function. Handler stubs are generated for operations annotated with the @handler trait in Smithy (or the x-handler vendor extension in OpenAPI), only generating the handler stubs for the chosen language for each operation. Documentation to come once this feature has been further fleshed out. --- .../type-safe-api/scripts/generators/generate | 18 +- .../java-lambda-handlers/config.yaml | 4 + .../templates/handlers.handlebars | 46 + .../scripts/generators/post-process.ts | 109 + .../scripts/generators/pre-process-spec.ts | 8 +- .../python-lambda-handlers/config.yaml | 4 + .../templates/handlers.handlebars | 43 + .../typescript-lambda-handlers/config.yaml | 4 + .../templates/handlers.handlebars | 45 + .../src/project/codegen/components/utils.ts | 5 + .../src/project/codegen/generate.ts | 117 + .../generated-java-handlers-project.ts | 152 + .../generated-python-handlers-project.ts | 128 + .../generated-typescript-handlers-project.ts | 177 + .../model/openapi/open-api-definition.ts | 57 +- .../components/smithy-aws-pdk-prelude.ts | 135 + .../components/smithy-build-gradle-file.ts | 13 +- .../project/model/smithy/smithy-definition.ts | 29 +- .../model/type-safe-api-model-project.ts | 21 +- .../src/project/type-safe-api-project.ts | 153 +- packages/type-safe-api/src/project/types.ts | 81 +- .../type-safe-api-project.test.ts.snap | 6063 ++++++++++++++++- ...nerated-java-handlers-project.test.ts.snap | 498 ++ ...rated-python-handlers-project.test.ts.snap | 389 ++ ...d-typescript-handlers-project.test.ts.snap | 1402 ++++ .../generated-java-handlers-project.test.ts | 29 + .../generated-python-handlers-project.test.ts | 31 + ...erated-typescript-handlers-project.test.ts | 25 + .../type-safe-api-model-project.test.ts.snap | 978 ++- .../model/type-safe-api-model-project.test.ts | 37 +- .../project/type-safe-api-project.test.ts | 47 +- .../test/resources/specs/handlers.yaml | 251 + .../__snapshots__/docs.test.ts.snap | 9 +- .../java-lambda-handlers.test.ts.snap | 61 + .../__snapshots__/java.test.ts.snap | 6 +- .../python-lambda-handlers.test.ts.snap | 51 + .../__snapshots__/python.test.ts.snap | 6 +- .../typescript-lambda-handlers.test.ts.snap | 55 + .../typescript-react-query-hooks.test.ts.snap | 6 +- .../__snapshots__/typescript.test.ts.snap | 6 +- .../generators/java-lambda-handlers.test.ts | 84 + .../generators/python-lambda-handlers.test.ts | 71 + .../typescript-lambda-handlers.test.ts | 63 + 43 files changed, 11269 insertions(+), 248 deletions(-) create mode 100644 packages/type-safe-api/scripts/generators/java-lambda-handlers/config.yaml create mode 100644 packages/type-safe-api/scripts/generators/java-lambda-handlers/templates/handlers.handlebars create mode 100644 packages/type-safe-api/scripts/generators/post-process.ts create mode 100644 packages/type-safe-api/scripts/generators/python-lambda-handlers/config.yaml create mode 100644 packages/type-safe-api/scripts/generators/python-lambda-handlers/templates/handlers.handlebars create mode 100644 packages/type-safe-api/scripts/generators/typescript-lambda-handlers/config.yaml create mode 100644 packages/type-safe-api/scripts/generators/typescript-lambda-handlers/templates/handlers.handlebars create mode 100644 packages/type-safe-api/src/project/codegen/handlers/generated-java-handlers-project.ts create mode 100644 packages/type-safe-api/src/project/codegen/handlers/generated-python-handlers-project.ts create mode 100644 packages/type-safe-api/src/project/codegen/handlers/generated-typescript-handlers-project.ts create mode 100644 packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-prelude.ts create mode 100644 packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-java-handlers-project.test.ts.snap create mode 100644 packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-python-handlers-project.test.ts.snap create mode 100644 packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-typescript-handlers-project.test.ts.snap create mode 100644 packages/type-safe-api/test/project/codegen/handlers/generated-java-handlers-project.test.ts create mode 100644 packages/type-safe-api/test/project/codegen/handlers/generated-python-handlers-project.test.ts create mode 100644 packages/type-safe-api/test/project/codegen/handlers/generated-typescript-handlers-project.test.ts create mode 100644 packages/type-safe-api/test/resources/specs/handlers.yaml create mode 100644 packages/type-safe-api/test/scripts/generators/__snapshots__/java-lambda-handlers.test.ts.snap create mode 100644 packages/type-safe-api/test/scripts/generators/__snapshots__/python-lambda-handlers.test.ts.snap create mode 100644 packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-lambda-handlers.test.ts.snap create mode 100644 packages/type-safe-api/test/scripts/generators/java-lambda-handlers.test.ts create mode 100644 packages/type-safe-api/test/scripts/generators/python-lambda-handlers.test.ts create mode 100644 packages/type-safe-api/test/scripts/generators/typescript-lambda-handlers.test.ts diff --git a/packages/type-safe-api/scripts/generators/generate b/packages/type-safe-api/scripts/generators/generate index 983e4be98..036db9710 100755 --- a/packages/type-safe-api/scripts/generators/generate +++ b/packages/type-safe-api/scripts/generators/generate @@ -51,6 +51,8 @@ install_packages \ @types/node@20.1.5 \ ts-node@10.9.1 \ ts-command-line-args@2.4.2 \ + lodash@4.17.21 \ + @types/lodash@4.14.197 \ @apidevtools/swagger-parser@10.1.0 \ openapi-types@12.1.0 @@ -59,7 +61,11 @@ install_packages \ log "preprocess spec :: $spec_path" processed_spec_path="$tmp_dir/.preprocessed-api.json" cp $script_dir/pre-process-spec.ts . -run_command ts-node pre-process-spec.ts --specPath="$working_dir/$spec_path" --outputSpecPath="$processed_spec_path" --extraVendorExtensions="$extra_vendor_extensions" ${smithy_json_path:+"--smithyJsonPath=$working_dir/$smithy_json_path"} +run_command ts-node pre-process-spec.ts \ + --specPath="$working_dir/$spec_path" \ + --outputSpecPath="$processed_spec_path" \ + --extraVendorExtensions="$extra_vendor_extensions" \ + ${smithy_json_path:+"--smithyJsonPath=$working_dir/$smithy_json_path"} # Support a special placeholder of {{src}} in config.yaml to ensure our custom templates get written to the correct folder sed 's|{{src}}|'"$src_dir"'|g' config.yaml > config.final.yaml @@ -109,6 +115,16 @@ if [ -f "$handlebars_ignore_file" ]; then fi fi +# Post processing +cp $script_dir/post-process.ts . +run_command ts-node post-process.ts \ + --outputPath="$working_dir/$output_path" \ + --srcDir="$src_dir" + +# Clean up empty directories left over by openapi generator +log "Cleaning up empty directories" +find "$working_dir/$output_path" -type d -empty -print -delete + echo "$generator_dir ($generator) OpenAPI generation done!" # Clean up diff --git a/packages/type-safe-api/scripts/generators/java-lambda-handlers/config.yaml b/packages/type-safe-api/scripts/generators/java-lambda-handlers/config.yaml new file mode 100644 index 000000000..a47a463db --- /dev/null +++ b/packages/type-safe-api/scripts/generators/java-lambda-handlers/config.yaml @@ -0,0 +1,4 @@ +files: + handlers.handlebars: + destinationFilename: {{src}}/__all_handlers.java + templateType: SupportingFiles diff --git a/packages/type-safe-api/scripts/generators/java-lambda-handlers/templates/handlers.handlebars b/packages/type-safe-api/scripts/generators/java-lambda-handlers/templates/handlers.handlebars new file mode 100644 index 000000000..832b14ade --- /dev/null +++ b/packages/type-safe-api/scripts/generators/java-lambda-handlers/templates/handlers.handlebars @@ -0,0 +1,46 @@ +###TSAPI_SPLIT_FILE### +{{#apiInfo ~}} +{{#apis ~}} +{{#operations ~}} +{{#operation ~}} +{{#if vendorExtensions.x-handler}} +{{#startsWith vendorExtensions.x-handler.language 'java'}} +###TSAPI_WRITE_FILE### +{ + "dir": ".", + "name": "{{operationIdCamelCase}}Handler", + "ext": ".java", + "overwrite": false, + "kebabCaseFileName": false +} +###/TSAPI_WRITE_FILE###package {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-package}}{{/apis.0}}{{/apiInfo}}; + +import {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-package}}{{/apis.0}}{{/apiInfo}}.api.Handlers.{{operationIdCamelCase}}; +import {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-package}}{{/apis.0}}{{/apiInfo}}.api.Handlers.{{operationIdCamelCase}}500Response; +import {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-package}}{{/apis.0}}{{/apiInfo}}.api.Handlers.{{operationIdCamelCase}}RequestInput; +import {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-package}}{{/apis.0}}{{/apiInfo}}.api.Handlers.{{operationIdCamelCase}}Response; +import {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-package}}{{/apis.0}}{{/apiInfo}}.model.*; + +/** + * Entry point for the AWS Lambda handler for the {{operationIdCamelCase}} operation. + * The {{operationIdCamelCase}} class manages marshalling inputs and outputs. + */ +public class {{operationIdCamelCase}}Handler extends {{operationIdCamelCase}} { + /** + * Type-safe handler for the {{operationIdCamelCase}} operation + */ + @Override + public {{operationIdCamelCase}}Response handle({{operationIdCamelCase}}RequestInput input) { + // TODO: Implement {{operationIdCamelCase}} Operation + return {{operationIdCamelCase}}500Response.of(InternalFailureErrorResponseContent.builder() + .message("Not Implemented!") + .build()); + } +} + +{{~/startsWith}} +{{~/if}} +{{~/operation}} +{{~/operations}} +{{~/apis}} +{{~/apiInfo}} \ No newline at end of file diff --git a/packages/type-safe-api/scripts/generators/post-process.ts b/packages/type-safe-api/scripts/generators/post-process.ts new file mode 100644 index 000000000..80c32e65e --- /dev/null +++ b/packages/type-safe-api/scripts/generators/post-process.ts @@ -0,0 +1,109 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as fs from "fs"; +import * as path from "path"; +import kebabCase from "lodash/kebabCase"; +import { parse } from "ts-command-line-args"; + +// Used to split OpenAPI generated files into multiple files in order to work around +// the restrictions around file naming and splitting in OpenAPI generator +const TSAPI_SPLIT_FILE_HEADER = "###TSAPI_SPLIT_FILE###"; +const TSAPI_WRITE_FILE_START = "###TSAPI_WRITE_FILE###"; +const TSAPI_WRITE_FILE_END = "###/TSAPI_WRITE_FILE###"; + +interface Arguments { + /** + * Path to the directory containing output files + */ + readonly outputPath: string; + /** + * Path to the source directory relative to the output directory + */ + readonly srcDir: string; +} + +interface WriteFileConfig { + readonly dir: string; + readonly name: string; + readonly ext: string; + readonly overwrite?: boolean; + readonly kebabCaseFileName?: boolean; +} + +void (async () => { + const args = parse({ + outputPath: { type: String }, + srcDir: { type: String }, + }); + + // OpenAPI generator writes a manifest called FILES which lists the files it generated. + const openApiGeneratedFilesManifestPath = path.join( + args.outputPath, + ".openapi-generator", + "FILES" + ); + + // Read the file paths from the manifest + const generatedFiles = fs + .readFileSync(openApiGeneratedFilesManifestPath, { encoding: "utf-8" }) + .split("\n") + .filter((x) => x); + + const additionalGeneratedFiles: string[] = []; + + // Loop over generated files + generatedFiles.forEach((generatedFile) => { + const filePath = path.join(args.outputPath, generatedFile); + + if (fs.existsSync(filePath)) { + const contents = fs.readFileSync(filePath, "utf-8"); + + if (contents.startsWith(TSAPI_SPLIT_FILE_HEADER)) { + // Split by the start template + contents + .split(TSAPI_WRITE_FILE_START) + .filter((t) => t.includes(TSAPI_WRITE_FILE_END)) + .forEach((destinationFileTemplate) => { + // Split by the end template to receive the file path, and contents + const [configString, newFileContents] = + destinationFileTemplate.split(TSAPI_WRITE_FILE_END); + const config = JSON.parse(configString) as WriteFileConfig; + + const newFileName = `${ + config.kebabCaseFileName ? kebabCase(config.name) : config.name + }${config.ext}`; + const relativeNewFileDir = path.join(args.srcDir, config.dir); + const relativeNewFilePath = path.join( + relativeNewFileDir, + newFileName + ); + const newFilePath = path.join(args.outputPath, relativeNewFilePath); + + // Write to the instructed file path (relative to the src dir) + if (!fs.existsSync(newFilePath) || config.overwrite) { + // Create it's containing directory if needed + fs.mkdirSync(path.join(args.outputPath, relativeNewFileDir), { + recursive: true, + }); + fs.writeFileSync(newFilePath, newFileContents); + + // Overwritten files are added to the manifest so that they can be cleaned up + // by clean-openapi-generated-code + if (config.overwrite) { + additionalGeneratedFiles.push(relativeNewFilePath); + } + } + }); + + // Delete the original file + fs.rmSync(filePath); + } + } + }); + + // Update the manifest with any overwritten files + fs.writeFileSync( + openApiGeneratedFilesManifestPath, + [...generatedFiles, ...additionalGeneratedFiles].join("\n") + ); +})(); diff --git a/packages/type-safe-api/scripts/generators/pre-process-spec.ts b/packages/type-safe-api/scripts/generators/pre-process-spec.ts index f22bf301f..bff42f824 100644 --- a/packages/type-safe-api/scripts/generators/pre-process-spec.ts +++ b/packages/type-safe-api/scripts/generators/pre-process-spec.ts @@ -1,7 +1,6 @@ /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ import * as fs from "fs"; -import * as path from "path"; import SwaggerParser from "@apidevtools/swagger-parser"; import { parse } from "ts-command-line-args"; @@ -76,9 +75,14 @@ void (async () => { Object.entries(operation.traits).forEach(([traitId, value]) => { // By default, we use x- for the vendor extension, but for extensions we support // directly from OpenAPI we apply a mapping (rather than repeat ourselves in the mustache templates). - const vendorExtension = + let vendorExtension = TRAIT_TO_SUPPORTED_OPENAPI_VENDOR_EXTENSION[traitId] ?? `x-${traitId}`; + // Special case for the handler trait where it's defined as part of the user's smithy model, so the namespace + // can be any namespace the user defines + if (traitId.endsWith("#handler")) { + vendorExtension = "x-handler"; + } spec.paths[operation.path][operation.method][vendorExtension] = value; }); } diff --git a/packages/type-safe-api/scripts/generators/python-lambda-handlers/config.yaml b/packages/type-safe-api/scripts/generators/python-lambda-handlers/config.yaml new file mode 100644 index 000000000..bc682fa28 --- /dev/null +++ b/packages/type-safe-api/scripts/generators/python-lambda-handlers/config.yaml @@ -0,0 +1,4 @@ +files: + handlers.handlebars: + destinationFilename: {{src}}/__all_handlers.py + templateType: SupportingFiles diff --git a/packages/type-safe-api/scripts/generators/python-lambda-handlers/templates/handlers.handlebars b/packages/type-safe-api/scripts/generators/python-lambda-handlers/templates/handlers.handlebars new file mode 100644 index 000000000..236c1dce9 --- /dev/null +++ b/packages/type-safe-api/scripts/generators/python-lambda-handlers/templates/handlers.handlebars @@ -0,0 +1,43 @@ +###TSAPI_SPLIT_FILE### +{{#apiInfo ~}} +{{#apis ~}} +{{#operations ~}} +{{#operation ~}} +{{#if vendorExtensions.x-handler}} +{{#startsWith vendorExtensions.x-handler.language 'python'}} +###TSAPI_WRITE_FILE### +{ + "dir": ".", + "name": "{{operationId}}", + "ext": ".py", + "overwrite": false +} +###/TSAPI_WRITE_FILE###from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.models import * +from {{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-module-name}}{{/apis.0}}{{/apiInfo}}.apis.tags.default_api_operation_config import ( + {{operationId}}_handler, {{operationIdCamelCase}}Request, {{operationIdCamelCase}}OperationResponses, ApiResponse +) + + +def {{operationId}}(input: {{operationIdCamelCase}}Request, **kwargs) -> {{operationIdCamelCase}}OperationResponses: + """ + Type-safe handler for the {{operationIdCamelCase}} operation + """ + # TODO: Implement {{operationIdCamelCase}} Operation + return ApiResponse( + status_code=500, + body=InternalFailureErrorResponseContent( + message="Not Implemented!"), + headers={} + ) + + +# Entry point for the AWS Lambda handler for the {{operationIdCamelCase}} operation. +# The {{operationId}}_handler method wraps the type-safe handler and manages marshalling inputs and outputs +handler = {{operationId}}_handler({{operationId}}) + +{{~/startsWith}} +{{~/if}} +{{~/operation}} +{{~/operations}} +{{~/apis}} +{{~/apiInfo}} \ No newline at end of file diff --git a/packages/type-safe-api/scripts/generators/typescript-lambda-handlers/config.yaml b/packages/type-safe-api/scripts/generators/typescript-lambda-handlers/config.yaml new file mode 100644 index 000000000..92c13b8e7 --- /dev/null +++ b/packages/type-safe-api/scripts/generators/typescript-lambda-handlers/config.yaml @@ -0,0 +1,4 @@ +files: + handlers.handlebars: + destinationFilename: {{src}}/__all_handlers.ts + templateType: SupportingFiles diff --git a/packages/type-safe-api/scripts/generators/typescript-lambda-handlers/templates/handlers.handlebars b/packages/type-safe-api/scripts/generators/typescript-lambda-handlers/templates/handlers.handlebars new file mode 100644 index 000000000..84712d44d --- /dev/null +++ b/packages/type-safe-api/scripts/generators/typescript-lambda-handlers/templates/handlers.handlebars @@ -0,0 +1,45 @@ +###TSAPI_SPLIT_FILE### +{{#apiInfo ~}} +{{#apis ~}} +{{#operations ~}} +{{#operation ~}} +{{#if vendorExtensions.x-handler}} +{{#startsWith vendorExtensions.x-handler.language 'typescript'}} +###TSAPI_WRITE_FILE### +{ + "dir": ".", + "name": "{{nickname}}", + "ext": ".ts", + "overwrite": false, + "kebabCaseFileName": true +} +###/TSAPI_WRITE_FILE###import { + {{nickname}}Handler, + {{operationIdCamelCase}}ChainedHandlerFunction, +} from "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-runtime-package-name}}{{/apis.0}}{{/apiInfo}}"; + +/** + * Type-safe handler for the {{operationIdCamelCase}} operation + */ +export const {{nickname}}: {{operationIdCamelCase}}ChainedHandlerFunction = async ({ input }) => { + // TODO: Implement {{operationIdCamelCase}} Operation + return { + statusCode: 500, + body: { + message: "Not Implemented!", + }, + }; +}; + +/** + * Entry point for the AWS Lambda handler for the {{operationIdCamelCase}} operation. + * The {{nickname}}Handler method wraps the type-safe handler and manages marshalling inputs and outputs + */ +export const handler = {{nickname}}Handler({{nickname}}); + +{{~/startsWith}} +{{~/if}} +{{~/operation}} +{{~/operations}} +{{~/apis}} +{{~/apiInfo}} \ No newline at end of file diff --git a/packages/type-safe-api/src/project/codegen/components/utils.ts b/packages/type-safe-api/src/project/codegen/components/utils.ts index 6e99f5c09..88d530c4e 100644 --- a/packages/type-safe-api/src/project/codegen/components/utils.ts +++ b/packages/type-safe-api/src/project/codegen/components/utils.ts @@ -10,9 +10,14 @@ import { MockResponseDataGenerationOptions } from "../../types"; */ export enum OtherGenerators { DOCS = "docs", + // Infrastructure TYPESCRIPT_CDK_INFRASTRUCTURE = "typescript-cdk-infrastructure", PYTHON_CDK_INFRASTRUCTURE = "python-cdk-infrastructure", JAVA_CDK_INFRASTRUCTURE = "java-cdk-infrastructure", + // Handlers + TYPESCRIPT_LAMBDA_HANDLERS = "typescript-lambda-handlers", + PYTHON_LAMBDA_HANDLERS = "python-lambda-handlers", + JAVA_LAMBDA_HANDLERS = "java-lambda-handlers", } export enum TypeSafeApiScript { diff --git a/packages/type-safe-api/src/project/codegen/generate.ts b/packages/type-safe-api/src/project/codegen/generate.ts index 2e8dd4c9b..e0b1abf23 100644 --- a/packages/type-safe-api/src/project/codegen/generate.ts +++ b/packages/type-safe-api/src/project/codegen/generate.ts @@ -7,6 +7,9 @@ import { GeneratedHtmlRedocDocumentationProject } from "./documentation/generate import { GeneratedHtml2DocumentationProject } from "./documentation/generated-html2-documentation-project"; import { GeneratedMarkdownDocumentationProject } from "./documentation/generated-markdown-documentation-project"; import { GeneratedPlantumlDocumentationProject } from "./documentation/generated-plantuml-documentation-project"; +import { GeneratedJavaHandlersProject } from "./handlers/generated-java-handlers-project"; +import { GeneratedPythonHandlersProject } from "./handlers/generated-python-handlers-project"; +import { GeneratedTypescriptHandlersProject } from "./handlers/generated-typescript-handlers-project"; import { GeneratedJavaCdkInfrastructureProject } from "./infrastructure/cdk/generated-java-cdk-infrastructure-project"; import { GeneratedPythonCdkInfrastructureProject } from "./infrastructure/cdk/generated-python-cdk-infrastructure-project"; import { GeneratedTypescriptCdkInfrastructureProject } from "./infrastructure/cdk/generated-typescript-cdk-infrastructure-project"; @@ -273,6 +276,120 @@ export const generateInfraProject = ( } }; +export interface GenerateHandlersProjectOptions + extends GenerateRuntimeProjectsOptions { + /** + * Generated runtime projects + */ + readonly generatedRuntimes: { + readonly java?: GeneratedJavaRuntimeProject; + readonly python?: GeneratedPythonRuntimeProject; + readonly typescript?: GeneratedTypescriptRuntimeProject; + }; +} + +/** + * Returns a generated handlers project for the given language + */ +const generateHandlersProject = ( + language: Language, + options: GenerateHandlersProjectOptions +): Project => { + const handlersName = `${options.parentPackageName}-${language}-handlers`; + const commonOptions = { + outdir: path.join(options.generatedCodeDir, language), + specPath: options.parsedSpecPath, + parent: options.parent, + smithyJsonModelPath: options.smithyJsonModelPath, + }; + + switch (language) { + case Language.TYPESCRIPT: { + logger.trace("Attempting to generate TYPESCRIPT handlers project."); + if (!options.generatedRuntimes.typescript) { + throw new Error( + "A typescript runtime project must be created for typescript handlers" + ); + } + return new GeneratedTypescriptHandlersProject({ + ...commonOptions, + name: sanitiseTypescriptPackageName(handlersName), + generatedTypescriptTypes: options.generatedRuntimes.typescript, + ...options.typescriptOptions, + isWithinMonorepo: options.isWithinMonorepo, + }); + } + case Language.PYTHON: { + logger.trace("Attempting to generate PYTHON handlers project."); + if (!options.generatedRuntimes.python) { + throw new Error( + "A python runtime project must be created for python handlers" + ); + } + return new GeneratedPythonHandlersProject({ + ...commonOptions, + name: sanitisePythonPackageName(handlersName), + moduleName: sanitisePythonModuleName(handlersName), + generatedPythonTypes: options.generatedRuntimes.python, + ...options.pythonOptions, + }); + } + case Language.JAVA: { + logger.trace("Attempting to generate JAVA handlers project."); + if (!options.generatedRuntimes.java) { + throw new Error( + "A java runtime project must be created for java handlers" + ); + } + return new GeneratedJavaHandlersProject({ + ...commonOptions, + name: sanitiseJavaProjectName(handlersName), + artifactId: sanitiseJavaArtifactId(handlersName), + groupId: "com.generated.api", + generatedJavaTypes: options.generatedRuntimes.java, + ...options.javaOptions, + }); + } + default: + throw new Error(`Unknown infrastructure language ${language}`); + } +}; + +/** + * Create handlers projects in the given languages + * @param languages the languages to generate for + * @param options options for the projects to be created + */ +export const generateHandlersProjects = ( + languages: Language[], + options: GenerateHandlersProjectOptions +): { [language: string]: Project } => { + new TextFile( + options.parent, + path.join(options.generatedCodeDir, "README.md"), + { + lines: [ + "## Handlers", + "", + "This directory contains lambda handlers for implementing your API.", + "", + "Whenever an operation is annotated with the `@handler` trait in Smithy (or the `x-handler` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", + ], + readonly: true, + } + ); + + const generatedHandlers: { [language: string]: Project } = {}; + languages.forEach((language) => { + const project = generateHandlersProject(language, options); + if (project != null) { + generatedHandlers[language] = project; + } + }); + + return generatedHandlers; +}; + /** * Create runtime projects in the given languages * @param languages the languages to generate for diff --git a/packages/type-safe-api/src/project/codegen/handlers/generated-java-handlers-project.ts b/packages/type-safe-api/src/project/codegen/handlers/generated-java-handlers-project.ts new file mode 100644 index 000000000..51059428b --- /dev/null +++ b/packages/type-safe-api/src/project/codegen/handlers/generated-java-handlers-project.ts @@ -0,0 +1,152 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as path from "path"; +import { DependencyType } from "projen"; +import { JavaProject } from "projen/lib/java"; +import { + CodeGenerationSourceOptions, + GeneratedJavaHandlersOptions, +} from "../../types"; +import { OpenApiGeneratorHandlebarsIgnoreFile } from "../components/open-api-generator-handlebars-ignore-file"; +import { OpenApiGeneratorIgnoreFile } from "../components/open-api-generator-ignore-file"; +import { OpenApiToolsJsonFile } from "../components/open-api-tools-json-file"; +import { + buildCleanOpenApiGeneratedCodeCommand, + buildInvokeOpenApiGeneratorCommandArgs, + buildTypeSafeApiExecCommand, + OtherGenerators, + TypeSafeApiScript, +} from "../components/utils"; +import { GeneratedJavaRuntimeProject } from "../runtime/generated-java-runtime-project"; + +export interface GeneratedJavaHandlersProjectOptions + extends GeneratedJavaHandlersOptions, + CodeGenerationSourceOptions { + /** + * The generated java types + */ + readonly generatedJavaTypes: GeneratedJavaRuntimeProject; +} + +export class GeneratedJavaHandlersProject extends JavaProject { + /** + * Options configured for the project + * @private + */ + private readonly options: GeneratedJavaHandlersProjectOptions; + + /** + * Source directory + * @private + */ + private readonly srcDir: string; + + /** + * Java package name + * @private + */ + private readonly packageName: string; + + constructor(options: GeneratedJavaHandlersProjectOptions) { + super({ + ...options, + sample: false, + junit: false, + }); + this.options = options; + this.packageName = `${this.pom.groupId}.${this.name}.handlers`; + this.srcDir = path.join( + "src", + "main", + "java", + ...this.packageName.split(".") + ); + + [ + `${options.generatedJavaTypes.pom.groupId}/${options.generatedJavaTypes.pom.artifactId}@${options.generatedJavaTypes.pom.version}`, + ] + .filter( + (dep) => + !this.deps.tryGetDependency(dep.split("@")[0], DependencyType.RUNTIME) + ) + .forEach((dep) => this.addDependency(dep)); + + // Remove the projen test dependency since otherwise it takes precedence, causing projen to be unavailable at synth time + this.deps.removeDependency("io.github.cdklabs/projen", DependencyType.TEST); + + // Add a dependency on the generated java types repository + this.pom.addRepository({ + url: `file://${path.relative( + this.outdir, + options.generatedJavaTypes.outdir + )}/dist/java`, + id: `${options.generatedJavaTypes.pom.groupId}-${options.generatedJavaTypes.pom.artifactId}-repo`, + }); + + // Ignore everything for the first mustache pass + const openapiGeneratorIgnore = new OpenApiGeneratorIgnoreFile(this); + openapiGeneratorIgnore.addPatterns("/*", "**/*", "*"); + // Ignore everything but the handler files for the handlebars pass + const openapiGeneratorHandlebarsIgnore = + new OpenApiGeneratorHandlebarsIgnoreFile(this); + openapiGeneratorHandlebarsIgnore.addPatterns( + "/*", + "**/*", + "*", + // This will be split into a file per targeted handler + `!${this.srcDir}/__all_handlers.java` + ); + + // Add OpenAPI Generator cli configuration + OpenApiToolsJsonFile.ensure(this).addOpenApiGeneratorCliConfig( + options.openApiGeneratorCliConfig + ); + + const generateTask = this.addTask("generate"); + generateTask.exec(buildCleanOpenApiGeneratedCodeCommand()); + generateTask.exec( + buildTypeSafeApiExecCommand( + TypeSafeApiScript.GENERATE, + this.buildGenerateCommandArgs() + ) + ); + + this.preCompileTask.spawn(generateTask); + + // Ignore the openapi generator metadata files + this.gitignore.addPatterns(".openapi-generator"); + + // Use the maven shade plugin to build a "super jar" which we can deploy to AWS Lambda + this.pom.addPlugin("org.apache.maven.plugins/maven-shade-plugin@3.3.0", { + configuration: { + createDependencyReducedPom: false, + }, + executions: [ + { + id: "shade-task", + phase: "package", + goals: ["shade"], + }, + ], + }); + } + + public buildGenerateCommandArgs = () => { + return buildInvokeOpenApiGeneratorCommandArgs({ + generator: "java", + specPath: this.options.specPath, + smithyJsonPath: this.options.smithyJsonModelPath, + generatorDirectory: OtherGenerators.JAVA_LAMBDA_HANDLERS, + srcDir: this.srcDir, + normalizers: { + KEEP_ONLY_FIRST_TAG_IN_OPERATION: true, + }, + extraVendorExtensions: { + "x-handlers-package": this.packageName, + "x-runtime-package": this.options.generatedJavaTypes.packageName, + }, + // Do not generate map/list types. Generator will use built in HashMap, ArrayList instead + generateAliasAsModel: false, + }); + }; +} diff --git a/packages/type-safe-api/src/project/codegen/handlers/generated-python-handlers-project.ts b/packages/type-safe-api/src/project/codegen/handlers/generated-python-handlers-project.ts new file mode 100644 index 000000000..23cf1df5d --- /dev/null +++ b/packages/type-safe-api/src/project/codegen/handlers/generated-python-handlers-project.ts @@ -0,0 +1,128 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as path from "path"; +import { DependencyType, SampleFile } from "projen"; +import { PythonProject } from "projen/lib/python"; +import { + CodeGenerationSourceOptions, + GeneratedPythonHandlersOptions, +} from "../../types"; +import { OpenApiGeneratorHandlebarsIgnoreFile } from "../components/open-api-generator-handlebars-ignore-file"; +import { OpenApiGeneratorIgnoreFile } from "../components/open-api-generator-ignore-file"; +import { OpenApiToolsJsonFile } from "../components/open-api-tools-json-file"; +import { + buildCleanOpenApiGeneratedCodeCommand, + buildInvokeOpenApiGeneratorCommandArgs, + buildTypeSafeApiExecCommand, + OtherGenerators, + TypeSafeApiScript, +} from "../components/utils"; +import { GeneratedPythonRuntimeProject } from "../runtime/generated-python-runtime-project"; + +export interface GeneratedPythonHandlersProjectOptions + extends GeneratedPythonHandlersOptions, + CodeGenerationSourceOptions { + /** + * The generated python types + */ + readonly generatedPythonTypes: GeneratedPythonRuntimeProject; +} + +export class GeneratedPythonHandlersProject extends PythonProject { + /** + * Options configured for the project + * @private + */ + private readonly options: GeneratedPythonHandlersProjectOptions; + + constructor(options: GeneratedPythonHandlersProjectOptions) { + super({ + sample: false, + pytest: false, + poetry: true, + poetryOptions: { + packages: [{ include: options.moduleName }], + // Module must be explicitly added to include since poetry excludes everything in .gitignore by default + include: [options.moduleName, `${options.moduleName}/**/*.py`], + }, + ...options, + }); + this.options = options; + + [ + `${options.generatedPythonTypes.name}@{path="${path.relative( + this.outdir, + options.generatedPythonTypes.outdir + )}", develop=true}`, + ] + .filter((dep) => !this.deps.tryGetDependency(dep, DependencyType.RUNTIME)) + .forEach((dep) => this.addDependency(dep)); + + // Ignore everything for the first mustache pass + const openapiGeneratorIgnore = new OpenApiGeneratorIgnoreFile(this); + openapiGeneratorIgnore.addPatterns("/*", "**/*", "*"); + // Ignore everything but the handler files for the handlebars pass + const openapiGeneratorHandlebarsIgnore = + new OpenApiGeneratorHandlebarsIgnoreFile(this); + openapiGeneratorHandlebarsIgnore.addPatterns( + "/*", + "**/*", + "*", + // This will be split into a file per targeted handler + `!${this.moduleName}/__all_handlers.py` + ); + + // Add OpenAPI Generator cli configuration + OpenApiToolsJsonFile.ensure(this).addOpenApiGeneratorCliConfig( + options.openApiGeneratorCliConfig + ); + + const generateTask = this.addTask("generate"); + generateTask.exec(buildCleanOpenApiGeneratedCodeCommand()); + generateTask.exec( + buildTypeSafeApiExecCommand( + TypeSafeApiScript.GENERATE, + this.buildGenerateCommandArgs() + ) + ); + + this.preCompileTask.spawn(generateTask); + + // Ignore the generated code + this.gitignore.addPatterns(".openapi-generator"); + + // Write __init__.py as sample code + new SampleFile(this, path.join(this.moduleName, "__init__.py"), { + contents: "#", + }); + + // Package task to build a distributable which can be deployed to lambda + this.packageTask.exec("mkdir -p dist/lambda && rm -rf dist/lambda/*"); + this.packageTask.exec( + `cp -r ${this.moduleName} dist/lambda/${this.moduleName}` + ); + this.packageTask.exec( + "poetry export --without-hashes --format=requirements.txt > dist/lambda/requirements.txt" + ); + this.packageTask.exec( + "pip install -r dist/lambda/requirements.txt --target dist/lambda --upgrade" + ); + } + + public buildGenerateCommandArgs = () => { + return buildInvokeOpenApiGeneratorCommandArgs({ + generator: "python", + specPath: this.options.specPath, + smithyJsonPath: this.options.smithyJsonModelPath, + generatorDirectory: OtherGenerators.PYTHON_LAMBDA_HANDLERS, + // Tell the generator where python source files live + srcDir: this.moduleName, + normalizers: { + KEEP_ONLY_FIRST_TAG_IN_OPERATION: true, + }, + extraVendorExtensions: { + "x-runtime-module-name": this.options.generatedPythonTypes.moduleName, + }, + }); + }; +} diff --git a/packages/type-safe-api/src/project/codegen/handlers/generated-typescript-handlers-project.ts b/packages/type-safe-api/src/project/codegen/handlers/generated-typescript-handlers-project.ts new file mode 100644 index 000000000..f48afd51e --- /dev/null +++ b/packages/type-safe-api/src/project/codegen/handlers/generated-typescript-handlers-project.ts @@ -0,0 +1,177 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as path from "path"; +import { DependencyType, IgnoreFile } from "projen"; +import { NodePackageManager } from "projen/lib/javascript"; +import { TypeScriptProject } from "projen/lib/typescript"; +import { + CodeGenerationSourceOptions, + GeneratedTypeScriptHandlersOptions, +} from "../../types"; +import { OpenApiGeneratorHandlebarsIgnoreFile } from "../components/open-api-generator-handlebars-ignore-file"; +import { OpenApiGeneratorIgnoreFile } from "../components/open-api-generator-ignore-file"; +import { OpenApiToolsJsonFile } from "../components/open-api-tools-json-file"; +import { + buildCleanOpenApiGeneratedCodeCommand, + buildInvokeOpenApiGeneratorCommandArgs, + buildTypeSafeApiExecCommand, + OtherGenerators, + TypeSafeApiScript, +} from "../components/utils"; +import { GeneratedTypescriptRuntimeProject } from "../runtime/generated-typescript-runtime-project"; + +export interface GeneratedTypescriptHandlersProjectOptions + extends GeneratedTypeScriptHandlersOptions, + CodeGenerationSourceOptions { + /** + * Generated typescript types project + */ + readonly generatedTypescriptTypes: GeneratedTypescriptRuntimeProject; + + /** + * Whether the infrastructure and client projects are parented by an nx-monorepo or not + */ + readonly isWithinMonorepo?: boolean; +} + +export class GeneratedTypescriptHandlersProject extends TypeScriptProject { + /** + * Options configured for the project + * @private + */ + private readonly options: GeneratedTypescriptHandlersProjectOptions; + + constructor(options: GeneratedTypescriptHandlersProjectOptions) { + super({ + ...options, + sampleCode: false, + tsconfig: { + compilerOptions: { + lib: ["dom", "es2019"], + // Generated code imports all models, and may not reference them all + noUnusedLocals: false, + noUnusedParameters: false, + skipLibCheck: true, + ...options?.tsconfig?.compilerOptions, + }, + }, + npmignoreEnabled: false, + }); + this.options = options; + + this.addDeps( + ...[ + // If within a monorepo, add a regular dependency. Otherwise, use a file dependency to ensure the runtime can be + // resolved + options.isWithinMonorepo + ? options.generatedTypescriptTypes.package.packageName + : `${ + options.generatedTypescriptTypes.package.packageName + }@file:${path.relative( + this.outdir, + options.generatedTypescriptTypes.outdir + )}`, + ].filter( + (dep) => !this.deps.tryGetDependency(dep, DependencyType.RUNTIME) + ) + ); + this.addDevDeps("esbuild"); + + // Minimal .npmignore to avoid impacting OpenAPI Generator + const npmignore = new IgnoreFile(this, ".npmignore"); + npmignore.addPatterns("/.projen/", "/src", "/dist"); + + // Ignore everything for the regular open api generator pass + const openapiGeneratorIgnore = new OpenApiGeneratorIgnoreFile(this); + openapiGeneratorIgnore.addPatterns("/*", "**/*", "*"); + // Ignore everything but the handler files for the handlebars pass + const openapiGeneratorHandlebarsIgnore = + new OpenApiGeneratorHandlebarsIgnoreFile(this); + openapiGeneratorHandlebarsIgnore.addPatterns( + "/*", + "**/*", + "*", + // This will be split into a file per targeted handler + `!${this.srcdir}/__all_handlers.ts` + ); + + // Add OpenAPI Generator cli configuration + OpenApiToolsJsonFile.ensure(this).addOpenApiGeneratorCliConfig( + options.openApiGeneratorCliConfig + ); + + const generateTask = this.addTask("generate"); + generateTask.exec(buildCleanOpenApiGeneratedCodeCommand()); + generateTask.exec( + buildTypeSafeApiExecCommand( + TypeSafeApiScript.GENERATE, + this.buildGenerateCommandArgs() + ) + ); + + this.preCompileTask.spawn(generateTask); + + // Ignore the openapi generator metadata + this.gitignore.addPatterns(".openapi-generator"); + + // Create a separate lambda bundle for each handler as part of the package task. + // Note that every typescript file directly in src is bundled by default, but users may specify their own + // entry point globs if they prefer a different directory structure. + this.packageTask.exec(`mkdir -p dist/lambda && rm -rf dist/lambda/*`); + this.packageTask.exec( + `esbuild --bundle ${( + options.handlerEntryPoints ?? [`${this.srcdir}/*.ts`] + ).join(" ")} --platform=node --outdir=dist/lambda` + ); + // Move each bundled file into a separate directory + this.packageTask.exec( + "for f in $(ls dist/lambda); do mkdir dist/lambda/$(basename $f .js) && mv dist/lambda/$f dist/lambda/$(basename $f .js)/index.js; done" + ); + + // If we're not in a monorepo, we need to link the generated types such that the local dependency can be resolved + if (!options.isWithinMonorepo) { + switch (this.package.packageManager) { + case NodePackageManager.NPM: + case NodePackageManager.YARN: + case NodePackageManager.YARN2: + this.tasks + .tryFind("install") + ?.prependExec( + `${this.package.packageManager} link ${this.options.generatedTypescriptTypes.package.packageName}` + ); + break; + case NodePackageManager.PNPM: + this.tasks + .tryFind("install") + ?.prependExec( + `${this.package.packageManager} link /${path.relative( + this.outdir, + this.options.generatedTypescriptTypes.outdir + )}` + ); + break; + default: + console.warn( + `Unknown package manager ${this.package.packageManager}. Cannot link generated typescript client.` + ); + } + } + } + + public buildGenerateCommandArgs = () => { + return buildInvokeOpenApiGeneratorCommandArgs({ + generator: "typescript-fetch", + specPath: this.options.specPath, + smithyJsonPath: this.options.smithyJsonModelPath, + generatorDirectory: OtherGenerators.TYPESCRIPT_LAMBDA_HANDLERS, + srcDir: this.srcdir, + normalizers: { + KEEP_ONLY_FIRST_TAG_IN_OPERATION: true, + }, + extraVendorExtensions: { + "x-runtime-package-name": + this.options.generatedTypescriptTypes.package.packageName, + }, + }); + }; +} diff --git a/packages/type-safe-api/src/project/model/openapi/open-api-definition.ts b/packages/type-safe-api/src/project/model/openapi/open-api-definition.ts index 6936f1da7..b1ccd6a9b 100644 --- a/packages/type-safe-api/src/project/model/openapi/open-api-definition.ts +++ b/packages/type-safe-api/src/project/model/openapi/open-api-definition.ts @@ -1,6 +1,7 @@ /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ import { SampleFile, Component } from "projen"; +import { Language } from "../../languages"; import { OpenApiModelOptions } from "../../types"; import { TypeSafeApiModelProject } from "../type-safe-api-model-project"; @@ -12,6 +13,10 @@ export interface OpenApiDefinitionOptions { * Options for the openapi model */ readonly openApiOptions: OpenApiModelOptions; + /** + * The languages users have specified for handler projects (if any) + */ + readonly handlerLanguages?: Language[]; } /** @@ -30,6 +35,8 @@ export class OpenApiDefinition extends Component { ) { super(project); + const firstHandlerLanguage = options.handlerLanguages?.[0]; + // Create a sample OpenAPI spec yaml if not defined new SampleFile(project, this.openApiSpecificationPath, { contents: `openapi: 3.0.3 @@ -39,7 +46,13 @@ info: paths: /hello: get: - operationId: sayHello + operationId: sayHello${ + firstHandlerLanguage + ? ` + x-handler: + language: ${firstHandlerLanguage}` + : "" + } parameters: - in: query name: name @@ -47,28 +60,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: diff --git a/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-prelude.ts b/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-prelude.ts new file mode 100644 index 000000000..c3d9805ea --- /dev/null +++ b/packages/type-safe-api/src/project/model/smithy/components/smithy-aws-pdk-prelude.ts @@ -0,0 +1,135 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import * as path from "path"; +import { Project, FileBase, IResolver } from "projen"; +import { Language } from "../../../languages"; + +/** + * Options for the aws-pdk/prelude.smithy file + */ +export interface SmithyAwsPdkPreludeOptions { + /** + * Path to the generated model directory in which to add the prelude + */ + readonly generatedModelDir: string; + /** + * Namespace for the smithy service + */ + readonly serviceNamespace: string; + /** + * Languages selected for handlers + */ + readonly handlerLanguages?: Language[]; +} + +/** + * Synthesize the aws-pdk/prelude.smithy file + */ +export class SmithyAwsPdkPrelude extends FileBase { + private readonly options: SmithyAwsPdkPreludeOptions; + + constructor(project: Project, options: SmithyAwsPdkPreludeOptions) { + super( + project, + path.join(options.generatedModelDir, "aws-pdk", "prelude.smithy"), + { + marker: true, + readonly: true, + } + ); + this.options = options; + } + + public synthesizeContent(_: IResolver): string | undefined { + const hasAnyHandlerProjects = + (this.options.handlerLanguages ?? []).length > 0; + + const traitValidator = hasAnyHandlerProjects + ? `{ + id: "ConfiguredHandlerProject" + name: "EmitEachSelector" + configuration: { + bindToTrait: ${this.options.serviceNamespace}#handler + selector: """ + [@trait|${ + this.options.serviceNamespace + }#handler: @{language} = typescript, java, python] + :not([@trait|${ + this.options.serviceNamespace + }#handler: @{language} = ${this.options.handlerLanguages?.join( + ", " + )}]) + """ + messageTemplate: """ + @@handler language @{trait|${ + this.options.serviceNamespace + }#handler|language} cannot be referenced unless a handler project is configured for this language. + Configured handler project languages are: ${this.options.handlerLanguages?.join( + ", " + )}. + You can add this language by configuring TypeSafeApiProject in your .projenrc + """ + } + }` + : `{ + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: ${this.options.serviceNamespace}#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + }`; + + return `// ${this.marker} + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: ${this.options.serviceNamespace}#handler + selector: """ + :not([@trait|${ + this.options.serviceNamespace + }#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|${ + this.options.serviceNamespace + }#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + ${traitValidator} +] + +namespace ${this.options.serviceNamespace} + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// ${ + hasAnyHandlerProjects + ? `You have configured handler projects for ${this.options.handlerLanguages?.join( + ", " + )}` + : "You have not configured any handler projects, so you cannot use this trait." + } +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + +`; + } +} diff --git a/packages/type-safe-api/src/project/model/smithy/components/smithy-build-gradle-file.ts b/packages/type-safe-api/src/project/model/smithy/components/smithy-build-gradle-file.ts index fd3ca7695..c271fa113 100644 --- a/packages/type-safe-api/src/project/model/smithy/components/smithy-build-gradle-file.ts +++ b/packages/type-safe-api/src/project/model/smithy/components/smithy-build-gradle-file.ts @@ -17,7 +17,7 @@ export interface SmithyBuildGradleFileOptions { export class SmithyBuildGradleFile extends FileBase { public static readonly fileDependencyPrefix: string = "file://"; - private readonly modelDir: string; + private readonly sources: string[]; private readonly dependencies: string[]; private readonly repositories: string[]; @@ -26,7 +26,7 @@ export class SmithyBuildGradleFile extends FileBase { marker: true, readonly: true, }); - this.modelDir = options.modelDir; + this.sources = [options.modelDir]; this.dependencies = options.dependencies; this.repositories = options.repositoryUrls?.map( (url) => `maven { url "${url}" }` @@ -40,6 +40,13 @@ export class SmithyBuildGradleFile extends FileBase { this.dependencies.push(...deps); } + /** + * Add source directories to the build.gradle + */ + public addSources(...sources: string[]) { + this.sources.push(...sources); + } + private renderDependency = (dep: string) => { if (dep.startsWith(SmithyBuildGradleFile.fileDependencyPrefix)) { return `files("${dep.substring( @@ -58,7 +65,7 @@ plugins { sourceSets { main { java { - srcDirs = ['${this.modelDir}'] + srcDirs = [${this.sources.map((s) => `'${s}'`).join(", ")}] } } } diff --git a/packages/type-safe-api/src/project/model/smithy/smithy-definition.ts b/packages/type-safe-api/src/project/model/smithy/smithy-definition.ts index e7ed54dee..721ae19e4 100644 --- a/packages/type-safe-api/src/project/model/smithy/smithy-definition.ts +++ b/packages/type-safe-api/src/project/model/smithy/smithy-definition.ts @@ -3,12 +3,14 @@ SPDX-License-Identifier: Apache-2.0 */ import * as path from "path"; import { Component, SampleDir } from "projen"; import { SmithyBuild } from "projen/lib/smithy/smithy-build"; +import { SmithyAwsPdkPrelude } from "./components/smithy-aws-pdk-prelude"; import { SmithyBuildGradleFile } from "./components/smithy-build-gradle-file"; import { SmithySettingsGradleFile } from "./components/smithy-settings-gradle-file"; import { buildTypeSafeApiExecCommand, TypeSafeApiScript, } from "../../codegen/components/utils"; +import { Language } from "../../languages"; import { SmithyModelOptions } from "../../types"; import { TypeSafeApiModelProject } from "../type-safe-api-model-project"; @@ -20,6 +22,10 @@ export interface SmithyDefinitionOptions { * Smithy engine options */ readonly smithyOptions: SmithyModelOptions; + /** + * The languages users have specified for handler projects (if any) + */ + readonly handlerLanguages?: Language[]; } /** @@ -56,7 +62,7 @@ export class SmithyDefinition extends Component { ) { super(project); - const { smithyOptions } = options; + const { smithyOptions, handlerLanguages } = options; // Ignore gradle wrapper by default if (smithyOptions.ignoreGradleWrapper ?? true) { @@ -111,6 +117,8 @@ export class SmithyDefinition extends Component { const { namespace: serviceNamespace, serviceName } = smithyOptions.serviceName; + const firstHandlerLanguage = options.handlerLanguages?.[0]; + // Create the default smithy model new SampleDir(project, modelDir, { files: { @@ -134,7 +142,11 @@ service ${serviceName} { namespace ${serviceNamespace} @readonly -@http(method: "GET", uri: "/hello") +@http(method: "GET", uri: "/hello")${ + firstHandlerLanguage + ? `\n@handler(language: "${firstHandlerLanguage}")` + : "" + } operation SayHello { input := { @httpQuery("name") @@ -231,6 +243,15 @@ structure NotAuthorizedError { }, }); + // Add the smithy prelude (managed by aws-pdk) + const generatedModelDir = path.join("generated", "main", "smithy"); + new SmithyAwsPdkPrelude(project, { + generatedModelDir, + serviceNamespace, + handlerLanguages, + }); + this.addSources(generatedModelDir); + const projectionOutputPath = path.join( "build", "smithyprojections", @@ -300,7 +321,9 @@ structure NotAuthorizedError { * resolved as relative paths. */ public addSources(...sources: string[]) { - this.smithyBuild.addSources(...this.asRelativePathsToProject(sources)); + const relativeSources = this.asRelativePathsToProject(sources); + this.smithyBuild.addSources(...relativeSources); + this.smithyBuildGradleFile.addSources(...relativeSources); } /** diff --git a/packages/type-safe-api/src/project/model/type-safe-api-model-project.ts b/packages/type-safe-api/src/project/model/type-safe-api-model-project.ts index 78c9d0889..3bd5421f6 100644 --- a/packages/type-safe-api/src/project/model/type-safe-api-model-project.ts +++ b/packages/type-safe-api/src/project/model/type-safe-api-model-project.ts @@ -8,6 +8,7 @@ import { buildTypeSafeApiExecCommand, TypeSafeApiScript, } from "../codegen/components/utils"; +import { Language } from "../languages"; import { ModelLanguage, ModelOptions } from "../types"; export interface TypeSafeApiModelProjectOptions extends ProjectOptions { @@ -19,6 +20,10 @@ export interface TypeSafeApiModelProjectOptions extends ProjectOptions { * Options for the model */ readonly modelOptions: ModelOptions; + /** + * The languages users have specified for handler projects (if any) + */ + readonly handlerLanguages?: Language[]; } export class TypeSafeApiModelProject extends Project { @@ -47,10 +52,7 @@ export class TypeSafeApiModelProject extends Project { this.generateTask = this.addTask("generate"); // Add the API definition - const { specPath, smithy, openapi } = this.addApiDefinition( - options.modelLanguage, - options.modelOptions - ); + const { specPath, smithy, openapi } = this.addApiDefinition(options); this.smithy = smithy; this.openapi = openapi; @@ -75,10 +77,11 @@ export class TypeSafeApiModelProject extends Project { }); } - private addApiDefinition = ( - modelLanguage: ModelLanguage, - modelOptions: ModelOptions - ) => { + private addApiDefinition = ({ + modelLanguage, + modelOptions, + handlerLanguages, + }: TypeSafeApiModelProjectOptions) => { if (modelLanguage === ModelLanguage.SMITHY) { if (!modelOptions.smithy) { throw new Error( @@ -89,6 +92,7 @@ export class TypeSafeApiModelProject extends Project { const smithyOptions = modelOptions.smithy; const smithy = new SmithyDefinition(this, { smithyOptions, + handlerLanguages, }); return { smithy, specPath: smithy.openApiSpecificationPath }; @@ -102,6 +106,7 @@ export class TypeSafeApiModelProject extends Project { const openApiOptions = modelOptions.openapi; const openapi = new OpenApiDefinition(this, { openApiOptions, + handlerLanguages, }); return { openapi, specPath: openapi.openApiSpecificationPath }; } else { diff --git a/packages/type-safe-api/src/project/type-safe-api-project.ts b/packages/type-safe-api/src/project/type-safe-api-project.ts index 2c1fcf7f0..b83e04fc5 100644 --- a/packages/type-safe-api/src/project/type-safe-api-project.ts +++ b/packages/type-safe-api/src/project/type-safe-api-project.ts @@ -20,6 +20,7 @@ import { generateDocsProjects, generateInfraProject, generateLibraryProjects, + generateHandlersProjects, } from "./codegen/generate"; import { GeneratedJavaRuntimeProject } from "./codegen/runtime/generated-java-runtime-project"; import { GeneratedPythonRuntimeProject } from "./codegen/runtime/generated-python-runtime-project"; @@ -36,6 +37,8 @@ import { ModelLanguage, ModelOptions, GeneratedInfrastructureCodeOptions, + GeneratedHandlersCodeOptions, + ProjectCollections, } from "./types"; /** @@ -81,6 +84,21 @@ export interface InfrastructureConfiguration { readonly options?: GeneratedInfrastructureCodeOptions; } +/** + * Configuration for generated lambda handlers + */ +export interface HandlersConfiguration { + /** + * The languages lambda handlers are written in. Specify multiple languages if you wish to implement different operations + * as AWS Lambda functions in different languages. + */ + readonly languages: Language[]; + /** + * Options for the infrastructure package. Note that only those provided for the specified language will apply. + */ + readonly options?: GeneratedHandlersCodeOptions; +} + /** * Configuration for generated documentation */ @@ -125,6 +143,10 @@ export interface TypeSafeApiProjectOptions extends ProjectOptions { * Configuration for generated infrastructure */ readonly infrastructure: InfrastructureConfiguration; + /** + * Configuration for lambda handlers for implementing the API + */ + readonly handlers?: HandlersConfiguration; /** * Configuration for generated documentation */ @@ -157,6 +179,10 @@ export class TypeSafeApiProject extends Project { * Generated infrastructure projects. Only the property corresponding to `infrastructure.language` will be defined. */ public readonly infrastructure: GeneratedCodeProjects; + /** + * Lambda handlers projects. Only the properties corresponding to `handlers.languages` will be defined. + */ + public readonly handlers: GeneratedCodeProjects; /** * Generated library projects. Only the properties corresponding to specified `library.libraries` will be defined. */ @@ -165,6 +191,10 @@ export class TypeSafeApiProject extends Project { * Generated documentation projects. Only the properties corresponding to specified `documentation.formats` will be defined. */ public readonly documentation: GeneratedDocumentationProjects; + /** + * Collections of all sub-projects managed by this project + */ + public readonly all: ProjectCollections; constructor(options: TypeSafeApiProjectOptions) { super(options); @@ -177,6 +207,8 @@ export class TypeSafeApiProject extends Project { ProjectUtils.isNamedInstanceOf(this.parent, NxMonorepoJavaProject) || ProjectUtils.isNamedInstanceOf(this.parent, NxMonorepoPythonProject)); + const handlerLanguages = [...new Set(options.handlers?.languages ?? [])]; + // API Definition project containing the model const modelDir = "model"; this.model = new TypeSafeApiModelProject({ @@ -185,14 +217,16 @@ export class TypeSafeApiProject extends Project { name: `${options.name}-model`, modelLanguage: options.model.language, modelOptions: options.model.options, + handlerLanguages, }); // Ensure we always generate a runtime project for the infrastructure language, regardless of what was specified by - // the user + // the user. Likewise we generate a runtime project for any handler languages specified const runtimeLanguages = [ ...new Set([ ...options.runtime.languages, options.infrastructure.language, + ...(options.handlers?.languages ?? []), ]), ]; @@ -337,6 +371,99 @@ export class TypeSafeApiProject extends Project { : undefined, }; + const handlersDir = "handlers"; + const handlersDirRelativeToParent = nxWorkspace + ? path.join(options.outdir!, handlersDir) + : handlersDir; + + const relativePathToModelDirFromHandlersDir = path.relative( + path.join(this.outdir, handlersDir, "language"), + path.join(this.outdir, modelDir) + ); + const parsedSpecRelativeToHandlersDir = path.join( + relativePathToModelDirFromHandlersDir, + this.model.parsedSpecFile + ); + const smithyJsonModelPathRelativeToHandlersDir = this.model.smithy + ? path.join( + relativePathToModelDirFromHandlersDir, + this.model.smithy.smithyJsonModelPath + ) + : undefined; + + // Declare the generated handlers projects + const generatedHandlersProjects = generateHandlersProjects( + handlerLanguages, + { + parent: nxWorkspace ? this.parent! : this, + parentPackageName: this.name, + generatedCodeDir: handlersDirRelativeToParent, + isWithinMonorepo: isNxWorkspace, + // Spec path relative to each generated handlers package dir + parsedSpecPath: parsedSpecRelativeToHandlersDir, + // Smithy model path relative to each generated handlers package dir + smithyJsonModelPath: smithyJsonModelPathRelativeToHandlersDir, + typescriptOptions: { + // Try to infer monorepo default release branch, otherwise default to mainline unless overridden + defaultReleaseBranch: nxWorkspace?.affected.defaultBase ?? "mainline", + packageManager: + this.parent && + ProjectUtils.isNamedInstanceOf(this.parent, NodeProject) + ? this.parent.package.packageManager + : NodePackageManager.YARN, + ...options.handlers?.options?.typescript, + }, + pythonOptions: { + authorName: "APJ Cope", + authorEmail: "apj-cope@amazon.com", + version: "0.0.0", + ...options.handlers?.options?.python, + }, + javaOptions: { + version: "0.0.0", + ...options.handlers?.options?.java, + }, + generatedRuntimes: { + typescript: this.runtime.typescript as + | GeneratedTypescriptRuntimeProject + | undefined, + python: this.runtime.python as + | GeneratedPythonRuntimeProject + | undefined, + java: this.runtime.java as GeneratedJavaRuntimeProject | undefined, + }, + } + ); + + this.handlers = { + typescript: generatedHandlersProjects[Language.TYPESCRIPT] + ? (generatedHandlersProjects[Language.TYPESCRIPT] as TypeScriptProject) + : undefined, + java: generatedHandlersProjects[Language.JAVA] + ? (generatedHandlersProjects[Language.JAVA] as JavaProject) + : undefined, + python: generatedHandlersProjects[Language.PYTHON] + ? (generatedHandlersProjects[Language.PYTHON] as PythonProject) + : undefined, + }; + + // Ensure the handlers project depends on the appropriate runtime projects + if (this.handlers.typescript) { + NxProject.ensure(this.handlers.typescript).addImplicitDependency( + this.runtime.typescript! + ); + } + if (this.handlers.java) { + NxProject.ensure(this.handlers.java).addImplicitDependency( + this.runtime.java! + ); + } + if (this.handlers.python) { + NxProject.ensure(this.handlers.python).addImplicitDependency( + this.runtime.python! + ); + } + const infraDir = path.join(generatedDir, "infrastructure"); const infraDirRelativeToParent = nxWorkspace ? path.join(options.outdir!, infraDir) @@ -416,6 +543,30 @@ export class TypeSafeApiProject extends Project { NxProject.ensure(infraProject).addImplicitDependency(this.model); + // Expose collections of projects + const allRuntimes = Object.values(generatedRuntimeProjects); + const allInfrastructure = [infraProject]; + const allLibraries = Object.values(generatedLibraryProjects); + const allDocumentation = Object.values(generatedDocs); + const allHandlers = Object.values(generatedHandlersProjects); + + this.all = { + model: [this.model], + runtimes: allRuntimes, + infrastructure: allInfrastructure, + libraries: allLibraries, + documentation: allDocumentation, + handlers: allHandlers, + projects: [ + this.model, + ...allRuntimes, + ...allInfrastructure, + ...allLibraries, + ...allDocumentation, + ...allHandlers, + ], + }; + if (!nxWorkspace) { // Add a task for the non-monorepo case to build the projects in the right order [ diff --git a/packages/type-safe-api/src/project/types.ts b/packages/type-safe-api/src/project/types.ts index 6827c383a..b0d5ecf47 100644 --- a/packages/type-safe-api/src/project/types.ts +++ b/packages/type-safe-api/src/project/types.ts @@ -208,6 +208,33 @@ export interface GeneratedJavaInfrastructureOptions GeneratedWithOpenApiGeneratorOptions, MockResponseGenerationOptions {} +/** + * Options for configuring a generated typescript handlers project + */ +export interface GeneratedTypeScriptHandlersOptions + extends TypeScriptProjectOptions, + GeneratedWithOpenApiGeneratorOptions { + /** + * Globs for lambda handler entry points, used by esbuild + * @default src/*.ts - all files directly under the src directory + */ + readonly handlerEntryPoints?: string[]; +} + +/** + * Options for configuring a generated python handlers project + */ +export interface GeneratedPythonHandlersOptions + extends PythonProjectOptions, + GeneratedWithOpenApiGeneratorOptions {} + +/** + * Options for configuring a generated java handlers project + */ +export interface GeneratedJavaHandlersOptions + extends JavaProjectOptions, + GeneratedWithOpenApiGeneratorOptions {} + /** * Options for configuring a generated typescript hooks library project */ @@ -234,7 +261,7 @@ export interface GeneratedRuntimeCodeOptions { } /** - * Options for generated clients + * Options for generated infrastructure */ export interface GeneratedInfrastructureCodeOptions { /** @@ -251,6 +278,58 @@ export interface GeneratedInfrastructureCodeOptions { readonly java?: GeneratedJavaInfrastructureOptions; } +/** + * Options for lambda handler projects for implementing API operations + */ +export interface GeneratedHandlersCodeOptions { + /** + * Options for the typescript handlers project. These override the default inferred options. + */ + readonly typescript?: GeneratedTypeScriptHandlersOptions; + /** + * Options for the python handlers project. These override the default inferred options. + */ + readonly python?: GeneratedPythonHandlersOptions; + /** + * Options for the java handlers project. These override the default inferred options. + */ + readonly java?: GeneratedJavaHandlersOptions; +} + +/** + * Collections of projects managed by type-safe-api + */ +export interface ProjectCollections { + /** + * Array of all projects managed by type-safe-api + */ + readonly projects: Project[]; + /** + * Array of all model projects + */ + readonly model: Project[]; + /** + * Array of all runtime projects + */ + readonly runtimes: Project[]; + /** + * Array of all infrastructure projects + */ + readonly infrastructure: Project[]; + /** + * Array of all library projects + */ + readonly libraries: Project[]; + /** + * Array of all documentation projects + */ + readonly documentation: Project[]; + /** + * Array of all handler projects + */ + readonly handlers: Project[]; +} + /** * Generated code projects */ diff --git a/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap b/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap index 6024f3bf7..66da0035f 100644 --- a/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap +++ b/packages/type-safe-api/test/project/__snapshots__/type-safe-api-project.test.ts.snap @@ -74,6 +74,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -87,6 +88,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -2592,6 +2594,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -2843,28 +2850,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -3038,6 +3071,7 @@ exports[`Type Safe Api Project Unit Tests OpenApi With java Infra in Monorepo 1` /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -3090,6 +3124,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -3245,6 +3280,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -6803,6 +6839,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -7113,28 +7154,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -7284,6 +7351,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -7297,6 +7365,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -9698,6 +9767,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -9949,28 +10023,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -10144,6 +10244,7 @@ exports[`Type Safe Api Project Unit Tests OpenApi With python Infra in Monorepo /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -10196,6 +10297,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -10351,6 +10453,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -13814,6 +13917,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -14124,28 +14232,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -14295,6 +14429,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -14308,6 +14443,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -17023,6 +17159,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -17274,28 +17415,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -17469,6 +17636,7 @@ exports[`Type Safe Api Project Unit Tests OpenApi With typescript Infra in Monor /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -17521,6 +17689,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -17676,6 +17845,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -21438,6 +21608,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -21748,28 +21923,54 @@ paths: type: string required: true responses: - '200': + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -21909,7 +22110,7 @@ components: } `; -exports[`Type Safe Api Project Unit Tests Smithy With TypeScript react-query hooks library 1`] = ` +exports[`Type Safe Api Project Unit Tests Smithy With Handlers 1`] = ` { ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ @@ -21918,7 +22119,7 @@ node_modules/ !/.projen/deps.json !/.projen/files.json !/generated/runtime/README.md -!/generated/libraries/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -21930,8 +22131,8 @@ node_modules/ ".projen/files.json", ".projen/tasks.json", "generated/infrastructure/README.md", - "generated/libraries/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -21974,11 +22175,15 @@ node_modules/ "exec": "npx projen build", }, { - "cwd": "generated/infrastructure/typescript", + "cwd": "generated/runtime/java", "exec": "npx projen build", }, { - "cwd": "generated/libraries/typescript-react-query-hooks", + "cwd": "generated/runtime/python", + "exec": "npx projen build", + }, + { + "cwd": "generated/infrastructure/typescript", "exec": "npx projen build", }, ], @@ -22187,7 +22392,7 @@ mocks "type": "runtime", }, { - "name": "smithy-typescript-react-query-hooks-typescript-runtime", + "name": "smithy-handlers-typescript-runtime", "type": "runtime", "version": "file:../../runtime/typescript", }, @@ -22264,7 +22469,7 @@ mocks "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", }, { - "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator typescript-fetch --spec-path ../../../model/.api.json --output-path . --generator-dir typescript-cdk-infrastructure --src-dir src --smithy-json-path ../../../model/build/smithyprojections/smithy-typescript-react-query-hooks-model/openapi/model/model.json --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-package-name":"smithy-typescript-react-query-hooks-typescript-runtime","x-relative-spec-path":"../assets/api.json","x-enable-mock-integrations":true}' --generate-alias-as-model", + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator typescript-fetch --spec-path ../../../model/.api.json --output-path . --generator-dir typescript-cdk-infrastructure --src-dir src --smithy-json-path ../../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-package-name":"smithy-handlers-typescript-runtime","x-relative-spec-path":"../assets/api.json","x-enable-mock-integrations":true}' --generate-alias-as-model", }, { "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate-mock-data --spec-path ../../../model/.api.json --output-path .", @@ -22282,7 +22487,7 @@ mocks "name": "install", "steps": [ { - "exec": "yarn link smithy-typescript-react-query-hooks-typescript-runtime", + "exec": "yarn link smithy-handlers-typescript-runtime", }, { "exec": "yarn install --check-files", @@ -22342,19 +22547,19 @@ mocks "exec": "yarn upgrade npm-check-updates", }, { - "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", }, { - "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", }, { - "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", }, { - "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", }, { - "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", }, { "exec": "yarn install --check-files", @@ -22601,7 +22806,7 @@ mocks "aws-cdk-lib": "*", "cdk-nag": "*", "constructs": "*", - "smithy-typescript-react-query-hooks-typescript-runtime": "file:../../runtime/typescript", + "smithy-handlers-typescript-runtime": "file:../../runtime/typescript", }, "devDependencies": { "@types/node": "^16", @@ -22611,7 +22816,7 @@ mocks }, "license": "Apache-2.0", "main": "lib/index.js", - "name": "smithy-typescript-react-query-hooks-typescript-infra", + "name": "smithy-handlers-typescript-infra", "scripts": { "build": "npx projen build", "compile": "npx projen compile", @@ -22632,10 +22837,10 @@ mocks "generated/infrastructure/typescript/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "implicitDependencies": [ - "smithy-typescript-react-query-hooks-typescript-runtime", - "smithy-typescript-react-query-hooks-model", + "smithy-handlers-typescript-runtime", + "smithy-handlers-model", ], - "name": "smithy-typescript-react-query-hooks-typescript-infra", + "name": "smithy-handlers-typescript-infra", "root": "generated/infrastructure/typescript", "targets": { "build": { @@ -22789,147 +22994,4806 @@ mocks "src/**/*.ts", ], }, - "generated/libraries/README.md": "## Generated Libraries + "generated/runtime/README.md": "## Generated Runtimes -This directory contains generated libraries based on your API model.", - "generated/libraries/typescript-react-query-hooks/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +This directory contains generated runtime projects based on your API model. + +Each runtime project includes types from your API model, as well as type-safe client and server code.", + "generated/runtime/java/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". /.gitattributes linguist-generated /.gitignore linguist-generated -/.npmrc linguist-generated /.openapi-generator-ignore linguist-generated -/.openapi-generator-ignore-handlebars linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated /.projen/tasks.json linguist-generated -/LICENSE linguist-generated /openapitools.json linguist-generated -/package.json linguist-generated -/tsconfig.dev.json linguist-generated -/tsconfig.json linguist-generated -/yarn.lock linguist-generated", - "generated/libraries/typescript-react-query-hooks/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/pom.xml linguist-generated", + "generated/runtime/java/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ !/.gitattributes !/.projen/tasks.json !/.projen/deps.json !/.projen/files.json -!/package.json -!/LICENSE -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json -pids -*.pid -*.seed -*.pid.lock -lib-cov -coverage -*.lcov -.nyc_output -build/Release -node_modules/ -jspm_packages/ -*.tsbuildinfo -.eslintcache -*.tgz -.yarn-integrity -.cache -!/.projenrc.js -!/.npmrc -!/test/ -!/tsconfig.json -!/tsconfig.dev.json -!/src/ -/lib -/dist/ +!/pom.xml +.classpath +.project +.settings +target +dist/java !/.openapi-generator-ignore -!/.openapi-generator-ignore-handlebars !/openapitools.json src -.npmignore +docs +api README.md .openapi-generator ", - "generated/libraries/typescript-react-query-hooks/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + "generated/runtime/java/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". .gitignore -package.json -tsconfig.json -tsconfig.esm.json -.npmignore -**/*Hooks.ts -", - "generated/libraries/typescript-react-query-hooks/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -/* -**/* -* -!**/*Hooks.ts +pom.xml +gradle +gradle/**/* +gradlew +gradle.properties +gradlew.bat +build.gradle +settings.gradle +build.sbt +.travis.yml +git_push.sh +src/test +src/test/**/* +src/main/AndroidManifest.xml ", - "generated/libraries/typescript-react-query-hooks/.projen/deps.json": { + "generated/runtime/java/.projen/deps.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "dependencies": [ { - "name": "@types/node", + "metadata": { + "configuration": { + "source": "1.8", + "target": "1.8", + }, + }, + "name": "org.apache.maven.plugins/maven-compiler-plugin", "type": "build", - "version": "^16", + "version": "3.8.1", }, { - "name": "@types/react", + "metadata": { + "configuration": { + "rules": [ + { + "requireMavenVersion": [ + { + "version": "3.6", + }, + ], + }, + ], + }, + "executions": [ + { + "goals": [ + "enforce", + ], + "id": "enforce-maven", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-enforcer-plugin", "type": "build", + "version": "3.0.0-M3", }, { - "name": "npm-check-updates", + "metadata": { + "configuration": { + "archive": { + "index": true, + "manifest": { + "addDefaultImplementationEntries": true, + "addDefaultSpecificationEntries": true, + }, + }, + }, + }, + "name": "org.apache.maven.plugins/maven-jar-plugin", "type": "build", - "version": "^16", + "version": "3.2.0", }, { - "name": "projen", + "metadata": { + "configuration": { + "additionalJOptions": { + "additionalJOption": [ + "-J-XX:+TieredCompilation", + "-J-XX:TieredStopAtLevel=1", + ], + }, + "detectJavaApiLink": false, + "failOnError": false, + "show": "protected", + }, + "executions": [ + { + "goals": [ + "jar", + ], + "id": "attach-javadocs", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-javadoc-plugin", "type": "build", + "version": "3.2.0", }, { - "name": "react", + "metadata": { + "executions": [ + { + "goals": [ + "jar", + ], + "id": "attach-sources", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-source-plugin", "type": "build", + "version": "3.2.1", }, { - "name": "typescript", - "type": "build", + "name": "com.amazonaws/aws-lambda-java-core", + "type": "runtime", + "version": "1.2.1", }, { - "name": "react", - "type": "peer", + "name": "com.amazonaws/aws-lambda-java-events", + "type": "runtime", + "version": "3.11.0", }, { - "name": "@tanstack/react-query", + "name": "com.google.code.findbugs/jsr305", + "type": "runtime", + "version": "3.0.2", + }, + { + "name": "com.google.code.gson/gson", + "type": "runtime", + "version": "2.9.1", + }, + { + "name": "com.squareup.okhttp3/logging-interceptor", + "type": "runtime", + "version": "4.10.0", + }, + { + "name": "com.squareup.okhttp3/okhttp", + "type": "runtime", + "version": "4.10.0", + }, + { + "name": "io.gsonfire/gson-fire", + "type": "runtime", + "version": "1.8.5", + }, + { + "name": "io.swagger/swagger-annotations", + "type": "runtime", + "version": "1.6.8", + }, + { + "name": "jakarta.annotation/jakarta.annotation-api", + "type": "runtime", + "version": "1.3.5", + }, + { + "name": "javax.ws.rs/javax.ws.rs-api", + "type": "runtime", + "version": "2.1.1", + }, + { + "name": "javax.ws.rs/jsr311-api", + "type": "runtime", + "version": "1.1.1", + }, + { + "name": "org.apache.commons/commons-lang3", "type": "runtime", + "version": "3.12.0", + }, + { + "name": "org.openapitools/jackson-databind-nullable", + "type": "runtime", + "version": "0.2.4", + }, + { + "name": "org.projectlombok/lombok", + "type": "runtime", + "version": "1.18.24", + }, + { + "name": "org.junit.jupiter/junit-jupiter-api", + "type": "test", + "version": "5.9.1", + }, + { + "name": "org.mockito/mockito-core", + "type": "test", + "version": "3.12.4", }, ], }, - "generated/libraries/typescript-react-query-hooks/.projen/files.json": { + "generated/runtime/java/.projen/files.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", "files": [ ".gitattributes", ".gitignore", - ".npmrc", ".openapi-generator-ignore", - ".openapi-generator-ignore-handlebars", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", - "LICENSE", "openapitools.json", - "tsconfig.dev.json", - "tsconfig.json", + "pom.xml", ], }, - "generated/libraries/typescript-react-query-hooks/.projen/tasks.json": { + "generated/runtime/java/.projen/tasks.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", - "env": { - "PATH": "$(npx -c "node --print process.env.PATH")", - }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "mvn compiler:compile", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../../..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator java --spec-path ../../../model/.api.json --output-path . --generator-dir java --src-dir src/main/java/com/generated/api/smithyhandlersjavaruntime/runtime --smithy-json-path ../../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --additional-properties "useSingleRequestParameter=true,groupId=com.generated.api,artifactId=smithy-handlers-java-runtime,artifactVersion=0.0.0,invokerPackage=com.generated.api.smithyhandlersjavaruntime.runtime,apiPackage=com.generated.api.smithyhandlersjavaruntime.runtime.api,modelPackage=com.generated.api.smithyhandlersjavaruntime.runtime.model,hideGenerationTimestamp=true,additionalModelTypeAnnotations=@lombok.AllArgsConstructor\\ @lombok.experimental.SuperBuilder" --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true"", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "env": { + "MAVEN_OPTS": "-XX:+TieredCompilation -XX:TieredStopAtLevel=1", + }, + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/java", + }, + { + "exec": "mvn deploy -D=altDeploymentRepository=local::default::file:///$PWD/dist/java", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "generated/runtime/java/README.md": "# replace this", + "generated/runtime/java/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "generated/runtime/java/pom.xml": " + + 4.0.0 + com.generated.api + smithy-handlers-java-runtime + 0.0.0 + jar + smithyhandlersjavaruntime + + UTF-8 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + 3.6 + + + + + + enforce-maven + + enforce + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + true + + true + true + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + false + protected + false + + -J-XX:+TieredCompilation + -J-XX:TieredStopAtLevel=1 + + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar + + + + + + + + + com.amazonaws + aws-lambda-java-core + 1.2.1 + + + com.amazonaws + aws-lambda-java-events + 3.11.0 + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.google.code.gson + gson + 2.9.1 + + + com.squareup.okhttp3 + logging-interceptor + 4.10.0 + + + com.squareup.okhttp3 + okhttp + 4.10.0 + + + io.gsonfire + gson-fire + 1.8.5 + + + io.swagger + swagger-annotations + 1.6.8 + + + jakarta.annotation + jakarta.annotation-api + 1.3.5 + + + javax.ws.rs + javax.ws.rs-api + 2.1.1 + + + javax.ws.rs + jsr311-api + 1.1.1 + + + org.apache.commons + commons-lang3 + 3.12.0 + + + org.openapitools + jackson-databind-nullable + 0.2.4 + + + org.projectlombok + lombok + 1.18.24 + + + org.junit.jupiter + junit-jupiter-api + 5.9.1 + test + + + org.mockito + mockito-core + 3.12.4 + test + + + +", + "generated/runtime/python/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.openapi-generator-ignore linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/openapitools.json linguist-generated +/pyproject.toml linguist-generated", + "generated/runtime/python/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/pyproject.toml +/poetry.toml +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ +*.mo +*.pot +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +instance/ +.webassets-cache +.scrapy +docs/_build/ +.pybuilder/ +target/ +.ipynb_checkpoints +profile_default/ +ipython_config.py +__pypackages__/ +celerybeat-schedule +celerybeat.pid +*.sage.py +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.spyderproject +.spyproject +.ropeproject +/site +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +cython_debug/ +!/.openapi-generator-ignore +!/openapitools.json +smithy_handlers_python_runtime +docs +README.md +.openapi-generator +", + "generated/runtime/python/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +test +test/* +test/**/* +.gitlab-ci.yml +.travis.yml +git_push.sh +tox.ini +requirements.txt +test-requirements.txt +setup.py +setup.cfg +", + "generated/runtime/python/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "certifi", + "type": "runtime", + "version": "^14.5.14", + }, + { + "name": "frozendict", + "type": "runtime", + "version": "~2.3.4", + }, + { + "name": "python-dateutil", + "type": "runtime", + "version": "~2.7.0", + }, + { + "name": "setuptools", + "type": "runtime", + "version": "^21.0.0", + }, + { + "name": "typing_extensions", + "type": "runtime", + "version": "~4.3.0", + }, + { + "name": "urllib3", + "type": "runtime", + "version": "~1.26.7", + }, + ], + }, + "generated/runtime/python/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".openapi-generator-ignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "openapitools.json", + "poetry.toml", + "pyproject.toml", + ], + }, + "generated/runtime/python/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(echo $(poetry env info -p)/bin:$PATH)", + "VIRTUAL_ENV": "$(poetry env info -p)", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../../..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator python --spec-path ../../../model/.api.json --output-path . --generator-dir python --src-dir smithy_handlers_python_runtime --smithy-json-path ../../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --additional-properties "packageName=smithy_handlers_python_runtime,projectName=smithy-handlers-python-runtime" --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --generate-alias-as-model", + }, + ], + }, + "install": { + "description": "Install and upgrade dependencies", + "name": "install", + "steps": [ + { + "exec": "mkdir -p smithy_handlers_python_runtime && touch smithy_handlers_python_runtime/__init__.py", + }, + { + "exec": "poetry update", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "poetry build", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "publish": { + "description": "Uploads the package to PyPI.", + "name": "publish", + "steps": [ + { + "exec": "poetry publish", + }, + ], + }, + "publish:test": { + "description": "Uploads the package against a test PyPI endpoint.", + "name": "publish:test", + "steps": [ + { + "exec": "poetry publish -r testpypi", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "generated/runtime/python/README.md": "# replace this", + "generated/runtime/python/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "generated/runtime/python/poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +[repositories.testpypi] +url = "https://test.pypi.org/legacy/" +", + "generated/runtime/python/pyproject.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +[build-system] +requires = [ "poetry_core>=1.0.0" ] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "smithy-handlers-python-runtime" +version = "0.0.0" +description = "" +authors = [ "APJ Cope " ] +readme = "README.md" +include = [ + "smithy_handlers_python_runtime", + "smithy_handlers_python_runtime/**/*.py" +] +dev-dependencies = { } + + [[tool.poetry.packages]] + include = "smithy_handlers_python_runtime" + + [tool.poetry.dependencies] + certifi = "^14.5.14" + frozendict = "~2.3.4" + python-dateutil = "~2.7.0" + setuptools = "^21.0.0" + typing_extensions = "~4.3.0" + urllib3 = "~1.26.7" + python = "^3.7" +", + "generated/runtime/typescript/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.npmignore linguist-generated +/.npmrc linguist-generated +/.openapi-generator-ignore linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/LICENSE linguist-generated +/openapitools.json linguist-generated +/package.json linguist-generated +/tsconfig.dev.json linguist-generated +/tsconfig.json linguist-generated +/yarn.lock linguist-generated", + "generated/runtime/typescript/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/package.json +!/LICENSE +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +!/.projenrc.js +!/.npmrc +!/test/ +!/tsconfig.json +!/tsconfig.dev.json +!/src/ +/lib +/dist/ +!/.npmignore +!/.openapi-generator-ignore +!/openapitools.json +src +.npmignore +README.md +.openapi-generator +", + "generated/runtime/typescript/.npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/.projen/ +/src +/dist +", + "generated/runtime/typescript/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +package.json +tsconfig.json +tsconfig.esm.json +.npmignore +", + "generated/runtime/typescript/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "@types/node", + "type": "build", + "version": "^16", + }, + { + "name": "npm-check-updates", + "type": "build", + "version": "^16", + }, + { + "name": "projen", + "type": "build", + }, + { + "name": "typescript", + "type": "build", + }, + { + "name": "@types/aws-lambda", + "type": "runtime", + }, + ], + }, + "generated/runtime/typescript/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".npmignore", + ".npmrc", + ".openapi-generator-ignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "LICENSE", + "openapitools.json", + "tsconfig.dev.json", + "tsconfig.json", + ], + }, + "generated/runtime/typescript/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(npx -c "node --print process.env.PATH")", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "tsc --build", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../../..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator typescript-fetch --spec-path ../../../model/.api.json --output-path . --generator-dir typescript --src-dir src --smithy-json-path ../../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --additional-properties "npmName=smithy-handlers-typescript-runtime,typescriptThreePlus=true,useSingleParameter=true,supportsES6=true" --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --generate-alias-as-model", + }, + ], + }, + "install": { + "description": "Install project dependencies and update lockfile (non-frozen)", + "name": "install", + "steps": [ + { + "exec": "yarn install --check-files", + }, + { + "exec": "yarn link", + }, + ], + }, + "install:ci": { + "description": "Install project dependencies using frozen lockfile", + "name": "install:ci", + "steps": [ + { + "exec": "yarn install --check-files --frozen-lockfile", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/js", + }, + { + "exec": "mv $(npm pack) dist/js/", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "post-upgrade": { + "description": "Runs after upgrading dependencies", + "name": "post-upgrade", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + "upgrade": { + "description": "upgrade dependencies", + "env": { + "CI": "0", + }, + "name": "upgrade", + "steps": [ + { + "exec": "yarn upgrade npm-check-updates", + }, + { + "exec": "npm-check-updates --dep dev --upgrade --target=minor", + }, + { + "exec": "npm-check-updates --dep optional --upgrade --target=minor", + }, + { + "exec": "npm-check-updates --dep peer --upgrade --target=minor", + }, + { + "exec": "npm-check-updates --dep prod --upgrade --target=minor", + }, + { + "exec": "npm-check-updates --dep bundle --upgrade --target=minor", + }, + { + "exec": "yarn install --check-files", + }, + { + "exec": "yarn upgrade", + }, + { + "exec": "npx projen", + }, + { + "spawn": "post-upgrade", + }, + ], + }, + "watch": { + "description": "Watch & compile in the background", + "name": "watch", + "steps": [ + { + "exec": "tsc --build -w", + }, + ], + }, + }, + }, + "generated/runtime/typescript/LICENSE": " + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License 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. +", + "generated/runtime/typescript/README.md": "# replace this", + "generated/runtime/typescript/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "generated/runtime/typescript/package.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": { + "@types/aws-lambda": "*", + }, + "devDependencies": { + "@types/node": "^16", + "npm-check-updates": "^16", + "projen": "*", + "typescript": "*", + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "smithy-handlers-typescript-runtime", + "scripts": { + "build": "npx projen build", + "compile": "npx projen compile", + "default": "npx projen default", + "generate": "npx projen generate", + "package": "npx projen package", + "post-compile": "npx projen post-compile", + "post-upgrade": "npx projen post-upgrade", + "pre-compile": "npx projen pre-compile", + "projen": "npx projen", + "test": "npx projen test", + "upgrade": "npx projen upgrade", + "watch": "npx projen watch", + }, + "types": "lib/index.d.ts", + "version": "0.0.0", + }, + "generated/runtime/typescript/tsconfig.dev.json": { + "compilerOptions": { + "alwaysStrict": false, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "noImplicitReturns": false, + "noImplicitThis": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": false, + "strictNullChecks": false, + "strictPropertyInitialization": false, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [ + "node_modules", + ], + "include": [ + ".projenrc.js", + "src/**/*.ts", + "test/**/*.ts", + ], + }, + "generated/runtime/typescript/tsconfig.json": { + "compilerOptions": { + "alwaysStrict": false, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "noImplicitReturns": false, + "noImplicitThis": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "lib", + "resolveJsonModule": true, + "rootDir": "src", + "skipLibCheck": true, + "strict": false, + "strictNullChecks": false, + "strictPropertyInitialization": false, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [], + "include": [ + "src/**/*.ts", + ], + }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", + "handlers/java/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/openapitools.json linguist-generated +/pom.xml linguist-generated +/project.json linguist-generated", + "handlers/java/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/pom.xml +.classpath +.project +.settings +target +dist/java +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +.openapi-generator +!/project.json +", + "handlers/java/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +/* +**/* +* +", + "handlers/java/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/* +**/* +* +!src/main/java/com/generated/api/smithyhandlersjavahandlers/handlers/__all_handlers.java +", + "handlers/java/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "metadata": { + "configuration": { + "source": "1.8", + "target": "1.8", + }, + }, + "name": "org.apache.maven.plugins/maven-compiler-plugin", + "type": "build", + "version": "3.8.1", + }, + { + "metadata": { + "configuration": { + "rules": [ + { + "requireMavenVersion": [ + { + "version": "3.6", + }, + ], + }, + ], + }, + "executions": [ + { + "goals": [ + "enforce", + ], + "id": "enforce-maven", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-enforcer-plugin", + "type": "build", + "version": "3.0.0-M3", + }, + { + "metadata": { + "configuration": { + "archive": { + "index": true, + "manifest": { + "addDefaultImplementationEntries": true, + "addDefaultSpecificationEntries": true, + }, + }, + }, + }, + "name": "org.apache.maven.plugins/maven-jar-plugin", + "type": "build", + "version": "3.2.0", + }, + { + "metadata": { + "configuration": { + "additionalJOptions": { + "additionalJOption": [ + "-J-XX:+TieredCompilation", + "-J-XX:TieredStopAtLevel=1", + ], + }, + "detectJavaApiLink": false, + "failOnError": false, + "show": "protected", + }, + "executions": [ + { + "goals": [ + "jar", + ], + "id": "attach-javadocs", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-javadoc-plugin", + "type": "build", + "version": "3.2.0", + }, + { + "metadata": { + "configuration": { + "createDependencyReducedPom": false, + }, + "executions": [ + { + "goals": [ + "shade", + ], + "id": "shade-task", + "phase": "package", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-shade-plugin", + "type": "build", + "version": "3.3.0", + }, + { + "metadata": { + "executions": [ + { + "goals": [ + "jar", + ], + "id": "attach-sources", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-source-plugin", + "type": "build", + "version": "3.2.1", + }, + { + "name": "com.generated.api/smithy-handlers-java-runtime", + "type": "runtime", + "version": "0.0.0", + }, + ], + }, + "handlers/java/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "openapitools.json", + "pom.xml", + "project.json", + ], + }, + "handlers/java/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "mvn compiler:compile", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator java --spec-path ../../model/.api.json --output-path . --generator-dir java-lambda-handlers --src-dir src/main/java/com/generated/api/smithyhandlersjavahandlers/handlers --smithy-json-path ../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-handlers-package":"com.generated.api.smithyhandlersjavahandlers.handlers","x-runtime-package":"com.generated.api.smithyhandlersjavaruntime.runtime"}'", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "env": { + "MAVEN_OPTS": "-XX:+TieredCompilation -XX:TieredStopAtLevel=1", + }, + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/java", + }, + { + "exec": "mvn deploy -D=altDeploymentRepository=local::default::file:///$PWD/dist/java", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "handlers/java/README.md": "# replace this", + "handlers/java/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "handlers/java/pom.xml": " + + 4.0.0 + com.generated.api + smithy-handlers-java-handlers + 0.0.0 + jar + smithyhandlersjavahandlers + + UTF-8 + + + + file://../../generated/runtime/java/dist/java + com.generated.api-smithy-handlers-java-runtime-repo + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + 3.6 + + + + + + enforce-maven + + enforce + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + true + + true + true + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + false + protected + false + + -J-XX:+TieredCompilation + -J-XX:TieredStopAtLevel=1 + + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.3.0 + + false + + + + shade-task + + shade + + package + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar + + + + + + + + + com.generated.api + smithy-handlers-java-runtime + 0.0.0 + + + +", + "handlers/java/project.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "implicitDependencies": [ + "smithyhandlersjavaruntime", + ], + "name": "smithyhandlersjavahandlers", + "root": "handlers/java", + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen build", + "cwd": "handlers/java", + }, + }, + "compile": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen compile", + "cwd": "handlers/java", + }, + }, + "default": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen default", + "cwd": "handlers/java", + }, + }, + "generate": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen generate", + "cwd": "handlers/java", + }, + }, + "package": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen package", + "cwd": "handlers/java", + }, + }, + "post-compile": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen post-compile", + "cwd": "handlers/java", + }, + }, + "pre-compile": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen pre-compile", + "cwd": "handlers/java", + }, + }, + "test": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen test", + "cwd": "handlers/java", + }, + }, + }, + }, + "handlers/python/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/openapitools.json linguist-generated +/project.json linguist-generated +/pyproject.toml linguist-generated", + "handlers/python/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/pyproject.toml +/poetry.toml +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ +*.mo +*.pot +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +instance/ +.webassets-cache +.scrapy +docs/_build/ +.pybuilder/ +target/ +.ipynb_checkpoints +profile_default/ +ipython_config.py +__pypackages__/ +celerybeat-schedule +celerybeat.pid +*.sage.py +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.spyderproject +.spyproject +.ropeproject +/site +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +cython_debug/ +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +.openapi-generator +!/project.json +", + "handlers/python/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +/* +**/* +* +", + "handlers/python/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/* +**/* +* +!smithy_handlers_python_handlers/__all_handlers.py +", + "handlers/python/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "smithy-handlers-python-runtime", + "type": "runtime", + "version": "{path="../../generated/runtime/python", develop=true}", + }, + ], + }, + "handlers/python/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "openapitools.json", + "poetry.toml", + "project.json", + "pyproject.toml", + ], + }, + "handlers/python/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(echo $(poetry env info -p)/bin:$PATH)", + "VIRTUAL_ENV": "$(poetry env info -p)", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator python --spec-path ../../model/.api.json --output-path . --generator-dir python-lambda-handlers --src-dir smithy_handlers_python_handlers --smithy-json-path ../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"smithy_handlers_python_runtime"}' --generate-alias-as-model", + }, + ], + }, + "install": { + "description": "Install and upgrade dependencies", + "name": "install", + "steps": [ + { + "exec": "poetry update", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "poetry build", + }, + { + "exec": "mkdir -p dist/lambda && rm -rf dist/lambda/*", + }, + { + "exec": "cp -r smithy_handlers_python_handlers dist/lambda/smithy_handlers_python_handlers", + }, + { + "exec": "poetry export --without-hashes --format=requirements.txt > dist/lambda/requirements.txt", + }, + { + "exec": "pip install -r dist/lambda/requirements.txt --target dist/lambda --upgrade", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "publish": { + "description": "Uploads the package to PyPI.", + "name": "publish", + "steps": [ + { + "exec": "poetry publish", + }, + ], + }, + "publish:test": { + "description": "Uploads the package against a test PyPI endpoint.", + "name": "publish:test", + "steps": [ + { + "exec": "poetry publish -r testpypi", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "handlers/python/README.md": "# replace this", + "handlers/python/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "handlers/python/poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +[repositories.testpypi] +url = "https://test.pypi.org/legacy/" +", + "handlers/python/project.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "implicitDependencies": [ + "smithy-handlers-python-runtime", + ], + "name": "smithy-handlers-python-handlers", + "root": "handlers/python", + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen build", + "cwd": "handlers/python", + }, + }, + "compile": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen compile", + "cwd": "handlers/python", + }, + }, + "default": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen default", + "cwd": "handlers/python", + }, + }, + "generate": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen generate", + "cwd": "handlers/python", + }, + }, + "install": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen install", + "cwd": "handlers/python", + }, + }, + "package": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen package", + "cwd": "handlers/python", + }, + }, + "post-compile": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen post-compile", + "cwd": "handlers/python", + }, + }, + "pre-compile": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen pre-compile", + "cwd": "handlers/python", + }, + }, + "publish": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen publish", + "cwd": "handlers/python", + }, + }, + "publish:test": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen publish:test", + "cwd": "handlers/python", + }, + }, + "test": { + "executor": "nx:run-commands", + "options": { + "command": "npx projen test", + "cwd": "handlers/python", + }, + }, + }, + }, + "handlers/python/pyproject.toml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +[build-system] +requires = [ "poetry_core>=1.0.0" ] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "smithy-handlers-python-handlers" +version = "0.0.0" +description = "" +authors = [ "APJ Cope " ] +readme = "README.md" +include = [ + "smithy_handlers_python_handlers", + "smithy_handlers_python_handlers/**/*.py" +] +dev-dependencies = { } + + [[tool.poetry.packages]] + include = "smithy_handlers_python_handlers" + + [tool.poetry.dependencies] + python = "^3.7" + + [tool.poetry.dependencies.smithy-handlers-python-runtime] + path = "../../generated/runtime/python" + develop = true +", + "handlers/python/smithy_handlers_python_handlers/__init__.py": "#", + "handlers/typescript/.eslintrc.json": { + "env": { + "jest": true, + "node": true, + }, + "extends": [ + "plugin:import/typescript", + ], + "ignorePatterns": [ + "*.js", + "*.d.ts", + "node_modules/", + "*.generated.ts", + "coverage", + ], + "overrides": [], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2018, + "project": "./tsconfig.dev.json", + "sourceType": "module", + }, + "plugins": [ + "@typescript-eslint", + "import", + ], + "root": true, + "rules": { + "@typescript-eslint/indent": [ + "error", + 2, + ], + "@typescript-eslint/member-delimiter-style": [ + "error", + ], + "@typescript-eslint/member-ordering": [ + "error", + { + "default": [ + "public-static-field", + "public-static-method", + "protected-static-field", + "protected-static-method", + "private-static-field", + "private-static-method", + "field", + "constructor", + "method", + ], + }, + ], + "@typescript-eslint/no-floating-promises": [ + "error", + ], + "@typescript-eslint/no-require-imports": [ + "error", + ], + "@typescript-eslint/no-shadow": [ + "error", + ], + "@typescript-eslint/return-await": [ + "error", + ], + "array-bracket-newline": [ + "error", + "consistent", + ], + "array-bracket-spacing": [ + "error", + "never", + ], + "brace-style": [ + "error", + "1tbs", + { + "allowSingleLine": true, + }, + ], + "comma-dangle": [ + "error", + "always-multiline", + ], + "comma-spacing": [ + "error", + { + "after": true, + "before": false, + }, + ], + "curly": [ + "error", + "multi-line", + "consistent", + ], + "dot-notation": [ + "error", + ], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": [ + "**/test/**", + "**/build-tools/**", + ], + "optionalDependencies": false, + "peerDependencies": true, + }, + ], + "import/no-unresolved": [ + "error", + ], + "import/order": [ + "warn", + { + "alphabetize": { + "caseInsensitive": true, + "order": "asc", + }, + "groups": [ + "builtin", + "external", + ], + }, + ], + "indent": [ + "off", + ], + "key-spacing": [ + "error", + ], + "keyword-spacing": [ + "error", + ], + "max-len": [ + "error", + { + "code": 150, + "ignoreComments": true, + "ignoreRegExpLiterals": true, + "ignoreStrings": true, + "ignoreTemplateLiterals": true, + "ignoreUrls": true, + }, + ], + "no-bitwise": [ + "error", + ], + "no-duplicate-imports": [ + "error", + ], + "no-multi-spaces": [ + "error", + { + "ignoreEOLComments": false, + }, + ], + "no-multiple-empty-lines": [ + "error", + ], + "no-return-await": [ + "off", + ], + "no-shadow": [ + "off", + ], + "no-trailing-spaces": [ + "error", + ], + "object-curly-newline": [ + "error", + { + "consistent": true, + "multiline": true, + }, + ], + "object-curly-spacing": [ + "error", + "always", + ], + "object-property-newline": [ + "error", + { + "allowAllPropertiesOnSameLine": true, + }, + ], + "quote-props": [ + "error", + "consistent-as-needed", + ], + "quotes": [ + "error", + "single", + { + "avoidEscape": true, + }, + ], + "semi": [ + "error", + "always", + ], + "space-before-blocks": [ + "error", + ], + }, + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [ + ".ts", + ".tsx", + ], + }, + "import/resolver": { + "node": {}, + "typescript": { + "alwaysTryTypes": true, + "project": "./tsconfig.dev.json", + }, + }, + }, + }, + "handlers/typescript/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.eslintrc.json linguist-generated +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.npmignore linguist-generated +/.npmrc linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/LICENSE linguist-generated +/openapitools.json linguist-generated +/package.json linguist-generated +/project.json linguist-generated +/tsconfig.dev.json linguist-generated +/tsconfig.json linguist-generated +/yarn.lock linguist-generated", + "handlers/typescript/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/package.json +!/LICENSE +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +!/.projenrc.js +/test-reports/ +junit.xml +/coverage/ +!/.npmrc +!/test/ +!/tsconfig.json +!/tsconfig.dev.json +!/src/ +/lib +/dist/ +!/.eslintrc.json +!/.npmignore +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +.openapi-generator +!/project.json +", + "handlers/typescript/.npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/.projen/ +/src +/dist +", + "handlers/typescript/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +/* +**/* +* +", + "handlers/typescript/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/* +**/* +* +!src/__all_handlers.ts +", + "handlers/typescript/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "@types/jest", + "type": "build", + }, + { + "name": "@types/node", + "type": "build", + "version": "^16", + }, + { + "name": "@typescript-eslint/eslint-plugin", + "type": "build", + "version": "^5", + }, + { + "name": "@typescript-eslint/parser", + "type": "build", + "version": "^5", + }, + { + "name": "esbuild", + "type": "build", + }, + { + "name": "eslint-import-resolver-node", + "type": "build", + }, + { + "name": "eslint-import-resolver-typescript", + "type": "build", + }, + { + "name": "eslint-plugin-import", + "type": "build", + }, + { + "name": "eslint", + "type": "build", + "version": "^8", + }, + { + "name": "jest", + "type": "build", + }, + { + "name": "jest-junit", + "type": "build", + "version": "^15", + }, + { + "name": "npm-check-updates", + "type": "build", + "version": "^16", + }, + { + "name": "projen", + "type": "build", + }, + { + "name": "ts-jest", + "type": "build", + }, + { + "name": "typescript", + "type": "build", + }, + { + "name": "smithy-handlers-typescript-runtime", + "type": "runtime", + "version": "file:../../generated/runtime/typescript", + }, + ], + }, + "handlers/typescript/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".eslintrc.json", + ".gitattributes", + ".gitignore", + ".npmignore", + ".npmrc", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "LICENSE", + "openapitools.json", + "project.json", + "tsconfig.dev.json", + "tsconfig.json", + ], + }, + "handlers/typescript/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(npx -c "node --print process.env.PATH")", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "tsc --build", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../..", + "exec": "npx projen default", + }, + ], + }, + "eslint": { + "description": "Runs eslint against the codebase", + "name": "eslint", + "steps": [ + { + "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator typescript-fetch --spec-path ../../model/.api.json --output-path . --generator-dir typescript-lambda-handlers --src-dir src --smithy-json-path ../../model/build/smithyprojections/smithy-handlers-model/openapi/model/model.json --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-package-name":"smithy-handlers-typescript-runtime"}' --generate-alias-as-model", + }, + ], + }, + "install": { + "description": "Install project dependencies and update lockfile (non-frozen)", + "name": "install", + "steps": [ + { + "exec": "yarn link smithy-handlers-typescript-runtime", + }, + { + "exec": "yarn install --check-files", + }, + ], + }, + "install:ci": { + "description": "Install project dependencies using frozen lockfile", + "name": "install:ci", + "steps": [ + { + "exec": "yarn install --check-files --frozen-lockfile", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/js", + }, + { + "exec": "mv $(npm pack) dist/js/", + }, + { + "exec": "mkdir -p dist/lambda && rm -rf dist/lambda/*", + }, + { + "exec": "esbuild --bundle src/*.ts --platform=node --outdir=dist/lambda", + }, + { + "exec": "for f in $(ls dist/lambda); do mkdir dist/lambda/$(basename $f .js) && mv dist/lambda/$f dist/lambda/$(basename $f .js)/index.js; done", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "post-upgrade": { + "description": "Runs after upgrading dependencies", + "name": "post-upgrade", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + "steps": [ + { + "exec": "jest --passWithNoTests --updateSnapshot", + "receiveArgs": true, + }, + { + "spawn": "eslint", + }, + ], + }, + "test:watch": { + "description": "Run jest in watch mode", + "name": "test:watch", + "steps": [ + { + "exec": "jest --watch", + }, + ], + }, + "upgrade": { + "description": "upgrade dependencies", + "env": { + "CI": "0", + }, + "name": "upgrade", + "steps": [ + { + "exec": "yarn upgrade npm-check-updates", + }, + { + "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='smithy-handlers-typescript-runtime'", + }, + { + "exec": "yarn install --check-files", + }, + { + "exec": "yarn upgrade", + }, + { + "exec": "npx projen", + }, + { + "spawn": "post-upgrade", + }, + ], + }, + "watch": { + "description": "Watch & compile in the background", + "name": "watch", + "steps": [ + { + "exec": "tsc --build -w", + }, + ], + }, + }, + }, + "handlers/typescript/LICENSE": " + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License 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. +", + "handlers/typescript/README.md": "# replace this", + "handlers/typescript/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "handlers/typescript/package.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": { + "smithy-handlers-typescript-runtime": "file:../../generated/runtime/typescript", + }, + "devDependencies": { + "@types/jest": "*", + "@types/node": "^16", + "@typescript-eslint/eslint-plugin": "^5", + "@typescript-eslint/parser": "^5", + "esbuild": "*", + "eslint": "^8", + "eslint-import-resolver-node": "*", + "eslint-import-resolver-typescript": "*", + "eslint-plugin-import": "*", + "jest": "*", + "jest-junit": "^15", + "npm-check-updates": "^16", + "projen": "*", + "ts-jest": "*", + "typescript": "*", + }, + "jest": { + "clearMocks": true, + "collectCoverage": true, + "coverageDirectory": "coverage", + "coveragePathIgnorePatterns": [ + "/node_modules/", + ], + "coverageReporters": [ + "json", + "lcov", + "clover", + "cobertura", + "text", + ], + "globals": { + "ts-jest": { + "tsconfig": "tsconfig.dev.json", + }, + }, + "preset": "ts-jest", + "reporters": [ + "default", + [ + "jest-junit", + { + "outputDirectory": "test-reports", + }, + ], + ], + "testMatch": [ + "/src/**/__tests__/**/*.ts?(x)", + "/(test|src)/**/*(*.)@(spec|test).ts?(x)", + ], + "testPathIgnorePatterns": [ + "/node_modules/", + ], + "watchPathIgnorePatterns": [ + "/node_modules/", + ], + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "smithy-handlers-typescript-handlers", + "scripts": { + "build": "npx projen build", + "compile": "npx projen compile", + "default": "npx projen default", + "eslint": "npx projen eslint", + "generate": "npx projen generate", + "package": "npx projen package", + "post-compile": "npx projen post-compile", + "post-upgrade": "npx projen post-upgrade", + "pre-compile": "npx projen pre-compile", + "projen": "npx projen", + "test": "npx projen test", + "test:watch": "npx projen test:watch", + "upgrade": "npx projen upgrade", + "watch": "npx projen watch", + }, + "types": "lib/index.d.ts", + "version": "0.0.0", + }, + "handlers/typescript/project.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "implicitDependencies": [ + "smithy-handlers-typescript-runtime", + ], + "name": "smithy-handlers-typescript-handlers", + "root": "handlers/typescript", + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen build", + "cwd": "handlers/typescript", + }, + }, + "compile": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen compile", + "cwd": "handlers/typescript", + }, + }, + "default": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen default", + "cwd": "handlers/typescript", + }, + }, + "eslint": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen eslint", + "cwd": "handlers/typescript", + }, + }, + "generate": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen generate", + "cwd": "handlers/typescript", + }, + }, + "package": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen package", + "cwd": "handlers/typescript", + }, + }, + "post-compile": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen post-compile", + "cwd": "handlers/typescript", + }, + }, + "post-upgrade": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen post-upgrade", + "cwd": "handlers/typescript", + }, + }, + "pre-compile": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen pre-compile", + "cwd": "handlers/typescript", + }, + }, + "test": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen test", + "cwd": "handlers/typescript", + }, + }, + "test:watch": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen test:watch", + "cwd": "handlers/typescript", + }, + }, + "upgrade": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen upgrade", + "cwd": "handlers/typescript", + }, + }, + "watch": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen watch", + "cwd": "handlers/typescript", + }, + }, + }, + }, + "handlers/typescript/tsconfig.dev.json": { + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [ + "node_modules", + ], + "include": [ + ".projenrc.js", + "src/**/*.ts", + "test/**/*.ts", + ], + }, + "handlers/typescript/tsconfig.json": { + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "lib", + "resolveJsonModule": true, + "rootDir": "src", + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [], + "include": [ + "src/**/*.ts", + ], + }, + "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +gradle +gradlew +gradlew.bat +.gradle +!/settings.gradle +!/build.gradle +!/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy +build +smithy-output +.api.json +", + "model/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", + "settings.gradle", + "smithy-build.json", + ], + }, + "model/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 copy-gradle-wrapper", + }, + { + "exec": "./gradlew build", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-handlers-model/openapi/openapi/MyService.openapi.json --output-path .api.json", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "model/README.md": "# Smithy Model + +This project defines the API operations and their inputs and outputs, using an interface definition language called [Smithy](https://smithy.io/2.0/). + +The default entrypoint for the API is \`src/main/smithy/main.smithy\`. You can add more Smithy files (and subfolders) in the \`src/main/smithy\` directory, and these will be discovered as part of the project's build task. + +Resources: + - [Smithy Documentation](https://smithy.io/2.0/) + - [Type Safe API Documentation](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api) + +## Adding Operations + +To add an operation, we can use the \`operation\` shape. It should be annotated with the \`@http\` trait, which defines the method and path for the operation. Each operation has \`input\`, \`output\` and \`errors\`. You can define the \`input\` and \`output\` inline using the \`:=\` syntax. + +\`\`\`smithy +/// This is an example operation. +@http(method: "POST", uri: "/foo/{myUrlParam}") +operation CreateFoo { + input := { + /// This parameter comes from the url + @httpLabel + myUrlParam: String + + /// Since there's no @httpLabel or @httpQuery annotation, + /// this parameter will be in the POST request body + @reqired + someParameter: String + + /// This parameter is also in the body, but is optional + anotherParameter: Double + } + output := { + @required + foo: Foo + } + errors: [ApiError] +} +\`\`\` + +In the above, we've referenced a shape called \`Foo\` in the output. Let's define that as a \`structure\`: + +\`\`\`smithy +structure Foo { + /// Some documentation about this property + @required + myProperty: Integer +} +\`\`\` + +When we're happy with our new operation, we must add it to our \`service\`. By default, the \`service\` shape is in the \`src/main/smithy/main.smithy\` file. + +\`\`\`smithy +@restJson1 +service MyApi { + version: "1.0" + operations: [ + SayHello + CreateFoo // <- add the new operation here + ] +} +\`\`\` + +After adding the operation, please follow the remaining instructions in the [main README](../README.md). + +## Resources + +A common pattern is to use resources to model parts of your API. These are collections of operations which for managing an entity with an identifier. In a resource, you define the identifier as well as operations to manage the entity's lifecycle. For example: + +\`\`\`smithy +resource PetResource { + identifiers: { + petId: String + } + read: GetPet + list: ListPets + update: UpdatePet + create: CreatePet + delete: DeletePet +} +\`\`\` + +For the resource to be included in your API, you must attach it to the \`service\` by adding it to the service's \`resources\` property: + +\`\`\`smithy +@restJson1 +service MyApi { + version: "1.0" + resources: [ + PetResource + ] +} +\`\`\` + +For more details, see the [Smithy documentation](https://smithy.io/2.0/spec/service-types.html#resource). + +## Customising the Smithy Build + +The build task for this project will by default generate an Open API specification from the Smithy model, which is then used to generate the runtime, infrastructure, and documentation projects. + +You can further customise the build via editing the \`TypeSafeApiProject\` \`model.options.smithyBuildOptions\` in the root \`.projenrc\` file. This includes adding projections, or customising the \`openapi\` projection used to generate the Open API specification. + +For details about customising the build, please see the [Type Safe API README](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api), and refer to the [Smithy Build documentation](https://smithy.io/2.0/guides/building-models/build-config.html). +", + "model/build.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +plugins { + id "software.amazon.smithy" version "0.6.0" +} + +sourceSets { + main { + java { + srcDirs = ['src/main/smithy', 'generated/main/smithy'] + } + } +} + +// Dependencies can be added by configuring smithyBuildOptions in your .projenrc file +repositories { + mavenLocal() + mavenCentral() +} + +// Dependencies can be added by configuring smithyBuildOptions in your .projenrc file +dependencies { + implementation "software.amazon.smithy:smithy-cli:1.28.0" + implementation "software.amazon.smithy:smithy-model:1.28.0" + implementation "software.amazon.smithy:smithy-openapi:1.28.0" + implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" +} +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "ConfiguredHandlerProject" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + [@trait|com.test#handler: @{language} = typescript, java, python] + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @@handler language @{trait|com.test#handler|language} cannot be referenced unless a handler project is configured for this language. + Configured handler project languages are: typescript, java, python. + You can add this language by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have configured handler projects for typescript, java, python +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + +", + "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +rootProject.name = 'smithy-handlers-model' +", + "model/smithy-build.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "maven": { + "dependencies": [ + "software.amazon.smithy:smithy-cli:1.28.0", + "software.amazon.smithy:smithy-model:1.28.0", + "software.amazon.smithy:smithy-openapi:1.28.0", + "software.amazon.smithy:smithy-aws-traits:1.28.0", + ], + "repositories": [ + { + "url": "https://repo.maven.apache.org/maven2/", + }, + { + "url": "file://~/.m2/repository", + }, + ], + }, + "projections": { + "openapi": { + "plugins": { + "openapi": { + "service": "com.test#MyService", + "tags": true, + }, + }, + }, + }, + "sources": [ + "src/main/smithy", + "generated/main/smithy", + ], + "version": "2.0", + }, + "model/src/main/smithy/main.smithy": "$version: "2" +namespace com.test + +use aws.protocols#restJson1 + +/// A sample smithy api +@restJson1 +service MyService { + version: "1.0" + operations: [SayHello] + errors: [ + BadRequestError + NotAuthorizedError + InternalFailureError + ] +}", + "model/src/main/smithy/operations/say-hello.smithy": "$version: "2" +namespace com.test + +@readonly +@http(method: "GET", uri: "/hello") +@handler(language: "typescript") +operation SayHello { + input := { + @httpQuery("name") + @required + name: String + } + output := { + @required + message: String + } + errors: [NotFoundError] +} +", + "model/src/main/smithy/types/errors.smithy": "$version: "2" +namespace com.test + +/// An error message +string ErrorMessage + +/// An internal failure at the fault of the server +@error("server") +@httpError(500) +structure InternalFailureError { + /// Message with details about the error + @required + message: ErrorMessage +} + +/// An error at the fault of the client sending invalid input +@error("client") +@httpError(400) +structure BadRequestError { + /// Message with details about the error + @required + message: ErrorMessage +} + +/// An error due to the client attempting to access a missing resource +@error("client") +@httpError(404) +structure NotFoundError { + /// Message with details about the error + @required + message: ErrorMessage +} + +/// An error due to the client not being authorized to access the resource +@error("client") +@httpError(403) +structure NotAuthorizedError { + /// Message with details about the error + @required + message: ErrorMessage +} +", +} +`; + +exports[`Type Safe Api Project Unit Tests Smithy With TypeScript react-query hooks library 1`] = ` +{ + ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/generated/runtime/README.md +!/generated/libraries/README.md +!/handlers/README.md +!/generated/infrastructure/README.md +", + ".projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "generated/infrastructure/README.md", + "generated/libraries/README.md", + "generated/runtime/README.md", + "handlers/README.md", + ], + }, + ".projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "default", + }, + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "cwd": "model", + "exec": "npx projen build", + }, + { + "cwd": "generated/runtime/typescript", + "exec": "npx projen build", + }, + { + "cwd": "generated/infrastructure/typescript", + "exec": "npx projen build", + }, + { + "cwd": "generated/libraries/typescript-react-query-hooks", + "exec": "npx projen build", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + }, + "eject": { + "description": "Remove projen from the project", + "env": { + "PROJEN_EJECTING": "true", + }, + "name": "eject", + "steps": [ + { + "spawn": "default", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "README.md": "# Type Safe API + +This project contains an API built with [Type Safe API](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api). + +## Project Structure + +This project consists of the following components: + +### Model + +The \`model\` folder contains the API model, which defines the API operations and their inputs and outputs. For more details, please refer to the [model project README](./model/README.md). + +### Runtime + +The \`runtime\` folder contains subprojects for each of the selected runtime languages. These projects include types as well as client and server code, generated from the model. + +### Infrastructure + +The \`infrastructure\` folder contains a subproject for the selected infrastructure language. This includes a CDK construct which defines the API Gateway resources to deploy the API defined by the model. + +### Documentation + +The \`documentation\` folder contains documentation generated from the model, for each of the selected documentation formats. + +## Adding Operations + +This section describes the steps required to add a new operation to your API. + +### Define the Operation + +The API operations are defined by the API model. Please see the [model project README](./model/README.md) for instructions for the specific model language used. + +### Build the Project + +Next, build the project using the project's build command. This will vary depending on the overall project setup, and is likely documented in the top level README. + +The build will trigger regeneration of the \`runtime\`, \`infrastructure\` and \`documentation\` projects, which will include your new operation. + +### Add an Integration + +If you are using the CDK construct defined in the \`infrastructure\` folder, you likely encountered a type error in your CDK project, since the construct requires an integration for every operation defined in the model. + +Please refer to the [Type Safe API documentation](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api) for details about how to add integrations in your chosen infrastructure language. + +### Implement the Operation + +Finally, you'll need to implement the operation. If using AWS Lambda for your API integrations, you can make use of the generated lambda handler wrappers from one of the \`runtime\` projects. These wrappers provide typed interfaces for operations, providing auto-complete in your IDE for inputs, and ensuring you return the output (or one of the errors) defined in the model. + +For more details about using the handler wrappers in the various supported languages, please refer to the [Type Safe API documentation](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api). +", + "generated/infrastructure/README.md": "## Generated Infrastructure + +This directory contains a generated type-safe CDK construct which will can the API gateway infrastructure for an API based on your model.", + "generated/infrastructure/typescript/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.npmignore linguist-generated +/.npmrc linguist-generated +/.openapi-generator-ignore linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/LICENSE linguist-generated +/openapitools.json linguist-generated +/package.json linguist-generated +/project.json linguist-generated +/tsconfig.dev.json linguist-generated +/tsconfig.json linguist-generated +/yarn.lock linguist-generated", + "generated/infrastructure/typescript/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/package.json +!/LICENSE +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +!/.projenrc.js +!/.npmrc +!/test/ +!/tsconfig.json +!/tsconfig.dev.json +!/src/ +/lib +/dist/ +!/.npmignore +!/.openapi-generator-ignore +!/openapitools.json +/assets/api.json +src +.openapi-generator +mocks +!/project.json +", + "generated/infrastructure/typescript/.npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/.projen/ +/src +/dist +", + "generated/infrastructure/typescript/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +/* +**/* +* +!src/index.ts +!src/api.ts +!src/mock-integrations.ts +", + "generated/infrastructure/typescript/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "@types/node", + "type": "build", + "version": "^16", + }, + { + "name": "npm-check-updates", + "type": "build", + "version": "^16", + }, + { + "name": "projen", + "type": "build", + }, + { + "name": "typescript", + "type": "build", + }, + { + "name": "@aws-prototyping-sdk/type-safe-api", + "type": "runtime", + }, + { + "name": "aws-cdk-lib", + "type": "runtime", + }, + { + "name": "cdk-nag", + "type": "runtime", + }, + { + "name": "constructs", + "type": "runtime", + }, + { + "name": "smithy-typescript-react-query-hooks-typescript-runtime", + "type": "runtime", + "version": "file:../../runtime/typescript", + }, + ], + }, + "generated/infrastructure/typescript/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".npmignore", + ".npmrc", + ".openapi-generator-ignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "LICENSE", + "openapitools.json", + "project.json", + "tsconfig.dev.json", + "tsconfig.json", + ], + }, + "generated/infrastructure/typescript/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(npx -c "node --print process.env.PATH")", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "tsc --build", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "cwd": "../../..", + "exec": "npx projen default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator typescript-fetch --spec-path ../../../model/.api.json --output-path . --generator-dir typescript-cdk-infrastructure --src-dir src --smithy-json-path ../../../model/build/smithyprojections/smithy-typescript-react-query-hooks-model/openapi/model/model.json --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-package-name":"smithy-typescript-react-query-hooks-typescript-runtime","x-relative-spec-path":"../assets/api.json","x-enable-mock-integrations":true}' --generate-alias-as-model", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate-mock-data --spec-path ../../../model/.api.json --output-path .", + }, + { + "exec": "mkdir -p assets", + }, + { + "exec": "cp -f ../../../model/.api.json assets/api.json", + }, + ], + }, + "install": { + "description": "Install project dependencies and update lockfile (non-frozen)", + "name": "install", + "steps": [ + { + "exec": "yarn link smithy-typescript-react-query-hooks-typescript-runtime", + }, + { + "exec": "yarn install --check-files", + }, + ], + }, + "install:ci": { + "description": "Install project dependencies using frozen lockfile", + "name": "install:ci", + "steps": [ + { + "exec": "yarn install --check-files --frozen-lockfile", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/js", + }, + { + "exec": "mv $(npm pack) dist/js/", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "post-upgrade": { + "description": "Runs after upgrading dependencies", + "name": "post-upgrade", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + "upgrade": { + "description": "upgrade dependencies", + "env": { + "CI": "0", + }, + "name": "upgrade", + "steps": [ + { + "exec": "yarn upgrade npm-check-updates", + }, + { + "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + }, + { + "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='smithy-typescript-react-query-hooks-typescript-runtime'", + }, + { + "exec": "yarn install --check-files", + }, + { + "exec": "yarn upgrade", + }, + { + "exec": "npx projen", + }, + { + "spawn": "post-upgrade", + }, + ], + }, + "watch": { + "description": "Watch & compile in the background", + "name": "watch", + "steps": [ + { + "exec": "tsc --build -w", + }, + ], + }, + }, + }, + "generated/infrastructure/typescript/LICENSE": " + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License 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. +", + "generated/infrastructure/typescript/README.md": "# replace this", + "generated/infrastructure/typescript/openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "generated/infrastructure/typescript/package.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": { + "@aws-prototyping-sdk/type-safe-api": "*", + "aws-cdk-lib": "*", + "cdk-nag": "*", + "constructs": "*", + "smithy-typescript-react-query-hooks-typescript-runtime": "file:../../runtime/typescript", + }, + "devDependencies": { + "@types/node": "^16", + "npm-check-updates": "^16", + "projen": "*", + "typescript": "*", + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "smithy-typescript-react-query-hooks-typescript-infra", + "scripts": { + "build": "npx projen build", + "compile": "npx projen compile", + "default": "npx projen default", + "generate": "npx projen generate", + "package": "npx projen package", + "post-compile": "npx projen post-compile", + "post-upgrade": "npx projen post-upgrade", + "pre-compile": "npx projen pre-compile", + "projen": "npx projen", + "test": "npx projen test", + "upgrade": "npx projen upgrade", + "watch": "npx projen watch", + }, + "types": "lib/index.d.ts", + "version": "0.0.0", + }, + "generated/infrastructure/typescript/project.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "implicitDependencies": [ + "smithy-typescript-react-query-hooks-typescript-runtime", + "smithy-typescript-react-query-hooks-model", + ], + "name": "smithy-typescript-react-query-hooks-typescript-infra", + "root": "generated/infrastructure/typescript", + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen build", + "cwd": "generated/infrastructure/typescript", + }, + }, + "compile": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen compile", + "cwd": "generated/infrastructure/typescript", + }, + }, + "default": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen default", + "cwd": "generated/infrastructure/typescript", + }, + }, + "generate": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen generate", + "cwd": "generated/infrastructure/typescript", + }, + }, + "package": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen package", + "cwd": "generated/infrastructure/typescript", + }, + }, + "post-compile": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen post-compile", + "cwd": "generated/infrastructure/typescript", + }, + }, + "post-upgrade": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen post-upgrade", + "cwd": "generated/infrastructure/typescript", + }, + }, + "pre-compile": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen pre-compile", + "cwd": "generated/infrastructure/typescript", + }, + }, + "test": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen test", + "cwd": "generated/infrastructure/typescript", + }, + }, + "upgrade": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen upgrade", + "cwd": "generated/infrastructure/typescript", + }, + }, + "watch": { + "executor": "nx:run-commands", + "options": { + "command": "yarn projen watch", + "cwd": "generated/infrastructure/typescript", + }, + }, + }, + }, + "generated/infrastructure/typescript/tsconfig.dev.json": { + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [ + "node_modules", + ], + "include": [ + ".projenrc.js", + "src/**/*.ts", + "test/**/*.ts", + ], + }, + "generated/infrastructure/typescript/tsconfig.json": { + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "lib", + "resolveJsonModule": true, + "rootDir": "src", + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [], + "include": [ + "src/**/*.ts", + ], + }, + "generated/libraries/README.md": "## Generated Libraries + +This directory contains generated libraries based on your API model.", + "generated/libraries/typescript-react-query-hooks/.gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +/.gitattributes linguist-generated +/.gitignore linguist-generated +/.npmrc linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/LICENSE linguist-generated +/openapitools.json linguist-generated +/package.json linguist-generated +/tsconfig.dev.json linguist-generated +/tsconfig.json linguist-generated +/yarn.lock linguist-generated", + "generated/libraries/typescript-react-query-hooks/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/package.json +!/LICENSE +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +!/.projenrc.js +!/.npmrc +!/test/ +!/tsconfig.json +!/tsconfig.dev.json +!/src/ +/lib +/dist/ +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +src +.npmignore +README.md +.openapi-generator +", + "generated/libraries/typescript-react-query-hooks/.openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +package.json +tsconfig.json +tsconfig.esm.json +.npmignore +**/*Hooks.ts +", + "generated/libraries/typescript-react-query-hooks/.openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/* +**/* +* +!**/*Hooks.ts +", + "generated/libraries/typescript-react-query-hooks/.projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "@types/node", + "type": "build", + "version": "^16", + }, + { + "name": "@types/react", + "type": "build", + }, + { + "name": "npm-check-updates", + "type": "build", + "version": "^16", + }, + { + "name": "projen", + "type": "build", + }, + { + "name": "react", + "type": "build", + }, + { + "name": "typescript", + "type": "build", + }, + { + "name": "react", + "type": "peer", + }, + { + "name": "@tanstack/react-query", + "type": "runtime", + }, + ], + }, + "generated/libraries/typescript-react-query-hooks/.projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".npmrc", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "LICENSE", + "openapitools.json", + "tsconfig.dev.json", + "tsconfig.json", + ], + }, + "generated/libraries/typescript-react-query-hooks/.projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(npx -c "node --print process.env.PATH")", + }, "tasks": { "build": { "description": "Full release build", @@ -24010,6 +28874,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -24023,6 +28892,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -24036,6 +28906,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -24226,7 +29097,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -24244,6 +29115,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-typescript-react-query-hooks-model' @@ -24278,6 +29197,7 @@ rootProject.name = 'smithy-typescript-react-query-hooks-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -24370,6 +29290,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -24383,6 +29304,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -26888,6 +31810,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -26901,6 +31828,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -26914,6 +31842,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -27104,7 +32033,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -27122,6 +32051,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-java-model' @@ -27156,6 +32133,7 @@ rootProject.name = 'smithy-java-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -27401,6 +32379,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With java Infra in Monorepo 1`] /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -27453,6 +32432,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -27608,6 +32588,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -31166,6 +36147,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -31179,6 +36165,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -31193,6 +36180,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -31378,7 +36366,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -31396,6 +36384,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -31493,6 +36529,7 @@ rootProject.name = 'smithy-java-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -31714,6 +36751,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -31727,6 +36765,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -33597,6 +38636,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -33610,6 +38654,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -33623,6 +38668,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -33813,7 +38859,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -33831,6 +38877,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-npm-model' @@ -33865,6 +38959,7 @@ rootProject.name = 'smithy-npm-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -34111,6 +39206,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With npm Package Manager in Mon /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated", ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -34162,6 +39258,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -34317,6 +39414,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -37074,6 +42172,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -37087,6 +42190,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -37101,6 +42205,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -37286,7 +42391,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -37304,6 +42409,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -37401,6 +42554,7 @@ rootProject.name = 'smithy-npm-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -37622,6 +42776,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -37635,6 +42790,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -39510,6 +44666,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -39523,6 +44684,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -39536,6 +44698,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -39726,7 +44889,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -39744,6 +44907,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-pnpm-model' @@ -39778,6 +44989,7 @@ rootProject.name = 'smithy-pnpm-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -40023,6 +45235,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With pnpm Package Manager in Mo /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /pnpm-lock.yaml linguist-generated /pnpm-workspace.yaml linguist-generated /tsconfig.dev.json linguist-generated @@ -40076,6 +45289,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md !/pnpm-workspace.yaml ", @@ -40236,6 +45450,7 @@ resolution-mode=highest "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "pnpm-workspace.yaml", "tsconfig.dev.json", "tsconfig.json", @@ -42999,6 +48214,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -43012,6 +48232,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -43026,6 +48247,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -43211,7 +48433,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -43229,6 +48451,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -43326,6 +48596,7 @@ rootProject.name = 'smithy-pnpm-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -43559,6 +48830,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -43572,6 +48844,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -45973,6 +51246,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -45986,6 +51264,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -45999,6 +51278,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -46189,7 +51469,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -46207,6 +51487,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-python-model' @@ -46241,6 +51569,7 @@ rootProject.name = 'smithy-python-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -46486,6 +51815,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With python Infra in Monorepo 1 /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -46538,6 +51868,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -46693,6 +52024,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -50156,6 +55488,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -50169,6 +55506,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -50183,6 +55521,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -50368,7 +55707,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -50386,6 +55725,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -50483,6 +55870,7 @@ rootProject.name = 'smithy-python-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -50704,6 +56092,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -50717,6 +56106,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -53432,6 +58822,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -53445,6 +58840,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -53458,6 +58854,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -53648,7 +59045,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -53666,6 +59063,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-typescript-model' @@ -53700,6 +59145,7 @@ rootProject.name = 'smithy-typescript-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -53945,6 +59391,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With typescript Infra in Monore /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -53997,6 +59444,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -54152,6 +59600,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -57914,6 +63363,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -57927,6 +63381,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -57941,6 +63396,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -58126,7 +63582,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -58144,6 +63600,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -58241,6 +63745,7 @@ rootProject.name = 'smithy-typescript-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -58462,6 +63967,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -58475,6 +63981,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -60345,6 +65852,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -60358,6 +65870,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -60371,6 +65884,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -60561,7 +66075,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -60579,6 +66093,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-yarn-model' @@ -60613,6 +66175,7 @@ rootProject.name = 'smithy-yarn-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -60858,6 +66421,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With yarn Package Manager in Mo /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -60910,6 +66474,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -61065,6 +66630,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -63823,6 +69389,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -63836,6 +69407,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -63850,6 +69422,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -64035,7 +69608,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -64053,6 +69626,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -64150,6 +69771,7 @@ rootProject.name = 'smithy-yarn-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -64371,6 +69993,7 @@ node_modules/ !/.projen/files.json !/generated/runtime/README.md !/generated/documentation/README.md +!/handlers/README.md !/generated/infrastructure/README.md ", ".projen/files.json": { @@ -64384,6 +70007,7 @@ node_modules/ "generated/documentation/README.md", "generated/infrastructure/README.md", "generated/runtime/README.md", + "handlers/README.md", ], }, ".projen/tasks.json": { @@ -66254,6 +71878,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -66267,6 +71896,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -66280,6 +71910,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -66470,7 +72101,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -66488,6 +72119,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "model/settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". rootProject.name = 'smithy-yarn2-model' @@ -66522,6 +72201,7 @@ rootProject.name = 'smithy-yarn2-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -66767,6 +72447,7 @@ exports[`Type Safe Api Project Unit Tests Smithy With yarn2 Package Manager in M /packages/api/generated/documentation/README.md linguist-generated /packages/api/generated/infrastructure/README.md linguist-generated /packages/api/generated/runtime/README.md linguist-generated +/packages/api/handlers/README.md linguist-generated /tsconfig.dev.json linguist-generated /tsconfig.json linguist-generated /yarn.lock linguist-generated", @@ -66823,6 +72504,7 @@ jspm_packages/ !/.syncpackrc.json !/packages/api/generated/runtime/README.md !/packages/api/generated/documentation/README.md +!/packages/api/handlers/README.md !/packages/api/generated/infrastructure/README.md ", ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". @@ -66978,6 +72660,7 @@ tsconfig.tsbuildinfo "packages/api/generated/documentation/README.md", "packages/api/generated/infrastructure/README.md", "packages/api/generated/runtime/README.md", + "packages/api/handlers/README.md", "tsconfig.dev.json", "tsconfig.json", ], @@ -69736,6 +75419,11 @@ tsconfig.esm.json "src/**/*.ts", ], }, + "packages/api/handlers/README.md": "## Handlers + +This directory contains lambda handlers for implementing your API. + +Whenever an operation is annotated with the \`@handler\` trait in Smithy (or the \`x-handler\` vendor extension in OpenAPI), a stub handler implementation will be generated for you, which you are free to modify.", "packages/api/model/.gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ !/.gitattributes @@ -69749,6 +75437,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -69763,6 +75452,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "project.json", "settings.gradle", "smithy-build.json", @@ -69948,7 +75638,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -69966,6 +75656,54 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "packages/api/model/generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "packages/api/model/project.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -70063,6 +75801,7 @@ rootProject.name = 'smithy-yarn2-model' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, diff --git a/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-java-handlers-project.test.ts.snap b/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-java-handlers-project.test.ts.snap new file mode 100644 index 000000000..2a53015ee --- /dev/null +++ b/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-java-handlers-project.test.ts.snap @@ -0,0 +1,498 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Generated Java Handlers Code Unit Tests Synth 1`] = ` +{ + ".gitattributes": "# ~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen". + +/.gitattributes linguist-generated +/.github/workflows/pull-request-lint.yml linguist-generated +/.gitignore linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/openapitools.json linguist-generated +/pom.xml linguist-generated", + ".github/workflows/pull-request-lint.yml": "# ~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen". + +name: pull-request-lint +on: + pull_request_target: + types: + - labeled + - opened + - synchronize + - reopened + - ready_for_review + - edited +jobs: + validate: + name: Validate PR title + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: amannn/action-semantic-pull-request@v5.0.2 + env: + GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} + with: + types: |- + feat + fix + chore + requireScope: false +", + ".gitignore": "# ~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/.github/workflows/pull-request-lint.yml +!/pom.xml +.classpath +.project +.settings +target +dist/java +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +.openapi-generator +", + ".openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen". +.gitignore +/* +**/* +* +", + ".openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen". +/* +**/* +* +!src/main/java/test/test-java-handlers/handlers/__all_handlers.java +", + ".projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen".", + "dependencies": [ + { + "metadata": { + "configuration": { + "source": "1.8", + "target": "1.8", + }, + }, + "name": "org.apache.maven.plugins/maven-compiler-plugin", + "type": "build", + "version": "3.8.1", + }, + { + "metadata": { + "configuration": { + "rules": [ + { + "requireMavenVersion": [ + { + "version": "3.6", + }, + ], + }, + ], + }, + "executions": [ + { + "goals": [ + "enforce", + ], + "id": "enforce-maven", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-enforcer-plugin", + "type": "build", + "version": "3.0.0-M3", + }, + { + "metadata": { + "configuration": { + "archive": { + "index": true, + "manifest": { + "addDefaultImplementationEntries": true, + "addDefaultSpecificationEntries": true, + }, + }, + }, + }, + "name": "org.apache.maven.plugins/maven-jar-plugin", + "type": "build", + "version": "3.2.0", + }, + { + "metadata": { + "configuration": { + "additionalJOptions": { + "additionalJOption": [ + "-J-XX:+TieredCompilation", + "-J-XX:TieredStopAtLevel=1", + ], + }, + "detectJavaApiLink": false, + "failOnError": false, + "show": "protected", + }, + "executions": [ + { + "goals": [ + "jar", + ], + "id": "attach-javadocs", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-javadoc-plugin", + "type": "build", + "version": "3.2.0", + }, + { + "metadata": { + "configuration": { + "createDependencyReducedPom": false, + }, + "executions": [ + { + "goals": [ + "shade", + ], + "id": "shade-task", + "phase": "package", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-shade-plugin", + "type": "build", + "version": "3.3.0", + }, + { + "metadata": { + "executions": [ + { + "goals": [ + "jar", + ], + "id": "attach-sources", + }, + ], + }, + "name": "org.apache.maven.plugins/maven-source-plugin", + "type": "build", + "version": "3.2.1", + }, + { + "name": "org.codehaus.mojo/exec-maven-plugin", + "type": "build", + "version": "3.0.0", + }, + { + "name": "test/com.aws.pdk.test.runtime", + "type": "runtime", + "version": "1.0.0", + }, + ], + }, + ".projen/files.json": { + "//": "~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen".", + "files": [ + ".gitattributes", + ".github/workflows/pull-request-lint.yml", + ".gitignore", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "openapitools.json", + "pom.xml", + ], + }, + ".projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen".", + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "default", + }, + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "clobber": { + "condition": "git diff --exit-code > /dev/null", + "description": "hard resets to HEAD of origin and cleans the local repo", + "env": { + "BRANCH": "$(git branch --show-current)", + }, + "name": "clobber", + "steps": [ + { + "exec": "git checkout -b scratch", + "name": "save current HEAD in "scratch" branch", + }, + { + "exec": "git checkout $BRANCH", + }, + { + "exec": "git fetch origin", + "name": "fetch latest changes from origin", + }, + { + "exec": "git reset --hard origin/$BRANCH", + "name": "hard reset to origin commit", + }, + { + "exec": "git clean -fdx", + "name": "clean all untracked files", + }, + { + "say": "ready to rock! (unpushed commits are under the "scratch" branch)", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "mvn compiler:compile", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "exec": "mvn compiler:testCompile --quiet", + }, + { + "exec": "mvn exec:java --quiet -Dexec.mainClass=projenrc -Dexec.classpathScope="test"", + }, + ], + }, + "eject": { + "description": "Remove projen from the project", + "env": { + "PROJEN_EJECTING": "true", + }, + "name": "eject", + "steps": [ + { + "spawn": "default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator java --spec-path my-spec.json --output-path . --generator-dir java-lambda-handlers --src-dir src/main/java/test/test-java-handlers/handlers --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-handlers-package":"test.test-java-handlers.handlers","x-runtime-package":"test.test-java-client.runtime"}'", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "env": { + "MAVEN_OPTS": "-XX:+TieredCompilation -XX:TieredStopAtLevel=1", + }, + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/java", + }, + { + "exec": "mvn deploy -D=altDeploymentRepository=local::default::file:///$PWD/dist/java", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "README.md": "# replace this", + "openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit src/test/java/projenrc.java and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "pom.xml": " + + 4.0.0 + test + com.aws.pdk.test.handlers + 1.0.0 + jar + test-java-handlers + + UTF-8 + + + + file://../java-client/dist/java + test-com.aws.pdk.test.runtime-repo + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + 3.6 + + + + + + enforce-maven + + enforce + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + true + + true + true + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + false + protected + false + + -J-XX:+TieredCompilation + -J-XX:TieredStopAtLevel=1 + + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.3.0 + + false + + + + shade-task + + shade + + package + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + + + + test + com.aws.pdk.test.runtime + 1.0.0 + + + +", +} +`; diff --git a/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-python-handlers-project.test.ts.snap b/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-python-handlers-project.test.ts.snap new file mode 100644 index 000000000..1d4b101f4 --- /dev/null +++ b/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-python-handlers-project.test.ts.snap @@ -0,0 +1,389 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Generated Python Handlers Code Unit Tests Synth 1`] = ` +{ + ".gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". + +/.gitattributes linguist-generated +/.github/workflows/pull-request-lint.yml linguist-generated +/.gitignore linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/openapitools.json linguist-generated +/pyproject.toml linguist-generated", + ".github/workflows/pull-request-lint.yml": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". + +name: pull-request-lint +on: + pull_request_target: + types: + - labeled + - opened + - synchronize + - reopened + - ready_for_review + - edited +jobs: + validate: + name: Validate PR title + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: amannn/action-semantic-pull-request@v5.0.2 + env: + GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} + with: + types: |- + feat + fix + chore + requireScope: false +", + ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/.github/workflows/pull-request-lint.yml +!/pyproject.toml +/poetry.toml +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ +*.mo +*.pot +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +instance/ +.webassets-cache +.scrapy +docs/_build/ +.pybuilder/ +target/ +.ipynb_checkpoints +profile_default/ +ipython_config.py +__pypackages__/ +celerybeat-schedule +celerybeat.pid +*.sage.py +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.spyderproject +.spyproject +.ropeproject +/site +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +cython_debug/ +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +.openapi-generator +", + ".openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". +.gitignore +/* +**/* +* +", + ".openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". +/* +**/* +* +!test_handlers/__all_handlers.py +", + ".projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", + "dependencies": [ + { + "name": "projen", + "type": "devenv", + "version": "99.99.99", + }, + { + "name": "test-python-client", + "type": "runtime", + "version": "{path="../python-client", develop=true}", + }, + ], + }, + ".projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", + "files": [ + ".gitattributes", + ".github/workflows/pull-request-lint.yml", + ".gitignore", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "openapitools.json", + "poetry.toml", + "pyproject.toml", + ], + }, + ".projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", + "env": { + "PATH": "$(echo $(poetry env info -p)/bin:$PATH)", + "VIRTUAL_ENV": "$(poetry env info -p)", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "default", + }, + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "clobber": { + "condition": "git diff --exit-code > /dev/null", + "description": "hard resets to HEAD of origin and cleans the local repo", + "env": { + "BRANCH": "$(git branch --show-current)", + }, + "name": "clobber", + "steps": [ + { + "exec": "git checkout -b scratch", + "name": "save current HEAD in "scratch" branch", + }, + { + "exec": "git checkout $BRANCH", + }, + { + "exec": "git fetch origin", + "name": "fetch latest changes from origin", + }, + { + "exec": "git reset --hard origin/$BRANCH", + "name": "hard reset to origin commit", + }, + { + "exec": "git clean -fdx", + "name": "clean all untracked files", + }, + { + "say": "ready to rock! (unpushed commits are under the "scratch" branch)", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "exec": "python .projenrc.py", + }, + ], + }, + "eject": { + "description": "Remove projen from the project", + "env": { + "PROJEN_EJECTING": "true", + }, + "name": "eject", + "steps": [ + { + "spawn": "default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator python --spec-path my-spec.json --output-path . --generator-dir python-lambda-handlers --src-dir test_handlers --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-module-name":"test_client"}' --generate-alias-as-model", + }, + ], + }, + "install": { + "description": "Install and upgrade dependencies", + "name": "install", + "steps": [ + { + "exec": "poetry update", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "poetry build", + }, + { + "exec": "mkdir -p dist/lambda && rm -rf dist/lambda/*", + }, + { + "exec": "cp -r test_handlers dist/lambda/test_handlers", + }, + { + "exec": "poetry export --without-hashes --format=requirements.txt > dist/lambda/requirements.txt", + }, + { + "exec": "pip install -r dist/lambda/requirements.txt --target dist/lambda --upgrade", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "publish": { + "description": "Uploads the package to PyPI.", + "name": "publish", + "steps": [ + { + "exec": "poetry publish", + }, + ], + }, + "publish:test": { + "description": "Uploads the package against a test PyPI endpoint.", + "name": "publish:test", + "steps": [ + { + "exec": "poetry publish -r testpypi", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "README.md": "# replace this", + "openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "poetry.toml": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". + +[repositories.testpypi] +url = "https://test.pypi.org/legacy/" +", + "pyproject.toml": "# ~~ Generated by projen. To modify, edit .projenrc.py and run "npx projen". + +[build-system] +requires = [ "poetry_core>=1.0.0" ] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "test-python-handlers" +version = "1.0.0" +description = "" +authors = [ "test " ] +readme = "README.md" +include = [ "test_handlers", "test_handlers/**/*.py" ] + + [[tool.poetry.packages]] + include = "test_handlers" + + [tool.poetry.dependencies] + python = "^3.7" + + [tool.poetry.dependencies.test-python-client] + path = "../python-client" + develop = true + + [tool.poetry.dev-dependencies] + projen = "99.99.99" +", + "test_handlers/__init__.py": "#", +} +`; diff --git a/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-typescript-handlers-project.test.ts.snap b/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-typescript-handlers-project.test.ts.snap new file mode 100644 index 000000000..f377f2dcd --- /dev/null +++ b/packages/type-safe-api/test/project/codegen/handlers/__snapshots__/generated-typescript-handlers-project.test.ts.snap @@ -0,0 +1,1402 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Generated Typescript Handlers Code Unit Tests Synth 1`] = ` +{ + ".eslintrc.json": { + "env": { + "jest": true, + "node": true, + }, + "extends": [ + "plugin:import/typescript", + ], + "ignorePatterns": [ + "*.js", + "*.d.ts", + "node_modules/", + "*.generated.ts", + "coverage", + "!.projenrc.js", + ], + "overrides": [ + { + "files": [ + ".projenrc.js", + ], + "rules": { + "@typescript-eslint/no-require-imports": "off", + "import/no-extraneous-dependencies": "off", + }, + }, + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2018, + "project": "./tsconfig.dev.json", + "sourceType": "module", + }, + "plugins": [ + "@typescript-eslint", + "import", + ], + "root": true, + "rules": { + "@typescript-eslint/indent": [ + "error", + 2, + ], + "@typescript-eslint/member-delimiter-style": [ + "error", + ], + "@typescript-eslint/member-ordering": [ + "error", + { + "default": [ + "public-static-field", + "public-static-method", + "protected-static-field", + "protected-static-method", + "private-static-field", + "private-static-method", + "field", + "constructor", + "method", + ], + }, + ], + "@typescript-eslint/no-floating-promises": [ + "error", + ], + "@typescript-eslint/no-require-imports": [ + "error", + ], + "@typescript-eslint/no-shadow": [ + "error", + ], + "@typescript-eslint/return-await": [ + "error", + ], + "array-bracket-newline": [ + "error", + "consistent", + ], + "array-bracket-spacing": [ + "error", + "never", + ], + "brace-style": [ + "error", + "1tbs", + { + "allowSingleLine": true, + }, + ], + "comma-dangle": [ + "error", + "always-multiline", + ], + "comma-spacing": [ + "error", + { + "after": true, + "before": false, + }, + ], + "curly": [ + "error", + "multi-line", + "consistent", + ], + "dot-notation": [ + "error", + ], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": [ + "**/test/**", + "**/build-tools/**", + ], + "optionalDependencies": false, + "peerDependencies": true, + }, + ], + "import/no-unresolved": [ + "error", + ], + "import/order": [ + "warn", + { + "alphabetize": { + "caseInsensitive": true, + "order": "asc", + }, + "groups": [ + "builtin", + "external", + ], + }, + ], + "indent": [ + "off", + ], + "key-spacing": [ + "error", + ], + "keyword-spacing": [ + "error", + ], + "max-len": [ + "error", + { + "code": 150, + "ignoreComments": true, + "ignoreRegExpLiterals": true, + "ignoreStrings": true, + "ignoreTemplateLiterals": true, + "ignoreUrls": true, + }, + ], + "no-bitwise": [ + "error", + ], + "no-duplicate-imports": [ + "error", + ], + "no-multi-spaces": [ + "error", + { + "ignoreEOLComments": false, + }, + ], + "no-multiple-empty-lines": [ + "error", + ], + "no-return-await": [ + "off", + ], + "no-shadow": [ + "off", + ], + "no-trailing-spaces": [ + "error", + ], + "object-curly-newline": [ + "error", + { + "consistent": true, + "multiline": true, + }, + ], + "object-curly-spacing": [ + "error", + "always", + ], + "object-property-newline": [ + "error", + { + "allowAllPropertiesOnSameLine": true, + }, + ], + "quote-props": [ + "error", + "consistent-as-needed", + ], + "quotes": [ + "error", + "single", + { + "avoidEscape": true, + }, + ], + "semi": [ + "error", + "always", + ], + "space-before-blocks": [ + "error", + ], + }, + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [ + ".ts", + ".tsx", + ], + }, + "import/resolver": { + "node": {}, + "typescript": { + "alwaysTryTypes": true, + "project": "./tsconfig.dev.json", + }, + }, + }, + }, + ".gitattributes": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +*.snap linguist-generated +/.eslintrc.json linguist-generated +/.gitattributes linguist-generated +/.github/pull_request_template.md linguist-generated +/.github/workflows/build.yml linguist-generated +/.github/workflows/pull-request-lint.yml linguist-generated +/.github/workflows/release.yml linguist-generated +/.github/workflows/upgrade-main.yml linguist-generated +/.gitignore linguist-generated +/.mergify.yml linguist-generated +/.npmignore linguist-generated +/.npmrc linguist-generated +/.openapi-generator-ignore linguist-generated +/.openapi-generator-ignore-handlebars linguist-generated +/.projen/** linguist-generated +/.projen/deps.json linguist-generated +/.projen/files.json linguist-generated +/.projen/tasks.json linguist-generated +/LICENSE linguist-generated +/openapitools.json linguist-generated +/package.json linguist-generated +/tsconfig.dev.json linguist-generated +/tsconfig.json linguist-generated +/yarn.lock linguist-generated", + ".github/pull_request_template.md": "Fixes #", + ".github/workflows/build.yml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +name: build +on: + pull_request: {} + workflow_dispatch: {} +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + self_mutation_happened: \${{ steps.self_mutation.outputs.self_mutation_happened }} + env: + CI: "true" + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: \${{ github.event.pull_request.head.ref }} + repository: \${{ github.event.pull_request.head.repo.full_name }} + - name: Install dependencies + run: yarn install --check-files + - name: build + run: npx projen build + - name: Find mutations + id: self_mutation + run: |- + git add . + git diff --staged --patch --exit-code > .repo.patch || echo "self_mutation_happened=true" >> $GITHUB_OUTPUT + - name: Upload patch + if: steps.self_mutation.outputs.self_mutation_happened + uses: actions/upload-artifact@v3 + with: + name: .repo.patch + path: .repo.patch + - name: Fail build on mutation + if: steps.self_mutation.outputs.self_mutation_happened + run: |- + echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch." + cat .repo.patch + exit 1 + self-mutation: + needs: build + runs-on: ubuntu-latest + permissions: + contents: write + if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository) + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + token: \${{ secrets.PROJEN_GITHUB_TOKEN }} + ref: \${{ github.event.pull_request.head.ref }} + repository: \${{ github.event.pull_request.head.repo.full_name }} + - name: Download patch + uses: actions/download-artifact@v3 + with: + name: .repo.patch + path: \${{ runner.temp }} + - name: Apply patch + run: '[ -s \${{ runner.temp }}/.repo.patch ] && git apply \${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."' + - name: Set git identity + run: |- + git config user.name "github-actions" + git config user.email "github-actions@github.com" + - name: Push changes + env: + PULL_REQUEST_REF: \${{ github.event.pull_request.head.ref }} + run: |- + git add . + git commit -s -m "chore: self mutation" + git push origin HEAD:$PULL_REQUEST_REF +", + ".github/workflows/pull-request-lint.yml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +name: pull-request-lint +on: + pull_request_target: + types: + - labeled + - opened + - synchronize + - reopened + - ready_for_review + - edited +jobs: + validate: + name: Validate PR title + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: amannn/action-semantic-pull-request@v5.0.2 + env: + GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} + with: + types: |- + feat + fix + chore + requireScope: false +", + ".github/workflows/release.yml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +name: release +on: + push: + branches: + - main + workflow_dispatch: {} +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + latest_commit: \${{ steps.git_remote.outputs.latest_commit }} + env: + CI: "true" + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set git identity + run: |- + git config user.name "github-actions" + git config user.email "github-actions@github.com" + - name: Install dependencies + run: yarn install --check-files --frozen-lockfile + - name: release + run: npx projen release + - name: Check for new commits + id: git_remote + run: echo "latest_commit=$(git ls-remote origin -h \${{ github.ref }} | cut -f1)" >> $GITHUB_OUTPUT + - name: Backup artifact permissions + if: \${{ steps.git_remote.outputs.latest_commit == github.sha }} + run: cd dist && getfacl -R . > permissions-backup.acl + continue-on-error: true + - name: Upload artifact + if: \${{ steps.git_remote.outputs.latest_commit == github.sha }} + uses: actions/upload-artifact@v3 + with: + name: build-artifact + path: dist + release_github: + name: Publish to GitHub Releases + needs: release + runs-on: ubuntu-latest + permissions: + contents: write + if: needs.release.outputs.latest_commit == github.sha + steps: + - uses: actions/setup-node@v3 + with: + node-version: 16.x + - name: Download build artifacts + uses: actions/download-artifact@v3 + with: + name: build-artifact + path: dist + - name: Restore build artifact permissions + run: cd dist && setfacl --restore=permissions-backup.acl + continue-on-error: true + - name: Release + env: + GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} + GITHUB_REPOSITORY: \${{ github.repository }} + GITHUB_REF: \${{ github.ref }} + run: errout=$(mktemp); gh release create $(cat dist/releasetag.txt) -R $GITHUB_REPOSITORY -F dist/changelog.md -t $(cat dist/releasetag.txt) --target $GITHUB_REF 2> $errout && true; exitcode=$?; if [ $exitcode -ne 0 ] && ! grep -q "Release.tag_name already exists" $errout; then cat $errout; exit $exitcode; fi +", + ".github/workflows/upgrade-main.yml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +name: upgrade-main +on: + workflow_dispatch: {} + schedule: + - cron: 0 0 * * * +jobs: + upgrade: + name: Upgrade + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + patch_created: \${{ steps.create_patch.outputs.patch_created }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: main + - name: Install dependencies + run: yarn install --check-files --frozen-lockfile + - name: Upgrade dependencies + run: npx projen upgrade + - name: Find mutations + id: create_patch + run: |- + git add . + git diff --staged --patch --exit-code > .repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT + - name: Upload patch + if: steps.create_patch.outputs.patch_created + uses: actions/upload-artifact@v3 + with: + name: .repo.patch + path: .repo.patch + pr: + name: Create Pull Request + needs: upgrade + runs-on: ubuntu-latest + permissions: + contents: read + if: \${{ needs.upgrade.outputs.patch_created }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: main + - name: Download patch + uses: actions/download-artifact@v3 + with: + name: .repo.patch + path: \${{ runner.temp }} + - name: Apply patch + run: '[ -s \${{ runner.temp }}/.repo.patch ] && git apply \${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."' + - name: Set git identity + run: |- + git config user.name "github-actions" + git config user.email "github-actions@github.com" + - name: Create Pull Request + id: create-pr + uses: peter-evans/create-pull-request@v4 + with: + token: \${{ secrets.PROJEN_GITHUB_TOKEN }} + commit-message: |- + chore(deps): upgrade dependencies + + Upgrades project dependencies. See details in [workflow run]. + + [Workflow Run]: https://github.com/\${{ github.repository }}/actions/runs/\${{ github.run_id }} + + ------ + + *Automatically created by projen via the "upgrade-main" workflow* + branch: github-actions/upgrade-main + title: "chore(deps): upgrade dependencies" + body: |- + Upgrades project dependencies. See details in [workflow run]. + + [Workflow Run]: https://github.com/\${{ github.repository }}/actions/runs/\${{ github.run_id }} + + ------ + + *Automatically created by projen via the "upgrade-main" workflow* + author: github-actions + committer: github-actions + signoff: true +", + ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +!/.github/workflows/pull-request-lint.yml +!/package.json +!/LICENSE +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +build/Release +node_modules/ +jspm_packages/ +*.tsbuildinfo +.eslintcache +*.tgz +.yarn-integrity +.cache +!/.projenrc.js +/test-reports/ +junit.xml +/coverage/ +!/.github/workflows/build.yml +/dist/changelog.md +/dist/version.txt +!/.github/workflows/release.yml +!/.mergify.yml +!/.github/workflows/upgrade-main.yml +!/.github/pull_request_template.md +!/.npmrc +!/test/ +!/tsconfig.json +!/tsconfig.dev.json +!/src/ +/lib +/dist/ +!/.eslintrc.json +!/.npmignore +!/.openapi-generator-ignore +!/.openapi-generator-ignore-handlebars +!/openapitools.json +.openapi-generator +", + ".mergify.yml": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +queue_rules: + - name: default + update_method: merge + conditions: + - "#approved-reviews-by>=1" + - -label~=(do-not-merge) + - status-success=build +pull_request_rules: + - name: Automatic merge on approval and successful build + actions: + delete_head_branch: {} + queue: + method: squash + name: default + commit_message_template: |- + {{ title }} (#{{ number }}) + + {{ body }} + conditions: + - "#approved-reviews-by>=1" + - -label~=(do-not-merge) + - status-success=build +", + ".npmignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/.projen/ +/src +/dist +", + ".openapi-generator-ignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +.gitignore +/* +**/* +* +", + ".openapi-generator-ignore-handlebars": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +/* +**/* +* +!src/__all_handlers.ts +", + ".projen/deps.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": [ + { + "name": "@types/jest", + "type": "build", + }, + { + "name": "@types/node", + "type": "build", + "version": "^16", + }, + { + "name": "@typescript-eslint/eslint-plugin", + "type": "build", + "version": "^5", + }, + { + "name": "@typescript-eslint/parser", + "type": "build", + "version": "^5", + }, + { + "name": "esbuild", + "type": "build", + }, + { + "name": "eslint-import-resolver-node", + "type": "build", + }, + { + "name": "eslint-import-resolver-typescript", + "type": "build", + }, + { + "name": "eslint-plugin-import", + "type": "build", + }, + { + "name": "eslint", + "type": "build", + "version": "^8", + }, + { + "name": "jest", + "type": "build", + }, + { + "name": "jest-junit", + "type": "build", + "version": "^15", + }, + { + "name": "npm-check-updates", + "type": "build", + "version": "^16", + }, + { + "name": "projen", + "type": "build", + }, + { + "name": "standard-version", + "type": "build", + "version": "^9", + }, + { + "name": "ts-jest", + "type": "build", + }, + { + "name": "typescript", + "type": "build", + }, + { + "name": "test-ts-client", + "type": "runtime", + "version": "file:../ts-client", + }, + ], + }, + ".projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".eslintrc.json", + ".gitattributes", + ".github/pull_request_template.md", + ".github/workflows/build.yml", + ".github/workflows/pull-request-lint.yml", + ".github/workflows/release.yml", + ".github/workflows/upgrade-main.yml", + ".gitignore", + ".mergify.yml", + ".npmignore", + ".npmrc", + ".openapi-generator-ignore", + ".openapi-generator-ignore-handlebars", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "LICENSE", + "openapitools.json", + "tsconfig.dev.json", + "tsconfig.json", + ], + }, + ".projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "env": { + "PATH": "$(npx -c "node --print process.env.PATH")", + }, + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "default", + }, + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "bump": { + "condition": "! git log --oneline -1 | grep -q "chore(release):"", + "description": "Bumps version based on latest git tag and generates a changelog entry", + "env": { + "BUMPFILE": "dist/version.txt", + "CHANGELOG": "dist/changelog.md", + "OUTFILE": "package.json", + "RELEASETAG": "dist/releasetag.txt", + "RELEASE_TAG_PREFIX": "", + }, + "name": "bump", + "steps": [ + { + "builtin": "release/bump-version", + }, + ], + }, + "clobber": { + "condition": "git diff --exit-code > /dev/null", + "description": "hard resets to HEAD of origin and cleans the local repo", + "env": { + "BRANCH": "$(git branch --show-current)", + }, + "name": "clobber", + "steps": [ + { + "exec": "git checkout -b scratch", + "name": "save current HEAD in "scratch" branch", + }, + { + "exec": "git checkout $BRANCH", + }, + { + "exec": "git fetch origin", + "name": "fetch latest changes from origin", + }, + { + "exec": "git reset --hard origin/$BRANCH", + "name": "hard reset to origin commit", + }, + { + "exec": "git clean -fdx", + "name": "clean all untracked files", + }, + { + "say": "ready to rock! (unpushed commits are under the "scratch" branch)", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "exec": "tsc --build", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + "steps": [ + { + "exec": "node .projenrc.js", + }, + ], + }, + "eject": { + "description": "Remove projen from the project", + "env": { + "PROJEN_EJECTING": "true", + }, + "name": "eject", + "steps": [ + { + "spawn": "default", + }, + ], + }, + "eslint": { + "description": "Runs eslint against the codebase", + "name": "eslint", + "steps": [ + { + "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 clean-openapi-generated-code --code-path .", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 generate --generator typescript-fetch --spec-path my-spec.json --output-path . --generator-dir typescript-lambda-handlers --src-dir src --openapi-normalizer "KEEP_ONLY_FIRST_TAG_IN_OPERATION=true" --extra-vendor-extensions '{"x-runtime-package-name":"test-ts-client"}' --generate-alias-as-model", + }, + ], + }, + "install": { + "description": "Install project dependencies and update lockfile (non-frozen)", + "name": "install", + "steps": [ + { + "exec": "yarn link test-ts-client", + }, + { + "exec": "yarn install --check-files", + }, + ], + }, + "install:ci": { + "description": "Install project dependencies using frozen lockfile", + "name": "install:ci", + "steps": [ + { + "exec": "yarn install --check-files --frozen-lockfile", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + "steps": [ + { + "exec": "mkdir -p dist/js", + }, + { + "exec": "mv $(npm pack) dist/js/", + }, + { + "exec": "mkdir -p dist/lambda && rm -rf dist/lambda/*", + }, + { + "exec": "esbuild --bundle src/*.ts --platform=node --outdir=dist/lambda", + }, + { + "exec": "for f in $(ls dist/lambda); do mkdir dist/lambda/$(basename $f .js) && mv dist/lambda/$f dist/lambda/$(basename $f .js)/index.js; done", + }, + ], + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "post-upgrade": { + "description": "Runs after upgrading dependencies", + "name": "post-upgrade", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "release": { + "description": "Prepare a release from "main" branch", + "env": { + "RELEASE": "true", + }, + "name": "release", + "steps": [ + { + "exec": "rm -fr dist", + }, + { + "spawn": "bump", + }, + { + "spawn": "build", + }, + { + "spawn": "unbump", + }, + { + "exec": "git diff --ignore-space-at-eol --exit-code", + }, + ], + }, + "test": { + "description": "Run tests", + "name": "test", + "steps": [ + { + "exec": "jest --passWithNoTests --updateSnapshot", + "receiveArgs": true, + }, + { + "spawn": "eslint", + }, + ], + }, + "test:watch": { + "description": "Run jest in watch mode", + "name": "test:watch", + "steps": [ + { + "exec": "jest --watch", + }, + ], + }, + "unbump": { + "description": "Restores version to 0.0.0", + "env": { + "BUMPFILE": "dist/version.txt", + "CHANGELOG": "dist/changelog.md", + "OUTFILE": "package.json", + "RELEASETAG": "dist/releasetag.txt", + "RELEASE_TAG_PREFIX": "", + }, + "name": "unbump", + "steps": [ + { + "builtin": "release/reset-version", + }, + ], + }, + "upgrade": { + "description": "upgrade dependencies", + "env": { + "CI": "0", + }, + "name": "upgrade", + "steps": [ + { + "exec": "yarn upgrade npm-check-updates", + }, + { + "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='test-ts-client'", + }, + { + "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='test-ts-client'", + }, + { + "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='test-ts-client'", + }, + { + "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='test-ts-client'", + }, + { + "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='test-ts-client'", + }, + { + "exec": "yarn install --check-files", + }, + { + "exec": "yarn upgrade", + }, + { + "exec": "npx projen", + }, + { + "spawn": "post-upgrade", + }, + ], + }, + "watch": { + "description": "Watch & compile in the background", + "name": "watch", + "steps": [ + { + "exec": "tsc --build -w", + }, + ], + }, + }, + }, + "LICENSE": " + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License 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. +", + "README.md": "# replace this", + "openapitools.json": { + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "generator-cli": { + "storageDir": "~/.open-api-generator-cli", + "version": "6.3.0", + }, + "spaces": 2, + }, + "package.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "dependencies": { + "test-ts-client": "file:../ts-client", + }, + "devDependencies": { + "@types/jest": "*", + "@types/node": "^16", + "@typescript-eslint/eslint-plugin": "^5", + "@typescript-eslint/parser": "^5", + "esbuild": "*", + "eslint": "^8", + "eslint-import-resolver-node": "*", + "eslint-import-resolver-typescript": "*", + "eslint-plugin-import": "*", + "jest": "*", + "jest-junit": "^15", + "npm-check-updates": "^16", + "projen": "*", + "standard-version": "^9", + "ts-jest": "*", + "typescript": "*", + }, + "jest": { + "clearMocks": true, + "collectCoverage": true, + "coverageDirectory": "coverage", + "coveragePathIgnorePatterns": [ + "/node_modules/", + ], + "coverageReporters": [ + "json", + "lcov", + "clover", + "cobertura", + "text", + ], + "globals": { + "ts-jest": { + "tsconfig": "tsconfig.dev.json", + }, + }, + "preset": "ts-jest", + "reporters": [ + "default", + [ + "jest-junit", + { + "outputDirectory": "test-reports", + }, + ], + ], + "testMatch": [ + "/src/**/__tests__/**/*.ts?(x)", + "/(test|src)/**/*(*.)@(spec|test).ts?(x)", + ], + "testPathIgnorePatterns": [ + "/node_modules/", + ], + "watchPathIgnorePatterns": [ + "/node_modules/", + ], + }, + "license": "Apache-2.0", + "main": "lib/index.js", + "name": "test-ts-handlers", + "scripts": { + "build": "npx projen build", + "bump": "npx projen bump", + "clobber": "npx projen clobber", + "compile": "npx projen compile", + "default": "npx projen default", + "eject": "npx projen eject", + "eslint": "npx projen eslint", + "generate": "npx projen generate", + "package": "npx projen package", + "post-compile": "npx projen post-compile", + "post-upgrade": "npx projen post-upgrade", + "pre-compile": "npx projen pre-compile", + "projen": "npx projen", + "release": "npx projen release", + "test": "npx projen test", + "test:watch": "npx projen test:watch", + "unbump": "npx projen unbump", + "upgrade": "npx projen upgrade", + "watch": "npx projen watch", + }, + "types": "lib/index.d.ts", + "version": "0.0.0", + }, + "tsconfig.dev.json": { + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [ + "node_modules", + ], + "include": [ + ".projenrc.js", + "src/**/*.ts", + "test/**/*.ts", + ], + }, + "tsconfig.json": { + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "dom", + "es2019", + ], + "module": "CommonJS", + "noEmitOnError": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "lib", + "resolveJsonModule": true, + "rootDir": "src", + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2019", + }, + "exclude": [], + "include": [ + "src/**/*.ts", + ], + }, +} +`; diff --git a/packages/type-safe-api/test/project/codegen/handlers/generated-java-handlers-project.test.ts b/packages/type-safe-api/test/project/codegen/handlers/generated-java-handlers-project.test.ts new file mode 100644 index 000000000..ef53a9dcd --- /dev/null +++ b/packages/type-safe-api/test/project/codegen/handlers/generated-java-handlers-project.test.ts @@ -0,0 +1,29 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import path from "path"; +import { GeneratedJavaHandlersProject } from "../../../../src/project/codegen/handlers/generated-java-handlers-project"; +import { GeneratedJavaRuntimeProject } from "../../../../src/project/codegen/runtime/generated-java-runtime-project"; +import { synthProject } from "../../snapshot-utils"; + +describe("Generated Java Handlers Code Unit Tests", () => { + it("Synth", () => { + const project = new GeneratedJavaHandlersProject({ + outdir: path.resolve(__dirname, "java-handlers"), + name: "test-java-handlers", + artifactId: "com.aws.pdk.test.handlers", + groupId: "test", + version: "1.0.0", + specPath: "my-spec.json", + generatedJavaTypes: new GeneratedJavaRuntimeProject({ + outdir: path.resolve(__dirname, "java-client"), + name: "test-java-client", + artifactId: "com.aws.pdk.test.runtime", + groupId: "test", + version: "1.0.0", + specPath: "my-spec.json", + }), + }); + + expect(synthProject(project)).toMatchSnapshot(); + }); +}); diff --git a/packages/type-safe-api/test/project/codegen/handlers/generated-python-handlers-project.test.ts b/packages/type-safe-api/test/project/codegen/handlers/generated-python-handlers-project.test.ts new file mode 100644 index 000000000..2323dbc79 --- /dev/null +++ b/packages/type-safe-api/test/project/codegen/handlers/generated-python-handlers-project.test.ts @@ -0,0 +1,31 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import path from "path"; +import { GeneratedPythonHandlersProject } from "../../../../src/project/codegen/handlers/generated-python-handlers-project"; +import { GeneratedPythonRuntimeProject } from "../../../../src/project/codegen/runtime/generated-python-runtime-project"; +import { synthProject } from "../../snapshot-utils"; + +describe("Generated Python Handlers Code Unit Tests", () => { + it("Synth", () => { + const project = new GeneratedPythonHandlersProject({ + outdir: path.resolve(__dirname, "python-handlers"), + name: "test-python-handlers", + moduleName: "test_handlers", + authorEmail: "me@example.com", + authorName: "test", + version: "1.0.0", + specPath: "my-spec.json", + generatedPythonTypes: new GeneratedPythonRuntimeProject({ + outdir: path.resolve(__dirname, "python-client"), + name: "test-python-client", + moduleName: "test_client", + authorEmail: "me@example.com", + authorName: "test", + version: "1.0.0", + specPath: "my-spec.json", + }), + }); + + expect(synthProject(project)).toMatchSnapshot(); + }); +}); diff --git a/packages/type-safe-api/test/project/codegen/handlers/generated-typescript-handlers-project.test.ts b/packages/type-safe-api/test/project/codegen/handlers/generated-typescript-handlers-project.test.ts new file mode 100644 index 000000000..45d53b432 --- /dev/null +++ b/packages/type-safe-api/test/project/codegen/handlers/generated-typescript-handlers-project.test.ts @@ -0,0 +1,25 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import path from "path"; +import { GeneratedTypescriptHandlersProject } from "../../../../src/project/codegen/handlers/generated-typescript-handlers-project"; +import { GeneratedTypescriptRuntimeProject } from "../../../../src/project/codegen/runtime/generated-typescript-runtime-project"; +import { synthProject } from "../../snapshot-utils"; + +describe("Generated Typescript Handlers Code Unit Tests", () => { + it("Synth", () => { + const project = new GeneratedTypescriptHandlersProject({ + outdir: path.resolve(__dirname, "ts-handlers"), + name: "test-ts-handlers", + defaultReleaseBranch: "main", + specPath: "my-spec.json", + generatedTypescriptTypes: new GeneratedTypescriptRuntimeProject({ + outdir: path.resolve(__dirname, "ts-client"), + name: "test-ts-client", + defaultReleaseBranch: "main", + specPath: "my-spec.json", + }), + }); + + expect(synthProject(project)).toMatchSnapshot(); + }); +}); diff --git a/packages/type-safe-api/test/project/model/__snapshots__/type-safe-api-model-project.test.ts.snap b/packages/type-safe-api/test/project/model/__snapshots__/type-safe-api-model-project.test.ts.snap index ed79ec2ce..c0a0a5255 100644 --- a/packages/type-safe-api/test/project/model/__snapshots__/type-safe-api-model-project.test.ts.snap +++ b/packages/type-safe-api/test/project/model/__snapshots__/type-safe-api-model-project.test.ts.snap @@ -262,28 +262,376 @@ paths: type: string required: true responses: - '200': + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SayHelloResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' +components: + schemas: + SayHelloResponseContent: + type: object + properties: + message: + type: string + required: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message +", +} +`; + +exports[`Type Safe Api Model Project Unit Tests OpenAPI With Handlers 1`] = ` +{ + ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +.api.json +", + ".projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + ], + }, + ".projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "default", + }, + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + }, + "eject": { + "description": "Remove projen from the project", + "env": { + "PROJEN_EJECTING": "true", + }, + "name": "eject", + "steps": [ + { + "spawn": "default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path src/main/openapi/main.yaml --output-path .api.json", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "README.md": "# OpenAPI Model + +This project defines the API operations and their inputs and outputs, using [OpenAPI v3](https://swagger.io/specification/v3/). + +The entrypoint for the API is \`src/main/openapi/main.yaml\`. You can add more yaml files (and subfolders) in the \`src/main/openapi\` directory and these will be included in your API definition so long as they are referencable from \`main.yaml\`. + +Resources: + - [OpenAPI v3 Documentation](https://swagger.io/specification/v3/) + - [Type Safe API Documentation](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api) + +## Adding Operations + +To add an operation, we must edit the \`paths\` section of the OpenAPI document. We add the desired path and HTTP method for the operation, as well as its inputs and outputs, for example: + +\`\`\`yaml +paths: + /foo/{myUrlParam}: + post: + operationId: CreateFoo + parameters: + - name: myUrlParam + in: path + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFooRequest' + responses: + 200: + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFooResponse' +\`\`\` + +Notice we used \`$ref\` to reference \`components\` in the OpenAPI specification. We define these next: + +\`\`\`yaml +components: + schemas: + CreateFooRequest: + type: object + properties: + someParameter: + type: string + anotherParameter: + type: double + required: + - someParameter + CreateFooResponse: + type: object + properties: + foo: + $ref: '#/components/schemas/Foo' + required: + - foo + Foo: + type: object + properties: + myProperty: + type: integer + required: + - myProperty +\`\`\` + +Notice above we also used a reference to \`Foo\` in the \`CreateFooResponse\` + +After adding the operation, please follow the remaining instructions in the [main README](../README.md). + +## Breaking Up The Model + +You may find that a single \`main.yaml\` file becomes unwieldy as the API grows. You can split the file up using references to local files within the \`src/main/openapi\` directory. + +For example, you might choose to structure your spec as follows: + +\`\`\` +|_ src/main/openapi/ + |_ main.yaml + |_ paths/ + |_ index.yaml + |_ sayHello.yaml + |_ schemas/ + |_ index.yaml + |_ helloResponse.yaml +\`\`\` + +Where \`main.yaml\` looks as follows: + +\`\`\`yaml +openapi: 3.0.3 +info: + version: 1.0.0 + title: Example API +paths: + $ref: './paths/index.yaml' +components: + schemas: + $ref: './schemas/index.yaml' +\`\`\` + +\`paths/index.yaml\`: + +\`\`\`yaml +/hello: + get: + $ref: './sayHello.yaml' +\`\`\` + +\`paths/sayHello.yaml\`: + +\`\`\`yaml +operationId: sayHello +parameters: + - in: query + name: name + schema: + type: string + required: true +responses: + '200': + description: Successful response + content: + 'application/json': + schema: + $ref: '../schemas/helloResponse.yaml' +\`\`\` + +\`schemas/index.yaml\`: + +\`\`\`yaml +HelloResponse: + $ref: './helloResponse.yaml' +\`\`\` + +\`schemas/helloResponse.yaml\`: + +\`\`\`yaml +type: object +properties: + message: + type: string +required: + - message +\`\`\` +", + "src/main/openapi/main.yaml": "openapi: 3.0.3 +info: + version: 1.0.0 + title: MyService +paths: + /hello: + get: + operationId: sayHello + x-handler: + language: java + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: description: Successful response content: 'application/json': schema: $ref: '#/components/schemas/SayHelloResponseContent' - '400': - description: Error response + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input content: 'application/json': schema: - $ref: '#/components/schemas/ApiErrorResponseContent' + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' components: schemas: - ApiErrorResponseContent: + SayHelloResponseContent: type: object properties: - errorMessage: + message: type: string required: - - errorMessage - SayHelloResponseContent: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: type: object properties: message: @@ -294,7 +642,419 @@ components: } `; -exports[`Type Safe Api Model Project Unit Tests Smithy 1`] = ` +exports[`Type Safe Api Model Project Unit Tests Smithy 1`] = ` +{ + ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +node_modules/ +!/.gitattributes +!/.projen/tasks.json +!/.projen/deps.json +!/.projen/files.json +gradle +gradlew +gradlew.bat +.gradle +!/settings.gradle +!/build.gradle +!/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy +build +smithy-output +.api.json +", + ".projen/files.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "files": [ + ".gitattributes", + ".gitignore", + ".projen/deps.json", + ".projen/files.json", + ".projen/tasks.json", + "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", + "settings.gradle", + "smithy-build.json", + ], + }, + ".projen/tasks.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "tasks": { + "build": { + "description": "Full release build", + "name": "build", + "steps": [ + { + "spawn": "default", + }, + { + "spawn": "pre-compile", + }, + { + "spawn": "compile", + }, + { + "spawn": "post-compile", + }, + { + "spawn": "test", + }, + { + "spawn": "package", + }, + ], + }, + "compile": { + "description": "Only compile", + "name": "compile", + "steps": [ + { + "spawn": "generate", + }, + ], + }, + "default": { + "description": "Synthesize project files", + "name": "default", + }, + "eject": { + "description": "Remove projen from the project", + "env": { + "PROJEN_EJECTING": "true", + }, + "name": "eject", + "steps": [ + { + "spawn": "default", + }, + ], + }, + "generate": { + "name": "generate", + "steps": [ + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 copy-gradle-wrapper", + }, + { + "exec": "./gradlew build", + }, + { + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-model/openapi/openapi/MyService.openapi.json --output-path .api.json", + }, + ], + }, + "package": { + "description": "Creates the distribution package", + "name": "package", + }, + "post-compile": { + "description": "Runs after successful compilation", + "name": "post-compile", + }, + "pre-compile": { + "description": "Prepare the project for compilation", + "name": "pre-compile", + }, + "test": { + "description": "Run tests", + "name": "test", + }, + }, + }, + "README.md": "# Smithy Model + +This project defines the API operations and their inputs and outputs, using an interface definition language called [Smithy](https://smithy.io/2.0/). + +The default entrypoint for the API is \`src/main/smithy/main.smithy\`. You can add more Smithy files (and subfolders) in the \`src/main/smithy\` directory, and these will be discovered as part of the project's build task. + +Resources: + - [Smithy Documentation](https://smithy.io/2.0/) + - [Type Safe API Documentation](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api) + +## Adding Operations + +To add an operation, we can use the \`operation\` shape. It should be annotated with the \`@http\` trait, which defines the method and path for the operation. Each operation has \`input\`, \`output\` and \`errors\`. You can define the \`input\` and \`output\` inline using the \`:=\` syntax. + +\`\`\`smithy +/// This is an example operation. +@http(method: "POST", uri: "/foo/{myUrlParam}") +operation CreateFoo { + input := { + /// This parameter comes from the url + @httpLabel + myUrlParam: String + + /// Since there's no @httpLabel or @httpQuery annotation, + /// this parameter will be in the POST request body + @reqired + someParameter: String + + /// This parameter is also in the body, but is optional + anotherParameter: Double + } + output := { + @required + foo: Foo + } + errors: [ApiError] +} +\`\`\` + +In the above, we've referenced a shape called \`Foo\` in the output. Let's define that as a \`structure\`: + +\`\`\`smithy +structure Foo { + /// Some documentation about this property + @required + myProperty: Integer +} +\`\`\` + +When we're happy with our new operation, we must add it to our \`service\`. By default, the \`service\` shape is in the \`src/main/smithy/main.smithy\` file. + +\`\`\`smithy +@restJson1 +service MyApi { + version: "1.0" + operations: [ + SayHello + CreateFoo // <- add the new operation here + ] +} +\`\`\` + +After adding the operation, please follow the remaining instructions in the [main README](../README.md). + +## Resources + +A common pattern is to use resources to model parts of your API. These are collections of operations which for managing an entity with an identifier. In a resource, you define the identifier as well as operations to manage the entity's lifecycle. For example: + +\`\`\`smithy +resource PetResource { + identifiers: { + petId: String + } + read: GetPet + list: ListPets + update: UpdatePet + create: CreatePet + delete: DeletePet +} +\`\`\` + +For the resource to be included in your API, you must attach it to the \`service\` by adding it to the service's \`resources\` property: + +\`\`\`smithy +@restJson1 +service MyApi { + version: "1.0" + resources: [ + PetResource + ] +} +\`\`\` + +For more details, see the [Smithy documentation](https://smithy.io/2.0/spec/service-types.html#resource). + +## Customising the Smithy Build + +The build task for this project will by default generate an Open API specification from the Smithy model, which is then used to generate the runtime, infrastructure, and documentation projects. + +You can further customise the build via editing the \`TypeSafeApiProject\` \`model.options.smithyBuildOptions\` in the root \`.projenrc\` file. This includes adding projections, or customising the \`openapi\` projection used to generate the Open API specification. + +For details about customising the build, please see the [Type Safe API README](https://github.com/aws/aws-prototyping-sdk/tree/mainline/packages/type-safe-api), and refer to the [Smithy Build documentation](https://smithy.io/2.0/guides/building-models/build-config.html). +", + "build.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +plugins { + id "software.amazon.smithy" version "0.6.0" +} + +sourceSets { + main { + java { + srcDirs = ['src/main/smithy', 'generated/main/smithy'] + } + } +} + +// Dependencies can be added by configuring smithyBuildOptions in your .projenrc file +repositories { + mavenLocal() + mavenCentral() +} + +// Dependencies can be added by configuring smithyBuildOptions in your .projenrc file +dependencies { + implementation "software.amazon.smithy:smithy-cli:1.28.0" + implementation "software.amazon.smithy:smithy-model:1.28.0" + implementation "software.amazon.smithy:smithy-openapi:1.28.0" + implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" +} +", + "generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + +", + "settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". +rootProject.name = 'smithy-model' +", + "smithy-build.json": { + "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", + "maven": { + "dependencies": [ + "software.amazon.smithy:smithy-cli:1.28.0", + "software.amazon.smithy:smithy-model:1.28.0", + "software.amazon.smithy:smithy-openapi:1.28.0", + "software.amazon.smithy:smithy-aws-traits:1.28.0", + ], + "repositories": [ + { + "url": "https://repo.maven.apache.org/maven2/", + }, + { + "url": "file://~/.m2/repository", + }, + ], + }, + "projections": { + "openapi": { + "plugins": { + "openapi": { + "service": "com.test#MyService", + "tags": true, + }, + }, + }, + }, + "sources": [ + "src/main/smithy", + "generated/main/smithy", + ], + "version": "2.0", + }, + "src/main/smithy/main.smithy": "$version: "2" +namespace com.test + +use aws.protocols#restJson1 + +/// A sample smithy api +@restJson1 +service MyService { + version: "1.0" + operations: [SayHello] + errors: [ + BadRequestError + NotAuthorizedError + InternalFailureError + ] +}", + "src/main/smithy/operations/say-hello.smithy": "$version: "2" +namespace com.test + +@readonly +@http(method: "GET", uri: "/hello") +operation SayHello { + input := { + @httpQuery("name") + @required + name: String + } + output := { + @required + message: String + } + errors: [NotFoundError] +} +", + "src/main/smithy/types/errors.smithy": "$version: "2" +namespace com.test + +/// An error message +string ErrorMessage + +/// An internal failure at the fault of the server +@error("server") +@httpError(500) +structure InternalFailureError { + /// Message with details about the error + @required + message: ErrorMessage +} + +/// An error at the fault of the client sending invalid input +@error("client") +@httpError(400) +structure BadRequestError { + /// Message with details about the error + @required + message: ErrorMessage +} + +/// An error due to the client attempting to access a missing resource +@error("client") +@httpError(404) +structure NotFoundError { + /// Message with details about the error + @required + message: ErrorMessage +} + +/// An error due to the client not being authorized to access the resource +@error("client") +@httpError(403) +structure NotAuthorizedError { + /// Message with details about the error + @required + message: ErrorMessage +} +", +} +`; + +exports[`Type Safe Api Model Project Unit Tests Smithy With Build Options 1`] = ` { ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ @@ -309,6 +1069,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -322,6 +1083,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -388,7 +1150,7 @@ smithy-output "exec": "./gradlew build", }, { - "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-model/openapi/openapi/MyService.openapi.json --output-path .api.json", + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-model-with-build-options/openapi/openapi/MyService.openapi.json --output-path .api.json", }, ], }, @@ -521,7 +1283,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy', 'yet/another', '../another-absolute'] } } } @@ -539,9 +1301,57 @@ dependencies { implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" } +", + "generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -rootProject.name = 'smithy-model' +rootProject.name = 'smithy-model-with-build-options' ", "smithy-build.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -565,6 +1375,8 @@ rootProject.name = 'smithy-model' "openapi": { "plugins": { "openapi": { + "forbidGreedyLabels": true, + "ignoreUnsupportedTraits": true, "service": "com.test#MyService", "tags": true, }, @@ -573,6 +1385,11 @@ rootProject.name = 'smithy-model' }, "sources": [ "src/main/smithy", + "foo/bar", + "../some-other-directory", + "generated/main/smithy", + "yet/another", + "../another-absolute", ], "version": "2.0", }, @@ -655,7 +1472,7 @@ structure NotAuthorizedError { } `; -exports[`Type Safe Api Model Project Unit Tests Smithy With Build Options 1`] = ` +exports[`Type Safe Api Model Project Unit Tests Smithy With Dependencies 1`] = ` { ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ @@ -670,6 +1487,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -683,6 +1501,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -749,7 +1568,7 @@ smithy-output "exec": "./gradlew build", }, { - "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-model-with-build-options/openapi/openapi/MyService.openapi.json --output-path .api.json", + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-model-consumer/openapi/openapi/Consumer.openapi.json --output-path .api.json", }, ], }, @@ -882,7 +1701,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -899,10 +1718,59 @@ dependencies { implementation "software.amazon.smithy:smithy-model:1.28.0" implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" + implementation files("../smithy-model-lib/build/libs/smithy-model-lib.jar") +} +", + "generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "TraitNotPermitted" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + * + """ + messageTemplate: """ + @@handler trait cannot be used unless handler project languages have been configured. + You can add handler projects by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have not configured any handler projects, so you cannot use this trait. +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String } + ", "settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -rootProject.name = 'smithy-model-with-build-options' +rootProject.name = 'smithy-model-consumer' ", "smithy-build.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -926,9 +1794,7 @@ rootProject.name = 'smithy-model-with-build-options' "openapi": { "plugins": { "openapi": { - "forbidGreedyLabels": true, - "ignoreUnsupportedTraits": true, - "service": "com.test#MyService", + "service": "com.test#Consumer", "tags": true, }, }, @@ -936,10 +1802,7 @@ rootProject.name = 'smithy-model-with-build-options' }, "sources": [ "src/main/smithy", - "foo/bar", - "../some-other-directory", - "yet/another", - "../another-absolute", + "generated/main/smithy", ], "version": "2.0", }, @@ -950,7 +1813,7 @@ use aws.protocols#restJson1 /// A sample smithy api @restJson1 -service MyService { +service Consumer { version: "1.0" operations: [SayHello] errors: [ @@ -1022,7 +1885,7 @@ structure NotAuthorizedError { } `; -exports[`Type Safe Api Model Project Unit Tests Smithy With Dependencies 1`] = ` +exports[`Type Safe Api Model Project Unit Tests Smithy With Handlers 1`] = ` { ".gitignore": "# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". node_modules/ @@ -1037,6 +1900,7 @@ gradlew.bat !/settings.gradle !/build.gradle !/smithy-build.json +!/generated/main/smithy/aws-pdk/prelude.smithy build smithy-output .api.json @@ -1050,6 +1914,7 @@ smithy-output ".projen/files.json", ".projen/tasks.json", "build.gradle", + "generated/main/smithy/aws-pdk/prelude.smithy", "settings.gradle", "smithy-build.json", ], @@ -1116,7 +1981,7 @@ smithy-output "exec": "./gradlew build", }, { - "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-model-consumer/openapi/openapi/Consumer.openapi.json --output-path .api.json", + "exec": "npx --yes -p @aws-prototyping-sdk/type-safe-api@0.0.0 parse-openapi-spec --spec-path build/smithyprojections/smithy-handlers/openapi/openapi/MyService.openapi.json --output-path .api.json", }, ], }, @@ -1249,7 +2114,7 @@ plugins { sourceSets { main { java { - srcDirs = ['src/main/smithy'] + srcDirs = ['src/main/smithy', 'generated/main/smithy'] } } } @@ -1266,11 +2131,60 @@ dependencies { implementation "software.amazon.smithy:smithy-model:1.28.0" implementation "software.amazon.smithy:smithy-openapi:1.28.0" implementation "software.amazon.smithy:smithy-aws-traits:1.28.0" - implementation files("../smithy-model-lib/build/libs/smithy-model-lib.jar") } +", + "generated/main/smithy/aws-pdk/prelude.smithy": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". + +$version: "2" + +metadata validators = [ + { + id: "SupportedLanguage" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + :not([@trait|com.test#handler: @{language} = typescript, java, python]) + """ + messageTemplate: """ + @{trait|com.test#handler|language} is not supported by type-safe-api. + Supported languages are "typescript", "java" and "python". + """ + } + } + { + id: "ConfiguredHandlerProject" + name: "EmitEachSelector" + configuration: { + bindToTrait: com.test#handler + selector: """ + [@trait|com.test#handler: @{language} = typescript, java, python] + :not([@trait|com.test#handler: @{language} = python, typescript]) + """ + messageTemplate: """ + @@handler language @{trait|com.test#handler|language} cannot be referenced unless a handler project is configured for this language. + Configured handler project languages are: python, typescript. + You can add this language by configuring TypeSafeApiProject in your .projenrc + """ + } + } +] + +namespace com.test + +/// Add this trait to an operation to generate a lambda handler stub for the operation. +/// You have configured handler projects for python, typescript +@trait(selector: "operation") +structure handler { + /// The language you will implement the lambda in. + /// Valid values: typescript, java, python + @required + language: String +} + ", "settings.gradle": "// ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". -rootProject.name = 'smithy-model-consumer' +rootProject.name = 'smithy-handlers' ", "smithy-build.json": { "//": "~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".", @@ -1294,7 +2208,7 @@ rootProject.name = 'smithy-model-consumer' "openapi": { "plugins": { "openapi": { - "service": "com.test#Consumer", + "service": "com.test#MyService", "tags": true, }, }, @@ -1302,6 +2216,7 @@ rootProject.name = 'smithy-model-consumer' }, "sources": [ "src/main/smithy", + "generated/main/smithy", ], "version": "2.0", }, @@ -1312,7 +2227,7 @@ use aws.protocols#restJson1 /// A sample smithy api @restJson1 -service Consumer { +service MyService { version: "1.0" operations: [SayHello] errors: [ @@ -1326,6 +2241,7 @@ namespace com.test @readonly @http(method: "GET", uri: "/hello") +@handler(language: "python") operation SayHello { input := { @httpQuery("name") diff --git a/packages/type-safe-api/test/project/model/type-safe-api-model-project.test.ts b/packages/type-safe-api/test/project/model/type-safe-api-model-project.test.ts index 986722c99..d2f84faea 100644 --- a/packages/type-safe-api/test/project/model/type-safe-api-model-project.test.ts +++ b/packages/type-safe-api/test/project/model/type-safe-api-model-project.test.ts @@ -1,7 +1,7 @@ /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ import path from "path"; -import { ModelLanguage, TypeSafeApiModelProject } from "../../../src"; +import { Language, ModelLanguage, TypeSafeApiModelProject } from "../../../src"; import { synthProject, synthSmithyProject } from "../snapshot-utils"; describe("Type Safe Api Model Project Unit Tests", () => { @@ -109,6 +109,41 @@ describe("Type Safe Api Model Project Unit Tests", () => { expect(synthProject(project)).toMatchSnapshot(); }); + it("Smithy With Handlers", () => { + const project = new TypeSafeApiModelProject({ + outdir: path.resolve(__dirname, "smithy-handlers"), + name: "smithy-handlers", + modelLanguage: ModelLanguage.SMITHY, + modelOptions: { + smithy: { + serviceName: { + namespace: "com.test", + serviceName: "MyService", + }, + }, + }, + handlerLanguages: [Language.PYTHON, Language.TYPESCRIPT], + }); + + expect(synthSmithyProject(project)).toMatchSnapshot(); + }); + + it("OpenAPI With Handlers", () => { + const project = new TypeSafeApiModelProject({ + outdir: path.resolve(__dirname, "openapi-handlers"), + name: "openapi-handlers", + modelLanguage: ModelLanguage.OPENAPI, + modelOptions: { + openapi: { + title: "MyService", + }, + }, + handlerLanguages: [Language.JAVA, Language.PYTHON], + }); + + expect(synthProject(project)).toMatchSnapshot(); + }); + it("Throws For Missing Smithy Options", () => { expect(() => { new TypeSafeApiModelProject({ diff --git a/packages/type-safe-api/test/project/type-safe-api-project.test.ts b/packages/type-safe-api/test/project/type-safe-api-project.test.ts index 5d1095323..c6f075189 100644 --- a/packages/type-safe-api/test/project/type-safe-api-project.test.ts +++ b/packages/type-safe-api/test/project/type-safe-api-project.test.ts @@ -6,14 +6,14 @@ import { NodePackageManager } from "projen/lib/javascript"; import { synthProject, synthSmithyProject } from "./snapshot-utils"; import { DocumentationFormat, + GeneratedTypeScriptInfrastructureOptions, + GeneratedTypeScriptReactQueryHooksOptions, + GeneratedTypeScriptRuntimeOptions, Language, Library, ModelLanguage, - TypeSafeApiProject, OpenApiGeneratorCliConfig, - GeneratedTypeScriptReactQueryHooksOptions, - GeneratedTypeScriptInfrastructureOptions, - GeneratedTypeScriptRuntimeOptions, + TypeSafeApiProject, } from "../../src"; describe("Type Safe Api Project Unit Tests", () => { @@ -325,6 +325,45 @@ describe("Type Safe Api Project Unit Tests", () => { expect(synthSmithyProject(project)).toMatchSnapshot(); }); + it("Smithy With Handlers", () => { + const project = new TypeSafeApiProject({ + name: `smithy-handlers`, + outdir: path.resolve(__dirname, `smithy-handlers`), + infrastructure: { + language: Language.TYPESCRIPT, + }, + runtime: { + languages: [Language.TYPESCRIPT], + }, + model: { + language: ModelLanguage.SMITHY, + options: { + smithy: { + serviceName: { + namespace: "com.test", + serviceName: "MyService", + }, + }, + }, + }, + handlers: { + languages: [Language.TYPESCRIPT, Language.JAVA, Language.PYTHON], + }, + }); + + // Runtime languages should be added for each handler + expect(project.runtime.typescript).toBeDefined(); + expect(project.runtime.java).toBeDefined(); + expect(project.runtime.python).toBeDefined(); + + // Handlers should be present + expect(project.handlers.typescript).toBeDefined(); + expect(project.handlers.java).toBeDefined(); + expect(project.handlers.python).toBeDefined(); + + expect(synthSmithyProject(project)).toMatchSnapshot(); + }); + it("Custom OpenAPI Generator CLI Configuration", () => { const openApiGeneratorCliConfig: OpenApiGeneratorCliConfig = { version: "6.2.0", diff --git a/packages/type-safe-api/test/resources/specs/handlers.yaml b/packages/type-safe-api/test/resources/specs/handlers.yaml new file mode 100644 index 000000000..4d2e78a42 --- /dev/null +++ b/packages/type-safe-api/test/resources/specs/handlers.yaml @@ -0,0 +1,251 @@ +openapi: 3.0.3 +info: + version: 1.0.0 + title: ${options.openApiOptions.title} +paths: + /java/1: + get: + operationId: javaOne + x-handler: + language: java + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SuccessResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' + /java/2: + get: + operationId: javaTwo + x-handler: + language: java + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SuccessResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' + /python/1: + get: + operationId: pythonOne + x-handler: + language: python + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SuccessResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' + /python/2: + get: + operationId: pythonTwo + x-handler: + language: python + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SuccessResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' + /typescript/1: + get: + operationId: typescriptOne + x-handler: + language: typescript + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SuccessResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' + /typescript/2: + get: + operationId: typescriptTwo + x-handler: + language: typescript + parameters: + - in: query + name: name + schema: + type: string + required: true + responses: + 200: + description: Successful response + content: + 'application/json': + schema: + $ref: '#/components/schemas/SuccessResponseContent' + 500: + description: An internal failure at the fault of the server + content: + 'application/json': + schema: + $ref: '#/components/schemas/InternalFailureErrorResponseContent' + 400: + description: An error at the fault of the client sending invalid input + content: + 'application/json': + schema: + $ref: '#/components/schemas/BadRequestErrorResponseContent' + 403: + description: An error due to the client not being authorized to access the resource + content: + 'application/json': + schema: + $ref: '#/components/schemas/NotAuthorizedErrorResponseContent' +components: + schemas: + SuccessResponseContent: + type: object + properties: + message: + type: string + required: + - message + InternalFailureErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + BadRequestErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message + NotAuthorizedErrorResponseContent: + type: object + properties: + message: + type: string + required: + - message diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/docs.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/docs.test.ts.snap index 77f57e89b..ae8c019c7 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/docs.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/docs.test.ts.snap @@ -27,8 +27,7 @@ exports[`Docs Generation Script Unit Tests Generates html2 1`] = ` #!docs/README.md ", ".openapi-generator/FILES": ".openapi-generator-ignore -index.html -", +index.html", ".openapi-generator/VERSION": "6.3.0", "index.html": " @@ -5339,8 +5338,7 @@ Models/MapResponse_mapProperty_value.md Models/TestRequest.md Models/TestResponse.md Models/TestResponse_messages_inner.md -README.md -", +README.md", ".openapi-generator/VERSION": "6.3.0", "Apis/DefaultApi.md": "# DefaultApi @@ -5666,8 +5664,7 @@ exports[`Docs Generation Script Unit Tests Generates plantuml 1`] = ` #!docs/README.md ", ".openapi-generator/FILES": ".openapi-generator-ignore -schemas.plantuml -", +schemas.plantuml", ".openapi-generator/VERSION": "6.3.0", "openapitools.json": { "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/java-lambda-handlers.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/java-lambda-handlers.test.ts.snap new file mode 100644 index 000000000..73a90b8ea --- /dev/null +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/java-lambda-handlers.test.ts.snap @@ -0,0 +1,61 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Java Handlers Code Generation Script Unit Tests Generates With handlers.yaml 1`] = ` +"package test.test-handlers.handlers; + +import test.test-runtime.runtime.api.Handlers.JavaOne; +import test.test-runtime.runtime.api.Handlers.JavaOne500Response; +import test.test-runtime.runtime.api.Handlers.JavaOneRequestInput; +import test.test-runtime.runtime.api.Handlers.JavaOneResponse; +import test.test-runtime.runtime.model.*; + +/** + * Entry point for the AWS Lambda handler for the JavaOne operation. + * The JavaOne class manages marshalling inputs and outputs. + */ +public class JavaOneHandler extends JavaOne { + /** + * Type-safe handler for the JavaOne operation + */ + @Override + public JavaOneResponse handle(JavaOneRequestInput input) { + // TODO: Implement JavaOne Operation + return JavaOne500Response.of(InternalFailureErrorResponseContent.builder() + .message("Not Implemented!") + .build()); + } +} + +" +`; + +exports[`Java Handlers Code Generation Script Unit Tests Generates With handlers.yaml 2`] = ` +"package test.test-handlers.handlers; + +import test.test-runtime.runtime.api.Handlers.JavaTwo; +import test.test-runtime.runtime.api.Handlers.JavaTwo500Response; +import test.test-runtime.runtime.api.Handlers.JavaTwoRequestInput; +import test.test-runtime.runtime.api.Handlers.JavaTwoResponse; +import test.test-runtime.runtime.model.*; + +/** + * Entry point for the AWS Lambda handler for the JavaTwo operation. + * The JavaTwo class manages marshalling inputs and outputs. + */ +public class JavaTwoHandler extends JavaTwo { + /** + * Type-safe handler for the JavaTwo operation + */ + @Override + public JavaTwoResponse handle(JavaTwoRequestInput input) { + // TODO: Implement JavaTwo Operation + return JavaTwo500Response.of(InternalFailureErrorResponseContent.builder() + .message("Not Implemented!") + .build()); + } +} + + + +" +`; diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap index b0384fb26..1c08659b6 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/java.test.ts.snap @@ -126,8 +126,7 @@ src/main/java/test/test/runtime/auth/HttpBearerAuth.java src/main/java/test/test/runtime/model/AbstractOpenApiSchema.java src/test/java/test/test/runtime/api/DefaultApiTest.java src/test/java/test/test/runtime/api/Tag1ApiTest.java -src/test/java/test/test/runtime/api/Tag2ApiTest.java -", +src/test/java/test/test/runtime/api/Tag2ApiTest.java", ".openapi-generator/VERSION": "6.3.0", "README.md": "# com.aws.pdk.test @@ -5940,8 +5939,7 @@ src/test/java/test/test/runtime/model/MapResponseMapPropertyValueTest.java src/test/java/test/test/runtime/model/MapResponseTest.java src/test/java/test/test/runtime/model/TestRequestTest.java src/test/java/test/test/runtime/model/TestResponseMessagesInnerTest.java -src/test/java/test/test/runtime/model/TestResponseTest.java -", +src/test/java/test/test/runtime/model/TestResponseTest.java", ".openapi-generator/VERSION": "6.3.0", "README.md": "# com.aws.pdk.test diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/python-lambda-handlers.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/python-lambda-handlers.test.ts.snap new file mode 100644 index 000000000..68cebc5ec --- /dev/null +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/python-lambda-handlers.test.ts.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Python Handlers Code Generation Script Unit Tests Generates With handlers.yaml 1`] = ` +"from test_client.models import * +from test_client.apis.tags.default_api_operation_config import ( + python_one_handler, PythonOneRequest, PythonOneOperationResponses, ApiResponse +) + + +def python_one(input: PythonOneRequest, **kwargs) -> PythonOneOperationResponses: + """ + Type-safe handler for the PythonOne operation + """ + # TODO: Implement PythonOne Operation + return ApiResponse( + status_code=500, + body=InternalFailureErrorResponseContent( + message="Not Implemented!"), + headers={} + ) + + +# Entry point for the AWS Lambda handler for the PythonOne operation. +# The python_one_handler method wraps the type-safe handler and manages marshalling inputs and outputs +handler = python_one_handler(python_one)" +`; + +exports[`Python Handlers Code Generation Script Unit Tests Generates With handlers.yaml 2`] = ` +"from test_client.models import * +from test_client.apis.tags.default_api_operation_config import ( + python_two_handler, PythonTwoRequest, PythonTwoOperationResponses, ApiResponse +) + + +def python_two(input: PythonTwoRequest, **kwargs) -> PythonTwoOperationResponses: + """ + Type-safe handler for the PythonTwo operation + """ + # TODO: Implement PythonTwo Operation + return ApiResponse( + status_code=500, + body=InternalFailureErrorResponseContent( + message="Not Implemented!"), + headers={} + ) + + +# Entry point for the AWS Lambda handler for the PythonTwo operation. +# The python_two_handler method wraps the type-safe handler and manages marshalling inputs and outputs +handler = python_two_handler(python_two)" +`; diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap index a4eb27a1f..bf6971f76 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/python.test.ts.snap @@ -122,8 +122,7 @@ test_project/model/__init__.py test_project/models/__init__.py test_project/rest.py test_project/schemas.py -tox.ini -", +tox.ini", ".openapi-generator/VERSION": "6.3.0", "README.md": "# test_project No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) @@ -7887,8 +7886,7 @@ test_project/model/test_response.pyi test_project/models/__init__.py test_project/rest.py test_project/schemas.py -tox.ini -", +tox.ini", ".openapi-generator/VERSION": "6.3.0", "README.md": "# test_project No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-lambda-handlers.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-lambda-handlers.test.ts.snap new file mode 100644 index 000000000..119344caf --- /dev/null +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-lambda-handlers.test.ts.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Typescript Handlers Code Generation Script Unit Tests Generates With handlers.yaml 1`] = ` +"import { + typescriptOneHandler, + TypescriptOneChainedHandlerFunction, +} from "test-client"; + +/** + * Type-safe handler for the TypescriptOne operation + */ +export const typescriptOne: TypescriptOneChainedHandlerFunction = async ({ input }) => { + // TODO: Implement TypescriptOne Operation + return { + statusCode: 500, + body: { + message: "Not Implemented!", + }, + }; +}; + +/** + * Entry point for the AWS Lambda handler for the TypescriptOne operation. + * The typescriptOneHandler method wraps the type-safe handler and manages marshalling inputs and outputs + */ +export const handler = typescriptOneHandler(typescriptOne); + +" +`; + +exports[`Typescript Handlers Code Generation Script Unit Tests Generates With handlers.yaml 2`] = ` +"import { + typescriptTwoHandler, + TypescriptTwoChainedHandlerFunction, +} from "test-client"; + +/** + * Type-safe handler for the TypescriptTwo operation + */ +export const typescriptTwo: TypescriptTwoChainedHandlerFunction = async ({ input }) => { + // TODO: Implement TypescriptTwo Operation + return { + statusCode: 500, + body: { + message: "Not Implemented!", + }, + }; +}; + +/** + * Entry point for the AWS Lambda handler for the TypescriptTwo operation. + * The typescriptTwoHandler method wraps the type-safe handler and manages marshalling inputs and outputs + */ +export const handler = typescriptTwoHandler(typescriptTwo);" +`; diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap index 825412e30..a3f96fbae 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-react-query-hooks.test.ts.snap @@ -476,8 +476,7 @@ src/apis/Tag2ApiClientProvider.tsx src/apis/index.ts src/apis/index.ts src/index.ts -src/runtime.ts -", +src/runtime.ts", ".openapi-generator/VERSION": "6.3.0", "LICENSE": " Apache License @@ -2121,8 +2120,7 @@ src/models/TestResponseMessagesInner.ts src/models/TestResponseMessagesInner.ts src/models/TestResponseMessagesInner.ts src/models/index.ts -src/runtime.ts -", +src/runtime.ts", ".openapi-generator/VERSION": "6.3.0", "LICENSE": " Apache License diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap index 9c4c0d5fd..e7e4f1cbb 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript.test.ts.snap @@ -44,8 +44,7 @@ src/apis/index.ts src/index.ts src/runtime.ts tsconfig.esm.json -tsconfig.json -", +tsconfig.json", ".openapi-generator/VERSION": "6.3.0", "README.md": "## test@1.0.0 @@ -1325,8 +1324,7 @@ src/models/TestResponseMessagesInner.ts src/models/index.ts src/runtime.ts tsconfig.esm.json -tsconfig.json -", +tsconfig.json", ".openapi-generator/VERSION": "6.3.0", "README.md": "## test@1.0.0 diff --git a/packages/type-safe-api/test/scripts/generators/java-lambda-handlers.test.ts b/packages/type-safe-api/test/scripts/generators/java-lambda-handlers.test.ts new file mode 100644 index 000000000..5ee06dd00 --- /dev/null +++ b/packages/type-safe-api/test/scripts/generators/java-lambda-handlers.test.ts @@ -0,0 +1,84 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import os from "os"; +import * as path from "path"; +import { exec } from "projen/lib/util"; +import { GeneratedJavaHandlersProject } from "../../../src/project/codegen/handlers/generated-java-handlers-project"; +import { GeneratedJavaRuntimeProject } from "../../../src/project/codegen/runtime/generated-java-runtime-project"; +import { withTmpDirSnapshot } from "../../project/snapshot-utils"; + +describe("Java Handlers Code Generation Script Unit Tests", () => { + it.each(["handlers.yaml"])("Generates With %s", (spec) => { + const specPath = path.resolve(__dirname, `../../resources/specs/${spec}`); + + const snapshot = withTmpDirSnapshot( + os.tmpdir(), + (outdir) => { + exec(`cp ${specPath} ${outdir}/spec.yaml`, { + cwd: path.resolve(__dirname), + }); + const runtimeOutdir = path.join(outdir, "runtime"); + const runtime = new GeneratedJavaRuntimeProject({ + name: "test-runtime", + artifactId: "com.aws.pdk.test.runtime", + groupId: "test", + version: "1.0.0", + outdir: runtimeOutdir, + specPath: "../spec.yaml", + }); + const handlersOutdir = path.join(outdir, "handlers"); + const project = new GeneratedJavaHandlersProject({ + name: "test-handlers", + artifactId: "com.aws.pdk.test.handlers", + groupId: "test", + version: "1.0.0", + outdir: handlersOutdir, + specPath: "../spec.yaml", + generatedJavaTypes: runtime, + }); + project.synth(); + exec( + `${path.resolve( + __dirname, + "../../../scripts/generators/generate" + )} ${project.buildGenerateCommandArgs()}`, + { + cwd: handlersOutdir, + } + ); + }, + { + excludeGlobs: GeneratedJavaRuntimeProject.openApiIgnorePatterns, + parseJson: false, + } + ); + + expect( + snapshot[ + "handlers/src/main/java/test/test-handlers/handlers/JavaOneHandler.java" + ] + ).toMatchSnapshot(); + expect( + snapshot[ + "handlers/src/main/java/test/test-handlers/handlers/JavaTwoHandler.java" + ] + ).toMatchSnapshot(); + + // Other language handlers should be skipped + expect( + Object.keys(snapshot).filter((p) => + p.toLowerCase().includes("typescript") + ) + ).toHaveLength(0); + expect( + Object.keys(snapshot).filter((p) => p.toLowerCase().includes("python")) + ).toHaveLength(0); + + // Split file should be deleted + expect( + Object.keys(snapshot).filter((p) => + p.toLowerCase().includes("__all_handlers") + ) + ).toHaveLength(0); + }); +}); diff --git a/packages/type-safe-api/test/scripts/generators/python-lambda-handlers.test.ts b/packages/type-safe-api/test/scripts/generators/python-lambda-handlers.test.ts new file mode 100644 index 000000000..045f70fbf --- /dev/null +++ b/packages/type-safe-api/test/scripts/generators/python-lambda-handlers.test.ts @@ -0,0 +1,71 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import os from "os"; +import * as path from "path"; +import { exec } from "projen/lib/util"; +import { GeneratedPythonHandlersProject } from "../../../src/project/codegen/handlers/generated-python-handlers-project"; +import { GeneratedPythonRuntimeProject } from "../../../src/project/codegen/runtime/generated-python-runtime-project"; +import { withTmpDirSnapshot } from "../../project/snapshot-utils"; + +describe("Python Handlers Code Generation Script Unit Tests", () => { + it.each(["handlers.yaml"])("Generates With %s", (spec) => { + const specPath = path.resolve(__dirname, `../../resources/specs/${spec}`); + + const snapshot = withTmpDirSnapshot(os.tmpdir(), (outdir) => { + exec(`cp ${specPath} ${outdir}/spec.yaml`, { + cwd: path.resolve(__dirname), + }); + const clientOutdir = path.join(outdir, "client"); + const client = new GeneratedPythonRuntimeProject({ + name: "test-client", + moduleName: "test_client", + authorEmail: "me@example.com", + authorName: "test", + version: "1.0.0", + outdir: clientOutdir, + specPath: "../spec.yaml", + }); + const handlersOutdir = path.join(outdir, "handlers"); + const project = new GeneratedPythonHandlersProject({ + name: "test-handlers", + moduleName: "test_handlers", + authorEmail: "me@example.com", + authorName: "test", + version: "1.0.0", + outdir: handlersOutdir, + specPath: "../spec.yaml", + generatedPythonTypes: client, + }); + project.synth(); + exec( + `${path.resolve( + __dirname, + "../../../scripts/generators/generate" + )} ${project.buildGenerateCommandArgs()}`, + { + cwd: handlersOutdir, + } + ); + }); + + expect(snapshot["handlers/test_handlers/python_one.py"]).toMatchSnapshot(); + expect(snapshot["handlers/test_handlers/python_two.py"]).toMatchSnapshot(); + + // Other language handlers should be skipped + expect( + Object.keys(snapshot).filter((p) => + p.toLowerCase().includes("typescript") + ) + ).toHaveLength(0); + expect( + Object.keys(snapshot).filter((p) => p.toLowerCase().includes("java")) + ).toHaveLength(0); + + // Split file should be deleted + expect( + Object.keys(snapshot).filter((p) => + p.toLowerCase().includes("__all_handlers") + ) + ).toHaveLength(0); + }); +}); diff --git a/packages/type-safe-api/test/scripts/generators/typescript-lambda-handlers.test.ts b/packages/type-safe-api/test/scripts/generators/typescript-lambda-handlers.test.ts new file mode 100644 index 000000000..bfb15c446 --- /dev/null +++ b/packages/type-safe-api/test/scripts/generators/typescript-lambda-handlers.test.ts @@ -0,0 +1,63 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 */ +import os from "os"; +import * as path from "path"; +import { exec } from "projen/lib/util"; +import { GeneratedTypescriptHandlersProject } from "../../../src/project/codegen/handlers/generated-typescript-handlers-project"; +import { GeneratedTypescriptRuntimeProject } from "../../../src/project/codegen/runtime/generated-typescript-runtime-project"; +import { withTmpDirSnapshot } from "../../project/snapshot-utils"; + +describe("Typescript Handlers Code Generation Script Unit Tests", () => { + it.each(["handlers.yaml"])("Generates With %s", (spec) => { + const specPath = path.resolve(__dirname, `../../resources/specs/${spec}`); + + const snapshot = withTmpDirSnapshot(os.tmpdir(), (outdir) => { + exec(`cp ${specPath} ${outdir}/spec.yaml`, { + cwd: path.resolve(__dirname), + }); + const clientOutdir = path.join(outdir, "client"); + const client = new GeneratedTypescriptRuntimeProject({ + name: "test-client", + defaultReleaseBranch: "main", + outdir: clientOutdir, + specPath: "../spec.yaml", + }); + const handlersOutdir = path.join(outdir, "handlers"); + const project = new GeneratedTypescriptHandlersProject({ + name: "test-handlers", + defaultReleaseBranch: "main", + outdir: handlersOutdir, + specPath: "../spec.yaml", + generatedTypescriptTypes: client, + }); + project.synth(); + exec( + `${path.resolve( + __dirname, + "../../../scripts/generators/generate" + )} ${project.buildGenerateCommandArgs()}`, + { + cwd: handlersOutdir, + } + ); + }); + + expect(snapshot["handlers/src/typescript-one.ts"]).toMatchSnapshot(); + expect(snapshot["handlers/src/typescript-two.ts"]).toMatchSnapshot(); + + // Other language handlers should be skipped + expect( + Object.keys(snapshot).filter((p) => p.toLowerCase().includes("python")) + ).toHaveLength(0); + expect( + Object.keys(snapshot).filter((p) => p.toLowerCase().includes("java")) + ).toHaveLength(0); + + // Split file should be deleted + expect( + Object.keys(snapshot).filter((p) => + p.toLowerCase().includes("__all_handlers") + ) + ).toHaveLength(0); + }); +});