fix(core): don't mark optional blocks fields as required in openapi

blocksToInputSchema ignored the attribute's required option, so a blocks field that is not required ended up in the required list of the POST request body in the generated OpenAPI spec. It now goes through maybeRequired like the other input converters.
This commit is contained in:
dualfroz committed 2026-10-17 03:33:16 +02:00
1 parent 63e22609c4
commit 5d6a2c5bac
4 files changed
+31 -6

No files matched your search

@@ -38,3 +38,26 @@ describe('CoreContentTypeRouteValidator query parameters', () => {
expect(filters?.safeParse({ unknown: { $eq: 'hello' } }).success).toBe(false);
});
});
describe('CoreContentTypeRouteValidator body', () => {
const strapi = {
getModel: jest.fn(() => ({
attributes: {
title: { type: 'string', required: true },
content: { type: 'blocks' },
},
})),
} as unknown as Core.Strapi;
const validator = new CoreContentTypeRouteValidator(strapi, 'api::article.article');
test('non-required blocks attributes are optional', () => {
const { properties } = z.toJSONSchema(validator.body, {
target: 'draft-2020-12',
io: 'output',
});
expect(properties?.data).toMatchObject({ required: ['title'] });
expect(validator.body.safeParse({ data: { title: 'Article' } }).success).toBe(true);
});
});
@@ -418,11 +418,16 @@ export const bigIntegerToInputSchema = (attribute: Schema.Attribute.BigInteger)
/**
* Converts a blocks attribute to a Zod schema for input validation.
* @param attribute - The Blocks attribute object from the Strapi schema.
* @returns A Zod schema for input validation of the blocks field.
*/
export const blocksToInputSchema = () => {
export const blocksToInputSchema = (attribute: Schema.Attribute.Blocks) => {
const { required } = attribute;
// TODO: better support blocks data structure
return z.array(z.any()).describe('A blocks field');
const schema = augmentSchema(z.array(z.any()), [maybeRequired(required)]);
return schema.describe('A blocks field');
};
/**
@@ -213,7 +213,7 @@ export const mapAttributeToInputSchema = (
case 'biginteger':
return attributes.bigIntegerToInputSchema(attribute);
case 'blocks':
return attributes.blocksToInputSchema();
return attributes.blocksToInputSchema(attribute);
case 'boolean':
return attributes.booleanToInputSchema(attribute);
case 'component':
@@ -2303,7 +2303,6 @@ exports[`openapi:generate should generate a spec describing i18n and users-permi
},
},
"required": [
"content",
"publishedAt",
],
"type": "object",
@@ -8339,7 +8338,6 @@ exports[`openapi:generate should generate a spec describing i18n and users-permi
},
},
"required": [
"blocks",
"required",
"publishedAt",
],
@@ -16792,7 +16790,6 @@ exports[`openapi:generate should generate a spec describing i18n and users-permi
"name",
"slug",
"isAvailable",
"description",
"publishedAt",
],
"type": "object",