aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 79 forks source link

amplify-appsync-simulator: "TypeError: this.map.entries is not a function" if the input JSON has a property called "map" at the top level #1676

Open sc0ttdav3y opened 1 year ago

sc0ttdav3y commented 1 year ago

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v20.3.1

Amplify CLI Version

1.0.0

What operating system are you using?

MacOS

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

N/A

Describe the bug

I'm using the ampify-appsync-simulator with a working back-end and established set of VTL templates. All works great in production, but in VTL I get the following error: TypeError: this.map.entries is not a function.

In VTL:

#set($resultObj = $util.parseJson($ctx.result.body))
$util.toJson($resultObj)

In my appsync output I get an empty response, even though I get valid JSON into the VTL template via $ctl.result.body.

I've debugged this in the library code and found the following:

  1. I can see that parseJson() parses the JSON string into a JavaMap.
  2. When toJson() is called, it ultimately runs a JSON.stringify() on the JavaMap object, but it fails with the unhandled error below.
  3. The root cause is that the input JSON has a property called map. If I rename that property then the template works.

Just speculation, but I suspect the map property is clobbering the internal this.map property set up in JavaMap, leading to a crash when it calls this.map.entities(). Crash log is below.

Expected behavior

I expect the VTL template to not crash for schemas that have map as a top-level property.

Reproduction steps

Here's the idea of a failing schema:

type Query {
    config: {
        version: String!
        map: MapConfig!
    }
}

type MapConfig {
    baseLayers: MapConfigBaseLayers!
}

... etc...

And the JSON the data source returns looks like this:

{
    "version": "1",
    "map": {
        ...
    }
}

If I remove the map line from the schema, then it works fine. If I add it and have the JSON from the data source return the property, then the crash occurs.

Project Identifier

No response

Log output

Relevant log showing the stack trace below.

``` # Put your logs below this line TypeError: this.map.entries is not a function at JavaMap.toJSON (/path/to/project/node_modules/amplify-appsync-simulator/lib/velocity/value-mapper/map.js:97:36) at JSON.stringify () at Object.toJson (/path/to/project/node_modules/amplify-appsync-simulator/lib/velocity/util/general-utils.js:46:56) at Velocity.getPropMethod (/path/to/project/node_modules/amplify-velocity-template/src/compile/references.js:313:23) at Velocity.getAttributes (/path/to/project/node_modules/amplify-velocity-template/src/compile/references.js:195:20) at Velocity. (/path/to/project/node_modules/amplify-velocity-template/src/compile/references.js:133:24) at Array.some () at utils. [as some] (/path/to/project/node_modules/amplify-velocity-template/src/utils.js:9:25) at Velocity.getReferences (/path/to/project/node_modules/amplify-velocity-template/src/compile/references.js:125:15) at Velocity. (/path/to/project/node_modules/amplify-velocity-template/src/compile/compile.js:76:39) at Array.forEach () at utils. [as forEach] (/path/to/project/node_modules/amplify-velocity-template/src/utils.js:9:25) at Velocity._render (/path/to/project/node_modules/amplify-velocity-template/src/compile/compile.js:66:13) at Velocity.render (/path/to/project/node_modules/amplify-velocity-template/src/compile/compile.js:36:22) at VelocityTemplate.render (/path/to/project/node_modules/amplify-appsync-simulator/lib/velocity/index.js:72:44) at AppSyncUnitResolver. (/path/to/project/node_modules/amplify-appsync-simulator/lib/resolvers/unit-resolver.js:115:54) at step (/path/to/project/node_modules/amplify-appsync-simulator/lib/resolvers/unit-resolver.js:48:23) at Object.next (/path/to/project/node_modules/amplify-appsync-simulator/lib/resolvers/unit-resolver.js:29:53) at fulfilled (/path/to/project/node_modules/amplify-appsync-simulator/lib/resolvers/unit-resolver.js:20:58) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) ```

Additional information

No response

Before submitting, please confirm:

josefaidt commented 1 year ago

Hey @sc0ttdav3y :wave: thanks for raising this! I'm going to transfer this over to our API repo for tracking purposes and better support!

sc0ttdav3y commented 1 year ago

Hi @josefaidt, I have contributed a PR to address this bug.

https://github.com/aws-amplify/amplify-cli/pull/13369