UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

137 lines (115 loc) 4.78 kB
import {type SchemaType} from '@sanity/types' import {uniqueId} from 'lodash' import {isValidElementType} from 'react-is' import {getConfigContextFromSource, getPublishedId, type Source} from 'sanity' import {structureLocaleNamespace} from '../i18n' import {ComponentBuilder, type ComponentInput} from './Component' import {DocumentBuilder, documentFromEditor, documentFromEditorWithInitialValue} from './Document' import {DocumentListBuilder} from './DocumentList' import {DocumentListItemBuilder} from './DocumentListItem' import { getDocumentTypeList, getDocumentTypeListItem, getDocumentTypeListItems, } from './documentTypeListItems' import { defaultInitialValueTemplateItems, InitialValueTemplateItemBuilder, menuItemsFromInitialValueTemplateItems, } from './InitialValueTemplateItem' import {ListBuilder} from './List' import {ListItemBuilder} from './ListItem' import {getOrderingMenuItem, getOrderingMenuItemsForSchemaType, MenuItemBuilder} from './MenuItem' import {MenuItemGroupBuilder} from './MenuItemGroup' import {type Divider} from './StructureNodes' import { type DefaultDocumentNodeResolver, type StructureBuilder, type StructureContext, type UserComponent, } from './types' import * as views from './views' /** @internal */ export interface StructureBuilderOptions { source: Source defaultDocumentNode?: DefaultDocumentNodeResolver } function hasIcon(schemaType?: SchemaType | string): boolean { if (!schemaType || typeof schemaType === 'string') { return false } return Boolean(schemaType.icon) } function getDefaultStructure(context: StructureContext): ListBuilder { const items = getDocumentTypeListItems(context) return new ListBuilder(context) .id('__root__') .title('Content') .i18n({title: {key: 'default-definition.content-title', ns: structureLocaleNamespace}}) .items(items) .showIcons(items.some((item) => hasIcon(item.getSchemaType()))) } /** @internal */ export function createStructureBuilder({ defaultDocumentNode, source, }: StructureBuilderOptions): StructureBuilder { const configContext = getConfigContextFromSource(source) const context: StructureContext = { ...source, getStructureBuilder: () => structureBuilder, resolveDocumentNode: (options) => { let builder = defaultDocumentNode?.(structureBuilder, {...options, ...configContext}) || new DocumentBuilder(context) if (!builder.getId()) { builder = builder.id('documentEditor') } if (options.documentId) { builder = builder.documentId(getPublishedId(options.documentId)) } return builder.schemaType(options.schemaType) }, } const structureBuilder: StructureBuilder = { defaults: () => getDefaultStructure(context), documentTypeList: (...args) => getDocumentTypeList(context, ...args), documentTypeListItem: (...args) => getDocumentTypeListItem(context, ...args), documentTypeListItems: (...args) => getDocumentTypeListItems(context, ...args), document: (...args) => new DocumentBuilder(context, ...args), documentWithInitialValueTemplate: (...args) => documentFromEditorWithInitialValue(context, ...args), defaultDocument: context.resolveDocumentNode, list: (...args) => new ListBuilder(context, ...args), listItem: (...args) => new ListItemBuilder(context, ...args), menuItem: (...args) => new MenuItemBuilder(context, ...args), menuItemGroup: (...args) => new MenuItemGroupBuilder(context, ...args), menuItemsFromInitialValueTemplateItems: (...args) => menuItemsFromInitialValueTemplateItems(context, ...args), documentList: (...args) => new DocumentListBuilder(context, ...args), documentListItem: (...args) => new DocumentListItemBuilder(context, ...args), orderingMenuItem: (...args) => getOrderingMenuItem(context, ...args), orderingMenuItemsForType: (...args) => getOrderingMenuItemsForSchemaType(context, ...args), editor: (...args) => documentFromEditor(context, ...args), defaultInitialValueTemplateItems: (...args) => defaultInitialValueTemplateItems(context, ...args), initialValueTemplateItem: ( templateId: string, parameters?: Record<string, unknown>, ): InitialValueTemplateItemBuilder => new InitialValueTemplateItemBuilder(context, { id: templateId, parameters, templateId, }), component: (spec?: ComponentInput | UserComponent) => { return isValidElementType(spec) ? new ComponentBuilder().component(spec as UserComponent) : new ComponentBuilder(spec as ComponentInput) }, divider: (): Divider => ({id: uniqueId('__divider__'), type: 'divider'}), view: views, context, } return structureBuilder }