Skip to content

Commit

Permalink
Merge pull request #194 from BEARlogin/fix-required
Browse files Browse the repository at this point in the history
 Fix Handling of Optional Zod Fields with NestJS Swagger
  • Loading branch information
Brian-McBride authored Mar 29, 2024
2 parents 633adcf + ab4c5c6 commit 9cad0ec
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 8 deletions.
65 changes: 61 additions & 4 deletions packages/zod-nestjs/src/lib/create-zod-dto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ describe('zod-nesjs create-zod-dto', () => {
const metadataFactory = getMetadataFactory(schema);

const generatedSchema = metadataFactory();
const personName = generatedSchema?.person.properties?.name as SchemaObject30
const tags = generatedSchema?.person.properties?.tags as SchemaObject30
const tagsItems = tags.items as SchemaObject30
const tagName = tagsItems.properties?.name as SchemaObject30
const personName = generatedSchema?.person.properties
?.name as SchemaObject30;
const tags = generatedSchema?.person.properties?.tags as SchemaObject30;
const tagsItems = tags.items as SchemaObject30;
const tagName = tagsItems.properties?.name as SchemaObject30;

expect(generatedSchema).toBeDefined();
expect(personName.type).toEqual('string');
Expand All @@ -150,6 +151,62 @@ describe('zod-nesjs create-zod-dto', () => {
expect(generatedSchema?.name.type).toEqual('string');
expect(generatedSchema?.name.nullable).toBe(true);
});

it('should correct work with optional fields and make required fields false', () => {
const schema = z.object({
pagination: z
.object({
limit: z.number(),
offset: z.number(),
})
.optional(),
filter: z
.object({
category: z.string().uuid(),
userId: z.string().uuid(),
})
.optional(),
sort: z
.object({
field: z.string(),
order: z.string(),
})
.optional(),
});
const metadataFactory = getMetadataFactory(schema);

const generatedSchema = metadataFactory();
expect(generatedSchema?.pagination.required).toEqual(false);
expect(generatedSchema?.sort.required).toEqual(false);
expect(generatedSchema?.filter.required).toEqual(false);
});

it('should correct work with optional fields and make required field true and optional field false', () => {
const schema = z.object({
pagination: z
.object({
limit: z.number(),
offset: z.number(),
})
.optional(),
filter: z
.object({
category: z.string().uuid(),
userId: z.string().uuid(),
})
.optional(),
sort: z.object({
field: z.string(),
order: z.string(),
}),
});
const metadataFactory = getMetadataFactory(schema);

const generatedSchema = metadataFactory();
expect(generatedSchema?.pagination.required).toEqual(false);
expect(generatedSchema?.sort.required).toEqual(true);
expect(generatedSchema?.filter.required).toEqual(false);
});
});

function getMetadataFactory(zodRef: OpenApiZodAny) {
Expand Down
8 changes: 4 additions & 4 deletions packages/zod-nestjs/src/lib/create-zod-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const createZodDto = <T extends OpenApiZodAny>(
)) {
SchemaHolderClass.convertSchemaObject(
subSchemaObject,
schemaObject.required?.includes(key)
schemaObject.required?.includes(key) ?? false
);
}

Expand All @@ -141,9 +141,9 @@ export const createZodDto = <T extends OpenApiZodAny>(
if (Array.isArray(convertedSchemaObject.type)) {
convertedSchemaObject.nullable =
convertedSchemaObject.type.includes('null') || undefined;
convertedSchemaObject.type = convertedSchemaObject.type.find(
(item) => item !== 'null'
) || 'string';
convertedSchemaObject.type =
convertedSchemaObject.type.find((item) => item !== 'null') ||
'string';
} else if (convertedSchemaObject.type === 'null') {
convertedSchemaObject.type = 'string'; // There ist no explicit null value in OpenAPI 3.0
convertedSchemaObject.nullable = true;
Expand Down

0 comments on commit 9cad0ec

Please sign in to comment.