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
110 lines (96 loc) • 3.29 kB
text/typescript
import {type SchemaType} from '@sanity/types'
import {isRecord} from 'sanity'
import {DocumentBuilder} from './Document'
import {
type ListItem,
ListItemBuilder,
type ListItemInput,
type UnserializedListItem,
} from './ListItem'
import {HELP_URL, SerializeError} from './SerializeError'
import {type SerializeOptions} from './StructureNodes'
import {type StructureContext} from './types'
/**
* Interface for document list item input
*
* @public
*/
export interface DocumentListItemInput extends ListItemInput {
/** Document list item input schema type. See {@link SchemaType} */
schemaType: SchemaType | string
}
/**
* Interface for document list item
*
* @public
*/
export interface DocumentListItem extends ListItem {
/** Document schema type. See {@link SchemaType} */
schemaType: SchemaType
/** Document ID */
_id: string
}
/**
* Partial document list item
*
* @public
*/
export type PartialDocumentListItem = Partial<UnserializedListItem>
const createDefaultChildResolver =
(context: StructureContext, spec: PartialDocumentListItem) => (documentId: string) => {
const schemaType =
spec.schemaType &&
(typeof spec.schemaType === 'string' ? spec.schemaType : spec.schemaType.name)
return schemaType
? context.resolveDocumentNode({schemaType, documentId})
: new DocumentBuilder(context).id('documentEditor').documentId(documentId)
}
/**
* Class for building a document list item
*
* @public
*/
export class DocumentListItemBuilder extends ListItemBuilder {
/** Document list options. See {@link PartialDocumentListItem} */
protected spec: PartialDocumentListItem
constructor(
/**
* Structure context. See {@link StructureContext}
*/
protected _context: StructureContext,
spec?: DocumentListItemInput,
) {
super(_context, spec)
this.spec = spec ? spec : {}
}
/**
* Serialize document list item
* @param options - serialization options. See {@link SerializeOptions}
* @returns document list item object based on path provided in options. See {@link DocumentListItem}
*/
serialize(options: SerializeOptions = {path: []}): DocumentListItem {
const spec = super.serialize({...options, titleIsOptional: true})
if (!spec.schemaType) {
throw new SerializeError(
'`schemaType` is required for document list items',
options.path,
options.index,
).withHelpUrl(HELP_URL.SCHEMA_TYPE_REQUIRED)
}
const child = spec.child || createDefaultChildResolver(this._context, spec)
return {...spec, child, schemaType: spec.schemaType, _id: spec.id}
}
/** Clone Document list item builder (allows for options overriding)
* @param withSpec - Document list item builder options. See {@link PartialDocumentListItem}
* @returns document list item builder. See {@link DocumentListItemBuilder}
*/
clone(withSpec?: PartialDocumentListItem): DocumentListItemBuilder {
const builder = new DocumentListItemBuilder(this._context)
builder.spec = {...this.spec, ...(withSpec || {})}
return builder
}
}
/** @internal */
export function isDocumentListItem(item: unknown): item is DocumentListItem {
return isRecord(item) && typeof item.schemaType !== 'undefined' && typeof item._id === 'string'
}