From b33ff3b82f88de23202c982dbdeea604c13fdad4 Mon Sep 17 00:00:00 2001 From: nesmachny Date: Fri, 22 May 2026 12:49:07 +0100 Subject: [PATCH] fix(core): emdash types reads un-enveloped /schema response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `emdash types` crashed with "Cannot read properties of undefined (reading 'collections')". The client's schemaExport() routed through the enveloped request() helper, but the /schema endpoint returns a bare { collections, version } object — it now reads the raw response directly. Adds a failing-then-passing unit test and a changeset. Co-Authored-By: Claude Opus 4.7 --- .changeset/fix-emdash-types-schema-export.md | 5 +++ packages/core/src/client/index.ts | 6 +++- .../core/tests/unit/client/client.test.ts | 33 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-emdash-types-schema-export.md diff --git a/.changeset/fix-emdash-types-schema-export.md b/.changeset/fix-emdash-types-schema-export.md new file mode 100644 index 000000000..024f4a41f --- /dev/null +++ b/.changeset/fix-emdash-types-schema-export.md @@ -0,0 +1,5 @@ +--- +"emdash": patch +--- + +Fixes `emdash types` crashing with "Cannot read properties of undefined (reading 'collections')". The client's `schemaExport()` routed through the enveloped `request()` helper, but the `/schema` endpoint returns a bare `{ collections, version }` object — it now reads the raw response directly. diff --git a/packages/core/src/client/index.ts b/packages/core/src/client/index.ts index 346d224b4..d78f0f89d 100644 --- a/packages/core/src/client/index.ts +++ b/packages/core/src/client/index.ts @@ -387,7 +387,11 @@ export class EmDashClient { /** Export full schema as JSON (used by `emdash types`) */ async schemaExport(): Promise { - return this.request("GET", "/schema"); + // The /schema endpoint returns a bare { collections, version } object, + // not the standard { data } envelope — parse the raw response directly. + const response = await this.requestRaw("GET", "/schema"); + await this.assertOk(response); + return (await response.json()) as SchemaExport; } /** Export schema as TypeScript type definitions (used by `emdash types`) */ diff --git a/packages/core/tests/unit/client/client.test.ts b/packages/core/tests/unit/client/client.test.ts index 7693dddf0..391eb2e1d 100644 --- a/packages/core/tests/unit/client/client.test.ts +++ b/packages/core/tests/unit/client/client.test.ts @@ -737,4 +737,37 @@ describe("EmDashClient", () => { expect(result[0]!.name).toBe("primary"); }); }); + + describe("schemaExport()", () => { + it("returns the un-enveloped /schema response body", async () => { + // The /schema endpoint returns a bare { collections, version } + // object — it is NOT wrapped in the standard { data } envelope. + const schemaBody = { + collections: [{ slug: "posts", label: "Posts", fields: [] }], + version: "abc123", + }; + const backend = createMockBackend([ + { + method: "GET", + path: "/schema", + handler: () => + new Response(JSON.stringify(schemaBody), { + status: 200, + headers: { "Content-Type": "application/json" }, + }), + }, + ]); + + const client = new EmDashClient({ + baseUrl: "http://localhost:4321", + token: "test", + interceptors: [backend], + }); + + const schema = await client.schemaExport(); + expect(schema.collections).toHaveLength(1); + expect(schema.collections[0]!.slug).toBe("posts"); + expect(schema.version).toBe("abc123"); + }); + }); });