@sanity/schema
Version:
## Terminology
1 lines • 92.7 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/legacy/types/utils.ts","../src/legacy/types/any.ts","../src/legacy/types/array.ts","../src/legacy/preview/deprecationUtils.ts","../src/legacy/preview/JSONStringifyHuman.ts","../src/legacy/preview/fallbackPrepare.ts","../src/legacy/preview/portableText.ts","../src/legacy/preview/guessPreviewConfig.ts","../src/legacy/preview/createPreviewGetter.ts","../src/legacy/types/blocks/defaults.ts","../src/legacy/types/blocks/block.ts","../src/legacy/types/blocks/span.ts","../src/legacy/preview/primitivePreview.ts","../src/legacy/types/boolean.ts","../src/legacy/types/crossDatasetReference.ts","../src/legacy/types/date.ts","../src/legacy/types/datetime.ts","../src/legacy/ordering/guessOrderingConfig.ts","../src/legacy/searchConfig/normalize.ts","../src/legacy/types/object.ts","../src/legacy/types/document.ts","../src/legacy/types/email.ts","../src/legacy/types/file.ts","../src/legacy/types/globalDocumentReference.ts","../src/legacy/types/image/fieldDefs.ts","../src/legacy/types/image.ts","../src/legacy/types/number.ts","../src/legacy/types/reference.ts","../src/legacy/types/string.ts","../src/legacy/types/text.ts","../src/legacy/types/url.ts","../src/legacy/Schema.ts","../src/_exports/index.ts"],"sourcesContent":["interface Config {\n enumerable?: boolean\n writable?: boolean\n}\nexport function lazyGetter(target: any, key: any, getter: any, config: Config = {}) {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: config.enumerable !== false,\n get() {\n const val = getter()\n Object.defineProperty(target, key, {\n value: val,\n writable: Boolean(config.writable),\n configurable: false,\n })\n return val\n },\n })\n return target\n}\n\nexport function hiddenGetter(target: any, key: string, value: unknown) {\n Object.defineProperty(target, key, {\n enumerable: false,\n writable: false,\n configurable: false,\n value,\n })\n}\n\n//\n// const o = lazyGetter({}, 'expensive', function() {\n// console.log('doing expensive calculations')\n// return 'RESULT OF EXPENSIVE'\n// })\n//\n// console.log(o.expensive)\n// console.log(o.expensive)\n// console.log(o.expensive)\n","import {omit, pick} from 'lodash'\n\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst ANY_CORE = {\n name: 'any',\n type: null,\n jsonType: 'any',\n}\n\nexport const AnyType = {\n get() {\n return ANY_CORE\n },\n extend(subTypeDef: any, extendMember: any) {\n const ownProps = {\n ...subTypeDef,\n of: subTypeDef.of.map((fieldDef: any) => {\n return {\n name: fieldDef.name,\n type: extendMember(omit(fieldDef, 'name')),\n }\n }),\n }\n\n const parsed = Object.assign(pick(ANY_CORE, OVERRIDABLE_FIELDS), ownProps, {\n type: ANY_CORE,\n })\n\n hiddenGetter(parsed, OWN_PROPS_NAME, ownProps)\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.of) {\n throw new Error('Cannot override `of` property of subtypes of \"array\"')\n }\n const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import {pick} from 'lodash'\n\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst ARRAY_CORE = {\n name: 'array',\n type: null,\n jsonType: 'array',\n of: [],\n}\n\nexport const ArrayType = {\n get() {\n return ARRAY_CORE\n },\n extend(subTypeDef: any, createMemberType: any) {\n const parsed = Object.assign(pick(ARRAY_CORE, OVERRIDABLE_FIELDS), subTypeDef, {\n type: ARRAY_CORE,\n })\n lazyGetter(parsed, 'of', () => {\n return subTypeDef.of.map((ofTypeDef: any) => {\n return createMemberType(ofTypeDef)\n })\n })\n lazyGetter(parsed, OWN_PROPS_NAME, () => ({...subTypeDef, of: parsed.of}), {\n enumerable: false,\n writable: false,\n })\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.of) {\n throw new Error('Cannot override `of` property of subtypes of \"array\"')\n }\n const ownProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, ownProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, ownProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","export function warnIfPreviewOnOptions(type: any) {\n if (type.options && type.options.preview) {\n console.warn(`Heads up! The preview config is no longer defined on \"options\", but instead on the type/field itself.\nPlease move {options: {preview: ...}} to {..., preview: ...} on the type/field definition of \"${type.name}\".\n`)\n }\n}\n\nexport function warnIfPreviewHasFields(type: any) {\n const preview = type.preview || (type.options || {}).preview\n if (preview && 'fields' in preview) {\n console.warn(`Heads up! \"preview.fields\" should be renamed to \"preview.select\". Please update the preview config for \"${type.name}\".\n`)\n }\n}\n","import {pick} from 'lodash'\n\nfunction isEmpty(object: any) {\n for (const key in object) {\n if (object.hasOwnProperty(key)) {\n return false\n }\n }\n return true\n}\n\nfunction _stringify(value: any, options: any, depth: any): any {\n if (depth > options.maxDepth) {\n return '...'\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '[empty]'\n }\n const capLength = Math.max(value.length - options.maxBreadth)\n const asString: any = value\n .slice(0, options.maxBreadth)\n .map((item, index) => _stringify(item, options, depth + 1))\n .concat(capLength > 0 ? `…+${capLength}` : [])\n .join(', ')\n\n return depth === 0 ? asString : `[${asString}]`\n }\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value).filter(\n (key) => !options.ignoreKeys.includes(key) && typeof value[key] !== 'undefined',\n )\n\n if (isEmpty(pick(value, keys))) {\n return '{empty}'\n }\n\n const asString = keys\n .slice(0, options.maxBreadth)\n .map((key) => `${key}: ${_stringify(value[key], options, depth + 1)}`)\n .join(', ')\n\n return depth === 0 ? asString : `{${asString}}`\n }\n const asString = String(value)\n return asString === '' ? '\"\"' : asString\n}\n\nexport default function stringify(\n value: any,\n options: {maxDepth?: number; maxBreadth?: number; ignoreKeys?: string[]} = {},\n) {\n const opts = {\n maxDepth: 'maxDepth' in options ? options.maxDepth : 2,\n maxBreadth: 'maxBreadth' in options ? options.maxBreadth : 2,\n ignoreKeys: 'ignoreKeys' in options ? options.ignoreKeys : [],\n }\n return _stringify(value, opts, 0)\n}\n","import {pick} from 'lodash'\n\nimport stringify from './JSONStringifyHuman'\n\nconst OPTIONS = {\n maxEntries: 2,\n maxDepth: 2,\n maxBreadth: 2,\n ignoreKeys: ['_id', '_type', '_key', '_ref'],\n}\n\nexport function createFallbackPrepare(fieldNames: any) {\n return (value: any) => ({\n title: stringify(pick(value, fieldNames), OPTIONS),\n })\n}\n","type FieldDef = {\n type: string\n name: string\n of?: {type: string}[]\n}\n\nexport function isBlockField(field: FieldDef): boolean {\n return (\n (field.type === 'array' && field.of && field.of.some((member) => member.type === 'block')) ||\n false\n )\n}\n","import arrify from 'arrify'\nimport {isUndefined, omitBy} from 'lodash'\n\nimport {createFallbackPrepare} from './fallbackPrepare'\nimport {isBlockField} from './portableText'\n\nconst TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']\nconst DESCRIPTION_CANDIDATES = ['description', ...TITLE_CANDIDATES]\n\nfunction fieldHasReferenceTo(fieldDef: any, refType: any) {\n return arrify(fieldDef.to || []).some((memberTypeDef: any) => memberTypeDef.type === refType)\n}\n\nfunction isImageAssetField(fieldDef: any) {\n return fieldHasReferenceTo(fieldDef, 'sanity.imageAsset')\n}\n\nfunction resolveImageAssetPath(typeDef: any) {\n const fields = typeDef.fields || []\n const imageAssetField = fields.find(isImageAssetField)\n if (imageAssetField) {\n return imageAssetField.name\n }\n const fieldWithImageAsset = fields.find((fieldDef: any) =>\n (fieldDef.fields || []).some(isImageAssetField),\n )\n\n return fieldWithImageAsset ? `${fieldWithImageAsset.name}.asset` : undefined\n}\n\nfunction isFileAssetField(fieldDef: any) {\n return fieldHasReferenceTo(fieldDef, 'sanity.fileAsset')\n}\n\nfunction resolveFileAssetPath(typeDef: any) {\n const fields = typeDef.fields || []\n const assetField = fields.find(isFileAssetField)\n if (assetField) {\n return assetField.name\n }\n const fieldWithFileAsset = fields.find((fieldDef: any) =>\n (fieldDef.fields || []).some(isFileAssetField),\n )\n return fieldWithFileAsset ? `${fieldWithFileAsset.name}.asset` : undefined\n}\n\nexport default function guessPreviewFields(rawObjectTypeDef: any) {\n const objectTypeDef = {fields: [], ...rawObjectTypeDef}\n\n const stringFieldNames = objectTypeDef.fields\n .filter((field: any) => field.type === 'string')\n .map((field: any) => field.name)\n\n const blockFieldNames = objectTypeDef.fields.filter(isBlockField).map((field: any) => field.name)\n\n // Check if we have fields with names that is listed in candidate fields\n let titleField = TITLE_CANDIDATES.find(\n (candidate) => stringFieldNames.includes(candidate) || blockFieldNames.includes(candidate),\n )\n\n let descField = DESCRIPTION_CANDIDATES.find(\n (candidate) =>\n candidate !== titleField &&\n (stringFieldNames.includes(candidate) || blockFieldNames.includes(candidate)),\n )\n\n if (!titleField) {\n // Pick first defined string field\n titleField = stringFieldNames[0] || blockFieldNames[0]\n // Pick next as desc\n descField = stringFieldNames[1] || blockFieldNames[1]\n }\n\n const mediaField = objectTypeDef.fields.find((field: any) => field.type === 'image')\n\n const imageAssetPath = resolveImageAssetPath(objectTypeDef)\n\n if (!titleField) {\n const fileAssetPath = resolveFileAssetPath(objectTypeDef)\n if (fileAssetPath) {\n titleField = `${fileAssetPath}.originalFilename`\n }\n if (imageAssetPath) {\n titleField = `${imageAssetPath}.originalFilename`\n }\n }\n\n if (!titleField && !imageAssetPath) {\n // last resort, pick all fields and concat them\n const fieldNames = objectTypeDef.fields.map((field: any) => field.name)\n const fieldMapping = fieldNames.reduce((acc: any, fieldName: any) => {\n acc[fieldName] = fieldName\n return acc\n }, {})\n\n return {\n select: fieldMapping,\n prepare: createFallbackPrepare(fieldNames),\n }\n }\n\n const select = omitBy(\n {\n title: titleField,\n description: descField,\n media: mediaField ? mediaField.name : imageAssetPath,\n },\n isUndefined,\n )\n\n return {\n select: select,\n }\n}\n","import {pick} from 'lodash'\n\nimport {warnIfPreviewHasFields, warnIfPreviewOnOptions} from './deprecationUtils'\nimport guessPreviewConfig from './guessPreviewConfig'\n\nfunction parseSelection(selection: any) {\n return selection.reduce((acc: any, field: any) => {\n acc[field] = field\n return acc\n }, {})\n}\n\nfunction parsePreview(preview: any) {\n if (!preview) {\n return preview\n }\n const select = preview.select || preview.fields || {}\n if (Array.isArray(select)) {\n return {\n ...pick(preview, ['prepare', 'component']),\n select: parseSelection(select),\n }\n }\n return {\n ...pick(preview, ['prepare', 'component']),\n select,\n }\n}\n\nexport default function createPreviewGetter(objectTypeDef: any) {\n return function previewGetter() {\n warnIfPreviewOnOptions(objectTypeDef)\n warnIfPreviewHasFields(objectTypeDef)\n const preview = parsePreview(objectTypeDef.preview || (objectTypeDef.options || {}).preview)\n return preview || guessPreviewConfig(objectTypeDef)\n }\n}\n","export const DEFAULT_LINK_ANNOTATION = {\n type: 'object',\n name: 'link',\n title: 'Link',\n i18nTitleKey: 'inputs.portable-text.annotation.link',\n options: {\n modal: {type: 'popover'},\n },\n fields: [\n {\n name: 'href',\n type: 'url',\n title: 'Link',\n description: 'A valid web, email, phone, or relative link.',\n validation: (Rule: any) =>\n Rule.uri({\n scheme: ['http', 'https', 'tel', 'mailto'],\n allowRelative: true,\n }),\n },\n ],\n}\n\nexport const DEFAULT_TEXT_FIELD = {\n type: 'text',\n name: 'text',\n title: 'Text',\n}\n\nexport const DEFAULT_MARKS_FIELD = {\n name: 'marks',\n type: 'array',\n of: [{type: 'string'}],\n title: 'Marks',\n}\n\nexport const LIST_TYPES = {\n bullet: {\n title: 'Bulleted list',\n value: 'bullet',\n i18nTitleKey: 'inputs.portable-text.list-type.bullet',\n },\n numbered: {\n title: 'Numbered list',\n value: 'number',\n i18nTitleKey: 'inputs.portable-text.list-type.number',\n },\n}\n\nexport const DEFAULT_LIST_TYPES = [LIST_TYPES.bullet, LIST_TYPES.numbered]\n\nexport const BLOCK_STYLES = {\n normal: {title: 'Normal', value: 'normal', i18nTitleKey: 'inputs.portable-text.style.normal'},\n h1: {title: 'Heading 1', value: 'h1', i18nTitleKey: 'inputs.portable-text.style.h1'},\n h2: {title: 'Heading 2', value: 'h2', i18nTitleKey: 'inputs.portable-text.style.h2'},\n h3: {title: 'Heading 3', value: 'h3', i18nTitleKey: 'inputs.portable-text.style.h3'},\n h4: {title: 'Heading 4', value: 'h4', i18nTitleKey: 'inputs.portable-text.style.h4'},\n h5: {title: 'Heading 5', value: 'h5', i18nTitleKey: 'inputs.portable-text.style.h5'},\n h6: {title: 'Heading 6', value: 'h6', i18nTitleKey: 'inputs.portable-text.style.h6'},\n blockquote: {\n title: 'Quote',\n value: 'blockquote',\n i18nTitleKey: 'inputs.portable-text.style.quote',\n },\n}\n\nexport const DEFAULT_BLOCK_STYLES = [\n BLOCK_STYLES.normal,\n BLOCK_STYLES.h1,\n BLOCK_STYLES.h2,\n BLOCK_STYLES.h3,\n BLOCK_STYLES.h4,\n BLOCK_STYLES.h5,\n BLOCK_STYLES.h6,\n BLOCK_STYLES.blockquote,\n]\n\nexport const DECORATOR_STRONG = {\n title: 'Strong',\n value: 'strong',\n i18nTitleKey: 'inputs.portable-text.decorator.strong',\n}\nexport const DECORATOR_EMPHASIS = {\n title: 'Italic',\n value: 'em',\n i18nTitleKey: 'inputs.portable-text.decorator.emphasis',\n}\nexport const DECORATOR_CODE = {\n title: 'Code',\n value: 'code',\n i18nTitleKey: 'inputs.portable-text.decorator.code',\n}\nexport const DECORATOR_UNDERLINE = {\n title: 'Underline',\n value: 'underline',\n i18nTitleKey: 'inputs.portable-text.decorator.underline',\n}\nexport const DECORATOR_STRIKE = {\n title: 'Strike',\n value: 'strike-through',\n i18nTitleKey: 'inputs.portable-text.decorator.strike-through',\n}\n\nexport const DECORATORS = {\n strong: DECORATOR_STRONG,\n em: DECORATOR_EMPHASIS,\n code: DECORATOR_CODE,\n underline: DECORATOR_UNDERLINE,\n strikeThrough: DECORATOR_STRIKE,\n}\n\nexport const DEFAULT_DECORATORS = [\n DECORATORS.strong,\n DECORATORS.em,\n DECORATORS.code,\n DECORATORS.underline,\n DECORATORS.strikeThrough,\n]\n","import {pick} from 'lodash'\n\nimport createPreviewGetter from '../../preview/createPreviewGetter'\nimport {OWN_PROPS_NAME} from '../constants'\nimport {hiddenGetter, lazyGetter} from '../utils'\nimport {\n BLOCK_STYLES,\n DEFAULT_BLOCK_STYLES,\n DEFAULT_DECORATORS,\n DEFAULT_LINK_ANNOTATION,\n DEFAULT_LIST_TYPES,\n DEFAULT_MARKS_FIELD,\n DEFAULT_TEXT_FIELD,\n} from './defaults'\n\nconst INHERITED_FIELDS = [\n 'type',\n 'name',\n 'title',\n 'jsonType',\n 'description',\n 'options',\n 'fieldsets',\n 'icon',\n]\n\nconst BLOCK_CORE = {\n name: 'block',\n title: 'Block',\n type: null,\n jsonType: 'object',\n}\n\nconst DEFAULT_OPTIONS = {}\n\nexport const BlockType = {\n get() {\n return BLOCK_CORE\n },\n extend(subTypeDef: any, extendMember: any) {\n const options = {...(subTypeDef.options || DEFAULT_OPTIONS)}\n\n const {marks, styles, lists, of, ...rest} = subTypeDef\n\n const childrenField = createChildrenField(marks, of)\n const styleField = createStyleField(styles)\n const listItemField = createListItemField(lists)\n\n const markDefsField = {\n name: 'markDefs',\n title: 'Mark definitions',\n type: 'array',\n of: marks?.annotations || DEFAULT_ANNOTATIONS,\n }\n\n const levelField = {\n name: 'level',\n title: 'Indentation',\n type: 'number',\n }\n\n // NOTE: if you update this (EVEN THE ORDER OF FIELDS) you _NEED TO_ also\n // update `BlockSchemaType`, `isBlockSchemaType` and similar in `@sanity/types`\n const fields = [childrenField, styleField, listItemField, markDefsField, levelField].concat(\n subTypeDef.fields || [],\n )\n\n const ownProps = {...rest, options}\n\n const parsed = Object.assign(pick(BLOCK_CORE, INHERITED_FIELDS), ownProps, {\n type: BLOCK_CORE,\n })\n\n lazyGetter(parsed, 'fields', () => {\n return fields.map((fieldDef) => {\n const {name, ...type} = fieldDef\n return {\n name: name,\n type: extendMember(type),\n }\n })\n })\n\n lazyGetter(parsed, 'preview', createPreviewGetter(subTypeDef))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...ownProps,\n fields: parsed.fields,\n preview: parsed.preview,\n }),\n {enumerable: false, writable: false},\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.fields) {\n throw new Error('Cannot override `fields` of subtypes of \"block\"')\n }\n const subOwnProps = pick(extensionDef, INHERITED_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n\nfunction ensureNormalStyle(styles: any) {\n return styles.some((style: any) => style.value === 'normal')\n ? styles\n : [BLOCK_STYLES.normal, ...styles]\n}\n\nfunction createStyleField(styles: any) {\n return {\n name: 'style',\n title: 'Style',\n type: 'string',\n options: {\n list: ensureNormalStyle(styles || DEFAULT_BLOCK_STYLES),\n },\n }\n}\n\nfunction createListItemField(lists: any) {\n return {\n name: 'listItem',\n title: 'List type',\n type: 'string',\n options: {\n list: lists || DEFAULT_LIST_TYPES,\n },\n }\n}\n\nconst DEFAULT_ANNOTATIONS = [DEFAULT_LINK_ANNOTATION]\n\nfunction createChildrenField(marks: any, of = []) {\n return {\n name: 'children',\n title: 'Content',\n type: 'array',\n of: [\n {\n type: 'span',\n fields: [DEFAULT_TEXT_FIELD, DEFAULT_MARKS_FIELD],\n annotations: marks && marks.annotations ? marks.annotations : DEFAULT_ANNOTATIONS,\n decorators: marks && marks.decorators ? marks.decorators : DEFAULT_DECORATORS,\n },\n ...of.filter((memberType: any) => memberType.type !== 'span'),\n ],\n }\n}\n","import {pick} from 'lodash'\n\nimport createPreviewGetter from '../../preview/createPreviewGetter'\nimport {OWN_PROPS_NAME} from '../constants'\nimport {hiddenGetter, lazyGetter} from '../utils'\n\nconst INHERITED_FIELDS = [\n 'type',\n 'name',\n 'title',\n 'jsonType',\n 'description',\n 'options',\n 'fieldsets',\n 'icon',\n]\n\nconst SPAN_CORE = {\n name: 'span',\n title: 'Span',\n type: null,\n jsonType: 'object',\n}\n\nconst MARKS_FIELD = {\n name: 'marks',\n title: 'Marks',\n type: 'array',\n of: [{type: 'string'}],\n}\n\nconst TEXT_FIELD = {\n name: 'text',\n title: 'Text',\n type: 'string',\n}\n\nconst DEFAULT_OPTIONS = {}\n\nexport const SpanType = {\n get() {\n return SPAN_CORE\n },\n extend(subTypeDef: any, extendMember: any) {\n const options = {...(subTypeDef.options || DEFAULT_OPTIONS)}\n\n const {annotations = [], marks = []} = subTypeDef\n\n // NOTE: if you update this please also update `SpanSchemaType` in`@sanity/types`\n const fields = [MARKS_FIELD, TEXT_FIELD]\n\n const ownProps = {...subTypeDef, options}\n\n const parsed = Object.assign(pick(SPAN_CORE, INHERITED_FIELDS), ownProps, {\n type: SPAN_CORE,\n })\n\n lazyGetter(parsed, 'fields', () => {\n return fields.map((fieldDef) => {\n const {name, ...type} = fieldDef\n return {\n name: name,\n type: extendMember(type),\n }\n })\n })\n\n lazyGetter(parsed, 'annotations', () => annotations.map(extendMember))\n lazyGetter(parsed, 'marks', () => marks.map(extendMember))\n\n lazyGetter(parsed, 'preview', createPreviewGetter(subTypeDef))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...ownProps,\n fields: parsed.fields,\n annotations: parsed.annotations,\n marks: parsed.marks,\n preview: parsed.preview,\n }),\n {enumerable: false, writable: false},\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.fields) {\n throw new Error('Cannot override `fields` of subtypes of \"span\"')\n }\n const subOwnProps = pick(extensionDef, INHERITED_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","export default {\n prepare: (val: any) => ({title: String(val)}),\n}\n","import {pick} from 'lodash'\n\nimport primitivePreview from '../preview/primitivePreview'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst BOOLEAN_CORE = {\n name: 'boolean',\n title: 'Boolean',\n type: null,\n jsonType: 'boolean',\n}\n\nexport const BooleanType = {\n get() {\n return BOOLEAN_CORE\n },\n extend(subTypeDef: any) {\n const ownProps = {\n ...subTypeDef,\n preview: primitivePreview,\n }\n const parsed = Object.assign(pick(BOOLEAN_CORE, OVERRIDABLE_FIELDS), ownProps, {\n type: BOOLEAN_CORE,\n })\n\n hiddenGetter(parsed, OWN_PROPS_NAME, ownProps)\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import arrify from 'arrify'\nimport {capitalize, pick} from 'lodash'\n\nimport {resolveSearchConfigForBaseFieldPaths} from '../searchConfig/resolve'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nexport const REF_FIELD = {\n name: '_ref',\n title: 'Referenced document ID',\n type: 'string',\n}\n\nexport const WEAK_FIELD = {\n name: '_weak',\n title: 'Weak reference marker',\n type: 'boolean',\n}\n\nconst DATASET_FIELD = {\n name: '_dataset',\n title: 'Target dataset',\n type: 'string',\n}\n\nconst PROJECT_ID_FIELD = {\n name: '_projectId',\n title: 'Target project ID',\n type: 'string',\n hidden: true,\n}\n\nconst REFERENCE_FIELDS = [REF_FIELD, WEAK_FIELD, DATASET_FIELD, PROJECT_ID_FIELD]\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst CROSS_DATASET_REFERENCE_CORE = {\n name: 'crossDatasetReference',\n type: null,\n jsonType: 'object',\n}\n\nfunction humanize(arr: any, conjunction: any) {\n const len = arr.length\n if (len === 1) {\n return arr[0]\n }\n const first = arr.slice(0, len - 1)\n const last = arr[len - 1]\n return `${first.join(', ')} ${conjunction} ${last}`\n}\n\nfunction buildTitle(type: any) {\n if (!type.to || type.to.length === 0) {\n return 'Cross dataset Reference'\n }\n return `Cross dataset reference to ${humanize(\n arrify(type.to).map((toType: any) => toType.title || capitalize(toType.type)),\n 'or',\n ).toLowerCase()}`\n}\n\nexport const CrossDatasetReferenceType = {\n get() {\n return CROSS_DATASET_REFERENCE_CORE\n },\n extend(subTypeDef: any, createMemberType: any) {\n if (!subTypeDef.to) {\n throw new Error(\n `Missing \"to\" field in cross dataset reference definition. Check the type ${subTypeDef.name}`,\n )\n }\n const parsed = Object.assign(\n pick(CROSS_DATASET_REFERENCE_CORE, OVERRIDABLE_FIELDS),\n subTypeDef,\n {\n type: CROSS_DATASET_REFERENCE_CORE,\n },\n )\n\n lazyGetter(parsed, 'fields', () => {\n return REFERENCE_FIELDS.map((fieldDef) => {\n const {name, ...type} = fieldDef\n return {\n name: name,\n type: createMemberType(type),\n }\n })\n })\n\n lazyGetter(parsed, 'to', () => {\n return arrify(subTypeDef.to).map((toType: any) => {\n return {\n ...toType,\n // eslint-disable-next-line camelcase\n __experimental_search: resolveSearchConfigForBaseFieldPaths(toType),\n }\n })\n })\n\n lazyGetter(parsed, 'title', () => subTypeDef.title || buildTitle(parsed))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...subTypeDef,\n fields: parsed.fields,\n to: parsed.to,\n title: parsed.title,\n }),\n {enumerable: false, writable: false},\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.of) {\n throw new Error('Cannot override `of` of subtypes of \"reference\"')\n }\n const ownProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, ownProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, ownProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import {pick} from 'lodash'\n\nimport primitivePreview from '../preview/primitivePreview'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst DATE_CORE = {\n name: 'date',\n title: 'Datetime',\n type: null,\n jsonType: 'string',\n}\n\nexport const DateType = {\n get() {\n return DATE_CORE\n },\n extend(subTypeDef: any) {\n const ownProps = {\n ...subTypeDef,\n preview: primitivePreview,\n }\n const parsed = Object.assign(pick(DATE_CORE, OVERRIDABLE_FIELDS), ownProps, {\n type: DATE_CORE,\n })\n\n hiddenGetter(parsed, OWN_PROPS_NAME, ownProps)\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import {pick} from 'lodash'\n\nimport primitivePreview from '../preview/primitivePreview'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst DATETIME_CORE = {\n name: 'datetime',\n title: 'Datetime',\n type: null,\n jsonType: 'string',\n}\n\nexport const DateTimeType = {\n get() {\n return DATETIME_CORE\n },\n extend(subTypeDef: any) {\n const ownProps = {\n ...subTypeDef,\n preview: primitivePreview,\n }\n const parsed = Object.assign(pick(DATETIME_CORE, OVERRIDABLE_FIELDS), ownProps, {\n type: DATETIME_CORE,\n })\n hiddenGetter(parsed, OWN_PROPS_NAME, ownProps)\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import {type SortOrdering} from '@sanity/types'\nimport {capitalize, startCase} from 'lodash'\n\nconst CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption', 'description']\n\nconst PRIMITIVES = ['string', 'boolean', 'number']\n\nconst isPrimitive = (field: any) => PRIMITIVES.includes(field.type)\n\nexport default function guessOrderingConfig(objectTypeDef: any): SortOrdering[] {\n let candidates = CANDIDATES.filter((candidate) =>\n objectTypeDef.fields.some((field: any) => isPrimitive(field) && field.name === candidate),\n )\n\n // None of the candidates were found, fallback to all fields\n if (candidates.length === 0) {\n candidates = objectTypeDef.fields.filter(isPrimitive).map((field: any) => field.name)\n }\n\n return candidates.map(\n (name): SortOrdering => ({\n name: name,\n i18n: {\n title: {key: `default-orderings.${name}`, ns: 'studio'},\n },\n title: capitalize(startCase(name)),\n by: [{field: name, direction: 'asc'}],\n }),\n )\n}\n","import {isPlainObject, toPath} from 'lodash'\n\nexport function normalizeSearchConfigs(configs: any) {\n if (!Array.isArray(configs)) {\n throw new Error(\n 'The search config of a document type must be an array of search config objects',\n )\n }\n return configs.map((conf) => {\n if (conf === 'defaults') {\n return conf\n }\n if (!isPlainObject(conf)) {\n throw new Error('Search config must be an object of {path: string, weight: number}')\n }\n return {\n weight: 'weight' in conf ? conf.weight : 1,\n path: toPath(conf.path),\n mapWith: typeof conf.mapWith === 'string' ? conf.mapWith : undefined,\n }\n })\n}\n","import {\n type FieldGroup,\n type FieldGroupDefinition,\n type Fieldset,\n type FieldsetDefinition,\n type ObjectDefinition,\n type ObjectField,\n} from '@sanity/types'\nimport {castArray, flatMap, pick, startCase} from 'lodash'\n\nimport guessOrderingConfig from '../ordering/guessOrderingConfig'\nimport createPreviewGetter from '../preview/createPreviewGetter'\nimport {normalizeSearchConfigs} from '../searchConfig/normalize'\nimport {resolveSearchConfig} from '../searchConfig/resolve'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [\n ...DEFAULT_OVERRIDEABLE_FIELDS,\n 'orderings',\n '__experimental_search',\n 'blockEditor',\n 'icon',\n]\n\nexport const ObjectType = {\n get() {\n return {\n name: 'object',\n title: 'Object',\n type: null,\n jsonType: 'object',\n }\n },\n extend(rawSubTypeDef: any, createMemberType: any) {\n const subTypeDef = {fields: [], ...rawSubTypeDef}\n\n const options = {...subTypeDef.options}\n\n const ownProps = {\n ...subTypeDef,\n title: subTypeDef.title || (subTypeDef.name ? startCase(subTypeDef.name) : 'Object'),\n options: options,\n orderings: subTypeDef.orderings || guessOrderingConfig(subTypeDef),\n fields: subTypeDef.fields.map((fieldDef: any) => {\n const {name, fieldset, group, ...rest} = fieldDef\n\n const compiledField = {\n name,\n group,\n fieldset,\n }\n\n return lazyGetter(compiledField, 'type', () => {\n return createMemberType({\n ...rest,\n title: fieldDef.title || startCase(name),\n })\n })\n }),\n }\n\n const parsed = Object.assign(pick(this.get(), OVERRIDABLE_FIELDS), ownProps, {\n type: this.get(),\n })\n\n lazyGetter(parsed, 'fieldsets', () => {\n return createFieldsets(subTypeDef, parsed.fields)\n })\n\n lazyGetter(parsed, 'groups', () => {\n return createFieldsGroups(subTypeDef, parsed.fields)\n })\n\n lazyGetter(parsed, 'preview', createPreviewGetter(subTypeDef))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...ownProps,\n preview: parsed.preview,\n }),\n {enumerable: false, writable: false},\n )\n\n lazyGetter(\n parsed,\n '__experimental_search',\n () => {\n const userProvidedSearchConfig = subTypeDef.__experimental_search\n ? normalizeSearchConfigs(subTypeDef.__experimental_search)\n : null\n\n if (userProvidedSearchConfig) {\n return userProvidedSearchConfig.map((entry) =>\n entry === 'defaults' ? normalizeSearchConfigs(subTypeDef) : entry,\n )\n }\n return resolveSearchConfig(parsed)\n },\n {\n enumerable: false,\n },\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.fields) {\n throw new Error('Cannot override `fields` of subtypes of \"object\"')\n }\n\n const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n subOwnProps.title =\n extensionDef.title ||\n subTypeDef.title ||\n (subTypeDef.name ? startCase(subTypeDef.name) : 'Object')\n\n const current = Object.assign({}, parent, pick(extensionDef, OVERRIDABLE_FIELDS), {\n type: parent,\n })\n lazyGetter(current, '__experimental_search', () => parent.__experimental_search)\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n\nexport function createFieldsets(typeDef: ObjectDefinition, fields: ObjectField[]): Fieldset[] {\n const fieldsetsByName: Record<string, FieldsetDefinition & {fields: ObjectField[]}> = {}\n\n for (const fieldset of typeDef.fieldsets || []) {\n if (fieldsetsByName[fieldset.name]) {\n throw new Error(\n `Duplicate fieldset name \"${fieldset.name}\" found for type '${\n typeDef.title ? typeDef.title : startCase(typeDef.name)\n }'`,\n )\n }\n\n fieldsetsByName[fieldset.name] = {title: startCase(fieldset.name), ...fieldset, fields: []}\n }\n\n const fieldsets = new Set<Fieldset>()\n\n for (const field of fields) {\n if (!field.fieldset) {\n fieldsets.add({single: true, field})\n continue\n }\n\n const fieldset = fieldsetsByName[field.fieldset]\n if (!fieldset) {\n throw new Error(\n `Fieldset '${field.fieldset}' is not defined in schema for type '${typeDef.name}'`,\n )\n }\n\n fieldset.fields.push(field)\n\n // The Set will prevent duplicates\n fieldsets.add(fieldset)\n }\n\n return Array.from(fieldsets)\n}\n\nfunction createFieldsGroups(typeDef: ObjectDefinition, fields: ObjectField[]): FieldGroup[] {\n const groupsByName: Record<string, FieldGroupDefinition & {fields: ObjectField[]}> = {}\n\n let numDefaultGroups = 0\n for (const group of typeDef.groups || []) {\n if (groupsByName[group.name]) {\n throw new Error(\n `Duplicate group name \"${group.name}\" found for type '${\n typeDef.title ? typeDef.title : startCase(typeDef.name)\n }'`,\n )\n }\n\n groupsByName[group.name] = {title: startCase(group.name), ...group, fields: []}\n\n if (group.default && ++numDefaultGroups > 1) {\n // Throw if you have multiple default field groups defined\n throw new Error(\n `More than one field group defined as default for type '${\n typeDef.title ? typeDef.title : startCase(typeDef.name)\n }' - only 1 is supported`,\n )\n }\n }\n\n fields.forEach((field) => {\n const fieldGroupNames = castArray(field.group || [])\n if (fieldGroupNames.length === 0) {\n return\n }\n\n fieldGroupNames.forEach((fieldGroupName) => {\n const currentGroup = groupsByName[fieldGroupName]\n\n if (!currentGroup) {\n throw new Error(\n `Field group '${fieldGroupName}' is not defined in schema for type '${\n typeDef.title ? typeDef.name : startCase(typeDef.name)\n }'`,\n )\n }\n\n currentGroup.fields.push(field)\n })\n })\n\n return flatMap(groupsByName).filter((group) => group.fields.length > 0)\n}\n","import {ObjectType} from './object'\n\nconst DOCUMENT_CORE = {\n name: 'document',\n title: 'Document',\n type: null,\n jsonType: 'object',\n}\n\nexport const DocumentType = {\n get() {\n return DOCUMENT_CORE\n },\n extend: ObjectType.extend,\n}\n","import {pick} from 'lodash'\n\nimport primitivePreview from '../preview/primitivePreview'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst EMAIL_CORE = {\n name: 'email',\n title: 'Email',\n type: null,\n jsonType: 'string',\n}\n\nlazyGetter(\n EMAIL_CORE,\n OWN_PROPS_NAME,\n () => ({\n ...EMAIL_CORE,\n validation: (Rule: any) => Rule.email(),\n }),\n {enumerable: false},\n)\n\nexport const EmailType = {\n get() {\n return EMAIL_CORE\n },\n extend(subTypeDef: any) {\n const ownProps = {\n ...subTypeDef,\n preview: primitivePreview,\n }\n const parsed = Object.assign(pick(EMAIL_CORE, OVERRIDABLE_FIELDS), ownProps, {\n type: EMAIL_CORE,\n })\n hiddenGetter(parsed, OWN_PROPS_NAME, ownProps)\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, subOwnProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, subOwnProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import {pick, startCase} from 'lodash'\n\nimport createPreviewGetter from '../preview/createPreviewGetter'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {createFieldsets} from './object'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nexport const ASSET_FIELD = {\n name: 'asset',\n type: 'reference',\n to: {type: 'sanity.fileAsset'},\n}\n\nexport const MEDIA_LIBRARY_ASSET_FIELD = {\n name: 'media',\n type: 'globalDocumentReference',\n hidden: true,\n to: [{type: 'sanity.asset'}],\n}\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst FILE_CORE = {\n name: 'file',\n title: 'File',\n type: null,\n jsonType: 'object',\n}\n\nconst DEFAULT_OPTIONS = {\n accept: '',\n}\n\nexport const FileType = {\n get() {\n return FILE_CORE\n },\n extend(rawSubTypeDef: any, createMemberType: any) {\n const options = {...(rawSubTypeDef.options || DEFAULT_OPTIONS)}\n\n const fields = [ASSET_FIELD, MEDIA_LIBRARY_ASSET_FIELD, ...(rawSubTypeDef.fields || [])]\n\n const subTypeDef = {...rawSubTypeDef, fields}\n\n const parsed = Object.assign(pick(FILE_CORE, OVERRIDABLE_FIELDS), subTypeDef, {\n type: FILE_CORE,\n title: subTypeDef.title || (subTypeDef.name ? startCase(subTypeDef.name) : FILE_CORE.title),\n options: options,\n fields: subTypeDef.fields.map((fieldDef: any) => {\n const {name, fieldset, ...rest} = fieldDef\n\n const compiledField = {\n name,\n fieldset,\n isCustomized: Boolean(rawSubTypeDef.fields),\n }\n\n return lazyGetter(compiledField, 'type', () => {\n return createMemberType({\n ...rest,\n title: fieldDef.title || startCase(name),\n })\n })\n }),\n })\n\n lazyGetter(parsed, 'fieldsets', () => {\n return createFieldsets(subTypeDef, parsed.fields)\n })\n\n lazyGetter(parsed, 'preview', createPreviewGetter(Object.assign({}, subTypeDef, {fields})))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...subTypeDef,\n options,\n fields: parsed.fields,\n title: parsed.title,\n fieldsets: parsed.fieldsets,\n preview: parsed.preview,\n }),\n {enumerable: false, writable: false},\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.fields) {\n throw new Error('Cannot override `fields` of subtypes of \"file\"')\n }\n const ownProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, ownProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, ownProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import arrify from 'arrify'\nimport {pick} from 'lodash'\n\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nexport const REF_FIELD = {\n name: '_ref',\n title: 'Referenced document ID',\n type: 'string',\n}\n\nexport const WEAK_FIELD = {\n name: '_weak',\n title: 'Weak reference',\n type: 'boolean',\n}\n\nconst REFERENCE_FIELDS = [REF_FIELD, WEAK_FIELD]\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst GLOBAL_DOCUMENT_REFERENCE_CORE = {\n name: 'globalDocumentReference',\n title: 'Global Document Reference',\n type: null,\n jsonType: 'object',\n}\n\nfunction humanize(arr: any, conjunction: any) {\n const len = arr.length\n if (len === 1) {\n return arr[0]\n }\n const first = arr.slice(0, len - 1)\n const last = arr[len - 1]\n return `${first.join(', ')} ${conjunction} ${last}`\n}\n\nfunction buildTitle(type: any) {\n if (!type.to || type.to.length === 0) {\n return 'Global Document Reference'\n }\n return `Global Document Reference to ${humanize(\n arrify(type.to).map((toType: any) => toType.title),\n 'or',\n ).toLowerCase()}`\n}\n\nexport const GlobalDocumentReferenceType = {\n get() {\n return GLOBAL_DOCUMENT_REFERENCE_CORE\n },\n extend(subTypeDef: any, createMemberType: any) {\n if (!subTypeDef.to) {\n throw new Error(\n `Missing \"to\" field in global document reference definition. Check the type ${subTypeDef.name}`,\n )\n }\n const parsed = Object.assign(\n pick(GLOBAL_DOCUMENT_REFERENCE_CORE, OVERRIDABLE_FIELDS),\n subTypeDef,\n {\n type: GLOBAL_DOCUMENT_REFERENCE_CORE,\n },\n )\n\n lazyGetter(parsed, 'fields', () => {\n return REFERENCE_FIELDS.map((fieldDef) => {\n const {name, ...type} = fieldDef\n return {\n name: name,\n type: createMemberType(type),\n }\n })\n })\n\n lazyGetter(parsed, 'to', () => {\n return arrify(subTypeDef.to).map((toType: any) => {\n return {\n ...toType,\n }\n })\n })\n\n lazyGetter(parsed, 'title', () => subTypeDef.title || buildTitle(parsed))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...subTypeDef,\n fields: parsed.fields,\n to: parsed.to,\n title: parsed.title,\n }),\n {enumerable: false, writable: false},\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.of) {\n throw new Error('Cannot override `of` of subtypes of \"globalDocumentReference\"')\n }\n const ownProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, ownProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, ownProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","export const ASSET_FIELD = {\n name: 'asset',\n type: 'reference',\n to: [{type: 'sanity.imageAsset'}],\n}\n\nexport const HOTSPOT_FIELD = {\n name: 'hotspot',\n type: 'sanity.imageHotspot',\n}\n\nexport const CROP_FIELD = {\n name: 'crop',\n type: 'sanity.imageCrop',\n}\n\nexport const MEDIA_LIBRARY_ASSET_FIELD = {\n name: 'media',\n type: 'globalDocumentReference',\n hidden: true,\n to: [{type: 'sanity.asset'}],\n}\n","import {pick, startCase} from 'lodash'\n\nimport createPreviewGetter from '../preview/createPreviewGetter'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {ASSET_FIELD, CROP_FIELD, HOTSPOT_FIELD, MEDIA_LIBRARY_ASSET_FIELD} from './image/fieldDefs'\nimport {createFieldsets} from './object'\nimport {hiddenGetter, lazyGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst IMAGE_CORE = {\n name: 'image',\n title: 'Image',\n type: null,\n jsonType: 'object',\n}\n\nconst DEFAULT_OPTIONS = {}\n\nexport const ImageType = {\n get() {\n return IMAGE_CORE\n },\n extend(rawSubTypeDef: any, createMemberType: any) {\n const options = {...(rawSubTypeDef.options || DEFAULT_OPTIONS)}\n\n let hotspotFields = [HOTSPOT_FIELD, CROP_FIELD]\n if (!options.hotspot) {\n hotspotFields = hotspotFields.map((field) => ({...field, hidden: true}))\n }\n\n const fields = [\n ASSET_FIELD,\n MEDIA_LIBRARY_ASSET_FIELD,\n ...hotspotFields,\n ...(rawSubTypeDef.fields || []),\n ]\n const subTypeDef = {...rawSubTypeDef, fields}\n\n const parsed = Object.assign(pick(this.get(), OVERRIDABLE_FIELDS), subTypeDef, {\n type: IMAGE_CORE,\n title: subTypeDef.title || (subTypeDef.name ? startCase(subTypeDef.name) : IMAGE_CORE.title),\n options: options,\n fields: subTypeDef.fields.map((fieldDef: any) => {\n const {name, fieldset, ...rest} = fieldDef\n\n const compiledField = {\n name,\n fieldset,\n isCustomized: Boolean(rawSubTypeDef.fields),\n }\n\n return lazyGetter(compiledField, 'type', () => {\n return createMemberType({\n ...rest,\n title: fieldDef.title || startCase(name),\n })\n })\n }),\n })\n\n lazyGetter(parsed, 'fieldsets', () => {\n return createFieldsets(subTypeDef, parsed.fields)\n })\n\n lazyGetter(parsed, 'preview', createPreviewGetter(Object.assign({}, subTypeDef, {fields})))\n\n lazyGetter(\n parsed,\n OWN_PROPS_NAME,\n () => ({\n ...subTypeDef,\n options,\n fields: parsed.fields,\n title: parsed.title,\n fieldsets: parsed.fieldsets,\n preview: parsed.preview,\n }),\n {enumerable: false, writable: false},\n )\n\n return subtype(parsed)\n\n function subtype(parent: any) {\n return {\n get() {\n return parent\n },\n extend: (extensionDef: any) => {\n if (extensionDef.fields) {\n throw new Error('Cannot override `fields` of subtypes of \"image\"')\n }\n const ownProps = pick(extensionDef, OVERRIDABLE_FIELDS)\n const current = Object.assign({}, parent, ownProps, {\n type: parent,\n })\n hiddenGetter(current, OWN_PROPS_NAME, ownProps)\n return subtype(current)\n },\n }\n }\n },\n}\n","import {pick} from 'lodash'\n\nimport primitivePreview from '../preview/primitivePreview'\nimport {DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME} from './constants'\nimport {hiddenGetter} from './utils'\n\nconst OVERRIDABLE_FIELDS = [...DEFAULT_OVERRIDEABLE_FIELDS]\n\nconst NUMBER_CORE = {\n name: 'number',\n title: 'Number',\n type: null,\n jsonType: 'number',\n}\n\nexport const NumberType = {\n get() {\n return NUMBER_CORE\n },\n extend(subTypeDef: any) {\n const ownProps = {\n ...subTypeDef,\n preview: primitivePreview,\n }\n\n const parsed = Object.assign(pick(NUMBER_CORE, OVERRIDABLE_FIELDS), ownProps, {\n type: NUMBER_CORE,\n })\n\n hiddenGetter(parsed, OWN_PROPS_NAME, ownP