Skip to content

Commit 5c80a5e

Browse files
authored
fix(ts-rest-open-api): pathParams and query descriptions from zod .describe() (#364)
Move `"description"` out of `"schema"` as per OpenAPI spec: https://spec.openapis.org/oas/v3.1.0#parameter-object Fixes #305
1 parent 74eeee0 commit 5c80a5e

3 files changed

Lines changed: 21 additions & 9 deletions

File tree

.changeset/new-kids-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ts-rest/open-api": patch
3+
---
4+
5+
fix(ts-rest-open-api): pathParams and query descriptions from `zod` `.describe()`

libs/ts-rest/open-api/src/lib/ts-rest-open-api.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const postsRouter = c.router({
6868
method: 'GET',
6969
path: `/posts/:id/comments/:commentId`,
7070
pathParams: z.object({
71-
commentId: z.string().length(5),
71+
commentId: z.string().length(5).describe("the comment ID"),
7272
}),
7373
responses: {
7474
200: c.response<Post | null>(),
@@ -324,6 +324,7 @@ const expectedApiDoc = {
324324
in: 'path',
325325
name: 'commentId',
326326
required: true,
327+
description: 'the comment ID',
327328
schema: {
328329
type: 'string',
329330
minLength: 5,
@@ -571,7 +572,7 @@ describe('ts-rest-open-api', () => {
571572
},
572573
query: z
573574
.object({
574-
foo: z.string(),
575+
foo: z.string().describe("Foo"),
575576
})
576577
.refine((v) => v.foo === 'bar', {
577578
message: 'foo must be bar',
@@ -596,6 +597,7 @@ describe('ts-rest-open-api', () => {
596597
description: undefined,
597598
parameters: [
598599
{
600+
description: 'Foo',
599601
in: 'query',
600602
name: 'foo',
601603
required: true,

libs/ts-rest/open-api/src/lib/ts-rest-open-api.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,16 @@ const getPathParameters = (path: string, zodObject?: unknown) => {
7878
})) || [];
7979

8080
if (isZodObj) {
81-
const paramsFromZod = Object.entries(zodShape).map(([key, value]) => ({
82-
name: key,
83-
in: 'path' as const,
84-
required: true,
85-
schema: getOpenApiSchemaFromZod(value),
86-
}));
81+
const paramsFromZod = Object.entries(zodShape).map(([key, value]) => {
82+
const { description, ...schema } = getOpenApiSchemaFromZod(value)!;
83+
return {
84+
name: key,
85+
in: 'path' as const,
86+
required: true,
87+
schema,
88+
...(description && { description }),
89+
}
90+
});
8791

8892
params.push(...paramsFromZod);
8993
}
@@ -125,13 +129,14 @@ const getQueryParametersFromZod = (zodObject: unknown, jsonQuery = false) => {
125129
const zodShape = extractZodObjectShape(zodObject);
126130

127131
return Object.entries(zodShape).map(([key, value]) => {
128-
const schema = getOpenApiSchemaFromZod(value)!;
132+
const { description, ...schema } = getOpenApiSchemaFromZod(value)!;
129133
const isObject = (value as z.ZodTypeAny)._def.typeName === 'ZodObject';
130134
const isRequired = !(value as z.ZodTypeAny).isOptional();
131135

132136
return {
133137
name: key,
134138
in: 'query' as const,
139+
...(description && { description }),
135140
...(isRequired && { required: true }),
136141
...(jsonQuery
137142
? {

0 commit comments

Comments
 (0)