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
76 lines (58 loc) • 2.23 kB
text/typescript
import {isArraySchemaType, type SchemaType} from '@sanity/types'
import {get} from 'lodash'
export function getOption(type: SchemaType, optionName: string) {
return get(type.options, optionName)
}
const PSEUDO_OBJECTS = ['array', 'file', 'image', 'reference', 'slug']
const HIDDEN_FIELDS = ['asset', 'crop', 'hotspot', '_ref', '_weak']
const NO_LEVEL_LAYOUTS = ['tags']
const NO_LEVEL_TYPES = ['slug']
export function getTypeChain(type: SchemaType | undefined, visited: Set<SchemaType>): SchemaType[] {
if (!type) return []
if (visited.has(type)) return []
visited.add(type)
const next = type.type ? getTypeChain(type.type, visited) : []
return [type, ...next]
}
export function getFieldLevel(schemaType: SchemaType, currentLevel: number) {
return isArraySchemaType(schemaType)
? getArrayFieldLevel(schemaType, currentLevel)
: getObjectFieldLevel(schemaType, currentLevel)
}
function getObjectFieldLevel(schemaType: SchemaType, currentLevel: number): number {
const {type, options} = schemaType
const typeIfRelevant = asType(type, PSEUDO_OBJECTS)
const fields = schemaType?.jsonType === 'object' ? schemaType.fields : undefined
const typeName = typeIfRelevant?.name || ''
if (NO_LEVEL_TYPES.includes(typeName)) {
return 0
}
const isPseudoObject = PSEUDO_OBJECTS.includes(typeName)
const hasVisibleFields = (fields?.filter((f) => !HIDDEN_FIELDS.includes(f.name)).length ?? 0) > 0
const hasListOptions = (options?.list?.length ?? 0) > 0
if (hasVisibleFields || hasListOptions || !isPseudoObject) {
return currentLevel
}
return 0
}
function getArrayFieldLevel(schemaType: SchemaType, currentLevel: number): number {
const {options} = schemaType
const hasListOptions = (options?.list || [])?.length > 0
const isNoLevelLayout = NO_LEVEL_LAYOUTS.includes(options?.layout || '')
if (hasListOptions && !isNoLevelLayout) {
return currentLevel
}
return 0
}
function asType(
schemaType: SchemaType | undefined,
asOneOfTypes: string[],
): SchemaType | undefined {
if (schemaType?.name && asOneOfTypes.includes(schemaType?.name)) {
return schemaType
}
if (!schemaType) {
return undefined
}
return asType(schemaType.type, asOneOfTypes)
}