Description
Summary
Running npx emdash types --url --token fails with:
ERROR Failed to fetch schema: Cannot read properties of undefined (reading 'collections')
Tracing through the source, there are two separate defects that combine to make production type generation unusable.
Defect 1 — client unwrap mismatch
EmDashClient.request() (src/client/index.ts:775-780) returns json.data for every response:
const json = (await response.json()) as { data: T };
return json.data;
But the /_emdash/api/schema route (src/astro/routes/api/schema/index.ts:92) returns the schema un-enveloped:
return new Response(JSON.stringify({ ...schemaExport, version }), ...);
So client.schemaExport() returns undefined, and the CLI then dereferences schema.collections.length → crash. Other schema endpoints (e.g. /schema/collections) do use the { success, data } envelope — the inconsistency is the root cause.
Verified with curl: GET /_emdash/api/schema returns {"collections":[...], "version":"..."} with no data wrapper.
Defect 2 — dev/prod typegen divergence
Even with defect 1 fixed, the CLI calls /schema?format=typescript which produces a slim output:
// Generated by EmDash CLI
import type { PortableTextBlock } from "emdash";
export interface Page { ...; bylines?: ContentBylineCredit[]; }
export interface Post { ...; bylines?: ContentBylineCredit[]; }
Compared to what the dev server writes during astro:server:setup, this output is missing:
ContentBylineCredit in the import (file references it without importing → TS compile error)
declare module "emdash" { interface EmDashCollections { pages: Page; posts: Post; } } — without this, getEmDashCollection("posts") loses its typed return
The "rich" generator lives at POST /_emdash/api/typegen (src/astro/routes/api/typegen.ts:95) but is gated by import.meta.env.DEV, so it's unreachable on a deployed Worker.
Expected
npx emdash types --url --token should produce the same emdash-env.d.ts content the dev server writes locally — usable as-is.
Use case
CI workflow that regenerates emdash-env.d.ts from the deployed staging schema and opens a PR when the types drift, so devs don't have to remember to run npx emdash dev after a schema change in staging.
Steps to reproduce
- npx emdash types --url --token
- fails with exit code 1
- seems to be an issue with the CLI expecting data as envelope
- whilst /_emdash/api/schema yields collections as the top element, unenveloped
Environment
Version: emdash@0.14.0 (server commit 102535f)
Logs / error output
ERROR Failed to fetch schema: Cannot read properties of undefined (reading 'collections') 10:33:41 PM
=> no data property exists in the output.
Description
Summary
Running npx emdash types --url --token fails with:
ERROR Failed to fetch schema: Cannot read properties of undefined (reading 'collections')
Tracing through the source, there are two separate defects that combine to make production type generation unusable.
Defect 1 — client unwrap mismatch
EmDashClient.request() (src/client/index.ts:775-780) returns json.data for every response:
const json = (await response.json()) as { data: T };
return json.data;
But the /_emdash/api/schema route (src/astro/routes/api/schema/index.ts:92) returns the schema un-enveloped:
return new Response(JSON.stringify({ ...schemaExport, version }), ...);
So client.schemaExport() returns undefined, and the CLI then dereferences schema.collections.length → crash. Other schema endpoints (e.g. /schema/collections) do use the { success, data } envelope — the inconsistency is the root cause.
Verified with curl: GET /_emdash/api/schema returns {"collections":[...], "version":"..."} with no data wrapper.
Defect 2 — dev/prod typegen divergence
Even with defect 1 fixed, the CLI calls /schema?format=typescript which produces a slim output:
Compared to what the dev server writes during astro:server:setup, this output is missing:
ContentBylineCredit in the import (file references it without importing → TS compile error) declare module "emdash" { interface EmDashCollections { pages: Page; posts: Post; } } — without this, getEmDashCollection("posts") loses its typed returnThe "rich" generator lives at POST /_emdash/api/typegen (src/astro/routes/api/typegen.ts:95) but is gated by import.meta.env.DEV, so it's unreachable on a deployed Worker.
Expected
npx emdash types --url --token should produce the same emdash-env.d.ts content the dev server writes locally — usable as-is.
Use case
CI workflow that regenerates emdash-env.d.ts from the deployed staging schema and opens a PR when the types drift, so devs don't have to remember to run npx emdash dev after a schema change in staging.
Steps to reproduce
Environment
Version: emdash@0.14.0 (server commit 102535f)
Logs / error output