diff --git a/src/api.ts b/src/api.ts index a4f94c24..9ac076c4 100644 --- a/src/api.ts +++ b/src/api.ts @@ -653,6 +653,37 @@ export class APIGatewayVTL extends VTL { return super.eval(node as any, returnVar); } + /** + * Attempt to return the expression as a valid escaped json string. + * + * ```ts + * { + * x: input + * } + * ``` + * + * => + * + * ```ts + * { "x": $input.json('$') } + * ``` + * + * => + * + * ```ts + * "{ \"x\": $util.escapeJavaScript($input.json('$')) }" + * ``` + */ + public stringify(expr: Expr): string { + const json = this.exprToJson(expr); + return `"${json + .replace(/"/g, '\\"') + .replace( + /\$input\.json\('([^']*)'\)/g, + "$util.escapeJavaScript($input.json('$1'))" + )}"`; + } + /** * Renders a VTL string that will emit a JSON String representation of the {@link expr} to the VTL output. * diff --git a/src/step-function.ts b/src/step-function.ts index 34c94887..b7dbe63b 100644 --- a/src/step-function.ts +++ b/src/step-function.ts @@ -571,9 +571,7 @@ abstract class BaseStepFunction< .map(([argName, argVal]) => { if (argName === "input") { // stringify the JSON input - return `"${argName}":"$util.escapeJavaScript(${context.exprToJson( - argVal - )})"`; + return `"${argName}":${context.stringify(argVal)}`; } else { return `"${argName}":${context.exprToJson(argVal)}`; } diff --git a/test/__snapshots__/api.test.ts.snap b/test/__snapshots__/api.test.ts.snap index 0436c3aa..2f0a30b0 100644 --- a/test/__snapshots__/api.test.ts.snap +++ b/test/__snapshots__/api.test.ts.snap @@ -46,7 +46,7 @@ $input.json('$.error') "requestTemplates": Object { "application/json": "{ \\"stateMachineArn\\":\\"__REPLACED_TOKEN\\", -\\"input\\":\\"$util.escapeJavaScript({\\"num\\":$input.params('num'),\\"str\\":\\"$input.params('str')\\"})\\" +\\"input\\":\\"{\\\\\\"num\\\\\\":$input.params('num'),\\\\\\"str\\\\\\":\\\\\\"$input.params('str')\\\\\\"}\\" }", }, } @@ -81,7 +81,26 @@ Object { "requestTemplates": Object { "application/json": "{ \\"stateMachineArn\\":\\"__REPLACED_TOKEN\\", -\\"input\\":\\"$util.escapeJavaScript({\\"num\\":$input.params('num'),\\"str\\":\\"$input.params('str')\\"})\\" +\\"input\\":\\"{\\\\\\"num\\\\\\":$input.params('num'),\\\\\\"str\\\\\\":\\\\\\"$input.params('str')\\\\\\"}\\" +}", + }, +} +`; + +exports[`AWS integration with Standard Step Function using input data 1`] = ` +Object { + "integrationResponses": Array [ + Object { + "responseTemplates": Object { + "application/json": "$input.json('$.executionArn')", + }, + "statusCode": "200", + }, + ], + "requestTemplates": Object { + "application/json": "{ +\\"stateMachineArn\\":\\"__REPLACED_TOKEN\\", +\\"input\\":\\"{\\\\\\"num\\\\\\":$input.params('num'),\\\\\\"obj\\\\\\":$util.escapeJavaScript($input.json('$'))}\\" }", }, } diff --git a/test/api.test.ts b/test/api.test.ts index 72f0add8..7f45931a 100644 --- a/test/api.test.ts +++ b/test/api.test.ts @@ -167,6 +167,52 @@ test("AWS integration with Standard Step Function", () => { expect(getTemplates(method)).toMatchSnapshot(); }); +test("AWS integration with Standard Step Function using input data", () => { + const api = new aws_apigateway.RestApi(stack, "API"); + + const sfn = new StepFunction( + stack, + "SFN", + (_input: { + num: number; + obj: { + value: string; + }; + }) => { + return "done"; + } + ); + + const method = new AwsMethod( + { + httpMethod: "GET", + resource: api.root, + }, + ( + $input: ApiGatewayInput<{ + query: { + num: string; + str: string; + }; + body: { + value: string; + }; + }> + ) => + sfn({ + input: { + num: Number($input.params("num")), + obj: $input.data, + }, + }), + ($input) => { + return $input.data.executionArn; + } + ); + + expect(getTemplates(method)).toMatchSnapshot(); +}); + test("AWS integration with DynamoDB Table", () => { const api = new aws_apigateway.RestApi(stack, "API"); const table = Table.fromTable(