Repository: h3js/h3 (TypeScript)

Issue:
[nuxt] [request error] [unhandled] [500] The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Promise
### Environment

node: v16.17
nuxt: 3.4.2
nitro: 2.3.3

### Reproduction

Nuxt API requests using useAsyncData + $fetch in frontend and server api uses `await readBody`

### Describe the bug

frontend request
```js
const body = { params: { ...route.query } }

const { data, error } = await useAsyncData(
    'server-api',
    () => $fetch('/api/server-api', { method: 'post', body: body }),
    {
        initialCache: false
    }
).catch((e) => console.error(e))
```

server API composable
```js
export default defineEventHandler(async (event) => {

    const body = await readBody(event)
}
```

### Additional context

Same issue as described here https://github.com/unjs/h3/commit/19d133d by many others. 
This latest release `1.4.0` seems to break things.

There is a workaround but it doesn't feel like something we'd actually want to be doing all over projects.
https://github.com/unjs/h3/commit/19d133d#r109674536

### Logs

```sh
[nuxt] [request error] [unhandled] [500] The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Promise
```



Discussion: Would you be able to provide a reproduction? 🙏 
@danielroe this would be sort of a clone in terms of npm packages and env setup I have, but I cannot reproduce the issue on codesandbox. (note I have some `resolutions` on `package.json` to force some version to what I have locally)
https://codesandbox.io/p/sandbox/hellow-rkt3in

Locally and on the azure server we use I can definitely still reproduce the issue when I upgrade to 1.6.4. (Video below)

https://user-images.githubusercontent.com/39249777/235794974-f6d3ccd7-4b91-4e81-9d1b-08a4cb4c3fd9.mp4


Found it first introduced in https://github.com/unjs/h3/commit/19d133d6a33ffb742713f4d83f00f555aeb83224
I used [this](https://github.com/unjs/h3/commit/19d133d6a33ffb742713f4d83f00f555aeb83224#r109674536) workaround, in commit that @so1ve mentioned, to make work my api routes. But, api routes created by libs like `nuxt-vuefire` for example, that has not the workaround implemented, throw the error.

PS: Error only shows up in production. I use Firebase to deploy.
It suddenly worked in nuxt 3.5.1, and the workaround seemed to be buggy :( 
@so1ve so is the issue resolved now?
> @so1ve so is the issue resolved now?

I'm not sure. In my use case (nuxt) the issue is resolved, but h3 users may not.
Hi @danielroe ,

I just run `npx nuxi@latest upgrade --force` and the Nuxt is in 3.5.2. 

> I got error about [this](https://github.com/nuxt/nuxt/issues/13866) issue that block my build. So, I removed `yarn.lock` and reinstall. And this time the build works.

Locally, the requests works fine. But in Firebase, where I deployed my application, shows:

```
The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object
```

The workaround still works:

```ts
// @ts-expect-error - req.body is not defined in the type definitions
const body = await (event.node.req.body || readBody(event));
```
@danielroe , just created this Nuxt project with `npx nuxi@latest init app`: https://github.com/igorjacauna/issue-readbody

After deploy to Firebase, should show error when try to make a POST request to `/api/issue` with a body in request

In Function logs shows:

```
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object
    at new NodeError (node:internal/errors:387:5)
    at Function.from (node:buffer:328:9)
    at file:///workspace/node_modules/h3/dist/index.mjs:288:70
    at async readBody (file:///workspace/node_modules/h3/dist/index.mjs:314:16)
    at async file:///workspace/chunks/issue.post.mjs:6:18 {
  code: 'ERR_INVALID_ARG_TYPE'
}
```
Thanks @igorjacauna for the repro!

It even works (or rather breaks) without deploying to Firebase. Change `API_ID` in `.firebaserc` to something lowercase (like `appid`) and just add `firebase-tools` as a dependency, and you can run and reproduce it in the emulator:

```bash
yarn add --dev firebase-tools
NITRO_PRESET=firebase yarn build
yarn firebase emulators:start --only functions,hosting

# From another terminal:
curl -X POST 'http://localhost:5000/api/issue' -H 'Content-Type: application/json' --data-raw '{"test":1}'
```



Fix (patch):
diff --git a/src/utils/body.ts b/src/utils/body.ts
index 52cd9150a..382d7b993 100644
--- a/src/utils/body.ts
+++ b/src/utils/body.ts
@@ -30,9 +30,15 @@ export function readRawBody<E extends Encoding = "utf8">(
     (event.node.req as any)[RawBodySymbol] ||
     (event.node.req as any).body; /* unjs/unenv #8 */
   if (_rawBody) {
-    const promise = Promise.resolve(_rawBody).then((_resolved) =>
-      Buffer.isBuffer(_resolved) ? _resolved : Buffer.from(_resolved)
-    );
+    const promise = Promise.resolve(_rawBody).then((_resolved) => {
+      if (Buffer.isBuffer(_resolved)) {
+        return _resolved;
+      }
+      if (_resolved.constructor === Object) {
+        return Buffer.from(JSON.stringify(_resolved));
+      }
+      return Buffer.from(_resolved);
+    });
     return encoding
       ? promise.then((buff) => buff.toString(encoding))
       : (promise as Promise<any>);