Repository: winglang/wing (TypeScript)

Issue:
Api simulator does not support urlencoded body
### I tried this

```ts
bring cloud;
let api = new cloud.Api();
let EMPTY_JSON = Json { empty: "https://github.com/winglang/wing/issues/1947" };

api.post("/", inflight (request : cloud.ApiRequest): cloud.ApiResponse => {
    let body = request.body ?? EMPTY_JSON;

    let resp = cloud.ApiResponse{
        status: 200,
        body: body,
    };
    return resp;
});
```

### I expected this:

When calling this api post endpoint the response body is a json object of the input. 


### Instead, this happened

When posting an api call to the post endpoint with an `x-urlencoded-form` body the response is an empty body `{}`

### Is there a workaround?

no

### Component

SDK

### Wing Version

0.10.1

### Wing Console Version

_No response_

### Node.js Version

v18.13.0

### Platform(s)

MacOS

### Anything else?

Can be fixed by add the urlencoded middleware to the express server 
`this.app.use(express.urlencoded({ extended: true }));`


### Community Notes

<!-- Please keep this note for the community -->
* Please vote by adding a 👍 reaction to the issue to help us prioritize.
* If you are interested to work on this issue, please leave a comment.



Discussion: Congrats! :rocket: This was released in [Wing 0.11.1](https://github.com/winglang/wing/releases/tag/v0.11.1).



Fix (patch):
diff --git a/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts b/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts
index c7ef1f7f905..a470bde5388 100644
--- a/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts
+++ b/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts
@@ -50,12 +50,30 @@ function mapApigatewayEventToCloudApiRequest(
     ...request.queryStringParameters,
     ...request.multiValueQueryStringParameters,
   };
+
   return {
     path: request.path,
-    body: request.body ? JSON.parse(request.body) : "",
+    body: parseBody(request),
     headers: request.headers as Record<string, string>,
     method: parseHttpMethod(request.httpMethod),
     query: sanitizeParamLikeObject(query),
     vars: sanitizeParamLikeObject(request.pathParameters ?? {}),
   };
 }
+
+/**
+ * Parse body to JSON or empty string
+ * @param body body
+ * @returns JSON body
+ */
+function parseBody(request: APIGatewayProxyEvent) {
+  if (!request.body) return "";
+
+  const contentType = Object.entries(request.headers).find(
+    ([key, _]) => key.toLowerCase() === "content-type"
+  )?.[1];
+  if (contentType === "application/x-www-form-urlencoded") {
+    return Object.fromEntries(new URLSearchParams(request.body));
+  }
+  return JSON.parse(request.body);
+}
diff --git a/libs/wingsdk/src/target-sim/api.inflight.ts b/libs/wingsdk/src/target-sim/api.inflight.ts
index e315a1a0e8c..77a424ec150 100644
--- a/libs/wingsdk/src/target-sim/api.inflight.ts
+++ b/libs/wingsdk/src/target-sim/api.inflight.ts
@@ -39,6 +39,7 @@ export class Api implements IApiClient, ISimulatorResourceInstance {
 
     // Parse request bodies as json.
     this.app.use(express.json());
+    this.app.use(express.urlencoded({ extended: true }));
 
     for (const route of this.routes) {
       const method = route.method.toLowerCase() as