fix: type generation for block fields with no blocks (#7765)

This commit is contained in:
Paul
2024-08-19 16:34:19 -06:00
committed by GitHub
parent ebd43c7763
commit 0c36cbde73
2 changed files with 168 additions and 30 deletions

View File

@@ -62,6 +62,137 @@ describe('configToJSONSchema', () => {
})
})
it('should handle block fields with no blocks', async () => {
// @ts-expect-error
const config: Config = {
collections: [
{
slug: 'test',
fields: [
{
name: 'blockField',
type: 'blocks',
blocks: [],
},
{
name: 'blockFieldRequired',
type: 'blocks',
blocks: [],
required: true,
},
{
name: 'blockFieldWithFields',
type: 'blocks',
blocks: [
{
slug: 'test',
fields: [
{
name: 'field',
type: 'text',
},
],
},
],
},
{
name: 'blockFieldWithFieldsRequired',
type: 'blocks',
blocks: [
{
slug: 'test',
fields: [
{
name: 'field',
type: 'text',
required: true,
},
],
},
],
},
],
timestamps: false,
},
],
}
const sanitizedConfig = await sanitizeConfig(config)
const schema = configToJSONSchema(sanitizedConfig, 'text')
expect(schema?.definitions?.test).toStrictEqual({
type: 'object',
additionalProperties: false,
properties: {
id: {
type: 'string',
},
blockField: {
type: ['array', 'null'],
items: {},
},
blockFieldRequired: {
type: 'array',
items: {},
},
blockFieldWithFields: {
type: ['array', 'null'],
items: {
oneOf: [
{
type: 'object',
additionalProperties: false,
properties: {
id: {
type: ['string', 'null'],
},
blockName: {
type: ['string', 'null'],
},
blockType: {
const: 'test',
},
field: {
type: ['string', 'null'],
},
},
required: ['blockType'],
},
],
},
},
blockFieldWithFieldsRequired: {
type: ['array', 'null'],
items: {
oneOf: [
{
type: 'object',
additionalProperties: false,
properties: {
id: {
type: ['string', 'null'],
},
blockName: {
type: ['string', 'null'],
},
blockType: {
const: 'test',
},
field: {
type: 'string',
},
},
required: ['blockType', 'field'],
},
],
},
},
},
required: ['id', 'blockFieldRequired'],
title: 'Test',
})
})
it('should handle tabs and named tabs with required fields', async () => {
// @ts-expect-error
const config: Config = {

View File

@@ -396,40 +396,47 @@ export function fieldsToJSONSchema(
}
case 'blocks': {
// Check for a case where no blocks are provided.
// We need to generate an empty array for this case, note that JSON schema 4 doesn't support empty arrays
// so the best we can get is `unknown[]`
const hasBlocks = Boolean(field.blocks.length)
fieldSchema = {
type: withNullableJSONSchemaType('array', isRequired),
items: {
oneOf: field.blocks.map((block) => {
const blockFieldSchemas = fieldsToJSONSchema(
collectionIDFieldTypes,
block.fields,
interfaceNameDefinitions,
config,
)
items: hasBlocks
? {
oneOf: field.blocks.map((block) => {
const blockFieldSchemas = fieldsToJSONSchema(
collectionIDFieldTypes,
block.fields,
interfaceNameDefinitions,
config,
)
const blockSchema: JSONSchema4 = {
type: 'object',
additionalProperties: false,
properties: {
...blockFieldSchemas.properties,
blockType: {
const: block.slug,
},
},
required: ['blockType', ...blockFieldSchemas.required],
const blockSchema: JSONSchema4 = {
type: 'object',
additionalProperties: false,
properties: {
...blockFieldSchemas.properties,
blockType: {
const: block.slug,
},
},
required: ['blockType', ...blockFieldSchemas.required],
}
if (block.interfaceName) {
interfaceNameDefinitions.set(block.interfaceName, blockSchema)
return {
$ref: `#/definitions/${block.interfaceName}`,
}
}
return blockSchema
}),
}
if (block.interfaceName) {
interfaceNameDefinitions.set(block.interfaceName, blockSchema)
return {
$ref: `#/definitions/${block.interfaceName}`,
}
}
return blockSchema
}),
},
: {},
}
break
}