UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

116 lines (108 loc) 3.4 kB
import type { ArraySchemaType, BlockSchemaType, ObjectSchemaType, PortableTextBlock, SchemaType, SpanSchemaType, } from '@sanity/types' import type {PortableTextMemberSchemaTypes} from '../types/editor' export function createLegacySchema( portableTextType: ArraySchemaType<PortableTextBlock>, ): PortableTextMemberSchemaTypes { if (!portableTextType) { throw new Error("Parameter 'portabletextType' missing (required)") } const blockType = portableTextType.of?.find(findBlockType) as | BlockSchemaType | undefined if (!blockType) { throw new Error('Block type is not defined in this schema (required)') } const childrenField = blockType.fields?.find( (field) => field.name === 'children', ) as {type: ArraySchemaType} | undefined if (!childrenField) { throw new Error('Children field for block type found in schema (required)') } const ofType = childrenField.type.of if (!ofType) { throw new Error( 'Valid types for block children not found in schema (required)', ) } const spanType = ofType.find((memberType) => memberType.name === 'span') as | ObjectSchemaType | undefined if (!spanType) { throw new Error('Span type not found in schema (required)') } const inlineObjectTypes = (ofType.filter( (memberType) => memberType.name !== 'span', ) || []) as ObjectSchemaType[] const blockObjectTypes = (portableTextType.of?.filter( (field) => field.name !== blockType.name, ) || []) as ObjectSchemaType[] return { styles: resolveEnabledStyles(blockType), decorators: resolveEnabledDecorators(spanType), lists: resolveEnabledListItems(blockType), block: blockType, span: spanType, portableText: portableTextType, inlineObjects: inlineObjectTypes, blockObjects: blockObjectTypes, annotations: (spanType as SpanSchemaType).annotations, } } function resolveEnabledStyles(blockType: ObjectSchemaType) { const styleField = blockType.fields?.find( (btField) => btField.name === 'style', ) if (!styleField) { throw new Error( "A field with name 'style' is not defined in the block type (required).", ) } const textStyles = styleField.type.options?.list && styleField.type.options.list?.filter( (style: {value: string}) => style.value, ) if (!textStyles || textStyles.length === 0) { throw new Error( 'The style fields need at least one style ' + "defined. I.e: {title: 'Normal', value: 'normal'}.", ) } return textStyles } function resolveEnabledDecorators(spanType: ObjectSchemaType) { return (spanType as any).decorators } function resolveEnabledListItems(blockType: ObjectSchemaType) { const listField = blockType.fields?.find( (btField) => btField.name === 'listItem', ) if (!listField) { throw new Error( "A field with name 'listItem' is not defined in the block type (required).", ) } const listItems = listField.type.options?.list && listField.type.options.list.filter((list: {value: string}) => list.value) if (!listItems) { throw new Error('The list field need at least to be an empty array') } return listItems } function findBlockType(type: SchemaType): BlockSchemaType | null { if (type.type) { return findBlockType(type.type) } if (type.name === 'block') { return type as BlockSchemaType } return null }