Skip to content

Commit faa9bdf

Browse files
fix(openapi): read ~standard.jsonSchema via cast, not by widening StandardSchemaV1 (#3)
Adding `jsonSchema?` to the vendored `StandardSchemaV1.Props` diverged it from `@standard-schema/spec` and perturbed generic type inference in consumers — an endpoint's body type could collapse to `undefined` when the definer is used behind a generic wrapper. Revert the spec type to its original shape and read `~standard.jsonSchema` through a local cast in the generator instead. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3799281 commit faa9bdf

2 files changed

Lines changed: 15 additions & 30 deletions

File tree

packages/better-call/src/openapi.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ const BODY_METHODS = new Set<string>(["POST", "PUT", "PATCH", "DELETE"]);
120120

121121
const PATH_PARAM_REGEX = /:([A-Za-z0-9_]+)/g;
122122

123+
/**
124+
* The optional JSON Schema conversion exposed on `~standard.jsonSchema` per the
125+
* StandardJSONSchemaV1 proposal (https://standardschema.dev/json-schema). Read
126+
* via a local cast rather than by widening {@link StandardSchemaV1} itself —
127+
* modifying the vendored spec type perturbs generic inference in consumers.
128+
*/
129+
interface JSONSchemaConverter {
130+
input?: (options?: { target?: string }) => Record<string, any>;
131+
output?: (options?: { target?: string }) => Record<string, any>;
132+
}
133+
123134
/**
124135
* Convert a Standard Schema to a JSON Schema object using the library-agnostic
125136
* StandardJSONSchemaV1 interface (`schema["~standard"].jsonSchema`), natively
@@ -132,7 +143,10 @@ function toJsonSchema(
132143
schema: StandardSchemaV1 | undefined,
133144
io: "input" | "output",
134145
): Record<string, any> | undefined {
135-
const converter = schema?.["~standard"]?.jsonSchema;
146+
const std = schema?.["~standard"] as
147+
| { jsonSchema?: JSONSchemaConverter }
148+
| undefined;
149+
const converter = std?.jsonSchema;
136150
if (!converter) return undefined;
137151
try {
138152
const fn = io === "input" ? converter.input : converter.output;

packages/better-call/src/standard-schema.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,6 @@ export declare namespace StandardSchemaV1 {
1717
) => Result<Output> | Promise<Result<Output>>;
1818
/** Inferred types associated with the schema. */
1919
readonly types?: Types<Input, Output> | undefined;
20-
/**
21-
* Optional JSON Schema conversion, per the StandardJSONSchemaV1 proposal
22-
* (https://standardschema.dev/json-schema). Natively implemented by Zod
23-
* (>= 4.2), ArkType (>= 2.1.28), and others. Consumed by the OpenAPI
24-
* generator to describe request bodies and query parameters in a
25-
* library-agnostic way.
26-
*/
27-
readonly jsonSchema?: JSONSchemaConverter | undefined;
28-
}
29-
30-
/** Options accepted by the JSON Schema conversion methods. */
31-
export interface JSONSchemaOptions {
32-
/**
33-
* Target JSON Schema dialect. OpenAPI 3.1 aligns with `"draft-2020-12"`.
34-
*/
35-
readonly target?:
36-
| "draft-2020-12"
37-
| "draft-07"
38-
| "openapi-3.0"
39-
| (string & {});
40-
readonly [key: string]: unknown;
41-
}
42-
43-
/** The JSON Schema conversion interface exposed on `~standard.jsonSchema`. */
44-
export interface JSONSchemaConverter {
45-
/** JSON Schema describing accepted input values. */
46-
readonly input?: (options?: JSONSchemaOptions) => Record<string, unknown>;
47-
/** JSON Schema describing produced output values. */
48-
readonly output?: (options?: JSONSchemaOptions) => Record<string, unknown>;
4920
}
5021

5122
/** The result interface of the validate function. */

0 commit comments

Comments
 (0)