@sanity/presets

1.0.71.0.8
dist/index.js.map
~dist/index.js.mapModified
+1−1
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["defineEvent","PresetsAddedInfo","presetNames","PresetsAdded","name","version","description","PresetsAdded","TelemetryLog","log","event","data","RegistryRecord","id","presets","Set","logged","registries","Map","registerRegistry","set","recordPresetUsage","registryId","identifier","get","add","collectPresetsRegistryTelemetry","telemetry","record","size","presetNames","resetRegistries","clear","useTelemetry","useEffect","ComponentType","InputProps","collectPresetsRegistryTelemetry","Props","registryId","userInput","PresetsTelemetryCollector","t0","$","_c","UserInput","props","telemetry","t1","t2","renderDefault","FieldDefinition","FieldDefinitionBase","IntrinsicTypeName","SchemaTypeDefinition","PartialSchemaDefinition","RegistryContext","getPreset","presetName","config","Record","ProhibitedProperties","SanitizeProperties","ExcludedProperties","PropertyKey","Omit","Properties","DerivedConfig","Context","AliasedType","LockedProperties","map","input","Key","UserConfig","PresetDefinition","name","identifier","schemaType","registry","definePresetType","preset","AnyPresetDefinition","defineField","defineType","definePresetType","ctaType","name","identifier","schemaType","config","registry","fields","objectConfig","type","getPreset","title","description","options","layout","list","preview","select","linkType","url","referenceTitle","referenceName","prepare","referenceLabel","subtitle","defineField","defineType","definePresetType","ImageTypeConfig","altText","caption","hotspot","imageType","name","identifier","schemaType","config","fields","imageConfig","type","options","title","description","validation","rule","warning","preview","select","defineField","defineType","definePresetType","LinkToEntry","type","LinkTypeConfig","to","normalizeToTargets","entries","map","entry","linkType","name","identifier","schemaType","fields","objectConfig","referenceTargets","title","description","initialValue","options","layout","list","value","hidden","parent","validation","rule","uri","scheme","preview","select","url","referenceTitle","referenceName","prepare","referenceLabel","subtitle","ALL_FIELDS_GROUP","ArrayDefinition","defineArrayMember","defineField","defineType","FieldDefinition","SchemaTypeDefinition","definePresetType","PageBuilderBlock","LookupArrayPreset","name","wrapArrayAsPageBuilderBlock","arraySchema","components","undefined","title","type","fields","of","toPageBuilderArrayMember","block","lookupArrayPreset","arrayPreset","defineLazyContentField","blocks","cached","ReturnType","description","group","map","PageTypeConfig","pageBuilderBlocks","createPageType","identifier","schemaType","config","registry","groups","documentConfig","hidden","default","validation","rule","required","options","source","getPreset","pageType","defineArrayMember","defineType","definePresetType","RichTextObjectsConfig","link","image","cta","RichTextTypeConfig","objects","resolveObjects","Required","undefined","richTextType","name","identifier","schemaType","config","registry","arrayConfig","linkAnnotation","getPreset","title","ctaInline","imageMember","blockMember","type","marks","annotations","of","getImageDimensions","defineField","defineType","definePresetType","seoType","name","identifier","schemaType","config","fields","objectConfig","type","title","validation","rule","max","info","description","options","hotspot","previews","aspectRatio","Rule","custom","value","asset","_ref","height","width","warning","uuid","ComponentType","ArrayDefinition","FieldDefinition","InputProps","SchemaTypeDefinition","PresetsTelemetryCollector","AnyPresetDefinition","PresetDefinition","RegistryContext","UserConfig","ctaType","imageType","ImageTypeConfig","linkType","LinkTypeConfig","createPageType","pageType","PageTypeConfig","richTextType","seoType","recordPresetUsage","registerRegistry","PresetsRegistryConfig","link","image","page","DefineFunction","Preset","config","Context","AliasedType","LockedProperties","PresetsRegistry","defineLink","defineCta","defineSeo","defineImage","definePage","defineRichText","createPresetsRegistry","registryId","seed","DefinerRecord","registeredSchemas","Map","pageTypeWithLookup","lookupArrayPreset","name","registered","get","type","undefined","systemPresets","const","reduce","registry","preset","key","getPresetKey","createDefiner","charAt","toUpperCase","slice","Definer","Record","createRegistryContext","getPreset","presetConfig","definer","Error","CreateDefinerOptions","define","userConfig","length","identifier","registryContext","registryDefaults","mergedConfig","map","factoryConfig","schemaType","Parameters","set","applyMapHooks","addTelemetryComponent","mappedSchemaType","configName","configValue","Object","entries","existing","components","existingInput","input","props"],"sources":["../src/__telemetry__/presets.telemetry.ts","../src/telemetry.ts","../src/components/PresetsTelemetryCollector.tsx","../src/definePresetType.ts","../src/presets/cta-type/index.ts","../src/presets/image-type/index.ts","../src/presets/link-type/index.ts","../src/presets/page-type/index.ts","../src/presets/rich-text-type/index.ts","../src/presets/seo-type/index.ts","../src/registry.tsx"],"sourcesContent":["import {defineEvent} from '@sanity/telemetry'\n\ninterface PresetsAddedInfo {\n  presetNames: string[]\n}\n\nexport const PresetsAdded = defineEvent<PresetsAddedInfo>({\n  name: 'Presets Added',\n  version: 1,\n  description: 'Workspace using presets was accessed',\n})\n","import {PresetsAdded} from './__telemetry__/presets.telemetry'\n\n/**\n * Minimal interface for the subset of TelemetryLogger we need.\n * Avoids forcing callers to satisfy the full generic TelemetryLogger type.\n */\nexport interface TelemetryLog {\n  log(event: unknown, data: unknown): void\n}\n\ninterface RegistryRecord {\n  id: string\n  presets: Set<string>\n  logged: boolean\n}\n\nconst registries = new Map<string, RegistryRecord>()\n\nexport function registerRegistry(id: string): void {\n  registries.set(id, {id, presets: new Set(), logged: false})\n}\n\nexport function recordPresetUsage(registryId: string, identifier: string): void {\n  registries.get(registryId)?.presets.add(identifier)\n}\n\nexport function collectPresetsRegistryTelemetry(registryId: string, telemetry: TelemetryLog): void {\n  const record = registries.get(registryId)\n  if (!record || record.logged) return\n  record.logged = true\n  if (record.presets.size > 0) {\n    telemetry.log(PresetsAdded, {presetNames: [...record.presets]})\n  }\n}\n\n/** @internal */\nexport function resetRegistries(): void {\n  registries.clear()\n}\n","import {useTelemetry} from '@sanity/telemetry/react'\nimport {useEffect, type ComponentType} from 'react'\nimport type {InputProps} from 'sanity'\n\nimport {collectPresetsRegistryTelemetry} from '../telemetry'\n\ntype Props = InputProps & {\n  registryId: string\n  userInput?: ComponentType<InputProps>\n}\n\n/**\n * A transparent input component wrapper that triggers telemetry collection\n * for the presets registry. Renders the user-provided input component if\n * supplied, otherwise the default input component unchanged.\n *\n * Attached to every schema type produced by a define<Type> function via\n * components.input. The first instance to render for a given registry id\n * submits the PresetsAdded telemetry event; subsequent renders are no-ops.\n */\nexport const PresetsTelemetryCollector: ComponentType<Props> = ({\n  registryId,\n  userInput: UserInput,\n  ...props\n}) => {\n  const telemetry = useTelemetry()\n\n  useEffect(() => {\n    collectPresetsRegistryTelemetry(registryId, telemetry)\n  }, [registryId, telemetry])\n\n  if (UserInput) {\n    return <UserInput {...props} />\n  }\n\n  return props.renderDefault(props)\n}\n","import type {\n  FieldDefinition,\n  FieldDefinitionBase,\n  IntrinsicTypeName,\n  SchemaTypeDefinition,\n} from 'sanity'\n\nimport type {PartialSchemaDefinition} from './types'\n\nexport interface RegistryContext {\n  getPreset: (\n    presetName: string,\n    config?: Record<string, unknown>,\n  ) => SchemaTypeDefinition & FieldDefinition\n}\n\ntype ProhibitedProperties = 'type'\n\ntype SanitizeProperties<Properties, ExcludedProperties extends string | undefined> = [\n  ExcludedProperties,\n] extends [PropertyKey]\n  ? Omit<Properties, ExcludedProperties>\n  : Properties\n\nexport type DerivedConfig<\n  Context,\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n> = Context &\n  FieldDefinitionBase &\n  (AliasedType extends string\n    ? SanitizeProperties<\n        PartialSchemaDefinition<AliasedType>,\n        ProhibitedProperties | LockedProperties\n      >\n    : {}) & {\n    map?: AliasedType extends string\n      ? {\n          [Key in keyof PartialSchemaDefinition<AliasedType>]?: (\n            input: PartialSchemaDefinition<AliasedType>[Key],\n          ) => PartialSchemaDefinition<AliasedType>[Key]\n        }\n      : {}\n  }\n\n/**\n * The public-facing config shape that a registry's `define<Name>` function\n * accepts at the call site. Includes the full `DerivedConfig` with required\n * `name` (inherited from `FieldDefinitionBase`) and optional `map`.\n */\nexport type UserConfig<\n  Context = {},\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n> = DerivedConfig<Context, AliasedType, LockedProperties>\n\n/**\n * A preset definition describes how to produce a Sanity schema type.\n *\n * - `name` is the registry key for the preset (it determines the\n *   `define<Name>` function and the `PresetsRegistryConfig` key).\n * - `identifier` is an optional stable identifier used for telemetry.\n * - `schemaType` is the factory that produces the Sanity schema type. It\n *   receives the merged config (minus `map`) and the registry context, and\n *   returns a `SchemaTypeDefinition`.\n */\nexport interface PresetDefinition<\n  Context = {},\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n> {\n  name: string\n  identifier?: string\n  schemaType: (\n    config: Omit<DerivedConfig<Context, AliasedType, LockedProperties>, 'map' | 'name'> & {\n      name: string\n    },\n    registry: RegistryContext,\n  ) => SchemaTypeDefinition\n}\n\n/**\n * A typed passthrough for defining a preset. Given a `PresetDefinition`, it\n * returns the same value, narrowed to its concrete generic parameters so\n * downstream code can infer the preset's config type from it.\n *\n * This is intentionally lightweight: it performs no work at call time. The\n * registry is responsible for invoking `schemaType` when a preset is\n * instantiated, and for applying `map` hooks to the produced schema type.\n */\nexport function definePresetType<\n  Context = {},\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n>(\n  preset: PresetDefinition<Context, AliasedType, LockedProperties>,\n): PresetDefinition<Context, AliasedType, LockedProperties> {\n  return preset\n}\n\n/**\n * A preset definition with its generic parameters erased, for use in code\n * that handles presets generically (e.g. the registry).\n */\nexport type AnyPresetDefinition = PresetDefinition<any, any, any>\n","import {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport const ctaType = definePresetType<{}, 'object', 'preview'>({\n  name: 'cta',\n  identifier: 'core.cta',\n  schemaType: (config, registry) => {\n    const {fields, ...objectConfig} = config\n\n    return defineType({\n      ...objectConfig,\n      type: 'object',\n      fields: [\n        registry.getPreset('link', {name: 'link', title: 'Link'}),\n        defineField({\n          name: 'level',\n          title: 'Level',\n          description:\n            'The importance of the action relative to its siblings: level 1 being the primary action, 2 the secondary action, and so on.',\n          type: 'number',\n          options: {\n            layout: 'radio',\n            list: [1, 2, 3],\n          },\n        }),\n        ...(fields ?? []),\n      ],\n      preview: {\n        select: {\n          linkType: 'link.linkType',\n          url: 'link.url',\n          referenceTitle: 'link.reference.title',\n          referenceName: 'link.reference.name',\n        },\n        prepare({linkType, url, referenceTitle, referenceName}) {\n          const referenceLabel = referenceTitle || referenceName || 'No reference'\n          const title = linkType === 'external' ? url || 'No URL' : referenceLabel\n          return {title, subtitle: 'Button'}\n        },\n      },\n    })\n  },\n})\n","import {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport interface ImageTypeConfig {\n  altText?: boolean\n  caption?: boolean\n  hotspot?: boolean\n}\n\nexport const imageType = definePresetType<ImageTypeConfig, 'image', 'preview'>({\n  name: 'image',\n  identifier: 'core.image',\n  schemaType: (config) => {\n    const {altText = true, caption = true, hotspot = true, fields, ...imageConfig} = config\n\n    return defineType({\n      ...imageConfig,\n      type: 'image',\n      // hotspot is the curated default; callers override other image options (accept, sources, storeOriginalFilename) via the map.options hook\n      options: {\n        hotspot,\n      },\n      fields: [\n        ...(altText\n          ? [\n              defineField({\n                name: 'altText',\n                title: 'Alt text',\n                description:\n                  'Describes the image for screen readers and search engines. Important for accessibility.',\n                type: 'string',\n                validation: (rule) => rule.warning('Alt text improves accessibility.'),\n              }),\n            ]\n          : []),\n        ...(caption\n          ? [\n              defineField({\n                name: 'caption',\n                title: 'Caption',\n                type: 'text',\n              }),\n            ]\n          : []),\n        ...(fields ?? []),\n      ],\n      preview: {\n        select: {\n          title: altText ? 'altText' : caption ? 'caption' : 'asset.originalFilename',\n        },\n      },\n    })\n  },\n})\n","import {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\ntype LinkToEntry = string | {type: string}\n\nexport interface LinkTypeConfig {\n  to?: LinkToEntry[]\n}\n\nfunction normalizeToTargets(entries: LinkToEntry[]): {type: string}[] {\n  return entries.map((entry) => (typeof entry === 'string' ? {type: entry} : entry))\n}\n\nexport const linkType = definePresetType<LinkTypeConfig, 'object', 'preview'>({\n  name: 'link',\n  identifier: 'core.link',\n  schemaType: ({to, fields, ...objectConfig}) => {\n    const referenceTargets = normalizeToTargets(to ?? [])\n\n    return defineType({\n      ...objectConfig,\n      type: 'object',\n      fields: [\n        defineField({\n          name: 'linkType',\n          type: 'string',\n          title: 'Link Type',\n          description:\n            'Internal links point to a page in this project. External links point to a full URL.',\n          initialValue: 'internal',\n          options: {\n            layout: 'radio',\n            list: [\n              {title: 'Internal', value: 'internal'},\n              {title: 'External', value: 'external'},\n            ],\n          },\n        }),\n        defineField({\n          name: 'reference',\n          type: 'reference',\n          title: 'Internal Link',\n          to: referenceTargets,\n          hidden: ({parent}) => parent?.linkType === 'external',\n        }),\n        defineField({\n          name: 'url',\n          type: 'url',\n          title: 'URL',\n          description:\n            'Full URL including protocol, e.g. https://example.com. Supports http, https, mailto, and tel.',\n          hidden: ({parent}) => parent?.linkType === 'internal',\n          validation: (rule) =>\n            rule.uri({\n              scheme: ['http', 'https', 'mailto', 'tel'],\n            }),\n        }),\n        defineField({\n          name: 'openInNewTab',\n          type: 'boolean',\n          title: 'Open in New Tab',\n          initialValue: false,\n          hidden: ({parent}) => parent?.linkType === 'internal',\n        }),\n        ...(fields ?? []),\n      ],\n      preview: {\n        select: {\n          linkType: 'linkType',\n          url: 'url',\n          referenceTitle: 'reference.title',\n          referenceName: 'reference.name',\n        },\n        prepare({linkType, url, referenceTitle, referenceName}) {\n          const referenceLabel = referenceTitle || referenceName || 'No reference'\n          const title = linkType === 'external' ? url || 'No URL' : referenceLabel\n\n          return {\n            title,\n            subtitle: linkType === 'external' ? 'External link' : 'Internal link',\n          }\n        },\n      },\n    })\n  },\n})\n","import {\n  ALL_FIELDS_GROUP,\n  type ArrayDefinition,\n  defineArrayMember,\n  defineField,\n  defineType,\n  type FieldDefinition,\n  type SchemaTypeDefinition,\n} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport type PageBuilderBlock = string | (SchemaTypeDefinition & FieldDefinition)\n\ntype LookupArrayPreset = (name: string) => ArrayDefinition | undefined\n\n// Sanity rejects array members whose `type` resolves to another array. Wrap\n// array presets in an object so they can serve as page-builder members.\nfunction wrapArrayAsPageBuilderBlock(arraySchema: ArrayDefinition) {\n  const components = 'components' in arraySchema ? arraySchema.components : undefined\n  return defineArrayMember({\n    name: arraySchema.name,\n    title: arraySchema.title,\n    type: 'object',\n    fields: [\n      defineField({\n        name: 'content',\n        type: 'array',\n        of: arraySchema.of,\n        components,\n      }),\n    ],\n  })\n}\n\nfunction toPageBuilderArrayMember(block: PageBuilderBlock, lookupArrayPreset: LookupArrayPreset) {\n  if (typeof block === 'string') {\n    const arrayPreset = lookupArrayPreset(block)\n    if (arrayPreset) {\n      return wrapArrayAsPageBuilderBlock(arrayPreset)\n    }\n    return defineArrayMember({type: block})\n  }\n  if (block.type === 'array') {\n    // oxlint-disable-next-line no-unsafe-type-assertion -- discriminating on `type` does not narrow the intersected union\n    return wrapArrayAsPageBuilderBlock(block as ArrayDefinition)\n  }\n  return defineArrayMember(block)\n}\n\n// Defer building `content.of` so by-name references resolve after every\n// `define<X>` has run. Memoised for stable array identity across reads.\nfunction defineLazyContentField(\n  blocks: PageBuilderBlock[],\n  lookupArrayPreset: LookupArrayPreset,\n): FieldDefinition {\n  let cached: ReturnType<typeof toPageBuilderArrayMember>[] | undefined\n  return defineField({\n    name: 'content',\n    title: 'Content',\n    description:\n      'Page sections rendered in order. Add, remove, or reorder blocks to build the page.',\n    group: 'main',\n    type: 'array',\n    get of() {\n      cached ??= blocks.map((block) => toPageBuilderArrayMember(block, lookupArrayPreset))\n      return cached\n    },\n  })\n}\n\nexport interface PageTypeConfig {\n  pageBuilderBlocks?: PageBuilderBlock[]\n}\n\n// `lookupArrayPreset` is closure-injected by the registry to keep it off\n// the public `RegistryContext`. The default `pageType` below uses a no-op.\nexport function createPageType({lookupArrayPreset}: {lookupArrayPreset: LookupArrayPreset}) {\n  return definePresetType<PageTypeConfig, 'document'>({\n    name: 'page',\n    identifier: 'core.page',\n    schemaType: (config, registry) => {\n      const {pageBuilderBlocks, groups, fields, ...documentConfig} = config\n\n      return defineType({\n        ...documentConfig,\n        type: 'document',\n        groups: [\n          {\n            ...ALL_FIELDS_GROUP,\n            hidden: true,\n          },\n          {\n            name: 'main',\n            title: 'Main',\n            default: true,\n          },\n          {\n            name: 'metadata',\n            title: 'Metadata',\n          },\n          ...(groups ?? []),\n        ],\n        fields: [\n          defineField({\n            name: 'name',\n            title: 'Name',\n            description: 'Used as the page title and as the source for the auto-generated slug.',\n            type: 'string',\n            group: 'main',\n            validation: (rule) => rule.required(),\n          }),\n          defineField({\n            name: 'slug',\n            title: 'Slug',\n            type: 'slug',\n            group: 'main',\n            options: {\n              source: 'name',\n            },\n          }),\n          defineLazyContentField(pageBuilderBlocks ?? [], lookupArrayPreset),\n          registry.getPreset('seo', {\n            name: 'seo',\n            title: 'SEO',\n            group: 'metadata',\n          }),\n          ...(fields ?? []),\n        ],\n      })\n    },\n  })\n}\n\nexport const pageType = createPageType({lookupArrayPreset: () => undefined})\n","import {defineArrayMember, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport interface RichTextObjectsConfig {\n  link?: boolean\n  image?: boolean\n  cta?: boolean\n}\n\nexport interface RichTextTypeConfig {\n  /**\n   * Toggle the embedded objects (link annotations, image blocks, inline CTAs).\n   * Defaults to all enabled. Pass `false` to disable every object, or an\n   * object to toggle individual ones (e.g. `{link: false}`).\n   *\n   * Each object's options (link `to`, image `altText`, …) are\n   * configured on `createPresetsRegistry` and cascade into every rich text\n   * field. Use `map.of` for per-field structural changes.\n   */\n  objects?: boolean | RichTextObjectsConfig\n}\n\nfunction resolveObjects(objects: RichTextTypeConfig['objects']): Required<RichTextObjectsConfig> {\n  if (objects === false) return {link: false, image: false, cta: false}\n  if (objects === true || objects === undefined) return {link: true, image: true, cta: true}\n  const {link = true, image = true, cta = true} = objects\n  return {link, image, cta}\n}\n\nexport const richTextType = definePresetType<RichTextTypeConfig, 'array', 'of'>({\n  name: 'richText',\n  identifier: 'core.richText',\n  schemaType: (config, registry) => {\n    const {objects, ...arrayConfig} = config\n    const {link, image, cta} = resolveObjects(objects)\n\n    // The annotation name must be 'link' — Portable Text Editor's built-in link UI keys off this name.\n    const linkAnnotation = link\n      ? registry.getPreset('link', {name: 'link', title: 'Link'})\n      : undefined\n    const ctaInline = cta ? registry.getPreset('cta', {name: 'cta', title: 'CTA'}) : undefined\n    const imageMember = image\n      ? registry.getPreset('image', {name: 'richTextImage', title: 'Image'})\n      : undefined\n\n    const blockMember = defineArrayMember({\n      type: 'block',\n      marks: {annotations: linkAnnotation ? [linkAnnotation] : []},\n      ...(ctaInline && {of: [ctaInline]}),\n    })\n\n    return defineType({\n      ...arrayConfig,\n      type: 'array',\n      of: imageMember ? [blockMember, imageMember] : [blockMember],\n    })\n  },\n})\n","import {getImageDimensions} from '@sanity/asset-utils'\nimport {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport const seoType = definePresetType<{}, 'object'>({\n  name: 'seo',\n  identifier: 'core.seo',\n  schemaType: (config) => {\n    const {fields, ...objectConfig} = config\n\n    return defineType({\n      ...objectConfig,\n      type: 'object',\n      fields: [\n        defineField({\n          name: 'title',\n          title: 'Title',\n          type: 'string',\n          validation: (rule) => rule.max(70).info('Search engines may truncate this title.'),\n        }),\n        defineField({\n          name: 'description',\n          title: 'Description',\n          type: 'text',\n          validation: (rule) => rule.max(150).info('Search engines may truncate this description.'),\n        }),\n        defineField({\n          name: 'ogImage',\n          title: 'Open Graph image',\n          type: 'image',\n          description: 'Landscape 1200x630 (1.91:1)',\n          options: {\n            hotspot: {\n              previews: [\n                {\n                  title: 'Landscape (1.91:1)',\n                  aspectRatio: 1.91 / 1,\n                },\n              ],\n            },\n          },\n          validation: (Rule) =>\n            Rule.custom((value) => {\n              if (!value?.asset?._ref) {\n                return true\n              }\n\n              const {height, width} = getImageDimensions(value.asset?._ref)\n\n              if (height !== 630 || width !== 1200) {\n                return 'Open Graph images are recommended to be exactly 1200x630 (1.91:1) for the best social sharing previews.'\n              }\n\n              return true\n            }).warning(),\n        }),\n        ...(fields ?? []),\n      ],\n    })\n  },\n})\n","import {uuid} from '@sanity/uuid'\nimport {type ComponentType} from 'react'\nimport type {ArrayDefinition, FieldDefinition, InputProps, SchemaTypeDefinition} from 'sanity'\n\nimport {PresetsTelemetryCollector} from './components/PresetsTelemetryCollector'\nimport type {\n  AnyPresetDefinition,\n  PresetDefinition,\n  RegistryContext,\n  UserConfig,\n} from './definePresetType'\nimport {ctaType} from './presets/cta-type'\nimport {imageType, type ImageTypeConfig} from './presets/image-type'\nimport {linkType, type LinkTypeConfig} from './presets/link-type'\nimport {createPageType, pageType, type PageTypeConfig} from './presets/page-type'\nimport {richTextType} from './presets/rich-text-type'\nimport {seoType} from './presets/seo-type'\nimport {recordPresetUsage, registerRegistry} from './telemetry'\n\nexport interface PresetsRegistryConfig {\n  link?: LinkTypeConfig\n  image?: ImageTypeConfig\n  page?: PageTypeConfig\n}\n\ntype DefineFunction<Preset extends AnyPresetDefinition> =\n  Preset extends PresetDefinition<infer Context, infer AliasedType, infer LockedProperties>\n    ? (\n        config: UserConfig<Context, AliasedType, LockedProperties>,\n      ) => SchemaTypeDefinition & FieldDefinition\n    : never\n\nexport interface PresetsRegistry {\n  defineLink: DefineFunction<typeof linkType>\n  defineCta: DefineFunction<typeof ctaType>\n  defineSeo: DefineFunction<typeof seoType>\n  defineImage: DefineFunction<typeof imageType>\n  definePage: DefineFunction<typeof pageType>\n  defineRichText: DefineFunction<typeof richTextType>\n}\n\nexport function createPresetsRegistry(config: PresetsRegistryConfig = {}): PresetsRegistry {\n  const registryId = uuid()\n  registerRegistry(registryId)\n\n  // oxlint-disable-next-line no-unsafe-type-assertion -- seeding reduce with an empty object that is populated by each iteration\n  const seed = {} as DefinerRecord & PresetsRegistry\n\n  // Tracks the schema produced under each defined preset name so `pageType`\n  // can resolve string references in `pageBuilderBlocks` regardless of\n  // definition order, and wrap array-typed presets at the page builder\n  // boundary. Closure-injected into `pageType` via `createPageType` so it\n  // does not need to live on the public `RegistryContext`.\n  const registeredSchemas = new Map<string, SchemaTypeDefinition>()\n  const pageTypeWithLookup = createPageType({\n    lookupArrayPreset: (name) => {\n      const registered = registeredSchemas.get(name)\n      // oxlint-disable-next-line no-unsafe-type-assertion -- discriminating on `type` does not narrow the intersected union\n      return registered?.type === 'array' ? (registered as ArrayDefinition) : undefined\n    },\n  })\n\n  const systemPresets = [\n    linkType,\n    ctaType,\n    seoType,\n    imageType,\n    pageTypeWithLookup,\n    richTextType,\n  ] as const\n\n  return systemPresets.reduce((registry, preset) => {\n    const key = getPresetKey(preset.name)\n    registry[key] = createDefiner({registryId, preset, config, registry, registeredSchemas})\n    return registry\n  }, seed)\n}\n\nexport function getPresetKey(name: string): string {\n  return `define${name.charAt(0).toUpperCase()}${name.slice(1)}`\n}\n\ntype Definer = (config?: Record<string, unknown>) => SchemaTypeDefinition & FieldDefinition\ntype DefinerRecord = Record<string, Definer>\n\nfunction createRegistryContext({registry}: {registry: DefinerRecord}): RegistryContext {\n  return {\n    getPreset: (name, presetConfig) => {\n      const key = getPresetKey(name)\n      const definer = registry[key]\n      if (!definer) {\n        throw new Error(`Cannot resolve preset \"${name}\". No such preset in this registry.`)\n      }\n      return definer(presetConfig)\n    },\n  }\n}\n\ninterface CreateDefinerOptions {\n  registryId: string\n  preset: AnyPresetDefinition\n  config: PresetsRegistryConfig\n  registry: DefinerRecord\n  registeredSchemas: Map<string, SchemaTypeDefinition>\n}\n\nfunction createDefiner({\n  registryId,\n  preset,\n  config,\n  registry,\n  registeredSchemas,\n}: CreateDefinerOptions): Definer {\n  return function define(userConfig = {}) {\n    const name = userConfig['name']\n    if (typeof name !== 'string' || name.length === 0) {\n      throw new Error(\n        `${getPresetKey(preset.name)}: \"name\" is required. Pass {name: \"yourTypeName\"}.`,\n      )\n    }\n\n    recordPresetUsage(registryId, preset.identifier ?? 'unnamed')\n\n    const registryContext = createRegistryContext({registry})\n\n    // oxlint-disable-next-line no-unsafe-type-assertion -- PresetsRegistryConfig is keyed by preset name; dynamic lookup is safe\n    const registryDefaults = (config as Record<string, unknown>)[preset.name]\n    const mergedConfig: Record<string, unknown> = {\n      ...(typeof registryDefaults === 'object' && registryDefaults !== null\n        ? registryDefaults\n        : {}),\n      ...userConfig,\n    }\n\n    const {map, ...factoryConfig} = mergedConfig\n\n    const schemaType = preset.schemaType(\n      // oxlint-disable-next-line no-unsafe-type-assertion -- factoryConfig is the merged user config (minus `map`, with `name` injected); its shape matches the factory's expected parameter at runtime\n      factoryConfig as unknown as Parameters<AnyPresetDefinition['schemaType']>[0],\n      registryContext,\n    )\n\n    registeredSchemas.set(name, schemaType)\n\n    // oxlint-disable-next-line no-unsafe-type-assertion -- runtime value is a valid field definition\n    return applyMapHooks(\n      addTelemetryComponent(schemaType, registryId),\n      map,\n    ) as SchemaTypeDefinition & FieldDefinition\n  }\n}\n\nfunction applyMapHooks(schemaType: SchemaTypeDefinition, map: unknown): SchemaTypeDefinition {\n  if (!map || typeof map !== 'object') return schemaType\n\n  const mappedSchemaType: Record<string, unknown> = {}\n\n  for (const [configName, configValue] of Object.entries(map)) {\n    if (typeof configValue !== 'function') {\n      continue\n    }\n\n    mappedSchemaType[configName] = configValue(\n      // oxlint-disable-next-line no-unsafe-type-assertion -- map hooks operate on arbitrary schema type properties\n      schemaType[configName as keyof typeof schemaType],\n    )\n  }\n\n  return {...schemaType, ...mappedSchemaType}\n}\n\nfunction addTelemetryComponent(\n  schemaType: SchemaTypeDefinition,\n  registryId: string,\n): SchemaTypeDefinition {\n  const existing = 'components' in schemaType ? schemaType.components : undefined\n  const existingInput =\n    existing && 'input' in existing && typeof existing.input === 'function'\n      ? // oxlint-disable-next-line no-unsafe-type-assertion -- presets only produce object/document schema types, whose input components are assignable to ComponentType<InputProps>\n        (existing.input as ComponentType<InputProps>)\n      : undefined\n  // oxlint-disable-next-line no-unsafe-type-assertion -- spreading a discriminated union loses the discriminant; the runtime shape is still a valid SchemaTypeDefinition\n  return {\n    ...schemaType,\n    components: {\n      ...existing,\n      input: (props: InputProps) => (\n        <PresetsTelemetryCollector {...props} registryId={registryId} userInput={existingInput} />\n      ),\n    },\n  } as SchemaTypeDefinition\n}\n"],"mappings":";;;;;;;;AAMA,MAAaG,eAAeH,YAA8B;CACxDI,MAAM;CACNC,SAAS;CACTC,aAAa;AACf,CAAC,GCMKW,6BAAa,IAAIC,IAA4B;AAEnD,SAAgBC,iBAAiBN,IAAkB;CACjDI,WAAWG,IAAIP,IAAI;EAACA;EAAIC,yBAAS,IAAIC,IAAI;EAAGC,QAAQ;CAAK,CAAC;AAC5D;AAEA,SAAgBK,kBAAkBC,YAAoBC,YAA0B;CAC9EN,WAAWO,IAAIF,UAAU,CAAC,EAAER,QAAQW,IAAIF,UAAU;AACpD;AAEA,SAAgBG,gCAAgCJ,YAAoBK,WAA+B;CACjG,IAAMC,SAASX,WAAWO,IAAIF,UAAU;CACpC,CAACM,UAAUA,OAAOZ,WACtBY,OAAOZ,SAAS,IACZY,OAAOd,QAAQe,OAAO,KACxBF,UAAUlB,IAAIF,cAAc,EAACuB,aAAa,CAAC,GAAGF,OAAOd,OAAO,EAAC,CAAC;AAElE;;;;;;;;;;ACbA,MAAa2B,6BAAkDC,OAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAAC,EAAAL,YAAAC,WAAAK,WAAA,GAAAC,UAAAJ,IAK9DK,YAAkBd,aAAa,GAACe,IAAAC;CAQ/B,OAR+BN,EAAA,OAAAJ,cAAAI,EAAA,OAAAI,aAEtBC,WAAA;EACRX,gCAAgCE,YAAYQ,SAAS;CAAC,GACrDE,KAAA,CAACV,YAAYQ,SAAS,GAACJ,EAAA,KAAAJ,YAAAI,EAAA,KAAAI,WAAAJ,EAAA,KAAAK,IAAAL,EAAA,KAAAM,OAAAD,KAAAL,EAAA,IAAAM,KAAAN,EAAA,KAF1BT,UAAUc,IAEPC,EAAuB,GAEtBJ,YACK,oBAAC,WAAD,EAAU,GAAKC,MAAK,CAAA,IAGtBA,MAAKI,cAAeJ,KAAK;AAAC;;;;;;;;;;ACuDnC,SAAgBkC,iBAKdC,QAC0D;CAC1D,OAAOA;AACT;AC9FA,MAAaK,UAAUD,iBAA0C;CAC/DE,MAAM;CACNC,YAAY;CACZC,aAAaC,QAAQC,aAAa;EAChC,IAAM,EAACC,QAAQ,GAAGC,iBAAgBH;EAElC,OAAON,WAAW;GAChB,GAAGS;GACHC,MAAM;GACNF,QAAQ;IACND,SAASI,UAAU,QAAQ;KAACR,MAAM;KAAQS,OAAO;IAAM,CAAC;IACxDb,YAAY;KACVI,MAAM;KACNS,OAAO;KACPC,aACE;KACFH,MAAM;KACNI,SAAS;MACPC,QAAQ;MACRC,MAAM;OAAC;OAAG;OAAG;MAAC;KAChB;IACF,CAAC;IACD,GAAIR,UAAU,CAAA;GAAG;GAEnBS,SAAS;IACPC,QAAQ;KACNC,UAAU;KACVC,KAAK;KACLC,gBAAgB;KAChBC,eAAe;IACjB;IACAC,QAAQ,EAACJ,UAAUC,KAAKC,gBAAgBC,iBAAgB;KAGtD,OAAO;MAACV,OADMO,aAAa,aAAaC,OAAO,WADxBC,kBAAkBC,iBAAiB;MAE3CG,UAAU;KAAQ;IACnC;GACF;EACF,CAAC;CACH;AACF,CAAC,GCjCYQ,YAAYL,iBAAsD;CAC7EM,MAAM;CACNC,YAAY;CACZC,aAAaC,WAAW;EACtB,IAAM,EAACP,UAAU,IAAMC,UAAU,IAAMC,UAAU,IAAMM,QAAQ,GAAGC,gBAAeF;EAEjF,OAAOV,WAAW;GAChB,GAAGY;GACHC,MAAM;GAENC,SAAS,EACPT,QACF;GACAM,QAAQ;IACN,GAAIR,UACA,CACEJ,YAAY;KACVQ,MAAM;KACNQ,OAAO;KACPC,aACE;KACFH,MAAM;KACNI,aAAaC,SAASA,KAAKC,QAAQ,kCAAkC;IACvE,CAAC,CAAC,IAEJ,CAAA;IACJ,GAAIf,UACA,CACEL,YAAY;KACVQ,MAAM;KACNQ,OAAO;KACPF,MAAM;IACR,CAAC,CAAC,IAEJ,CAAA;IACJ,GAAIF,UAAU,CAAA;GAAG;GAEnBS,SAAS,EACPC,QAAQ,EACNN,OAAOZ,UAAU,YAAYC,UAAU,YAAY,yBACrD,EACF;EACF,CAAC;CACH;AACF,CAAC;AC5CD,SAASyB,mBAAmBC,SAA0C;CACpE,OAAOA,QAAQC,KAAKC,UAAW,OAAOA,SAAU,WAAW,EAACN,MAAMM,MAAK,IAAIA,KAAM;AACnF;AAEA,MAAaC,WAAWT,iBAAsD;CAC5EU,MAAM;CACNC,YAAY;CACZC,aAAa,EAACR,IAAIS,QAAQ,GAAGC,mBAAkB;EAC7C,IAAMC,mBAAmBV,mBAAmBD,MAAM,CAAA,CAAE;EAEpD,OAAOL,WAAW;GAChB,GAAGe;GACHZ,MAAM;GACNW,QAAQ;IACNf,YAAY;KACVY,MAAM;KACNR,MAAM;KACNc,OAAO;KACPC,aACE;KACFC,cAAc;KACdC,SAAS;MACPC,QAAQ;MACRC,MAAM,CACJ;OAACL,OAAO;OAAYM,OAAO;MAAU,GACrC;OAACN,OAAO;OAAYM,OAAO;MAAU,CAAC;KAE1C;IACF,CAAC;IACDxB,YAAY;KACVY,MAAM;KACNR,MAAM;KACNc,OAAO;KACPZ,IAAIW;KACJQ,SAAS,EAACC,aAAYA,QAAQf,aAAa;IAC7C,CAAC;IACDX,YAAY;KACVY,MAAM;KACNR,MAAM;KACNc,OAAO;KACPC,aACE;KACFM,SAAS,EAACC,aAAYA,QAAQf,aAAa;KAC3CgB,aAAaC,SACXA,KAAKC,IAAI,EACPC,QAAQ;MAAC;MAAQ;MAAS;MAAU;KAAK,EAC3C,CAAC;IACL,CAAC;IACD9B,YAAY;KACVY,MAAM;KACNR,MAAM;KACNc,OAAO;KACPE,cAAc;KACdK,SAAS,EAACC,aAAYA,QAAQf,aAAa;IAC7C,CAAC;IACD,GAAII,UAAU,CAAA;GAAG;GAEnBgB,SAAS;IACPC,QAAQ;KACNrB,UAAU;KACVsB,KAAK;KACLC,gBAAgB;KAChBC,eAAe;IACjB;IACAC,QAAQ,EAACzB,UAAUsB,KAAKC,gBAAgBC,iBAAgB;KAItD,OAAO;MACLjB,OAHYP,aAAa,aAAasB,OAAO,WADxBC,kBAAkBC,iBAAiB;MAKxDG,UAAU3B,aAAa,aAAa,kBAAkB;KACxD;IACF;GACF;EACF,CAAC;CACH;AACF,CAAC;ACpED,SAASuC,4BAA4BC,aAA8B;CACjE,IAAMC,aAAa,gBAAgBD,cAAcA,YAAYC,aAAaC,KAAAA;CAC1E,OAAOZ,kBAAkB;EACvBQ,MAAME,YAAYF;EAClBK,OAAOH,YAAYG;EACnBC,MAAM;EACNC,QAAQ,CACNd,YAAY;GACVO,MAAM;GACNM,MAAM;GACNE,IAAIN,YAAYM;GAChBL;EACF,CAAC,CAAC;CAEN,CAAC;AACH;AAEA,SAASM,yBAAyBC,OAAyBC,mBAAsC;CAC/F,IAAI,OAAOD,SAAU,UAAU;EAC7B,IAAME,cAAcD,kBAAkBD,KAAK;EAI3C,OAHIE,cACKX,4BAA4BW,WAAW,IAEzCpB,kBAAkB,EAACc,MAAMI,MAAK,CAAC;CACxC;CAKA,OAJIA,MAAMJ,SAAS,UAEVL,4BAA4BS,KAAwB,IAEtDlB,kBAAkBkB,KAAK;AAChC;AAIA,SAASG,uBACPC,QACAH,mBACiB;CACjB,IAAII;CACJ,OAAOtB,YAAY;EACjBO,MAAM;EACNK,OAAO;EACPY,aACE;EACFC,OAAO;EACPZ,MAAM;EACN,IAAIE,KAAK;GAEP,OADAO,WAAWD,OAAOK,KAAKT,UAAUD,yBAAyBC,OAAOC,iBAAiB,CAAC,GAC5EI;EACT;CACF,CAAC;AACH;AAQA,SAAgBO,eAAe,EAACX,qBAA4D;CAC1F,OAAOd,iBAA6C;EAClDG,MAAM;EACNuB,YAAY;EACZC,aAAaC,QAAQC,aAAa;GAChC,IAAM,EAACL,mBAAmBM,QAAQpB,QAAQ,GAAGqB,mBAAkBH;GAE/D,OAAO/B,WAAW;IAChB,GAAGkC;IACHtB,MAAM;IACNqB,QAAQ;KACN;MACE,GAAGrC;MACHuC,QAAQ;KACV;KACA;MACE7B,MAAM;MACNK,OAAO;MACPyB,SAAS;KACX;KACA;MACE9B,MAAM;MACNK,OAAO;KACT;KACA,GAAIsB,UAAU,CAAA;IAAG;IAEnBpB,QAAQ;KACNd,YAAY;MACVO,MAAM;MACNK,OAAO;MACPY,aAAa;MACbX,MAAM;MACNY,OAAO;MACPa,aAAaC,SAASA,KAAKC,SAAS;KACtC,CAAC;KACDxC,YAAY;MACVO,MAAM;MACNK,OAAO;MACPC,MAAM;MACNY,OAAO;MACPgB,SAAS,EACPC,QAAQ,OACV;KACF,CAAC;KACDtB,uBAAuBQ,qBAAqB,CAAA,GAAIV,iBAAiB;KACjEe,SAASU,UAAU,OAAO;MACxBpC,MAAM;MACNK,OAAO;MACPa,OAAO;KACT,CAAC;KACD,GAAIX,UAAU,CAAA;IAAG;GAErB,CAAC;EACH;CACF,CAAC;AACH;AAEwBe,eAAe,EAACX,yBAAyBP,KAAAA,EAAS,CAAC;AC/G3E,SAAS2C,eAAeD,SAAyE;CAC/F,IAAIA,YAAY,IAAO,OAAO;EAACJ,MAAM;EAAOC,OAAO;EAAOC,KAAK;CAAK;CACpE,IAAIE,YAAY,MAAQA,YAAYG,KAAAA,GAAW,OAAO;EAACP,MAAM;EAAMC,OAAO;EAAMC,KAAK;CAAI;CACzF,IAAM,EAACF,OAAO,IAAMC,QAAQ,IAAMC,MAAM,OAAQE;CAChD,OAAO;EAACJ;EAAMC;EAAOC;CAAG;AAC1B;AAEA,MAAaM,eAAeV,iBAAoD;CAC9EW,MAAM;CACNC,YAAY;CACZC,aAAaC,QAAQC,aAAa;EAChC,IAAM,EAACT,SAAS,GAAGU,gBAAeF,QAC5B,EAACZ,MAAMC,OAAOC,QAAOG,eAAeD,OAAO,GAG3CW,iBAAiBf,OACnBa,SAASG,UAAU,QAAQ;GAACP,MAAM;GAAQQ,OAAO;EAAM,CAAC,IACxDV,KAAAA,GACEW,YAAYhB,MAAMW,SAASG,UAAU,OAAO;GAACP,MAAM;GAAOQ,OAAO;EAAK,CAAC,IAAIV,KAAAA,GAC3EY,cAAclB,QAChBY,SAASG,UAAU,SAAS;GAACP,MAAM;GAAiBQ,OAAO;EAAO,CAAC,IACnEV,KAAAA,GAEEa,cAAcxB,kBAAkB;GACpCyB,MAAM;GACNC,OAAO,EAACC,aAAaR,iBAAiB,CAACA,cAAc,IAAI,CAAA,EAAE;GAC3D,GAAIG,aAAa,EAACM,IAAI,CAACN,SAAS,EAAC;EACnC,CAAC;EAED,OAAOrB,WAAW;GAChB,GAAGiB;GACHO,MAAM;GACNG,IAAIL,cAAc,CAACC,aAAaD,WAAW,IAAI,CAACC,WAAW;EAC7D,CAAC;CACH;AACF,CAAC,GCrDYS,UAAUD,iBAA+B;CACpDE,MAAM;CACNC,YAAY;CACZC,aAAaC,WAAW;EACtB,IAAM,EAACC,QAAQ,GAAGC,iBAAgBF;EAElC,OAAON,WAAW;GAChB,GAAGQ;GACHC,MAAM;GACNF,QAAQ;IACNR,YAAY;KACVI,MAAM;KACNO,OAAO;KACPD,MAAM;KACNE,aAAaC,SAASA,KAAKC,IAAI,EAAE,CAAC,CAACC,KAAK,yCAAyC;IACnF,CAAC;IACDf,YAAY;KACVI,MAAM;KACNO,OAAO;KACPD,MAAM;KACNE,aAAaC,SAASA,KAAKC,IAAI,GAAG,CAAC,CAACC,KAAK,+CAA+C;IAC1F,CAAC;IACDf,YAAY;KACVI,MAAM;KACNO,OAAO;KACPD,MAAM;KACNM,aAAa;KACbC,SAAS,EACPC,SAAS,EACPC,UAAU,CACR;MACER,OAAO;MACPS,aAAa,OAAO;KACtB,CAAC,EAEL,EACF;KACAR,aAAaS,SACXA,KAAKC,QAAQC,UAAU;MACrB,IAAI,CAACA,OAAOC,OAAOC,MACjB,OAAO;MAGT,IAAM,EAACC,QAAQC,UAAS5B,mBAAmBwB,MAAMC,OAAOC,IAAI;MAM5D,OAJIC,WAAW,OAAOC,UAAU,OACvB,4GAGF;KACT,CAAC,CAAC,CAACC,QAAQ;IACf,CAAC;IACD,GAAIpB,UAAU,CAAA;GAAG;EAErB,CAAC;CACH;AACF,CAAC;ACpBD,SAAgB6D,sBAAsBX,SAAgC,CAAC,GAAoB;CACzF,IAAMY,aAAazC,KAAK;CACxBsB,iBAAiBmB,UAAU;CAG3B,IAAMC,OAAO,CAAC,GAORE,oCAAoB,IAAIC,IAAkC,GAC1DC,qBAAqB9B,eAAe,EACxC+B,oBAAoBC,SAAS;EAC3B,IAAMC,aAAaL,kBAAkBM,IAAIF,IAAI;EAE7C,OAAOC,YAAYE,SAAS,UAAWF,aAAiCG,KAAAA;CAC1E,EACF,CAAC;CAWD,OAAOC;EARLvC;EACAH;EACAS;EACAR;EACAkC;EACA3B;CAGKkC,CAAa,CAACE,QAAQC,UAAUC,WAAW;EAChD,IAAMC,MAAMC,aAAaF,OAAOT,IAAI;EAEpC,OADAQ,SAASE,OAAOE,cAAc;GAACnB;GAAYgB;GAAQ5B;GAAQ2B;GAAUZ;EAAiB,CAAC,GAChFY;CACT,GAAGd,IAAI;AACT;AAEA,SAAgBiB,aAAaX,MAAsB;CACjD,OAAO,SAASA,KAAKa,OAAO,CAAC,CAAC,CAACC,YAAY,IAAId,KAAKe,MAAM,CAAC;AAC7D;AAKA,SAASG,sBAAsB,EAACV,YAAuD;CACrF,OAAO,EACLW,YAAYnB,MAAMoB,iBAAiB;EAEjC,IAAMC,UAAUb,SADJG,aAAaX,IACAU;EACzB,IAAI,CAACW,SACH,MAAUC,MAAM,0BAA0BtB,KAAI,oCAAqC;EAErF,OAAOqB,QAAQD,YAAY;CAC7B,EACF;AACF;AAUA,SAASR,cAAc,EACrBnB,YACAgB,QACA5B,QACA2B,UACAZ,qBACgC;CAChC,OAAO,SAAS4B,OAAOC,aAAa,CAAC,GAAG;EACtC,IAAMzB,OAAOyB,WAAW;EACxB,IAAI,OAAOzB,QAAS,YAAYA,KAAK0B,WAAW,GAC9C,MAAUJ,MACR,GAAGX,aAAaF,OAAOT,IAAI,EAAC,mDAC9B;EAGF3B,kBAAkBoB,YAAYgB,OAAOkB,cAAc,SAAS;EAE5D,IAAMC,kBAAkBV,sBAAsB,EAACV,SAAQ,CAAC,GAGlDqB,mBAAoBhD,OAAmC4B,OAAOT,OAQ9D,EAAC+B,KAAK,GAAGC,kBAAiBF;GAN9B,GAAI,OAAOD,oBAAqB,YAAYA,mBACxCA,mBACA,CAAC;GACL,GAAGJ;EAG2BK,GAE1BG,aAAaxB,OAAOwB,WAExBD,eACAJ,eACF;EAKA,OAHAhC,kBAAkBuC,IAAInC,MAAMiC,UAAU,GAG/BG,cACLC,sBAAsBJ,YAAYxC,UAAU,GAC5CsC,GACF;CACF;AACF;AAEA,SAASK,cAAcH,YAAkCF,KAAoC;CAC3F,IAAI,CAACA,OAAO,OAAOA,OAAQ,UAAU,OAAOE;CAE5C,IAAMK,mBAA4C,CAAC;CAEnD,KAAK,IAAM,CAACC,YAAYC,gBAAgBC,OAAOC,QAAQX,GAAG,GACpD,OAAOS,eAAgB,eAI3BF,iBAAiBC,cAAcC,YAE7BP,WAAWM,WACb;CAGF,OAAO;EAAC,GAAGN;EAAY,GAAGK;CAAgB;AAC5C;AAEA,SAASD,sBACPJ,YACAxC,YACsB;CACtB,IAAMkD,WAAW,gBAAgBV,aAAaA,WAAWW,aAAaxC,KAAAA,GAChEyC,gBACJF,YAAY,WAAWA,YAAY,OAAOA,SAASG,SAAU,aAExDH,SAASG,QACV1C,KAAAA;CAEN,OAAO;EACL,GAAG6B;EACHW,YAAY;GACV,GAAGD;GACHG,QAAQC,UACN,oBAAC,2BAAD;IAA2B,GAAIA;IAAmBtD;IAAY,WAAWoD;GAAc,CAAA;EAE3F;CACF;AACF"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["{\n  registryId,\n  userInput: UserInput,\n  ...props\n}","() => {\n    collectPresetsRegistryTelemetry(registryId, telemetry)\n  }","[registryId, telemetry]"],"sources":["../src/__telemetry__/presets.telemetry.ts","../src/telemetry.ts","../src/components/PresetsTelemetryCollector.tsx","../src/definePresetType.ts","../src/presets/cta-type/index.ts","../src/presets/image-type/index.ts","../src/presets/link-type/index.ts","../src/presets/page-type/index.ts","../src/presets/rich-text-type/index.ts","../src/presets/seo-type/index.ts","../src/registry.tsx"],"sourcesContent":["import {defineEvent} from '@sanity/telemetry'\n\ninterface PresetsAddedInfo {\n  presetNames: string[]\n}\n\nexport const PresetsAdded = defineEvent<PresetsAddedInfo>({\n  name: 'Presets Added',\n  version: 1,\n  description: 'Workspace using presets was accessed',\n})\n","import {PresetsAdded} from './__telemetry__/presets.telemetry'\n\n/**\n * Minimal interface for the subset of TelemetryLogger we need.\n * Avoids forcing callers to satisfy the full generic TelemetryLogger type.\n */\nexport interface TelemetryLog {\n  log(event: unknown, data: unknown): void\n}\n\ninterface RegistryRecord {\n  id: string\n  presets: Set<string>\n  logged: boolean\n}\n\nconst registries = new Map<string, RegistryRecord>()\n\nexport function registerRegistry(id: string): void {\n  registries.set(id, {id, presets: new Set(), logged: false})\n}\n\nexport function recordPresetUsage(registryId: string, identifier: string): void {\n  registries.get(registryId)?.presets.add(identifier)\n}\n\nexport function collectPresetsRegistryTelemetry(registryId: string, telemetry: TelemetryLog): void {\n  const record = registries.get(registryId)\n  if (!record || record.logged) return\n  record.logged = true\n  if (record.presets.size > 0) {\n    telemetry.log(PresetsAdded, {presetNames: [...record.presets]})\n  }\n}\n\n/** @internal */\nexport function resetRegistries(): void {\n  registries.clear()\n}\n","import {useTelemetry} from '@sanity/telemetry/react'\nimport {useEffect, type ComponentType} from 'react'\nimport type {InputProps} from 'sanity'\n\nimport {collectPresetsRegistryTelemetry} from '../telemetry'\n\ntype Props = InputProps & {\n  registryId: string\n  userInput?: ComponentType<InputProps>\n}\n\n/**\n * A transparent input component wrapper that triggers telemetry collection\n * for the presets registry. Renders the user-provided input component if\n * supplied, otherwise the default input component unchanged.\n *\n * Attached to every schema type produced by a define<Type> function via\n * components.input. The first instance to render for a given registry id\n * submits the PresetsAdded telemetry event; subsequent renders are no-ops.\n */\nexport const PresetsTelemetryCollector: ComponentType<Props> = ({\n  registryId,\n  userInput: UserInput,\n  ...props\n}) => {\n  const telemetry = useTelemetry()\n\n  useEffect(() => {\n    collectPresetsRegistryTelemetry(registryId, telemetry)\n  }, [registryId, telemetry])\n\n  if (UserInput) {\n    return <UserInput {...props} />\n  }\n\n  return props.renderDefault(props)\n}\n","import type {\n  FieldDefinition,\n  FieldDefinitionBase,\n  IntrinsicTypeName,\n  SchemaTypeDefinition,\n} from 'sanity'\n\nimport type {PartialSchemaDefinition} from './types'\n\nexport interface RegistryContext {\n  getPreset: (\n    presetName: string,\n    config?: Record<string, unknown>,\n  ) => SchemaTypeDefinition & FieldDefinition\n}\n\ntype ProhibitedProperties = 'type'\n\ntype SanitizeProperties<Properties, ExcludedProperties extends string | undefined> = [\n  ExcludedProperties,\n] extends [PropertyKey]\n  ? Omit<Properties, ExcludedProperties>\n  : Properties\n\nexport type DerivedConfig<\n  Context,\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n> = Context &\n  FieldDefinitionBase &\n  (AliasedType extends string\n    ? SanitizeProperties<\n        PartialSchemaDefinition<AliasedType>,\n        ProhibitedProperties | LockedProperties\n      >\n    : {}) & {\n    map?: AliasedType extends string\n      ? {\n          [Key in keyof PartialSchemaDefinition<AliasedType>]?: (\n            input: PartialSchemaDefinition<AliasedType>[Key],\n          ) => PartialSchemaDefinition<AliasedType>[Key]\n        }\n      : {}\n  }\n\n/**\n * The public-facing config shape that a registry's `define<Name>` function\n * accepts at the call site. Includes the full `DerivedConfig` with required\n * `name` (inherited from `FieldDefinitionBase`) and optional `map`.\n */\nexport type UserConfig<\n  Context = {},\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n> = DerivedConfig<Context, AliasedType, LockedProperties>\n\n/**\n * A preset definition describes how to produce a Sanity schema type.\n *\n * - `name` is the registry key for the preset (it determines the\n *   `define<Name>` function and the `PresetsRegistryConfig` key).\n * - `identifier` is an optional stable identifier used for telemetry.\n * - `schemaType` is the factory that produces the Sanity schema type. It\n *   receives the merged config (minus `map`) and the registry context, and\n *   returns a `SchemaTypeDefinition`.\n */\nexport interface PresetDefinition<\n  Context = {},\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n> {\n  name: string\n  identifier?: string\n  schemaType: (\n    config: Omit<DerivedConfig<Context, AliasedType, LockedProperties>, 'map' | 'name'> & {\n      name: string\n    },\n    registry: RegistryContext,\n  ) => SchemaTypeDefinition\n}\n\n/**\n * A typed passthrough for defining a preset. Given a `PresetDefinition`, it\n * returns the same value, narrowed to its concrete generic parameters so\n * downstream code can infer the preset's config type from it.\n *\n * This is intentionally lightweight: it performs no work at call time. The\n * registry is responsible for invoking `schemaType` when a preset is\n * instantiated, and for applying `map` hooks to the produced schema type.\n */\nexport function definePresetType<\n  Context = {},\n  AliasedType extends IntrinsicTypeName | undefined = undefined,\n  LockedProperties extends string | undefined = undefined,\n>(\n  preset: PresetDefinition<Context, AliasedType, LockedProperties>,\n): PresetDefinition<Context, AliasedType, LockedProperties> {\n  return preset\n}\n\n/**\n * A preset definition with its generic parameters erased, for use in code\n * that handles presets generically (e.g. the registry).\n */\nexport type AnyPresetDefinition = PresetDefinition<any, any, any>\n","import {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport const ctaType = definePresetType<{}, 'object', 'preview'>({\n  name: 'cta',\n  identifier: 'core.cta',\n  schemaType: (config, registry) => {\n    const {fields, ...objectConfig} = config\n\n    return defineType({\n      ...objectConfig,\n      type: 'object',\n      fields: [\n        registry.getPreset('link', {name: 'link', title: 'Link'}),\n        defineField({\n          name: 'level',\n          title: 'Level',\n          description:\n            'The importance of the action relative to its siblings: level 1 being the primary action, 2 the secondary action, and so on.',\n          type: 'number',\n          options: {\n            layout: 'radio',\n            list: [1, 2, 3],\n          },\n        }),\n        ...(fields ?? []),\n      ],\n      preview: {\n        select: {\n          linkType: 'link.linkType',\n          url: 'link.url',\n          referenceTitle: 'link.reference.title',\n          referenceName: 'link.reference.name',\n        },\n        prepare({linkType, url, referenceTitle, referenceName}) {\n          const referenceLabel = referenceTitle || referenceName || 'No reference'\n          const title = linkType === 'external' ? url || 'No URL' : referenceLabel\n          return {title, subtitle: 'Button'}\n        },\n      },\n    })\n  },\n})\n","import {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport interface ImageTypeConfig {\n  altText?: boolean\n  caption?: boolean\n  hotspot?: boolean\n}\n\nexport const imageType = definePresetType<ImageTypeConfig, 'image', 'preview'>({\n  name: 'image',\n  identifier: 'core.image',\n  schemaType: (config) => {\n    const {altText = true, caption = true, hotspot = true, fields, ...imageConfig} = config\n\n    return defineType({\n      ...imageConfig,\n      type: 'image',\n      // hotspot is the curated default; callers override other image options (accept, sources, storeOriginalFilename) via the map.options hook\n      options: {\n        hotspot,\n      },\n      fields: [\n        ...(altText\n          ? [\n              defineField({\n                name: 'altText',\n                title: 'Alt text',\n                description:\n                  'Describes the image for screen readers and search engines. Important for accessibility.',\n                type: 'string',\n                validation: (rule) => rule.warning('Alt text improves accessibility.'),\n              }),\n            ]\n          : []),\n        ...(caption\n          ? [\n              defineField({\n                name: 'caption',\n                title: 'Caption',\n                type: 'text',\n              }),\n            ]\n          : []),\n        ...(fields ?? []),\n      ],\n      preview: {\n        select: {\n          title: altText ? 'altText' : caption ? 'caption' : 'asset.originalFilename',\n        },\n      },\n    })\n  },\n})\n","import {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\ntype LinkToEntry = string | {type: string}\n\nexport interface LinkTypeConfig {\n  to?: LinkToEntry[]\n}\n\nfunction normalizeToTargets(entries: LinkToEntry[]): {type: string}[] {\n  return entries.map((entry) => (typeof entry === 'string' ? {type: entry} : entry))\n}\n\nexport const linkType = definePresetType<LinkTypeConfig, 'object', 'preview'>({\n  name: 'link',\n  identifier: 'core.link',\n  schemaType: ({to, fields, ...objectConfig}) => {\n    const referenceTargets = normalizeToTargets(to ?? [])\n\n    return defineType({\n      ...objectConfig,\n      type: 'object',\n      fields: [\n        defineField({\n          name: 'linkType',\n          type: 'string',\n          title: 'Link Type',\n          description:\n            'Internal links point to a page in this project. External links point to a full URL.',\n          initialValue: 'internal',\n          options: {\n            layout: 'radio',\n            list: [\n              {title: 'Internal', value: 'internal'},\n              {title: 'External', value: 'external'},\n            ],\n          },\n        }),\n        defineField({\n          name: 'reference',\n          type: 'reference',\n          title: 'Internal Link',\n          to: referenceTargets,\n          hidden: ({parent}) => parent?.linkType === 'external',\n        }),\n        defineField({\n          name: 'url',\n          type: 'url',\n          title: 'URL',\n          description:\n            'Full URL including protocol, e.g. https://example.com. Supports http, https, mailto, and tel.',\n          hidden: ({parent}) => parent?.linkType === 'internal',\n          validation: (rule) =>\n            rule.uri({\n              scheme: ['http', 'https', 'mailto', 'tel'],\n            }),\n        }),\n        defineField({\n          name: 'openInNewTab',\n          type: 'boolean',\n          title: 'Open in New Tab',\n          initialValue: false,\n          hidden: ({parent}) => parent?.linkType === 'internal',\n        }),\n        ...(fields ?? []),\n      ],\n      preview: {\n        select: {\n          linkType: 'linkType',\n          url: 'url',\n          referenceTitle: 'reference.title',\n          referenceName: 'reference.name',\n        },\n        prepare({linkType, url, referenceTitle, referenceName}) {\n          const referenceLabel = referenceTitle || referenceName || 'No reference'\n          const title = linkType === 'external' ? url || 'No URL' : referenceLabel\n\n          return {\n            title,\n            subtitle: linkType === 'external' ? 'External link' : 'Internal link',\n          }\n        },\n      },\n    })\n  },\n})\n","import {\n  ALL_FIELDS_GROUP,\n  type ArrayDefinition,\n  defineArrayMember,\n  defineField,\n  defineType,\n  type FieldDefinition,\n  type SchemaTypeDefinition,\n} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport type PageBuilderBlock = string | (SchemaTypeDefinition & FieldDefinition)\n\ntype LookupArrayPreset = (name: string) => ArrayDefinition | undefined\n\n// Sanity rejects array members whose `type` resolves to another array. Wrap\n// array presets in an object so they can serve as page-builder members.\nfunction wrapArrayAsPageBuilderBlock(arraySchema: ArrayDefinition) {\n  const components = 'components' in arraySchema ? arraySchema.components : undefined\n  return defineArrayMember({\n    name: arraySchema.name,\n    title: arraySchema.title,\n    type: 'object',\n    fields: [\n      defineField({\n        name: 'content',\n        type: 'array',\n        of: arraySchema.of,\n        components,\n      }),\n    ],\n  })\n}\n\nfunction toPageBuilderArrayMember(block: PageBuilderBlock, lookupArrayPreset: LookupArrayPreset) {\n  if (typeof block === 'string') {\n    const arrayPreset = lookupArrayPreset(block)\n    if (arrayPreset) {\n      return wrapArrayAsPageBuilderBlock(arrayPreset)\n    }\n    return defineArrayMember({type: block})\n  }\n  if (block.type === 'array') {\n    // oxlint-disable-next-line no-unsafe-type-assertion -- discriminating on `type` does not narrow the intersected union\n    return wrapArrayAsPageBuilderBlock(block as ArrayDefinition)\n  }\n  return defineArrayMember(block)\n}\n\n// Defer building `content.of` so by-name references resolve after every\n// `define<X>` has run. Memoised for stable array identity across reads.\nfunction defineLazyContentField(\n  blocks: PageBuilderBlock[],\n  lookupArrayPreset: LookupArrayPreset,\n): FieldDefinition {\n  let cached: ReturnType<typeof toPageBuilderArrayMember>[] | undefined\n  return defineField({\n    name: 'content',\n    title: 'Content',\n    description:\n      'Page sections rendered in order. Add, remove, or reorder blocks to build the page.',\n    group: 'main',\n    type: 'array',\n    get of() {\n      cached ??= blocks.map((block) => toPageBuilderArrayMember(block, lookupArrayPreset))\n      return cached\n    },\n  })\n}\n\nexport interface PageTypeConfig {\n  pageBuilderBlocks?: PageBuilderBlock[]\n}\n\n// `lookupArrayPreset` is closure-injected by the registry to keep it off\n// the public `RegistryContext`. The default `pageType` below uses a no-op.\nexport function createPageType({lookupArrayPreset}: {lookupArrayPreset: LookupArrayPreset}) {\n  return definePresetType<PageTypeConfig, 'document'>({\n    name: 'page',\n    identifier: 'core.page',\n    schemaType: (config, registry) => {\n      const {pageBuilderBlocks, groups, fields, ...documentConfig} = config\n\n      return defineType({\n        ...documentConfig,\n        type: 'document',\n        groups: [\n          {\n            ...ALL_FIELDS_GROUP,\n            hidden: true,\n          },\n          {\n            name: 'main',\n            title: 'Main',\n            default: true,\n          },\n          {\n            name: 'metadata',\n            title: 'Metadata',\n          },\n          ...(groups ?? []),\n        ],\n        fields: [\n          defineField({\n            name: 'name',\n            title: 'Name',\n            description: 'Used as the page title and as the source for the auto-generated slug.',\n            type: 'string',\n            group: 'main',\n            validation: (rule) => rule.required(),\n          }),\n          defineField({\n            name: 'slug',\n            title: 'Slug',\n            type: 'slug',\n            group: 'main',\n            options: {\n              source: 'name',\n            },\n          }),\n          defineLazyContentField(pageBuilderBlocks ?? [], lookupArrayPreset),\n          registry.getPreset('seo', {\n            name: 'seo',\n            title: 'SEO',\n            group: 'metadata',\n          }),\n          ...(fields ?? []),\n        ],\n      })\n    },\n  })\n}\n\nexport const pageType = createPageType({lookupArrayPreset: () => undefined})\n","import {defineArrayMember, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport interface RichTextObjectsConfig {\n  link?: boolean\n  image?: boolean\n  cta?: boolean\n}\n\nexport interface RichTextTypeConfig {\n  /**\n   * Toggle the embedded objects (link annotations, image blocks, inline CTAs).\n   * Defaults to all enabled. Pass `false` to disable every object, or an\n   * object to toggle individual ones (e.g. `{link: false}`).\n   *\n   * Each object's options (link `to`, image `altText`, …) are\n   * configured on `createPresetsRegistry` and cascade into every rich text\n   * field. Use `map.of` for per-field structural changes.\n   */\n  objects?: boolean | RichTextObjectsConfig\n}\n\nfunction resolveObjects(objects: RichTextTypeConfig['objects']): Required<RichTextObjectsConfig> {\n  if (objects === false) return {link: false, image: false, cta: false}\n  if (objects === true || objects === undefined) return {link: true, image: true, cta: true}\n  const {link = true, image = true, cta = true} = objects\n  return {link, image, cta}\n}\n\nexport const richTextType = definePresetType<RichTextTypeConfig, 'array', 'of'>({\n  name: 'richText',\n  identifier: 'core.richText',\n  schemaType: (config, registry) => {\n    const {objects, ...arrayConfig} = config\n    const {link, image, cta} = resolveObjects(objects)\n\n    // The annotation name must be 'link' — Portable Text Editor's built-in link UI keys off this name.\n    const linkAnnotation = link\n      ? registry.getPreset('link', {name: 'link', title: 'Link'})\n      : undefined\n    const ctaInline = cta ? registry.getPreset('cta', {name: 'cta', title: 'CTA'}) : undefined\n    const imageMember = image\n      ? registry.getPreset('image', {name: 'richTextImage', title: 'Image'})\n      : undefined\n\n    const blockMember = defineArrayMember({\n      type: 'block',\n      marks: {annotations: linkAnnotation ? [linkAnnotation] : []},\n      ...(ctaInline && {of: [ctaInline]}),\n    })\n\n    return defineType({\n      ...arrayConfig,\n      type: 'array',\n      of: imageMember ? [blockMember, imageMember] : [blockMember],\n    })\n  },\n})\n","import {getImageDimensions} from '@sanity/asset-utils'\nimport {defineField, defineType} from 'sanity'\n\nimport {definePresetType} from '../../definePresetType'\n\nexport const seoType = definePresetType<{}, 'object'>({\n  name: 'seo',\n  identifier: 'core.seo',\n  schemaType: (config) => {\n    const {fields, ...objectConfig} = config\n\n    return defineType({\n      ...objectConfig,\n      type: 'object',\n      fields: [\n        defineField({\n          name: 'title',\n          title: 'Title',\n          type: 'string',\n          validation: (rule) => rule.max(70).info('Search engines may truncate this title.'),\n        }),\n        defineField({\n          name: 'description',\n          title: 'Description',\n          type: 'text',\n          validation: (rule) => rule.max(150).info('Search engines may truncate this description.'),\n        }),\n        defineField({\n          name: 'ogImage',\n          title: 'Open Graph image',\n          type: 'image',\n          description: 'Landscape 1200x630 (1.91:1)',\n          options: {\n            hotspot: {\n              previews: [\n                {\n                  title: 'Landscape (1.91:1)',\n                  aspectRatio: 1.91 / 1,\n                },\n              ],\n            },\n          },\n          validation: (Rule) =>\n            Rule.custom((value) => {\n              if (!value?.asset?._ref) {\n                return true\n              }\n\n              const {height, width} = getImageDimensions(value.asset?._ref)\n\n              if (height !== 630 || width !== 1200) {\n                return 'Open Graph images are recommended to be exactly 1200x630 (1.91:1) for the best social sharing previews.'\n              }\n\n              return true\n            }).warning(),\n        }),\n        ...(fields ?? []),\n      ],\n    })\n  },\n})\n","import {uuid} from '@sanity/uuid'\nimport {type ComponentType} from 'react'\nimport type {ArrayDefinition, FieldDefinition, InputProps, SchemaTypeDefinition} from 'sanity'\n\nimport {PresetsTelemetryCollector} from './components/PresetsTelemetryCollector'\nimport type {\n  AnyPresetDefinition,\n  PresetDefinition,\n  RegistryContext,\n  UserConfig,\n} from './definePresetType'\nimport {ctaType} from './presets/cta-type'\nimport {imageType, type ImageTypeConfig} from './presets/image-type'\nimport {linkType, type LinkTypeConfig} from './presets/link-type'\nimport {createPageType, pageType, type PageTypeConfig} from './presets/page-type'\nimport {richTextType} from './presets/rich-text-type'\nimport {seoType} from './presets/seo-type'\nimport {recordPresetUsage, registerRegistry} from './telemetry'\n\nexport interface PresetsRegistryConfig {\n  link?: LinkTypeConfig\n  image?: ImageTypeConfig\n  page?: PageTypeConfig\n}\n\ntype DefineFunction<Preset extends AnyPresetDefinition> =\n  Preset extends PresetDefinition<infer Context, infer AliasedType, infer LockedProperties>\n    ? (\n        config: UserConfig<Context, AliasedType, LockedProperties>,\n      ) => SchemaTypeDefinition & FieldDefinition\n    : never\n\nexport interface PresetsRegistry {\n  defineLink: DefineFunction<typeof linkType>\n  defineCta: DefineFunction<typeof ctaType>\n  defineSeo: DefineFunction<typeof seoType>\n  defineImage: DefineFunction<typeof imageType>\n  definePage: DefineFunction<typeof pageType>\n  defineRichText: DefineFunction<typeof richTextType>\n}\n\nexport function createPresetsRegistry(config: PresetsRegistryConfig = {}): PresetsRegistry {\n  const registryId = uuid()\n  registerRegistry(registryId)\n\n  // oxlint-disable-next-line no-unsafe-type-assertion -- seeding reduce with an empty object that is populated by each iteration\n  const seed = {} as DefinerRecord & PresetsRegistry\n\n  // Tracks the schema produced under each defined preset name so `pageType`\n  // can resolve string references in `pageBuilderBlocks` regardless of\n  // definition order, and wrap array-typed presets at the page builder\n  // boundary. Closure-injected into `pageType` via `createPageType` so it\n  // does not need to live on the public `RegistryContext`.\n  const registeredSchemas = new Map<string, SchemaTypeDefinition>()\n  const pageTypeWithLookup = createPageType({\n    lookupArrayPreset: (name) => {\n      const registered = registeredSchemas.get(name)\n      // oxlint-disable-next-line no-unsafe-type-assertion -- discriminating on `type` does not narrow the intersected union\n      return registered?.type === 'array' ? (registered as ArrayDefinition) : undefined\n    },\n  })\n\n  const systemPresets = [\n    linkType,\n    ctaType,\n    seoType,\n    imageType,\n    pageTypeWithLookup,\n    richTextType,\n  ] as const\n\n  return systemPresets.reduce((registry, preset) => {\n    const key = getPresetKey(preset.name)\n    registry[key] = createDefiner({registryId, preset, config, registry, registeredSchemas})\n    return registry\n  }, seed)\n}\n\nexport function getPresetKey(name: string): string {\n  return `define${name.charAt(0).toUpperCase()}${name.slice(1)}`\n}\n\ntype Definer = (config?: Record<string, unknown>) => SchemaTypeDefinition & FieldDefinition\ntype DefinerRecord = Record<string, Definer>\n\nfunction createRegistryContext({registry}: {registry: DefinerRecord}): RegistryContext {\n  return {\n    getPreset: (name, presetConfig) => {\n      const key = getPresetKey(name)\n      const definer = registry[key]\n      if (!definer) {\n        throw new Error(`Cannot resolve preset \"${name}\". No such preset in this registry.`)\n      }\n      return definer(presetConfig)\n    },\n  }\n}\n\ninterface CreateDefinerOptions {\n  registryId: string\n  preset: AnyPresetDefinition\n  config: PresetsRegistryConfig\n  registry: DefinerRecord\n  registeredSchemas: Map<string, SchemaTypeDefinition>\n}\n\nfunction createDefiner({\n  registryId,\n  preset,\n  config,\n  registry,\n  registeredSchemas,\n}: CreateDefinerOptions): Definer {\n  return function define(userConfig = {}) {\n    const name = userConfig['name']\n    if (typeof name !== 'string' || name.length === 0) {\n      throw new Error(\n        `${getPresetKey(preset.name)}: \"name\" is required. Pass {name: \"yourTypeName\"}.`,\n      )\n    }\n\n    recordPresetUsage(registryId, preset.identifier ?? 'unnamed')\n\n    const registryContext = createRegistryContext({registry})\n\n    // oxlint-disable-next-line no-unsafe-type-assertion -- PresetsRegistryConfig is keyed by preset name; dynamic lookup is safe\n    const registryDefaults = (config as Record<string, unknown>)[preset.name]\n    const mergedConfig: Record<string, unknown> = {\n      ...(typeof registryDefaults === 'object' && registryDefaults !== null\n        ? registryDefaults\n        : {}),\n      ...userConfig,\n    }\n\n    const {map, ...factoryConfig} = mergedConfig\n\n    const schemaType = preset.schemaType(\n      // oxlint-disable-next-line no-unsafe-type-assertion -- factoryConfig is the merged user config (minus `map`, with `name` injected); its shape matches the factory's expected parameter at runtime\n      factoryConfig as unknown as Parameters<AnyPresetDefinition['schemaType']>[0],\n      registryContext,\n    )\n\n    registeredSchemas.set(name, schemaType)\n\n    // oxlint-disable-next-line no-unsafe-type-assertion -- runtime value is a valid field definition\n    return applyMapHooks(\n      addTelemetryComponent(schemaType, registryId),\n      map,\n    ) as SchemaTypeDefinition & FieldDefinition\n  }\n}\n\nfunction applyMapHooks(schemaType: SchemaTypeDefinition, map: unknown): SchemaTypeDefinition {\n  if (!map || typeof map !== 'object') return schemaType\n\n  const mappedSchemaType: Record<string, unknown> = {}\n\n  for (const [configName, configValue] of Object.entries(map)) {\n    if (typeof configValue !== 'function') {\n      continue\n    }\n\n    mappedSchemaType[configName] = configValue(\n      // oxlint-disable-next-line no-unsafe-type-assertion -- map hooks operate on arbitrary schema type properties\n      schemaType[configName as keyof typeof schemaType],\n    )\n  }\n\n  return {...schemaType, ...mappedSchemaType}\n}\n\nfunction addTelemetryComponent(\n  schemaType: SchemaTypeDefinition,\n  registryId: string,\n): SchemaTypeDefinition {\n  const existing = 'components' in schemaType ? schemaType.components : undefined\n  const existingInput =\n    existing && 'input' in existing && typeof existing.input === 'function'\n      ? // oxlint-disable-next-line no-unsafe-type-assertion -- presets only produce object/document schema types, whose input components are assignable to ComponentType<InputProps>\n        (existing.input as ComponentType<InputProps>)\n      : undefined\n  // oxlint-disable-next-line no-unsafe-type-assertion -- spreading a discriminated union loses the discriminant; the runtime shape is still a valid SchemaTypeDefinition\n  return {\n    ...schemaType,\n    components: {\n      ...existing,\n      input: (props: InputProps) => (\n        <PresetsTelemetryCollector {...props} registryId={registryId} userInput={existingInput} />\n      ),\n    },\n  } as SchemaTypeDefinition\n}\n"],"mappings":"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"}
\ No newline at end of file