Skip to content

Commit 4b011cd

Browse files
committed
feat: Build path/query/header OpenAPI parameters without
`SchemaAdapter.parseParamsRecord`
1 parent bca770e commit 4b011cd

4 files changed

Lines changed: 20 additions & 41 deletions

File tree

docs/content/server/validation.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,4 @@ Create your own adapter implementing the [`SchemaAdapter` interface](https://jsr
5757
You need to implement 3 functions:
5858

5959
1. `toJsonSchema` returns a JSON schema representation of the given schema.
60-
2. `parseParamsRecord` converts an object definition used for `path` and `query` parameters to `path`/`query` parameter definitions.
61-
3. `getMeta` returns metadata about the given schema.
60+
2. `getMeta` returns metadata about the given schema.

src/adapters/zod-schema-adapter.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,6 @@ export const zodSchemaAdapter: SchemaAdapter = {
2323
delete res.$schema;
2424
return res;
2525
},
26-
parseParamsRecord: (params: any) => {
27-
if (params?._zod?.def?.type !== "object")
28-
throw Error(
29-
"Query, params, and header schemas must be simple Zode objects defined with z.object({ ... })",
30-
);
31-
32-
return Object.entries(params._zod.def.shape).map(
33-
([key, schema]: [string, any]) => ({
34-
name: key,
35-
schema,
36-
optional: schema.safeParse(undefined).success,
37-
...z.globalRegistry.get(schema),
38-
}),
39-
);
40-
},
4126
getMeta: (schema: any) => {
4227
return z.globalRegistry.get(schema);
4328
},

src/open-api.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
import type { StandardSchemaV1 } from "@standard-schema/spec";
12
import type { OpenAPI } from "openapi-types";
2-
import type { App, BasePath, SchemaAdapter } from "./types";
33
import type { CreateAppOptions } from "./app";
4-
import type { StandardSchemaV1 } from "@standard-schema/spec";
5-
import { getHttpStatusName } from "./status";
4+
import { getMeta } from "./meta";
65
import {
76
ErrorResponseJsonSchema,
87
isZetaSchema,
98
type ZetaSchema,
109
} from "./schema";
11-
import { getMeta } from "./meta";
10+
import { getHttpStatusName } from "./status";
11+
import type { App, BasePath, SchemaAdapter } from "./types";
1212

1313
export function buildOpenApiDocs(
1414
options: CreateAppOptions<any> | undefined,
@@ -146,19 +146,25 @@ export function buildScalarHtml(
146146
function mapParameters(
147147
adapter: SchemaAdapter,
148148
schema: StandardSchemaV1 | undefined,
149-
_in: "query" | "path" | "header",
149+
in_: "query" | "path" | "header",
150150
): OpenAPI.Parameters {
151151
if (!schema) return [];
152152

153-
return adapter
154-
.parseParamsRecord(schema)
155-
.map(({ schema, optional, description, name }) => ({
153+
const openApiSchema = adapter.toJsonSchema(schema);
154+
if (openApiSchema.type !== "object")
155+
throw Error(
156+
`Param in ${in_} must have { "type": "object", ... }, but got ${JSON.stringify(openApiSchema, null, 2)}`,
157+
);
158+
159+
return Object.entries(openApiSchema.properties).map(
160+
([name, def]: [string, any]) => ({
156161
name,
157-
in: _in,
158-
description,
159-
schema: adapter.toJsonSchema(schema),
160-
required: !optional,
161-
}));
162+
in: in_,
163+
description: def.description,
164+
schema: def,
165+
required: !!openApiSchema.required?.includes(name),
166+
}),
167+
);
162168
}
163169

164170
function buildResponse(

src/types.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,17 +1037,6 @@ export interface SchemaAdapter {
10371037
* @returns The JSON schema.
10381038
*/
10391039
toJsonSchema: (schema: any) => any;
1040-
/**
1041-
* Used to pull out the openapi parameters from a schema.
1042-
* @param schema The schema to parse.
1043-
* @returns An array of objects used to generate the OpenAPI docs.
1044-
*/
1045-
parseParamsRecord: (schema: StandardSchemaV1) => Array<{
1046-
name: string;
1047-
optional: boolean;
1048-
schema: StandardSchemaV1;
1049-
description?: string;
1050-
}>;
10511040
getMeta: (schema: StandardSchemaV1) => Record<string, any> | undefined;
10521041
}
10531042

0 commit comments

Comments
 (0)