From 99d656f804edd7285e0d1c6ad9000bd6d9981e5a Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 8 Feb 2026 00:16:45 +0100 Subject: [PATCH 1/3] fix(client-nuxt): unwrap ComputedRef body before initial serialization When using `composable: 'useFetch'` with a `ComputedRef` as `body`, the client crashes with "Converting circular structure to JSON" because `serializeBody(opts)` receives the raw `ComputedRef` object. Vue's `ComputedRefImpl` has circular internal structure (`dep` <-> `computed`), causing `JSON.stringify` to throw. The reactive `watch` handler already handles this correctly because `reactive()` auto-unwraps refs, but the initial serialization on setup passes the raw ref. Fix: call `toValue(opts.body)` before the initial `serializeBody` call. Closes hey-api/openapi-ts#3360 --- .../base-url-false/client/client.gen.ts | 4 +- .../base-url-number/client/client.gen.ts | 4 +- .../base-url-strict/client/client.gen.ts | 4 +- .../base-url-string/client/client.gen.ts | 4 +- .../clean-false/client/client.gen.ts | 4 +- .../client-nuxt/default/client/client.gen.ts | 4 +- .../client/client.gen.ts | 4 +- .../sdk-client-optional/client/client.gen.ts | 4 +- .../sdk-client-required/client/client.gen.ts | 4 +- .../tsconfig-node16-sdk/client/client.gen.ts | 4 +- .../client/client.gen.ts | 4 +- .../3.1.x/sse-nuxt/client/client.gen.ts | 4 +- .../client-nuxt/__tests__/client.test.ts | 54 +++++++++++++++++++ .../@hey-api/client-nuxt/bundle/client.ts | 4 +- 14 files changed, 80 insertions(+), 26 deletions(-) diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-false/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-false/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-false/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-false/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-number/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-number/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-number/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-number/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-strict/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-strict/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-strict/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-strict/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-string/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-string/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-string/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/base-url-string/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/clean-false/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/clean-false/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/clean-false/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/clean-false/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/default/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/default/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/default/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/default/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/import-file-extension-ts/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/import-file-extension-ts/client/client.gen.ts index 871870f0c..3d53b77be 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/import-file-extension-ts/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/import-file-extension-ts/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen.ts'; import type { HttpMethod } from '../core/types.gen.ts'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-optional/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-optional/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-optional/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-optional/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-required/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-required/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-required/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/sdk-client-required/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-node16-sdk/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-node16-sdk/client/client.gen.ts index 92ec2459b..238190e82 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-node16-sdk/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-node16-sdk/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen.js'; import type { HttpMethod } from '../core/types.gen.js'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-nodenext-sdk/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-nodenext-sdk/client/client.gen.ts index 92ec2459b..238190e82 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-nodenext-sdk/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/tsconfig-nodenext-sdk/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen.js'; import type { HttpMethod } from '../core/types.gen.js'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-nuxt/client/client.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-nuxt/client/client.gen.ts index 3da9d23e9..e960f9bf5 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-nuxt/client/client.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/sse-nuxt/client/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../core/serverSentEvents.gen'; import type { HttpMethod } from '../core/types.gen'; @@ -138,7 +138,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); diff --git a/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts b/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts index 03e0aaba2..07ee8e6da 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts @@ -1,3 +1,7 @@ +// Mock $fetch global (Nuxt auto-import) +const $fetchMock = vi.fn(); +vi.stubGlobal('$fetch', $fetchMock); + // Mock Nuxt composables with realistic return values vi.mock('nuxt/app', () => ({ useAsyncData: vi.fn(() => ({ @@ -26,8 +30,58 @@ vi.mock('nuxt/app', () => ({ })), })); +import { useFetch } from 'nuxt/app'; +import { computed, ref } from 'vue'; + import { createClient } from '../bundle/client'; +describe('useFetch with computed body', () => { + it('does not throw when body is a ComputedRef', () => { + const client = createClient(); + const page = ref(1); + const body = computed(() => ({ page: page.value, pageSize: 10 })); + + expect(() => { + client.post({ + body, + composable: 'useFetch', + url: '/test', + }); + }).not.toThrow(); + }); + + it('serializes ComputedRef body correctly on initial call', () => { + const client = createClient(); + const body = computed(() => ({ page: 1, search: 'hello' })); + + client.post({ + body, + composable: 'useFetch', + url: '/test', + }); + + // useFetch should be called with the serialized body as a ref + expect(useFetch).toHaveBeenCalled(); + const callArgs = vi.mocked(useFetch).mock.calls.at(-1)!; + const opts = callArgs[1] as Record; + // body should be a ref containing the JSON-serialized value + expect((opts.body as { value: unknown }).value).toBe('{"search":"hello","page":1}'); + }); + + it('does not throw when body is a plain Ref', () => { + const client = createClient(); + const body = ref({ page: 1, pageSize: 10 }); + + expect(() => { + client.post({ + body, + composable: 'useFetch', + url: '/test', + }); + }).not.toThrow(); + }); +}); + describe('buildUrl', () => { const client = createClient(); diff --git a/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/bundle/client.ts b/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/bundle/client.ts index a746f2d3a..1d5990790 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/bundle/client.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/bundle/client.ts @@ -1,5 +1,5 @@ import { useAsyncData, useFetch, useLazyAsyncData, useLazyFetch } from 'nuxt/app'; -import { reactive, ref, watch } from 'vue'; +import { reactive, ref, toValue, watch } from 'vue'; import { createSseClient } from '../../client-core/bundle/serverSentEvents'; import type { HttpMethod } from '../../client-core/bundle/types'; @@ -136,7 +136,7 @@ export const createClient = (config: Config = {}): Client => { body: opts.body, bodySerializer: opts.bodySerializer, }); - const body = ref(serializeBody(opts)); + const body = ref(serializeBody({ ...opts, body: toValue(opts.body) })); opts.body = body; watch(bodyParams, (changed) => { body.value = serializeBody(changed); -- 2.51.2 From 8ac05f827c8c6b84361fb90602ae3a55ecbd90c9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 8 Feb 2026 00:23:12 +0100 Subject: [PATCH 2/3] fix(client-nuxt): correct JSON key order in test expectation --- .../src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts b/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts index 07ee8e6da..69a9f71ad 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/__tests__/client.test.ts @@ -65,7 +65,7 @@ describe('useFetch with computed body', () => { const callArgs = vi.mocked(useFetch).mock.calls.at(-1)!; const opts = callArgs[1] as Record; // body should be a ref containing the JSON-serialized value - expect((opts.body as { value: unknown }).value).toBe('{"search":"hello","page":1}'); + expect((opts.body as { value: unknown }).value).toBe('{"page":1,"search":"hello"}'); }); it('does not throw when body is a plain Ref', () => { -- 2.51.2 From ca52649a2f479478cc2842677c21c1bcfac69160 Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 8 Feb 2026 11:43:37 +0800 Subject: [PATCH 3/3] Create rare-glasses-smile.md --- .changeset/rare-glasses-smile.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rare-glasses-smile.md diff --git a/.changeset/rare-glasses-smile.md b/.changeset/rare-glasses-smile.md new file mode 100644 index 000000000..629ba51c0 --- /dev/null +++ b/.changeset/rare-glasses-smile.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +**plugin(@hey-api/client-nuxt)**: unwrap `ComputedRef` body before initial serialization -- 2.51.2