From c92239031086466f12d902614ef77413a8486e0e Mon Sep 17 00:00:00 2001 From: Jack Stevenson Date: Fri, 20 Oct 2023 10:03:06 +1100 Subject: [PATCH] fix(type-safe-api): fix typescript handler dist path for operations with inline request bodies (#607) When an operation has inline request body schemas (rather than a $ref) in OpenAPI, the operation ID is suffixed with "Operation" in the generated code, but the operation nickname remains unchanged. Previously, the operation ID was used for the handler dist reference in the generated functions, but the nickname was used to generate the actual filename. Address this by using the nickname in both places for typescript generated functions. Fixes #606 --- .../templates/functions.handlebars | 2 +- .../test/resources/specs/inline-body.yaml | 86 ++++ .../java-cdk-infrastructure.test.ts.snap | 420 +++++++++++++++++- .../python-cdk-infrastructure.test.ts.snap | 63 ++- ...typescript-cdk-infrastructure.test.ts.snap | 81 +++- .../java-cdk-infrastructure.test.ts | 93 ++-- .../python-cdk-infrastructure.test.ts | 71 +-- .../typescript-cdk-infrastructure.test.ts | 65 +-- 8 files changed, 767 insertions(+), 114 deletions(-) create mode 100644 packages/type-safe-api/test/resources/specs/inline-body.yaml diff --git a/packages/type-safe-api/scripts/type-safe-api/generators/typescript-cdk-infrastructure/templates/functions.handlebars b/packages/type-safe-api/scripts/type-safe-api/generators/typescript-cdk-infrastructure/templates/functions.handlebars index bb9bca4d0..ea5769aca 100644 --- a/packages/type-safe-api/scripts/type-safe-api/generators/typescript-cdk-infrastructure/templates/functions.handlebars +++ b/packages/type-safe-api/scripts/type-safe-api/generators/typescript-cdk-infrastructure/templates/functions.handlebars @@ -46,7 +46,7 @@ export class {{operationIdCamelCase}}Function extends {{#startsWith vendorExtens code: Code.fromAsset(path.resolve(__dirname, "..", {{#startsWith vendorExtensions.x-handler.language 'typescript' ~}} "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-typescript-asset-path}}{{/apis.0}}{{/apiInfo}}", - "###TSAPI_FN###{ "function": "kebabCase", "args": ["{{operationIdCamelCase}}"] }###/TSAPI_FN###", + "###TSAPI_FN###{ "function": "kebabCase", "args": ["{{nickname}}"] }###/TSAPI_FN###", {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'python' ~}} "{{#apiInfo}}{{#apis.0}}{{vendorExtensions.x-handlers-python-asset-path}}{{/apis.0}}{{/apiInfo}}", {{~/startsWith}}{{#startsWith vendorExtensions.x-handler.language 'java' ~}} diff --git a/packages/type-safe-api/test/resources/specs/inline-body.yaml b/packages/type-safe-api/test/resources/specs/inline-body.yaml new file mode 100644 index 000000000..0637c1ffd --- /dev/null +++ b/packages/type-safe-api/test/resources/specs/inline-body.yaml @@ -0,0 +1,86 @@ +openapi: 3.0.3 +info: + version: 1.0.0 + title: Test +paths: + /typescript: + post: + operationId: typescriptTest + x-handler: + language: typescript + requestBody: + required: true + content: + application/json: + # Schema is inline rather than a $ref + schema: + type: object + properties: + field1: + type: string + field2: + type: string + responses: + 200: + description: OK + content: + 'application/json': + schema: + $ref: '#/components/schemas/TestResponseContent' + /java: + post: + operationId: javaTest + x-handler: + language: java + requestBody: + required: true + content: + application/json: + # Schema is inline rather than a $ref + schema: + type: object + properties: + field1: + type: string + field2: + type: string + responses: + 200: + description: OK + content: + 'application/json': + schema: + $ref: '#/components/schemas/TestResponseContent' + /python: + post: + operationId: pythonTest + x-handler: + language: python + requestBody: + required: true + content: + application/json: + # Schema is inline rather than a $ref + schema: + type: object + properties: + field1: + type: string + field2: + type: string + responses: + 200: + description: OK + content: + 'application/json': + schema: + $ref: '#/components/schemas/TestResponseContent' +components: + schemas: + TestResponseContent: + type: object + properties: + message: + type: string + required: + - message diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/java-cdk-infrastructure.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/java-cdk-infrastructure.test.ts.snap index 1b9d46a7d..d3b517e19 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/java-cdk-infrastructure.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/java-cdk-infrastructure.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Java Infrastructure Code Generation Script Unit Tests Generates Functions 1`] = ` +exports[`Java Infrastructure Code Generation Script Unit Tests Generates Functions for handlers.yaml 1`] = ` [ [ "infra/src/main/java/test/test-infra/infra/functions/JavaOneFunction.java", @@ -832,6 +832,424 @@ public class TypescriptTwoFunctionProps implements FunctionProps { ] `; +exports[`Java Infrastructure Code Generation Script Unit Tests Generates Functions for inline-body.yaml 1`] = ` +[ + [ + "infra/src/main/java/test/test-infra/infra/functions/JavaTestFunction.java", + "package test.test-infra.infra.functions; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.services.lambda.Function; +import software.aws.pdk.type_safe_api.SnapStartFunction; +import software.constructs.Construct; + +/** + * Lambda function construct which points to the java implementation of JavaTest + */ +public class JavaTestFunction extends SnapStartFunction { + public JavaTestFunction(@NotNull Construct scope, @NotNull String id, @NotNull JavaTestFunctionProps props) { + super(scope, id, props); + } + + public JavaTestFunction(@NotNull Construct scope, @NotNull String id) { + this(scope, id, JavaTestFunctionProps.builder().build()); + } +} +", + ], + [ + "infra/src/main/java/test/test-infra/infra/functions/JavaTestFunctionProps.java", + "package test.test-infra.infra.functions; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.Duration; +import software.amazon.awscdk.Size; +import software.amazon.awscdk.services.codeguruprofiler.IProfilingGroup; +import software.amazon.awscdk.services.ec2.ISecurityGroup; +import software.amazon.awscdk.services.ec2.IVpc; +import software.amazon.awscdk.services.ec2.SubnetSelection; +import software.amazon.awscdk.services.iam.IRole; +import software.amazon.awscdk.services.iam.PolicyStatement; +import software.amazon.awscdk.services.kms.IKey; +import software.amazon.awscdk.services.lambda.AdotInstrumentationConfig; +import software.amazon.awscdk.services.lambda.Architecture; +import software.amazon.awscdk.services.lambda.Code; +import software.amazon.awscdk.services.lambda.FileSystem; +import software.amazon.awscdk.services.lambda.FunctionProps; +import software.amazon.awscdk.services.lambda.ICodeSigningConfig; +import software.amazon.awscdk.services.lambda.IDestination; +import software.amazon.awscdk.services.lambda.IEventSource; +import software.amazon.awscdk.services.lambda.ILayerVersion; +import software.amazon.awscdk.services.lambda.LambdaInsightsVersion; +import software.amazon.awscdk.services.lambda.LogRetentionRetryOptions; +import software.amazon.awscdk.services.lambda.ParamsAndSecretsLayerVersion; +import software.amazon.awscdk.services.lambda.Runtime; +import software.amazon.awscdk.services.lambda.RuntimeManagementMode; +import software.amazon.awscdk.services.lambda.Tracing; +import software.amazon.awscdk.services.lambda.VersionOptions; +import software.amazon.awscdk.services.logs.RetentionDays; +import software.amazon.awscdk.services.sns.ITopic; +import software.amazon.awscdk.services.sqs.IQueue; +import software.aws.pdk.type_safe_api.SnapStartFunctionProps; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +@lombok.Builder @lombok.Getter +public class JavaTestFunctionProps implements SnapStartFunctionProps { + private static String infraProjectAbsolutePath; + + static { + try { + try (InputStream stream = JavaTestFunctionProps.class.getClassLoader() + .getResourceAsStream("project-absolute-path.txt")) { + try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { + infraProjectAbsolutePath = new BufferedReader(inputStreamReader).lines().findFirst() + .orElseThrow(() -> new RuntimeException("No project-absolute-path.txt resource found")); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // Fixed props + private final Code code = Code.fromAsset(Paths.get(infraProjectAbsolutePath).resolve( + "../java-handlers/dist/java/test/com.aws.pdk.test.handlers/1.0.0/com.aws.pdk.test.handlers-1.0.0.jar" + ).toAbsolutePath().toString()); + private final String handler = "test.test-java-handlers.handlers.JavaTestHandler"; + private final Runtime runtime = Runtime.JAVA_17; + + // Props with defaults + @lombok.Builder.Default + Duration timeout = Duration.seconds(30); + @lombok.Builder.Default + Tracing tracing = Tracing.ACTIVE; + + // Remaining Function Props + AdotInstrumentationConfig adotInstrumentation; + Boolean allowAllOutbound; + Boolean allowPublicSubnet; + Architecture architecture; + ICodeSigningConfig codeSigningConfig; + VersionOptions currentVersionOptions; + IQueue deadLetterQueue; + Boolean deadLetterQueueEnabled; + ITopic deadLetterTopic; + String description; + Map environment; + IKey environmentEncryption; + Size ephemeralStorageSize; + List events; + FileSystem filesystem; + String functionName; + List initialPolicy; + LambdaInsightsVersion insightsVersion; + List layers; + RetentionDays logRetention; + LogRetentionRetryOptions logRetentionRetryOptions; + IRole logRetentionRole; + Number memorySize; + ParamsAndSecretsLayerVersion paramsAndSecrets; + Boolean profiling; + IProfilingGroup profilingGroup; + Number reservedConcurrentExecutions; + IRole role; + RuntimeManagementMode runtimeManagementMode; + List securityGroups; + IVpc vpc; + SubnetSelection vpcSubnets; + Duration maxEventAge; + IDestination onFailure; + IDestination onSuccess; + Number retryAttempts; +} + +", + ], + [ + "infra/src/main/java/test/test-infra/infra/functions/PythonTestFunction.java", + "package test.test-infra.infra.functions; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.services.lambda.Function; +import software.aws.pdk.type_safe_api.SnapStartFunction; +import software.constructs.Construct; + +/** + * Lambda function construct which points to the python implementation of PythonTest + */ +public class PythonTestFunction extends Function { + public PythonTestFunction(@NotNull Construct scope, @NotNull String id, @NotNull PythonTestFunctionProps props) { + super(scope, id, props); + } + + public PythonTestFunction(@NotNull Construct scope, @NotNull String id) { + this(scope, id, PythonTestFunctionProps.builder().build()); + } +} +", + ], + [ + "infra/src/main/java/test/test-infra/infra/functions/PythonTestFunctionProps.java", + "package test.test-infra.infra.functions; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.Duration; +import software.amazon.awscdk.Size; +import software.amazon.awscdk.services.codeguruprofiler.IProfilingGroup; +import software.amazon.awscdk.services.ec2.ISecurityGroup; +import software.amazon.awscdk.services.ec2.IVpc; +import software.amazon.awscdk.services.ec2.SubnetSelection; +import software.amazon.awscdk.services.iam.IRole; +import software.amazon.awscdk.services.iam.PolicyStatement; +import software.amazon.awscdk.services.kms.IKey; +import software.amazon.awscdk.services.lambda.AdotInstrumentationConfig; +import software.amazon.awscdk.services.lambda.Architecture; +import software.amazon.awscdk.services.lambda.Code; +import software.amazon.awscdk.services.lambda.FileSystem; +import software.amazon.awscdk.services.lambda.FunctionProps; +import software.amazon.awscdk.services.lambda.ICodeSigningConfig; +import software.amazon.awscdk.services.lambda.IDestination; +import software.amazon.awscdk.services.lambda.IEventSource; +import software.amazon.awscdk.services.lambda.ILayerVersion; +import software.amazon.awscdk.services.lambda.LambdaInsightsVersion; +import software.amazon.awscdk.services.lambda.LogRetentionRetryOptions; +import software.amazon.awscdk.services.lambda.ParamsAndSecretsLayerVersion; +import software.amazon.awscdk.services.lambda.Runtime; +import software.amazon.awscdk.services.lambda.RuntimeManagementMode; +import software.amazon.awscdk.services.lambda.Tracing; +import software.amazon.awscdk.services.lambda.VersionOptions; +import software.amazon.awscdk.services.logs.RetentionDays; +import software.amazon.awscdk.services.sns.ITopic; +import software.amazon.awscdk.services.sqs.IQueue; +import software.aws.pdk.type_safe_api.SnapStartFunctionProps; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +@lombok.Builder @lombok.Getter +public class PythonTestFunctionProps implements FunctionProps { + private static String infraProjectAbsolutePath; + + static { + try { + try (InputStream stream = PythonTestFunctionProps.class.getClassLoader() + .getResourceAsStream("project-absolute-path.txt")) { + try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { + infraProjectAbsolutePath = new BufferedReader(inputStreamReader).lines().findFirst() + .orElseThrow(() -> new RuntimeException("No project-absolute-path.txt resource found")); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // Fixed props + private final Code code = Code.fromAsset(Paths.get(infraProjectAbsolutePath).resolve( + "../python-handlers/dist/lambda" + ).toAbsolutePath().toString()); + private final String handler = "test_python_handlers.python_test.handler"; + private final Runtime runtime = Runtime.PYTHON_3_11; + + // Props with defaults + @lombok.Builder.Default + Duration timeout = Duration.seconds(30); + @lombok.Builder.Default + Tracing tracing = Tracing.ACTIVE; + + // Remaining Function Props + AdotInstrumentationConfig adotInstrumentation; + Boolean allowAllOutbound; + Boolean allowPublicSubnet; + Architecture architecture; + ICodeSigningConfig codeSigningConfig; + VersionOptions currentVersionOptions; + IQueue deadLetterQueue; + Boolean deadLetterQueueEnabled; + ITopic deadLetterTopic; + String description; + Map environment; + IKey environmentEncryption; + Size ephemeralStorageSize; + List events; + FileSystem filesystem; + String functionName; + List initialPolicy; + LambdaInsightsVersion insightsVersion; + List layers; + RetentionDays logRetention; + LogRetentionRetryOptions logRetentionRetryOptions; + IRole logRetentionRole; + Number memorySize; + ParamsAndSecretsLayerVersion paramsAndSecrets; + Boolean profiling; + IProfilingGroup profilingGroup; + Number reservedConcurrentExecutions; + IRole role; + RuntimeManagementMode runtimeManagementMode; + List securityGroups; + IVpc vpc; + SubnetSelection vpcSubnets; + Duration maxEventAge; + IDestination onFailure; + IDestination onSuccess; + Number retryAttempts; +} + +", + ], + [ + "infra/src/main/java/test/test-infra/infra/functions/TypescriptTestFunction.java", + "package test.test-infra.infra.functions; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.services.lambda.Function; +import software.aws.pdk.type_safe_api.SnapStartFunction; +import software.constructs.Construct; + +/** + * Lambda function construct which points to the typescript implementation of TypescriptTest + */ +public class TypescriptTestFunction extends Function { + public TypescriptTestFunction(@NotNull Construct scope, @NotNull String id, @NotNull TypescriptTestFunctionProps props) { + super(scope, id, props); + } + + public TypescriptTestFunction(@NotNull Construct scope, @NotNull String id) { + this(scope, id, TypescriptTestFunctionProps.builder().build()); + } +} +", + ], + [ + "infra/src/main/java/test/test-infra/infra/functions/TypescriptTestFunctionProps.java", + "package test.test-infra.infra.functions; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.Duration; +import software.amazon.awscdk.Size; +import software.amazon.awscdk.services.codeguruprofiler.IProfilingGroup; +import software.amazon.awscdk.services.ec2.ISecurityGroup; +import software.amazon.awscdk.services.ec2.IVpc; +import software.amazon.awscdk.services.ec2.SubnetSelection; +import software.amazon.awscdk.services.iam.IRole; +import software.amazon.awscdk.services.iam.PolicyStatement; +import software.amazon.awscdk.services.kms.IKey; +import software.amazon.awscdk.services.lambda.AdotInstrumentationConfig; +import software.amazon.awscdk.services.lambda.Architecture; +import software.amazon.awscdk.services.lambda.Code; +import software.amazon.awscdk.services.lambda.FileSystem; +import software.amazon.awscdk.services.lambda.FunctionProps; +import software.amazon.awscdk.services.lambda.ICodeSigningConfig; +import software.amazon.awscdk.services.lambda.IDestination; +import software.amazon.awscdk.services.lambda.IEventSource; +import software.amazon.awscdk.services.lambda.ILayerVersion; +import software.amazon.awscdk.services.lambda.LambdaInsightsVersion; +import software.amazon.awscdk.services.lambda.LogRetentionRetryOptions; +import software.amazon.awscdk.services.lambda.ParamsAndSecretsLayerVersion; +import software.amazon.awscdk.services.lambda.Runtime; +import software.amazon.awscdk.services.lambda.RuntimeManagementMode; +import software.amazon.awscdk.services.lambda.Tracing; +import software.amazon.awscdk.services.lambda.VersionOptions; +import software.amazon.awscdk.services.logs.RetentionDays; +import software.amazon.awscdk.services.sns.ITopic; +import software.amazon.awscdk.services.sqs.IQueue; +import software.aws.pdk.type_safe_api.SnapStartFunctionProps; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +@lombok.Builder @lombok.Getter +public class TypescriptTestFunctionProps implements FunctionProps { + private static String infraProjectAbsolutePath; + + static { + try { + try (InputStream stream = TypescriptTestFunctionProps.class.getClassLoader() + .getResourceAsStream("project-absolute-path.txt")) { + try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { + infraProjectAbsolutePath = new BufferedReader(inputStreamReader).lines().findFirst() + .orElseThrow(() -> new RuntimeException("No project-absolute-path.txt resource found")); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // Fixed props + private final Code code = Code.fromAsset(Paths.get(infraProjectAbsolutePath).resolve( + "../typescript-handlers/dist/lambda/typescript-test" + ).toAbsolutePath().toString()); + private final String handler = "index.handler"; + private final Runtime runtime = Runtime.NODEJS_18_X; + + // Props with defaults + @lombok.Builder.Default + Duration timeout = Duration.seconds(30); + @lombok.Builder.Default + Tracing tracing = Tracing.ACTIVE; + + // Remaining Function Props + AdotInstrumentationConfig adotInstrumentation; + Boolean allowAllOutbound; + Boolean allowPublicSubnet; + Architecture architecture; + ICodeSigningConfig codeSigningConfig; + VersionOptions currentVersionOptions; + IQueue deadLetterQueue; + Boolean deadLetterQueueEnabled; + ITopic deadLetterTopic; + String description; + Map environment; + IKey environmentEncryption; + Size ephemeralStorageSize; + List events; + FileSystem filesystem; + String functionName; + List initialPolicy; + LambdaInsightsVersion insightsVersion; + List layers; + RetentionDays logRetention; + LogRetentionRetryOptions logRetentionRetryOptions; + IRole logRetentionRole; + Number memorySize; + ParamsAndSecretsLayerVersion paramsAndSecrets; + Boolean profiling; + IProfilingGroup profilingGroup; + Number reservedConcurrentExecutions; + IRole role; + RuntimeManagementMode runtimeManagementMode; + List securityGroups; + IVpc vpc; + SubnetSelection vpcSubnets; + Duration maxEventAge; + IDestination onFailure; + IDestination onSuccess; + Number retryAttempts; +} +", + ], +] +`; + exports[`Java Infrastructure Code Generation Script Unit Tests Generates With Mocks Disabled 1`] = ` "package test.test-infra.infra; diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap index d034b31a9..71a3d1680 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/python-cdk-infrastructure.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Python Infrastructure Code Generation Script Unit Tests Generates Functions 1`] = ` +exports[`Python Infrastructure Code Generation Script Unit Tests Generates Functions for handlers.yaml 1`] = ` "from aws_cdk import Duration from aws_cdk.aws_lambda import ( Function, Runtime, Tracing, Code @@ -110,6 +110,67 @@ class TypescriptTwoFunction(Function): )" `; +exports[`Python Infrastructure Code Generation Script Unit Tests Generates Functions for inline-body.yaml 1`] = ` +"from aws_cdk import Duration +from aws_cdk.aws_lambda import ( + Function, Runtime, Tracing, Code +) +from aws_pdk.type_safe_api import SnapStartFunction +from os import path +from pathlib import Path + + + +class JavaTestFunction(SnapStartFunction): + """ + Lambda function construct which points to the java implementation of JavaTest + """ + def __init__(self, scope, id, **kwargs): + super().__init__(scope, id, + runtime=Runtime.JAVA_17, + handler="test.test-java-handlers.handlers.JavaTestHandler", + code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", + "../java-handlers/dist/java/test/com.aws.pdk.test.handlers/1.0.0/com.aws.pdk.test.handlers-1.0.0.jar", + )), + tracing=Tracing.ACTIVE, + timeout=Duration.seconds(30), + **kwargs, + ) + +class PythonTestFunction(Function): + """ + Lambda function construct which points to the python implementation of PythonTest + """ + def __init__(self, scope, id, **kwargs): + super().__init__(scope, id, + runtime=Runtime.PYTHON_3_11, + handler="test_python_handlers.python_test.handler", + code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", + "../python-handlers/dist/lambda", + )), + tracing=Tracing.ACTIVE, + timeout=Duration.seconds(30), + **kwargs, + ) + +class TypescriptTestFunction(Function): + """ + Lambda function construct which points to the typescript implementation of TypescriptTest + """ + def __init__(self, scope, id, **kwargs): + super().__init__(scope, id, + runtime=Runtime.NODEJS_18_X, + handler="index.handler", + code=Code.from_asset(path.join(str(Path(__file__).absolute().parent), "..", + "../typescript-handlers/dist/lambda", + "typescript-test", + )), + tracing=Tracing.ACTIVE, + timeout=Duration.seconds(30), + **kwargs, + )" +`; + exports[`Python Infrastructure Code Generation Script Unit Tests Generates With Mocks Disabled 1`] = ` "import json from aws_pdk.type_safe_api import Integrations, MockIntegration, TypeSafeApiIntegration diff --git a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-cdk-infrastructure.test.ts.snap b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-cdk-infrastructure.test.ts.snap index d3ed2cad5..309ee743b 100644 --- a/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-cdk-infrastructure.test.ts.snap +++ b/packages/type-safe-api/test/scripts/generators/__snapshots__/typescript-cdk-infrastructure.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Typescript Infrastructure Code Generation Script Unit Tests Generates Functions 1`] = ` +exports[`Typescript Infrastructure Code Generation Script Unit Tests Generates Functions for handlers.yaml 1`] = ` "import { Construct } from "constructs"; import { Duration } from "aws-cdk-lib"; import { SnapStartFunction, SnapStartFunctionProps } from "@aws/pdk/type-safe-api"; @@ -149,6 +149,85 @@ export class TypescriptTwoFunction extends Function { }" `; +exports[`Typescript Infrastructure Code Generation Script Unit Tests Generates Functions for inline-body.yaml 1`] = ` +"import { Construct } from "constructs"; +import { Duration } from "aws-cdk-lib"; +import { SnapStartFunction, SnapStartFunctionProps } from "@aws/pdk/type-safe-api"; +import { Code, Function, Runtime, Tracing, FunctionProps } from "aws-cdk-lib/aws-lambda"; +import * as path from "path"; + + +/** + * Options for the JavaTestFunction construct + */ +export interface JavaTestFunctionProps extends Omit {} + +/** + * Lambda function construct which points to the java implementation of JavaTest + */ +export class JavaTestFunction extends SnapStartFunction { + constructor(scope: Construct, id: string, props?: JavaTestFunctionProps) { + super(scope, id, { + runtime: Runtime.JAVA_17, + handler: "test.test-java-handlers.handlers.JavaTestHandler", + code: Code.fromAsset(path.resolve(__dirname, "..", + "../java-handlers/dist/java/test/com.aws.pdk.test.handlers/1.0.0/com.aws.pdk.test.handlers-1.0.0.jar", + )), + tracing: Tracing.ACTIVE, + timeout: Duration.seconds(30), + ...props, + }); + } +} + +/** + * Options for the PythonTestFunction construct + */ +export interface PythonTestFunctionProps extends Omit {} + +/** + * Lambda function construct which points to the python implementation of PythonTest + */ +export class PythonTestFunction extends Function { + constructor(scope: Construct, id: string, props?: PythonTestFunctionProps) { + super(scope, id, { + runtime: Runtime.PYTHON_3_11, + handler: "test_python_handlers.python_test.handler", + code: Code.fromAsset(path.resolve(__dirname, "..", + "../python-handlers/dist/lambda", + )), + tracing: Tracing.ACTIVE, + timeout: Duration.seconds(30), + ...props, + }); + } +} + +/** + * Options for the TypescriptTestOperationFunction construct + */ +export interface TypescriptTestOperationFunctionProps extends Omit {} + +/** + * Lambda function construct which points to the typescript implementation of TypescriptTestOperation + */ +export class TypescriptTestOperationFunction extends Function { + constructor(scope: Construct, id: string, props?: TypescriptTestOperationFunctionProps) { + super(scope, id, { + runtime: Runtime.NODEJS_18_X, + handler: "index.handler", + code: Code.fromAsset(path.resolve(__dirname, "..", + "../typescript-handlers/dist/lambda", + "typescript-test", + )), + tracing: Tracing.ACTIVE, + timeout: Duration.seconds(30), + ...props, + }); + } +}" +`; + exports[`Typescript Infrastructure Code Generation Script Unit Tests Generates With Mocks Disabled 1`] = ` "import { ApiError, diff --git a/packages/type-safe-api/test/scripts/generators/java-cdk-infrastructure.test.ts b/packages/type-safe-api/test/scripts/generators/java-cdk-infrastructure.test.ts index fe11fe8d1..f423fccde 100644 --- a/packages/type-safe-api/test/scripts/generators/java-cdk-infrastructure.test.ts +++ b/packages/type-safe-api/test/scripts/generators/java-cdk-infrastructure.test.ts @@ -130,53 +130,56 @@ describe("Java Infrastructure Code Generation Script Unit Tests", () => { ).toMatchSnapshot(); }); - it("Generates Functions", () => { - const specPath = path.resolve( - __dirname, - `../../resources/specs/handlers.yaml` - ); + it.each(["handlers.yaml", "inline-body.yaml"])( + "Generates Functions for %s", + (specFile) => { + const specPath = path.resolve( + __dirname, + `../../resources/specs/${specFile}` + ); - const snapshot = withTmpDirSnapshot( - os.tmpdir(), - (outdir) => { - exec(`cp ${specPath} ${outdir}/spec.yaml`, { - cwd: path.resolve(__dirname), - }); + const snapshot = withTmpDirSnapshot( + os.tmpdir(), + (outdir) => { + exec(`cp ${specPath} ${outdir}/spec.yaml`, { + cwd: path.resolve(__dirname), + }); - const { runtimes, handlers } = getTestHandlerProjects(outdir); + const { runtimes, handlers } = getTestHandlerProjects(outdir); - const infraOutdir = path.join(outdir, "infra"); - const project = new GeneratedJavaCdkInfrastructureProject({ - name: "test-infra", - artifactId: "com.aws.pdk.test.infra", - groupId: "test", - version: "1.0.0", - outdir: infraOutdir, - specPath: "../spec.yaml", - generatedJavaTypes: runtimes.java, - generatedHandlers: handlers, - }); - project.synth(); - exec( - `${path.resolve( - __dirname, - "../../../scripts/type-safe-api/generators/generate" - )} ${project.buildGenerateCommandArgs()}`, - { - cwd: infraOutdir, - } - ); - }, - { - excludeGlobs: GeneratedJavaRuntimeProject.openApiIgnorePatterns, - parseJson: false, - } - ); + const infraOutdir = path.join(outdir, "infra"); + const project = new GeneratedJavaCdkInfrastructureProject({ + name: "test-infra", + artifactId: "com.aws.pdk.test.infra", + groupId: "test", + version: "1.0.0", + outdir: infraOutdir, + specPath: "../spec.yaml", + generatedJavaTypes: runtimes.java, + generatedHandlers: handlers, + }); + project.synth(); + exec( + `${path.resolve( + __dirname, + "../../../scripts/type-safe-api/generators/generate" + )} ${project.buildGenerateCommandArgs()}`, + { + cwd: infraOutdir, + } + ); + }, + { + excludeGlobs: GeneratedJavaRuntimeProject.openApiIgnorePatterns, + parseJson: false, + } + ); - expect( - Object.entries(snapshot).filter(([file]: [string, any]) => - file.startsWith("infra/src/main/java/test/test-infra/infra/functions") - ) - ).toMatchSnapshot(); - }); + expect( + Object.entries(snapshot).filter(([file]: [string, any]) => + file.startsWith("infra/src/main/java/test/test-infra/infra/functions") + ) + ).toMatchSnapshot(); + } + ); }); diff --git a/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts b/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts index e28d3ec73..77528b429 100644 --- a/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts +++ b/packages/type-safe-api/test/scripts/generators/python-cdk-infrastructure.test.ts @@ -105,42 +105,45 @@ describe("Python Infrastructure Code Generation Script Unit Tests", () => { expect(snapshot["infra/test_infra/mock_integrations.py"]).toMatchSnapshot(); }); - it("Generates Functions", () => { - const specPath = path.resolve( - __dirname, - `../../resources/specs/handlers.yaml` - ); + it.each(["handlers.yaml", "inline-body.yaml"])( + "Generates Functions for %s", + (specFile) => { + const specPath = path.resolve( + __dirname, + `../../resources/specs/${specFile}` + ); - const snapshot = withTmpDirSnapshot(os.tmpdir(), (outdir) => { - exec(`cp ${specPath} ${outdir}/spec.yaml`, { - cwd: path.resolve(__dirname), - }); - const { runtimes, handlers } = getTestHandlerProjects(outdir); + const snapshot = withTmpDirSnapshot(os.tmpdir(), (outdir) => { + exec(`cp ${specPath} ${outdir}/spec.yaml`, { + cwd: path.resolve(__dirname), + }); + const { runtimes, handlers } = getTestHandlerProjects(outdir); - const infraOutdir = path.join(outdir, "infra"); - const project = new GeneratedPythonCdkInfrastructureProject({ - name: "test-infra", - moduleName: "test_infra", - authorEmail: "me@example.com", - authorName: "test", - version: "1.0.0", - outdir: infraOutdir, - specPath: "../spec.yaml", - generatedPythonTypes: runtimes.python, - generatedHandlers: handlers, + const infraOutdir = path.join(outdir, "infra"); + const project = new GeneratedPythonCdkInfrastructureProject({ + name: "test-infra", + moduleName: "test_infra", + authorEmail: "me@example.com", + authorName: "test", + version: "1.0.0", + outdir: infraOutdir, + specPath: "../spec.yaml", + generatedPythonTypes: runtimes.python, + generatedHandlers: handlers, + }); + project.synth(); + exec( + `${path.resolve( + __dirname, + "../../../scripts/type-safe-api/generators/generate" + )} ${project.buildGenerateCommandArgs()}`, + { + cwd: infraOutdir, + } + ); }); - project.synth(); - exec( - `${path.resolve( - __dirname, - "../../../scripts/type-safe-api/generators/generate" - )} ${project.buildGenerateCommandArgs()}`, - { - cwd: infraOutdir, - } - ); - }); - expect(snapshot["infra/test_infra/functions.py"]).toMatchSnapshot(); - }); + expect(snapshot["infra/test_infra/functions.py"]).toMatchSnapshot(); + } + ); }); diff --git a/packages/type-safe-api/test/scripts/generators/typescript-cdk-infrastructure.test.ts b/packages/type-safe-api/test/scripts/generators/typescript-cdk-infrastructure.test.ts index e3ceb19c5..46db2181e 100644 --- a/packages/type-safe-api/test/scripts/generators/typescript-cdk-infrastructure.test.ts +++ b/packages/type-safe-api/test/scripts/generators/typescript-cdk-infrastructure.test.ts @@ -96,38 +96,41 @@ describe("Typescript Infrastructure Code Generation Script Unit Tests", () => { expect(snapshot["infra/src/mock-integrations.ts"]).toMatchSnapshot(); }); - it("Generates Functions", () => { - const specPath = path.resolve( - __dirname, - `../../resources/specs/handlers.yaml` - ); + it.each(["handlers.yaml", "inline-body.yaml"])( + "Generates Functions for %s", + (specFile) => { + const specPath = path.resolve( + __dirname, + `../../resources/specs/${specFile}` + ); - const snapshot = withTmpDirSnapshot(os.tmpdir(), (outdir) => { - exec(`cp ${specPath} ${outdir}/spec.yaml`, { - cwd: path.resolve(__dirname), + const snapshot = withTmpDirSnapshot(os.tmpdir(), (outdir) => { + exec(`cp ${specPath} ${outdir}/spec.yaml`, { + cwd: path.resolve(__dirname), + }); + const { runtimes, handlers } = getTestHandlerProjects(outdir); + const infraOutdir = path.join(outdir, "infra"); + const project = new GeneratedTypescriptCdkInfrastructureProject({ + name: "test-infra", + defaultReleaseBranch: "main", + outdir: infraOutdir, + specPath: "../spec.yaml", + generatedTypescriptTypes: runtimes.typescript, + generatedHandlers: handlers, + }); + project.synth(); + exec( + `${path.resolve( + __dirname, + "../../../scripts/type-safe-api/generators/generate" + )} ${project.buildGenerateCommandArgs()}`, + { + cwd: infraOutdir, + } + ); }); - const { runtimes, handlers } = getTestHandlerProjects(outdir); - const infraOutdir = path.join(outdir, "infra"); - const project = new GeneratedTypescriptCdkInfrastructureProject({ - name: "test-infra", - defaultReleaseBranch: "main", - outdir: infraOutdir, - specPath: "../spec.yaml", - generatedTypescriptTypes: runtimes.typescript, - generatedHandlers: handlers, - }); - project.synth(); - exec( - `${path.resolve( - __dirname, - "../../../scripts/type-safe-api/generators/generate" - )} ${project.buildGenerateCommandArgs()}`, - { - cwd: infraOutdir, - } - ); - }); - expect(snapshot["infra/src/functions.ts"]).toMatchSnapshot(); - }); + expect(snapshot["infra/src/functions.ts"]).toMatchSnapshot(); + } + ); });