@seedprotocol/mapping 0.6.2 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +22 -3
  3. package/dist/applyMapping.d.ts +4 -2
  4. package/dist/applyMapping.d.ts.map +1 -1
  5. package/dist/autoMap-Dh9SiWhT.js +631 -0
  6. package/dist/autoMap-Dh9SiWhT.js.map +1 -0
  7. package/dist/edgeMapping.d.ts +21 -0
  8. package/dist/edgeMapping.d.ts.map +1 -0
  9. package/dist/index.d.ts +2 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +34 -34
  12. package/dist/react/FieldMapper.d.ts +12 -2
  13. package/dist/react/FieldMapper.d.ts.map +1 -1
  14. package/dist/react/FieldMapperWires.d.ts.map +1 -1
  15. package/dist/react/PropertyRows.d.ts +4 -2
  16. package/dist/react/PropertyRows.d.ts.map +1 -1
  17. package/dist/react/SourceRows.d.ts +4 -2
  18. package/dist/react/SourceRows.d.ts.map +1 -1
  19. package/dist/react/fieldMapperCore.d.ts +3 -1
  20. package/dist/react/fieldMapperCore.d.ts.map +1 -1
  21. package/dist/react/fieldMapperSlots.d.ts +1 -1
  22. package/dist/react/fieldMapperSlots.d.ts.map +1 -1
  23. package/dist/react/fieldMapperTheme.d.ts +1 -1
  24. package/dist/react/fieldMapperTheme.d.ts.map +1 -1
  25. package/dist/react/fieldMapperTransforms.d.ts +7 -0
  26. package/dist/react/fieldMapperTransforms.d.ts.map +1 -0
  27. package/dist/react/fieldMapperTypes.d.ts +11 -1
  28. package/dist/react/fieldMapperTypes.d.ts.map +1 -1
  29. package/dist/react/useFieldMapper.d.ts.map +1 -1
  30. package/dist/react.d.ts +2 -1
  31. package/dist/react.d.ts.map +1 -1
  32. package/dist/react.js +741 -658
  33. package/dist/react.js.map +1 -1
  34. package/dist/resolvedSources.d.ts.map +1 -1
  35. package/dist/types.d.ts +20 -3
  36. package/dist/types.d.ts.map +1 -1
  37. package/package.json +1 -1
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":[],"sources":["../src/react/fieldMapperControls.tsx","../src/react/fieldMapperSlots.ts","../src/react/fieldMapperCore.ts","../src/react/LookupEditor.tsx","../src/react/fieldMapperTheme.ts","../src/react/FieldMapperWires.tsx","../src/react/PropertyRows.tsx","../src/react/SourceRows.tsx","../src/react/useFieldMapper.ts","../src/react/FieldMapper.tsx"],"sourcesContent":["import React from 'react'\nimport type {\n FieldMapperButtonProps,\n FieldMapperPillProps,\n FieldMapperSelectProps,\n} from './fieldMapperSlots'\n\n/** Default native select used when no `components.Select` is provided. */\nexport function DefaultSelect({\n className,\n value,\n onChange,\n children,\n disabled,\n 'aria-label': ariaLabel,\n}: FieldMapperSelectProps) {\n return (\n <select\n className={className}\n aria-label={ariaLabel}\n disabled={disabled}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n >\n {children}\n </select>\n )\n}\n\n/** Default native button used when no `components.Button` is provided. */\nexport function DefaultButton({\n className,\n type = 'button',\n onClick,\n children,\n disabled,\n 'aria-label': ariaLabel,\n 'aria-pressed': ariaPressed,\n}: FieldMapperButtonProps) {\n return (\n <button\n type={type}\n className={className}\n onClick={onClick}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-pressed={ariaPressed}\n >\n {children}\n </button>\n )\n}\n\n/** Default span pill used when no `components.Pill` is provided. */\nexport function DefaultPill({\n className,\n children,\n}: FieldMapperPillProps) {\n return <span className={className}>{children}</span>\n}\n","import type { ComponentType, MouseEvent, ReactNode } from 'react'\nimport type { FieldMapperLayout } from './fieldMapperTypes'\n\nexport type FieldMapperSlot =\n | 'root'\n | 'toolbar'\n | 'filter'\n | 'coverage'\n | 'autoMapButton'\n | 'rowList'\n | 'row'\n | 'propertyLabel'\n | 'dataType'\n | 'sourceSelect'\n | 'transformSelect'\n | 'rowAccessory'\n | 'preview'\n | 'validation'\n | 'removeButton'\n | 'addButton'\n | 'inspector'\n | 'lookupEditor'\n | 'jsonPreview'\n\nexport type FieldMapperSlots = {\n autoMap?: boolean\n filter?: boolean\n inspector?: boolean\n preview?: 'row' | 'json' | 'both' | false\n /**\n * Lookup editor placement.\n * Unspecified defaults to `'row'` when `layout === 'rows'`, otherwise `'section'`.\n */\n lookups?: 'row' | 'section' | false\n}\n\nexport type ResolvedFieldMapperSlots = {\n autoMap: boolean\n filter: boolean\n inspector: boolean\n preview: 'row' | 'json' | 'both' | false\n lookups: 'row' | 'section' | false\n}\n\nexport type ResolveSlotsOptions = {\n /** Used when `slots.lookups` is unspecified. */\n layout?: FieldMapperLayout\n}\n\nexport type FieldMapperSelectProps = {\n className?: string\n value: string\n onChange: (value: string) => void\n 'aria-label'?: string\n children: ReactNode\n disabled?: boolean\n}\n\nexport type FieldMapperButtonProps = {\n className?: string\n type?: 'button' | 'submit' | 'reset'\n onClick?: (e: MouseEvent<HTMLButtonElement>) => void\n children: ReactNode\n disabled?: boolean\n 'aria-label'?: string\n 'aria-pressed'?: boolean | 'true' | 'false'\n}\n\nexport type FieldMapperPillProps = {\n children: ReactNode\n className?: string\n}\n\nexport type FieldMapperComponents = {\n Select?: ComponentType<FieldMapperSelectProps>\n Button?: ComponentType<FieldMapperButtonProps>\n Pill?: ComponentType<FieldMapperPillProps>\n}\n\nexport type ResolvedFieldMapperComponents = {\n Select: ComponentType<FieldMapperSelectProps>\n Button: ComponentType<FieldMapperButtonProps>\n Pill: ComponentType<FieldMapperPillProps>\n}\n\n/** Package class names per slot (merged with host `classNames`). */\nexport const SLOT_BASE_CLASS: Record<FieldMapperSlot, string> = {\n root: 'seed-field-mapper',\n toolbar: 'fm-toolbar',\n filter: 'fm-filter',\n coverage: 'fm-meta',\n autoMapButton: 'fm-btn fm-btn-primary',\n rowList: 'fm-row-list',\n row: 'fm-row',\n propertyLabel: 'fm-row-prop-name',\n dataType: 'fm-dtype',\n sourceSelect: 'fm-select',\n transformSelect: 'fm-select',\n rowAccessory: 'fm-row-accessory',\n preview: 'fm-row-preview',\n validation: 'fm-row-flag',\n removeButton: 'fm-remove',\n addButton: 'fm-btn',\n inspector: 'fm-inspector',\n lookupEditor: 'fm-lookups',\n jsonPreview: 'fm-preview',\n}\n\n/** Merge package slot class with optional host classNames entry. */\nexport function slotClass(\n slot: FieldMapperSlot,\n classNames?: Partial<Record<FieldMapperSlot, string>>,\n extra?: string | null,\n): string {\n return [SLOT_BASE_CLASS[slot], classNames?.[slot], extra]\n .filter(Boolean)\n .join(' ')\n}\n\n/**\n * Resolve slots + deprecated `showPreview` shim.\n * Default preview is `'both'` (row preview + JSON disclosure) when unspecified.\n * Unspecified lookups: `'row'` for rows layout, `'section'` for wires.\n */\nexport function resolveSlots(\n slots?: FieldMapperSlots,\n showPreview?: boolean,\n options?: ResolveSlotsOptions,\n): ResolvedFieldMapperSlots {\n let preview: ResolvedFieldMapperSlots['preview']\n if (slots?.preview !== undefined) {\n preview = slots.preview\n } else if (showPreview === false) {\n preview = false\n } else {\n preview = 'both'\n }\n\n let lookups: ResolvedFieldMapperSlots['lookups']\n if (slots?.lookups === false) {\n lookups = false\n } else if (slots?.lookups === 'row' || slots?.lookups === 'section') {\n lookups = slots.lookups\n } else {\n lookups = options?.layout === 'rows' ? 'row' : 'section'\n }\n\n return {\n autoMap: slots?.autoMap ?? true,\n filter: slots?.filter ?? true,\n inspector: slots?.inspector ?? true,\n preview,\n lookups,\n }\n}\n\nexport function showRowPreview(\n preview: ResolvedFieldMapperSlots['preview'],\n): boolean {\n return preview === 'row' || preview === 'both'\n}\n\nexport function showJsonPreview(\n preview: ResolvedFieldMapperSlots['preview'],\n): boolean {\n return preview === 'json' || preview === 'both'\n}\n","import { applyMapping, coerceValue } from '../applyMapping'\nimport { looksLikeUrl } from '../classifyUrl'\nimport {\n isRelationLookupTarget,\n resolveLookupMapped,\n sampleValueFromSource,\n shapeLookupValue,\n stripLookup,\n withLookupEntries,\n} from '../relationLookup'\nimport {\n normalizeMappingFromSourceId,\n parseResolvedSourceId,\n} from '../resolvedSources'\nimport type {\n FieldMapping,\n LookupEntry,\n MappingLookups,\n ResolveJob,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperCoverage,\n FieldMapperOption,\n FieldMapperRow,\n FieldMapperRowState,\n} from './fieldMapperTypes'\n\nexport function truncateSample(s: string, n = 40): string {\n const t = s.replace(/\\s+/g, ' ').trim()\n if (t.length <= n) return t\n return `${t.slice(0, n)}…`\n}\n\nexport function formatSourceOptionLabel(source: SourceNode): string {\n const head = source.subtitle\n ? `${source.label} · ${source.subtitle}`\n : source.label\n const sample = truncateSample(source.value, 36)\n if (!sample) return head\n return `${head} · \"${sample}\"`\n}\n\n/** Origin sources only — rows UI does not list `@extract`/`@file` cards. */\nexport function originSources(sources: SourceNode[]): SourceNode[] {\n return sources.filter((s) => s.kind !== 'resolved')\n}\n\nexport function buildSourceOptions(sources: SourceNode[]): FieldMapperOption[] {\n return originSources(sources).map((s) => ({\n value: s.id,\n label: formatSourceOptionLabel(s),\n sample: s.value,\n kind: s.kind,\n }))\n}\n\nexport function buildPropertyOptions(\n targets: TargetProperty[],\n): FieldMapperOption[] {\n return targets.map((t) => ({\n value: t.name,\n label: t.required ? `${t.name} *` : t.name,\n dataType: t.dataType,\n }))\n}\n\nfunction sourceLooksLikeUrl(source: SourceNode): boolean {\n if (source.kind === 'full' || source.kind === 'section') return false\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n if (url.trim().includes('<')) return false\n return looksLikeUrl(url)\n}\n\n/**\n * Transform required for a usable apply — mirrors autoMap / applyMapping rules.\n */\nexport function computeRequiredResolve(\n source: SourceNode | undefined,\n target: TargetProperty | undefined,\n): ResolveJob | null {\n if (!source || !target) return null\n if (isRelationLookupTarget(target)) return 'lookup'\n if (sourceLooksLikeUrl(source)) {\n if (target.dataType === 'Image' || target.dataType === 'File') return 'file'\n if (target.dataType === 'Html') return 'extract'\n }\n return null\n}\n\nexport type PreviewForEdgeOptions = {\n target?: TargetProperty\n lookups?: MappingLookups\n propertyName?: string\n mapping?: FieldMapping\n}\n\n/**\n * Sync row preview aligned with `applyMapping` / lookup tables.\n * `extract`/`file` stay descriptive (sync apply skips them).\n * `lookup` shows a stored-entry hit when present; otherwise a pending placeholder.\n * Plain copy shows the coerced value when a target is known.\n */\nexport function previewForEdge(\n source: SourceNode | undefined,\n resolve: ResolveJob | undefined,\n options?: PreviewForEdgeOptions,\n): string {\n if (!source) return ''\n if (resolve === 'extract') {\n return `‹extract HTML from ${truncateSample(source.value, 48)}›`\n }\n if (resolve === 'file') {\n return `‹file stored from ${truncateSample(source.value, 48)}›`\n }\n if (resolve === 'lookup') {\n const raw = source.value || source.label\n const mapping = options?.mapping ?? {\n sourceId: source.id,\n propertyName: options?.propertyName ?? options?.target?.name ?? '',\n resolve: 'lookup' as const,\n }\n const mapped = resolveLookupMapped(mapping, raw, options?.lookups)\n if (mapped !== undefined) {\n const shaped = options?.target\n ? shapeLookupValue(mapped, options.target)\n : mapped\n if (Array.isArray(shaped)) {\n return truncateSample(shaped.join(', '), 80)\n }\n return truncateSample(String(shaped), 80)\n }\n return `‹lookup ref for \"${truncateSample(source.value, 48)}\"›`\n }\n // Sync apply skips plain copies onto relation targets.\n if (options?.target && isRelationLookupTarget(options.target)) {\n return ''\n }\n if (options?.target) {\n const raw = source.value || source.label\n const coerced = coerceValue(raw, options.target.dataType)\n if (typeof coerced === 'string') return truncateSample(coerced, 80)\n if (typeof coerced === 'number' || typeof coerced === 'boolean') {\n return String(coerced)\n }\n try {\n return truncateSample(JSON.stringify(coerced), 80)\n } catch {\n return truncateSample(String(coerced), 80)\n }\n }\n return truncateSample(source.value, 80)\n}\n\n/**\n * JSON preview bag: sync `applyMapping` output plus `_pendingResolve` for\n * edges that require a host resolver (matches wires layout).\n */\nexport function buildSyncPreviewBag(\n sources: SourceNode[],\n mappings: FieldMapping[],\n targets: TargetProperty[],\n): Record<string, unknown> {\n const bag = applyMapping(sources, mappings, targets) as Record<\n string,\n unknown\n >\n const pendingResolve = mappings.filter(\n (m) => m.resolve && m.resolve !== 'lookup',\n )\n if (pendingResolve.length === 0) return bag\n return {\n ...bag,\n _pendingResolve: pendingResolve.map((m) => ({\n propertyName: m.propertyName,\n sourceId: m.sourceId,\n resolve: m.resolve,\n })),\n }\n}\n\nexport function rowState(args: {\n mapping?: FieldMapping\n requiredResolve: ResolveJob | null\n conflict?: boolean\n sampleValue?: string\n lookups?: MappingLookups\n}): FieldMapperRowState {\n if (args.conflict) return 'conflict'\n if (!args.mapping?.sourceId || !args.mapping.propertyName) return 'empty'\n const actual = args.mapping.resolve ?? null\n if (args.requiredResolve && actual !== args.requiredResolve) {\n return 'needsResolve'\n }\n if (actual === 'lookup') {\n const sample = args.sampleValue ?? ''\n if (\n !sample ||\n resolveLookupMapped(args.mapping, sample, args.lookups) === undefined\n ) {\n return 'needsLookup'\n }\n }\n return 'mapped'\n}\n\n\nexport function computeCoverage(\n targets: TargetProperty[],\n mappings: FieldMapping[],\n): FieldMapperCoverage {\n const mappedProps = new Set(\n mappings.filter((m) => m.sourceId && m.propertyName).map((m) => m.propertyName),\n )\n const missingRequired = targets\n .filter((t) => t.required && !mappedProps.has(t.name))\n .map((t) => t.name)\n return {\n mapped: mappedProps.size,\n total: targets.length,\n missingRequired,\n }\n}\n\nexport function findConflicts(rows: { id: string; propertyName?: string }[]): Set<string> {\n const seen = new Map<string, string>()\n const conflicts = new Set<string>()\n for (const row of rows) {\n const prop = row.propertyName\n if (!prop) continue\n const first = seen.get(prop)\n if (first) {\n conflicts.add(row.id)\n conflicts.add(first)\n } else {\n seen.set(prop, row.id)\n }\n }\n return conflicts\n}\n\nexport function attachLookupIfNeeded(\n edge: FieldMapping,\n target: TargetProperty | undefined,\n): FieldMapping {\n if (edge.resolve) {\n return edge.resolve === 'lookup' ? edge : stripLookup(edge)\n }\n if (target && isRelationLookupTarget(target)) {\n return { ...stripLookup(edge), resolve: 'lookup' }\n }\n return stripLookup(edge)\n}\n\nexport function applyLookupEntriesToMappings(\n mappings: FieldMapping[],\n rowKey: 'property' | 'source',\n rowId: string,\n edgeIds: string[],\n entries: LookupEntry[],\n): FieldMapping[] | null {\n if (rowKey === 'property') {\n const index = mappings.findIndex((m) => m.propertyName === rowId)\n if (index < 0) return null\n const prev = mappings[index]!\n if (prev.resolve !== 'lookup') return null\n const next = [...mappings]\n next[index] = withLookupEntries(prev, entries)\n return next\n }\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex < 0) return null\n const prev = mappings[edgeIndex]\n if (!prev || prev.resolve !== 'lookup') return null\n const next = [...mappings]\n next[edgeIndex] = withLookupEntries(prev, entries)\n return next\n}\n\nexport function upsertPropertyMapping(\n mappings: FieldMapping[],\n edge: FieldMapping,\n): FieldMapping[] {\n const next = mappings.filter((m) => m.propertyName !== edge.propertyName)\n next.push(edge)\n return next\n}\n\nexport function clearLookupsForProperties(\n lookups: MappingLookups,\n propertyNames: string[],\n): MappingLookups | null {\n if (propertyNames.length === 0) return null\n let changed = false\n const next = { ...lookups }\n for (const name of propertyNames) {\n if (name in next) {\n delete next[name]\n changed = true\n }\n }\n return changed ? next : null\n}\n\nexport function connectSourceToProperty(\n mappings: FieldMapping[],\n sources: SourceNode[],\n targets: TargetProperty[],\n sourceId: string,\n propertyName: string,\n): { mappings: FieldMapping[]; clearedLookupProps: string[] } {\n const targetsByName = new Map(targets.map((t) => [t.name, t]))\n let edge = normalizeMappingFromSourceId(sourceId, propertyName)\n edge = attachLookupIfNeeded(edge, targetsByName.get(propertyName))\n\n // Prefer origin source id even when host passed only resolved nodes\n if (!sources.some((s) => s.id === edge.sourceId)) {\n const origin = originSources(sources).find((s) => s.id === edge.sourceId)\n if (!origin && sources.some((s) => s.id === sourceId)) {\n // keep normalized edge as-is\n }\n }\n\n const prev = mappings.find((m) => m.propertyName === propertyName)\n const next = upsertPropertyMapping(mappings, edge)\n const clearedLookupProps: string[] = []\n if (prev?.resolve === 'lookup' && edge.resolve !== 'lookup') {\n clearedLookupProps.push(propertyName)\n }\n return { mappings: next, clearedLookupProps }\n}\n\nexport function removeMappingsForSourceId(\n mappings: FieldMapping[],\n sourceId: string,\n): { mappings: FieldMapping[]; clearedLookupProps: string[] } {\n const parsed = parseResolvedSourceId(sourceId)\n const clearedLookupProps: string[] = []\n const next = mappings.filter((c) => {\n let keep: boolean\n if (parsed) {\n keep = !(\n c.sourceId === parsed.originId && c.resolve === parsed.resolve\n )\n } else {\n keep = c.sourceId !== sourceId\n }\n if (!keep && c.resolve === 'lookup') {\n clearedLookupProps.push(c.propertyName)\n }\n return keep\n })\n return { mappings: next, clearedLookupProps }\n}\n\nexport function buildPropertyModeRows(args: {\n targets: TargetProperty[]\n mappings: FieldMapping[]\n sources: SourceNode[]\n lookups?: MappingLookups\n /** When set, only these property names appear (add-flow extras). */\n visiblePropertyNames?: Set<string> | null\n}): FieldMapperRow[] {\n const { targets, mappings, sources, lookups } = args\n const byName = new Map(mappings.map((m) => [m.propertyName, m]))\n const sourceById = new Map(originSources(sources).map((s) => [s.id, s]))\n // Also index all sources for resolve edges that still point at origin\n for (const s of sources) {\n if (!sourceById.has(s.id)) sourceById.set(s.id, s)\n }\n\n const list =\n args.visiblePropertyNames == null\n ? targets\n : targets.filter((t) => args.visiblePropertyNames!.has(t.name))\n\n return list.map((target) => {\n const mapping = byName.get(target.name)\n const source = mapping\n ? sourceById.get(mapping.sourceId)\n : undefined\n const requiredResolve = computeRequiredResolve(source, target)\n const sampleValue = sampleValueFromSource(source)\n const state = rowState({ mapping, requiredResolve, sampleValue, lookups })\n return {\n id: target.name,\n target,\n mapping,\n source,\n sampleValue,\n preview: previewForEdge(source, mapping?.resolve, {\n target,\n lookups,\n propertyName: target.name,\n mapping,\n }),\n requiredResolve,\n state,\n }\n })\n}\n\nexport type SourceModeDraft = {\n id: string\n sourceId?: string\n propertyName?: string\n resolve?: ResolveJob\n}\n\nexport function buildSourceModeRows(args: {\n mappings: FieldMapping[]\n edgeIds: string[]\n drafts: SourceModeDraft[]\n sources: SourceNode[]\n targets: TargetProperty[]\n lookups?: MappingLookups\n}): { rows: FieldMapperRow[]; conflicts: Set<string> } {\n const { mappings, edgeIds, drafts, sources, targets, lookups } = args\n const sourceById = new Map(sources.map((s) => [s.id, s]))\n const targetsByName = new Map(targets.map((t) => [t.name, t]))\n\n const edgeRows: {\n id: string\n propertyName?: string\n mapping?: FieldMapping\n source?: SourceNode\n target?: TargetProperty\n }[] = []\n\n for (let i = 0; i < mappings.length; i++) {\n const mapping = mappings[i]!\n const id = edgeIds[i] ?? `edge-${i}`\n edgeRows.push({\n id,\n propertyName: mapping.propertyName,\n mapping,\n source: sourceById.get(mapping.sourceId),\n target: targetsByName.get(mapping.propertyName),\n })\n }\n\n for (const draft of drafts) {\n edgeRows.push({\n id: draft.id,\n propertyName: draft.propertyName,\n mapping:\n draft.sourceId && draft.propertyName\n ? {\n sourceId: draft.sourceId,\n propertyName: draft.propertyName,\n ...(draft.resolve ? { resolve: draft.resolve } : {}),\n }\n : draft.sourceId || draft.propertyName\n ? {\n sourceId: draft.sourceId ?? '',\n propertyName: draft.propertyName ?? '',\n ...(draft.resolve ? { resolve: draft.resolve } : {}),\n }\n : undefined,\n source: draft.sourceId ? sourceById.get(draft.sourceId) : undefined,\n target: draft.propertyName\n ? targetsByName.get(draft.propertyName)\n : undefined,\n })\n }\n\n const conflicts = findConflicts(edgeRows)\n\n const rows: FieldMapperRow[] = edgeRows.map((r) => {\n const requiredResolve = computeRequiredResolve(r.source, r.target)\n const mapping =\n r.mapping && r.mapping.sourceId && r.mapping.propertyName\n ? r.mapping\n : r.mapping\n const sampleValue = sampleValueFromSource(r.source)\n const state = rowState({\n mapping:\n mapping && mapping.sourceId && mapping.propertyName\n ? mapping\n : undefined,\n requiredResolve,\n conflict: conflicts.has(r.id),\n sampleValue,\n lookups,\n })\n // Drafts with only source or only property stay empty\n const effectiveState =\n !mapping?.sourceId || !mapping?.propertyName\n ? conflicts.has(r.id)\n ? 'conflict'\n : 'empty'\n : state\n\n const complete =\n mapping && mapping.sourceId && mapping.propertyName ? mapping : undefined\n\n return {\n id: r.id,\n target: r.target,\n mapping: complete,\n source: r.source,\n sampleValue,\n preview: previewForEdge(r.source, complete?.resolve, {\n target: r.target,\n lookups,\n propertyName: complete?.propertyName,\n mapping: complete,\n }),\n requiredResolve,\n state: effectiveState,\n }\n })\n\n return { rows, conflicts }\n}\n\nexport function newRowId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 10)}`\n}\n\nexport function syncEdgeIds(\n prev: string[],\n mappingCount: number,\n): string[] {\n if (prev.length === mappingCount) return prev\n if (prev.length > mappingCount) return prev.slice(0, mappingCount)\n const next = [...prev]\n while (next.length < mappingCount) {\n next.push(newRowId('edge'))\n }\n return next\n}\n\nexport function filterPropertyNames(\n targets: TargetProperty[],\n mappings: FieldMapping[],\n mode: 'requiredAndMapped' | 'mapped' | 'all',\n extra: Set<string>,\n): Set<string> | null {\n if (mode === 'all') return null\n const mapped = new Set(mappings.map((m) => m.propertyName))\n const names = new Set<string>(extra)\n for (const t of targets) {\n if (mapped.has(t.name)) names.add(t.name)\n else if (mode === 'requiredAndMapped' && t.required) names.add(t.name)\n }\n return names\n}\n","import React, { useMemo } from 'react'\nimport { lookupEntriesFromMapping, normalizeLookupKey } from '../relationLookup'\nimport type {\n FieldMapping,\n LookupEntry,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type { FieldMapperSlot } from './fieldMapperSlots'\nimport { slotClass } from './fieldMapperSlots'\n\nfunction upsertEntry(\n entries: LookupEntry[],\n value: string,\n ref: string,\n): LookupEntry[] {\n const key = normalizeLookupKey(value)\n const trimmed = ref.trim()\n const next = entries.filter((e) => normalizeLookupKey(e.value) !== key)\n if (!trimmed) return next\n next.push({ value: key, ref: trimmed })\n return next\n}\n\nexport type LookupEditorProps = {\n mode: 'section' | 'row'\n /** Lookup edges to edit. Section: all lookup mappings; row: one property. */\n mappings: FieldMapping[]\n sources: SourceNode[]\n targets: TargetProperty[]\n onLookupChange: (mapping: FieldMapping, entries: LookupEntry[]) => void\n classNames?: Partial<Record<FieldMapperSlot, string>>\n /** Extra class on the root (e.g. nested-in-row modifier). */\n className?: string\n}\n\nfunction LookupBlock({\n mapping,\n sources,\n targetsByName,\n onLookupChange,\n compact,\n}: {\n mapping: FieldMapping\n sources: SourceNode[]\n targetsByName: Map<string, TargetProperty>\n onLookupChange: (mapping: FieldMapping, entries: LookupEntry[]) => void\n compact?: boolean\n}) {\n const source = sources.find((s) => s.id === mapping.sourceId)\n const sampleKey = normalizeLookupKey(source?.value || source?.label || '')\n const entries = lookupEntriesFromMapping(mapping)\n const keys = new Set<string>(\n entries.map((e) => normalizeLookupKey(e.value)).filter(Boolean),\n )\n if (sampleKey) keys.add(sampleKey)\n const keyList = [...keys]\n const target = targetsByName.get(mapping.propertyName)\n const refByKey = new Map(\n entries.map((e) => [normalizeLookupKey(e.value), e.ref]),\n )\n\n return (\n <div className=\"fm-lookup-block\">\n {!compact && (\n <h4>\n {mapping.propertyName}\n {target?.ref ? ` → ${target.ref}` : ''}\n </h4>\n )}\n <div className=\"fm-lookup-hint\">\n Map source strings to refs. Host owns Identity search/create.\n </div>\n {keyList.length === 0 ? (\n <div className=\"fm-lookup-hint\">\n No sample value yet — paste a source string key after connecting.\n </div>\n ) : (\n keyList.map((key) => (\n <div key={key} className=\"fm-lookup-row\">\n <div className=\"fm-lookup-key\" title={key}>\n {key || '(empty)'}\n </div>\n <input\n className=\"fm-lookup-input\"\n type=\"text\"\n placeholder=\"ref\"\n value={refByKey.get(key) ?? ''}\n onChange={(e) =>\n onLookupChange(mapping, upsertEntry(entries, key, e.target.value))\n }\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n ))\n )}\n </div>\n )\n}\n\n/**\n * Fallback string → ref editor when the host does not pass `renderLookup`.\n * Writes `FieldMapping.lookup.entries` via `onLookupChange`.\n */\nexport function LookupEditor({\n mode,\n mappings,\n sources,\n targets,\n onLookupChange,\n classNames,\n className,\n}: LookupEditorProps) {\n const lookupMappings = useMemo(\n () => mappings.filter((m) => m.resolve === 'lookup'),\n [mappings],\n )\n\n const targetsByName = useMemo(() => {\n const map = new Map<string, TargetProperty>()\n for (const t of targets) map.set(t.name, t)\n return map\n }, [targets])\n\n if (lookupMappings.length === 0) return null\n\n const rootClass = [\n slotClass('lookupEditor', classNames),\n mode === 'row' ? 'fm-lookups--row' : null,\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div className={rootClass}>\n {mode === 'section' && (\n <div className=\"fm-lookups-title\">Relation lookups</div>\n )}\n {lookupMappings.map((mapping) => (\n <LookupBlock\n key={`${mapping.sourceId}-${mapping.propertyName}`}\n mapping={mapping}\n sources={sources}\n targetsByName={targetsByName}\n onLookupChange={onLookupChange}\n compact={mode === 'row'}\n />\n ))}\n </div>\n )\n}\n","/** Number of cycling pair / map-color slots (`--fm-map-1` … `--fm-map-8`). */\nexport const FIELD_MAPPER_PAIR_SLOTS = 8\n\n/**\n * Theme modes for FieldMapper.\n * `'unstyled'` is a deprecated alias for `'none'` (kept for one minor).\n */\nexport type FieldMapperTheme = 'default' | 'structural' | 'none' | 'unstyled'\n\nexport type ResolvedFieldMapperTheme = 'default' | 'structural' | 'none'\n\nexport const THEME_STYLE_ID = 'seed-field-mapper-theme'\n\nfunction pairSlot(index: number): number {\n return index % FIELD_MAPPER_PAIR_SLOTS\n}\n\n/** Stroke for mapping index `i` — CSS vars by default so hosts can theme. */\nexport function connectionStrokeForIndex(\n index: number,\n connectionColors?: string[],\n): string {\n if (connectionColors && connectionColors.length > 0) {\n return connectionColors[index % connectionColors.length]!\n }\n const n = pairSlot(index) + 1\n return `var(--fm-map-${n}, var(--map-${n}, currentColor))`\n}\n\nexport { pairSlot }\n\n/** Map public theme prop (including deprecated `unstyled`) to a resolved mode. */\nexport function resolveTheme(\n theme: FieldMapperTheme = 'default',\n): ResolvedFieldMapperTheme {\n if (theme === 'unstyled') return 'none'\n return theme\n}\n\nconst PAINT_TOKENS = `\n --sfm-color-ground: #0f172a;\n --sfm-color-ink: #e2e8f0;\n --sfm-color-well: #1e293b;\n --sfm-color-line: #334155;\n --sfm-color-muted: #94a3b8;\n --sfm-color-faint: #64748b;\n --sfm-color-selection: #3b82f6;\n --sfm-color-warning: #fbbf24;\n --sfm-color-danger: #f87171;\n --sfm-color-highlight: #f59e0b;\n --sfm-map-1: #3b82f6;\n --sfm-map-2: #8b5cf6;\n --sfm-map-3: #ec4899;\n --sfm-map-4: #f59e0b;\n --sfm-map-5: #10b981;\n --sfm-map-6: #06b6d4;\n --sfm-map-7: #f97316;\n --sfm-map-8: #14b8a6;\n --fm-ground: var(--sfm-color-ground);\n --fm-ink: var(--sfm-color-ink);\n --fm-well: var(--sfm-color-well);\n --fm-line: var(--sfm-color-line);\n --fm-muted: var(--sfm-color-muted);\n --fm-faint: var(--sfm-color-faint);\n --fm-selection: var(--sfm-color-selection);\n --fm-highlight: var(--sfm-color-highlight);\n --fm-danger: var(--sfm-color-danger);\n --fm-warning: var(--sfm-color-warning);\n --fm-map-1: var(--sfm-map-1);\n --fm-map-2: var(--sfm-map-2);\n --fm-map-3: var(--sfm-map-3);\n --fm-map-4: var(--sfm-map-4);\n --fm-map-5: var(--sfm-map-5);\n --fm-map-6: var(--sfm-map-6);\n --fm-map-7: var(--sfm-map-7);\n --fm-map-8: var(--sfm-map-8);\n`\n\nconst STRUCTURAL_TOKENS = `\n --sfm-space-1: 4px;\n --sfm-space-2: 8px;\n --sfm-space-3: 12px;\n --sfm-space-4: 16px;\n --sfm-radius-sm: 4px;\n --sfm-radius-md: 8px;\n --sfm-radius-lg: 12px;\n --sfm-font-family: inherit;\n --sfm-font-mono: ui-monospace, monospace;\n --sfm-font-size-sm: 11px;\n --sfm-font-size-md: 13px;\n --sfm-control-height: 32px;\n --sfm-row-gap: var(--sfm-space-2);\n`\n\n/** Layout / spacing / display rules — no color paint. */\nexport const STRUCTURAL_THEME_CSS = `\n.seed-field-mapper {\n${STRUCTURAL_TOKENS}\n font-family: var(--sfm-font-family);\n border-radius: var(--sfm-radius-lg);\n padding: var(--sfm-space-4);\n}\n.seed-field-mapper * { box-sizing: border-box; }\n.seed-field-mapper .fm-toolbar {\n display: flex;\n gap: var(--sfm-space-2);\n align-items: center;\n margin-bottom: var(--sfm-space-3);\n flex-wrap: wrap;\n}\n.seed-field-mapper .fm-btn {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 6px var(--sfm-space-3);\n cursor: pointer;\n font-size: var(--sfm-font-size-md);\n min-height: var(--sfm-control-height);\n}\n.seed-field-mapper .fm-meta {\n font-size: 12px;\n margin-left: auto;\n}\n.seed-field-mapper .fm-banner {\n font-size: 12px;\n padding: var(--sfm-space-2) 10px;\n border-radius: var(--sfm-radius-md);\n margin-bottom: 10px;\n border: 1px solid;\n}\n.seed-field-mapper .fm-grid {\n position: relative;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 48px;\n min-height: 240px;\n}\n.seed-field-mapper .fm-col-title {\n font-size: var(--sfm-font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-card {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 10px var(--sfm-space-3);\n margin-bottom: var(--sfm-space-2);\n cursor: pointer;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n.seed-field-mapper .fm-label {\n font-weight: 600;\n font-size: var(--sfm-font-size-md);\n margin-bottom: var(--sfm-space-1);\n}\n.seed-field-mapper .fm-value {\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.seed-field-mapper .fm-kind {\n font-size: 10px;\n margin-left: 6px;\n}\n.seed-field-mapper .fm-prop-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-dtype {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: var(--sfm-radius-sm);\n border: 1px solid;\n}\n.seed-field-mapper .fm-remove {\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n padding: 0 var(--sfm-space-1);\n}\n.seed-field-mapper .fm-svg {\n position: absolute;\n inset: 0;\n pointer-events: none;\n overflow: visible;\n}\n.seed-field-mapper .fm-preview {\n margin-top: var(--sfm-space-3);\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: var(--sfm-space-3);\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n white-space: pre-wrap;\n max-height: 200px;\n overflow: auto;\n}\n.seed-field-mapper details.fm-preview {\n font-family: var(--sfm-font-family);\n white-space: normal;\n max-height: none;\n overflow: visible;\n padding: var(--sfm-space-2) var(--sfm-space-3);\n}\n.seed-field-mapper details.fm-preview > summary {\n cursor: pointer;\n font-size: var(--sfm-font-size-sm);\n list-style: disclosure-closed;\n}\n.seed-field-mapper details.fm-preview[open] > summary {\n list-style: disclosure-open;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-preview-body {\n margin: 0;\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n white-space: pre-wrap;\n max-height: 200px;\n overflow: auto;\n}\n.seed-field-mapper .fm-lookups {\n margin-top: var(--sfm-space-4);\n border-top: 1px solid;\n padding-top: var(--sfm-space-3);\n}\n.seed-field-mapper .fm-row .fm-lookups,\n.seed-field-mapper .fm-lookups--row {\n margin-top: var(--sfm-space-2);\n border-top: none;\n padding-top: 0;\n}\n.seed-field-mapper .fm-row .fm-lookup-block {\n margin-bottom: 0;\n padding: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookups-title {\n font-size: var(--sfm-font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-block {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 10px var(--sfm-space-3);\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-block h4 {\n margin: 0 0 var(--sfm-space-2);\n font-size: var(--sfm-font-size-md);\n font-weight: 600;\n}\n.seed-field-mapper .fm-lookup-hint {\n font-size: var(--sfm-font-size-sm);\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-row {\n display: grid;\n grid-template-columns: 1fr 1.4fr;\n gap: var(--sfm-space-2);\n align-items: center;\n margin-bottom: 6px;\n}\n.seed-field-mapper .fm-lookup-key {\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.seed-field-mapper .fm-lookup-input {\n width: 100%;\n border: 1px solid;\n border-radius: 6px;\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n padding: 6px var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-input:focus {\n outline: none;\n}\n.seed-field-mapper .fm-row-list {\n display: flex;\n flex-direction: column;\n gap: var(--sfm-row-gap);\n}\n.seed-field-mapper .fm-row {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 10px var(--sfm-space-3);\n}\n.seed-field-mapper .fm-row-main {\n display: grid;\n grid-template-columns: minmax(100px, 140px) 1fr auto auto auto;\n gap: var(--sfm-space-2);\n align-items: center;\n}\n.seed-field-mapper .fm-row-main-source {\n grid-template-columns: 1fr auto auto 1fr auto auto;\n}\n.seed-field-mapper .fm-row-accessory {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n.seed-field-mapper .fm-row-accessory:empty {\n display: none;\n}\n.seed-field-mapper .fm-row-prop {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.seed-field-mapper .fm-row-prop-name {\n font-weight: 600;\n font-size: var(--sfm-font-size-md);\n}\n.seed-field-mapper .fm-row-preview {\n margin-top: 6px;\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n}\n.seed-field-mapper .fm-row-flag {\n font-size: var(--sfm-font-size-sm);\n margin-top: var(--sfm-space-1);\n}\n.seed-field-mapper .fm-select {\n width: 100%;\n border: 1px solid;\n border-radius: 6px;\n font-size: 12px;\n padding: 6px var(--sfm-space-2);\n min-width: 0;\n min-height: var(--sfm-control-height);\n}\n.seed-field-mapper .fm-select:focus {\n outline: none;\n}\n.seed-field-mapper .fm-filter {\n display: flex;\n gap: 6px;\n margin-bottom: 10px;\n flex-wrap: wrap;\n}\n.seed-field-mapper .fm-inspector {\n margin-top: var(--sfm-space-3);\n border-top: 1px solid;\n padding-top: 10px;\n}\n.seed-field-mapper .fm-inspector summary {\n cursor: pointer;\n font-size: 12px;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-inspector-row {\n display: grid;\n grid-template-columns: 1fr 1.5fr auto;\n gap: var(--sfm-space-2);\n align-items: center;\n padding: 6px 0;\n border-bottom: 1px solid;\n font-size: 12px;\n}\n.seed-field-mapper .fm-into {\n font-size: var(--sfm-font-size-sm);\n}\n`\n\n/** Color / background / border-color paint on top of structural layout. */\nexport const PAINT_THEME_CSS = `\n.seed-field-mapper {\n${PAINT_TOKENS}\n color: var(--sfm-color-ink);\n background: var(--sfm-color-ground);\n}\n.seed-field-mapper .fm-btn {\n background: var(--sfm-color-well);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-btn:hover { border-color: var(--sfm-color-faint); }\n.seed-field-mapper .fm-btn-primary {\n background: var(--sfm-color-selection);\n border-color: var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-meta {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-banner {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-banner-warn {\n border-color: var(--sfm-color-warning);\n color: var(--sfm-color-warning);\n}\n.seed-field-mapper .fm-banner-danger {\n border-color: var(--sfm-color-danger);\n color: var(--sfm-color-danger);\n}\n.seed-field-mapper .fm-col-title {\n color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-card {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-card.active,\n.seed-field-mapper .fm-card.pending {\n border-color: var(--sfm-color-selection);\n box-shadow: 0 0 0 1px var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-card.mapped {\n border-color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-card.highlight {\n border-color: var(--sfm-color-highlight);\n}\n.seed-field-mapper .fm-value {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-kind {\n color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-dtype {\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-muted);\n background: transparent;\n}\n.seed-field-mapper .fm-remove {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-remove:hover { color: var(--sfm-color-danger); }\n.seed-field-mapper .fm-preview {\n background: color-mix(in srgb, var(--sfm-color-ground) 80%, black);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper details.fm-preview > summary {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-lookups {\n border-color: var(--sfm-color-line);\n}\n.seed-field-mapper .fm-lookups-title {\n color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-lookup-block {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-lookup-hint {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-lookup-key {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-lookup-input {\n background: var(--sfm-color-ground);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-lookup-input:focus {\n border-color: var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-row {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-row[data-state=\"needsResolve\"] {\n border-color: var(--sfm-color-warning);\n}\n.seed-field-mapper .fm-row[data-state=\"conflict\"] {\n border-color: var(--sfm-color-danger);\n}\n.seed-field-mapper .fm-row-preview {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-row-flag {\n color: var(--sfm-color-warning);\n}\n.seed-field-mapper .fm-select {\n background: var(--sfm-color-ground);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-select:focus {\n border-color: var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-filter .fm-btn[aria-pressed=\"true\"] {\n border-color: var(--sfm-color-selection);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-inspector {\n border-color: var(--sfm-color-line);\n}\n.seed-field-mapper .fm-inspector summary {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-inspector-row {\n border-color: var(--sfm-color-line);\n}\n.seed-field-mapper .fm-into {\n color: var(--sfm-color-faint);\n}\n`\n\n/** Wrap CSS in the package cascade layer so host rules win without specificity fights. */\nexport function wrapInThemeLayer(css: string): string {\n return `@layer seed-field-mapper {\\n${css}\\n}`\n}\n\n/** Build the CSS string for a resolved theme mode (`none` → empty). */\nexport function buildThemeCss(theme: ResolvedFieldMapperTheme): string {\n if (theme === 'none') return ''\n if (theme === 'structural') {\n return wrapInThemeLayer(STRUCTURAL_THEME_CSS)\n }\n return wrapInThemeLayer(`${STRUCTURAL_THEME_CSS}\\n${PAINT_THEME_CSS}`)\n}\n\n/** Full default theme CSS (structural + paint, layered). Exported for tests / hosts. */\nexport const DEFAULT_THEME_CSS = buildThemeCss('default')\n\nlet injectedTheme: ResolvedFieldMapperTheme | null = null\n\n/**\n * Inject theme CSS once into `document.head`. Updates the existing style node\n * when the resolved theme changes. No-op when `document` is unavailable (SSR)\n * or when `theme === 'none'`.\n */\nexport function ensureThemeInjected(theme: ResolvedFieldMapperTheme): void {\n if (typeof document === 'undefined') return\n if (theme === 'none') return\n\n const css = buildThemeCss(theme)\n const existing = document.getElementById(\n THEME_STYLE_ID,\n ) as HTMLStyleElement | null\n\n if (existing) {\n if (injectedTheme !== theme) {\n existing.textContent = css\n injectedTheme = theme\n }\n return\n }\n\n const el = document.createElement('style')\n el.id = THEME_STYLE_ID\n el.textContent = css\n document.head.appendChild(el)\n injectedTheme = theme\n}\n\n/** Test helper: reset document-once injection bookkeeping. */\nexport function resetThemeInjectionForTests(): void {\n injectedTheme = null\n if (typeof document === 'undefined') return\n const el = document.getElementById(THEME_STYLE_ID)\n if (!el) return\n if (typeof el.remove === 'function') {\n el.remove()\n } else if (el.parentNode) {\n el.parentNode.removeChild(el)\n }\n}\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n parseResolvedSourceId,\n resolvedSourceId,\n} from '../resolvedSources'\nimport type {\n FieldMapping,\n MappingLookups,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperSlot,\n ResolvedFieldMapperComponents,\n ResolvedFieldMapperSlots,\n} from './fieldMapperSlots'\nimport { showJsonPreview, slotClass } from './fieldMapperSlots'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport { buildSyncPreviewBag } from './fieldMapperCore'\nimport type {\n FieldMapperLookupRow,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\nimport { LookupEditor } from './LookupEditor'\nimport {\n connectionStrokeForIndex,\n pairSlot,\n} from './fieldMapperTheme'\n\ntype ConnectorPoint = {\n x1: number\n y1: number\n x2: number\n y2: number\n stroke: string\n mappingIndex: number\n mapping: FieldMapping\n}\n\nfunction displaySourceIdForMapping(\n mapping: FieldMapping,\n sources: SourceNode[],\n): string {\n if (!mapping.resolve) return mapping.sourceId\n const derived = resolvedSourceId(mapping.sourceId, mapping.resolve)\n if (sources.some((s) => s.id === derived)) return derived\n return mapping.sourceId\n}\n\nfunction truncate(s: string, n: number): string {\n const t = s.replace(/\\s+/g, ' ').trim()\n if (t.length <= n) return t\n return `${t.slice(0, n)}…`\n}\n\nexport type FieldMapperWiresProps = {\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n mapper: UseFieldMapperResult\n lookups?: MappingLookups\n onLookupsChange?: (lookups: MappingLookups) => void\n renderLookup?: (row: FieldMapperLookupRow) => React.ReactNode\n /** @deprecated Prefer CSS map tokens. */\n connectionColors?: string[]\n slots: ResolvedFieldMapperSlots\n classNames?: Partial<Record<FieldMapperSlot, string>>\n ui?: ResolvedFieldMapperComponents\n}\n\nexport function FieldMapperWires({\n sources,\n targets,\n mappings,\n mapper,\n onLookupsChange,\n renderLookup,\n connectionColors,\n slots,\n classNames,\n ui = {\n Select: DefaultSelect,\n Button: DefaultButton,\n Pill: DefaultPill,\n },\n}: FieldMapperWiresProps) {\n const Button = ui.Button\n const [activeSource, setActiveSource] = useState<string | null>(null)\n const [hoveredProp, setHoveredProp] = useState<string | null>(null)\n const [hoveredSource, setHoveredSource] = useState<string | null>(null)\n const [previewOpen, setPreviewOpen] = useState(false)\n const [svgDimensions, setSvgDimensions] = useState({ width: 0, height: 0 })\n const [connectorPoints, setConnectorPoints] = useState<ConnectorPoint[]>([])\n\n const containerRef = useRef<HTMLDivElement>(null)\n const sourceRefs = useRef<Record<string, HTMLDivElement | null>>({})\n const propRefs = useRef<Record<string, HTMLDivElement | null>>({})\n\n const mappingIndexByProp = useMemo(() => {\n const map = new Map<string, number>()\n mappings.forEach((m, i) => {\n map.set(m.propertyName, i)\n })\n return map\n }, [mappings])\n\n const mappingIndexesBySource = useMemo(() => {\n const map = new Map<string, number[]>()\n mappings.forEach((m, i) => {\n const displayId = displaySourceIdForMapping(m, sources)\n for (const key of new Set([m.sourceId, displayId])) {\n const list = map.get(key) ?? []\n list.push(i)\n map.set(key, list)\n }\n })\n return map\n }, [mappings, sources])\n\n const getConnectorPoints = useCallback((): ConnectorPoint[] => {\n if (!containerRef.current) return []\n const containerRect = containerRef.current.getBoundingClientRect()\n return mappings\n .map((mapping, i) => {\n const displayId = displaySourceIdForMapping(mapping, sources)\n const sourceEl =\n sourceRefs.current[displayId] ?? sourceRefs.current[mapping.sourceId]\n const propEl = propRefs.current[mapping.propertyName]\n if (!sourceEl || !propEl) return null\n\n const sR = sourceEl.getBoundingClientRect()\n const pR = propEl.getBoundingClientRect()\n\n return {\n x1: sR.right - containerRect.left,\n y1: sR.top + sR.height / 2 - containerRect.top,\n x2: pR.left - containerRect.left,\n y2: pR.top + pR.height / 2 - containerRect.top,\n stroke: connectionStrokeForIndex(i, connectionColors),\n mappingIndex: i,\n mapping,\n }\n })\n .filter((pt): pt is ConnectorPoint => pt !== null)\n }, [mappings, connectionColors, sources])\n\n useEffect(() => {\n const update = () => {\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect()\n setSvgDimensions({ width: rect.width, height: rect.height })\n }\n setConnectorPoints(getConnectorPoints())\n }\n update()\n window.addEventListener('resize', update)\n const timer = setInterval(update, 200)\n return () => {\n window.removeEventListener('resize', update)\n clearInterval(timer)\n }\n }, [getConnectorPoints, mappings, sources, targets])\n\n const handleSourceClick = (sourceId: string) => {\n setActiveSource((prev) => (prev === sourceId ? null : sourceId))\n }\n\n const handlePropClick = (propertyName: string) => {\n if (!activeSource) return\n mapper.connect(activeSource, propertyName)\n }\n\n const sourceHasMapping = (sourceId: string) => {\n const parsed = parseResolvedSourceId(sourceId)\n if (parsed) {\n return mappings.some(\n (c) =>\n c.sourceId === parsed.originId && c.resolve === parsed.resolve,\n )\n }\n return mappings.some((c) => c.sourceId === sourceId)\n }\n const mappingForProp = (propName: string) =>\n mappings.find((c) => c.propertyName === propName)\n\n const isEdgeHighlighted = (mapping: FieldMapping) => {\n if (hoveredProp) return mapping.propertyName === hoveredProp\n if (hoveredSource) {\n const displayId = displaySourceIdForMapping(mapping, sources)\n return (\n mapping.sourceId === hoveredSource || displayId === hoveredSource\n )\n }\n return false\n }\n\n const anyEdgeHighlighted = hoveredProp != null || hoveredSource != null\n\n const preview = useMemo(\n () => buildSyncPreviewBag(sources, mappings, targets),\n [sources, mappings, targets],\n )\n\n const { coverage } = mapper\n const jsonPreview = showJsonPreview(slots.preview)\n\n return (\n <>\n <div className={slotClass('toolbar', classNames)}>\n {slots.autoMap && (\n <Button\n className={slotClass('autoMapButton', classNames)}\n onClick={() => mapper.autoMap()}\n >\n Auto-map\n </Button>\n )}\n <span className={slotClass('coverage', classNames)}>\n {coverage.mapped} / {coverage.total} mapped\n {coverage.missingRequired.length > 0\n ? ` · ${coverage.missingRequired.length} required missing`\n : ''}\n {activeSource\n ? ' · click properties (source stays selected)'\n : ' · click a source'}\n </span>\n </div>\n\n <div className=\"fm-grid\" ref={containerRef}>\n <svg\n className=\"fm-svg\"\n width={svgDimensions.width}\n height={svgDimensions.height}\n >\n {connectorPoints.map((pt) => {\n const isHi = isEdgeHighlighted(pt.mapping)\n const midX = (pt.x1 + pt.x2) / 2\n return (\n <path\n key={`${pt.mapping.sourceId}-${pt.mapping.propertyName}-${pt.mapping.resolve ?? 'copy'}`}\n className=\"fm-connector\"\n data-mapping-index={pt.mappingIndex}\n data-pair={pairSlot(pt.mappingIndex)}\n d={`M ${pt.x1} ${pt.y1} C ${midX} ${pt.y1}, ${midX} ${pt.y2}, ${pt.x2} ${pt.y2}`}\n stroke={pt.stroke}\n strokeWidth={isHi ? 3 : 2}\n fill=\"none\"\n opacity={anyEdgeHighlighted && !isHi ? 0.25 : 0.85}\n />\n )\n })}\n </svg>\n\n <div>\n <div className=\"fm-col-title\">Sources</div>\n {sources.map((source) => {\n const mapped = sourceHasMapping(source.id)\n const isPending = activeSource === source.id\n const indexes = mappingIndexesBySource.get(source.id) ?? []\n const firstIndex = indexes[0]\n const isHi =\n hoveredSource === source.id ||\n (hoveredProp != null &&\n mappings.some((m) => {\n const displayId = displaySourceIdForMapping(m, sources)\n return (\n (m.sourceId === source.id || displayId === source.id) &&\n m.propertyName === hoveredProp\n )\n }))\n return (\n <div\n key={source.id}\n ref={(el) => {\n sourceRefs.current[source.id] = el\n }}\n className={`fm-card${isPending ? ' active pending' : ''}${mapped ? ' mapped' : ''}${isHi ? ' highlight' : ''}`}\n data-source-id={source.id}\n {...(indexes.length > 0\n ? {\n 'data-mapping-index': indexes.join(' '),\n 'data-pair': String(pairSlot(firstIndex!)),\n }\n : {})}\n onClick={() => handleSourceClick(source.id)}\n onMouseEnter={() => setHoveredSource(source.id)}\n onMouseLeave={() => setHoveredSource(null)}\n >\n <div className=\"fm-prop-row\">\n <div className=\"fm-label\">\n {source.label}\n {source.subtitle ? (\n <span className=\"fm-kind\">{source.subtitle}</span>\n ) : null}\n <span className=\"fm-kind\">{source.kind}</span>\n </div>\n {mapped && (\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label=\"Remove all mappings for source\"\n onClick={(e) => {\n e.stopPropagation()\n mapper.removeBySource(source.id)\n }}\n >\n ×\n </Button>\n )}\n </div>\n <div className=\"fm-value\">{truncate(source.value, 80)}</div>\n </div>\n )\n })}\n </div>\n\n <div>\n <div className=\"fm-col-title\">Model properties</div>\n {targets.map((prop) => {\n const mapped = mappingForProp(prop.name)\n const mappingIndex = mappingIndexByProp.get(prop.name)\n const isHi =\n hoveredProp === prop.name ||\n (hoveredSource != null &&\n mapped != null &&\n (mapped.sourceId === hoveredSource ||\n displaySourceIdForMapping(mapped, sources) ===\n hoveredSource))\n return (\n <div\n key={prop.name}\n ref={(el) => {\n propRefs.current[prop.name] = el\n }}\n className={`fm-card${mapped ? ' mapped' : ''}${isHi ? ' highlight' : ''}`}\n data-property-name={prop.name}\n {...(mappingIndex != null\n ? {\n 'data-mapping-index': String(mappingIndex),\n 'data-pair': String(pairSlot(mappingIndex)),\n }\n : {})}\n onClick={() => handlePropClick(prop.name)}\n onMouseEnter={() => setHoveredProp(prop.name)}\n onMouseLeave={() => setHoveredProp(null)}\n >\n <div className=\"fm-prop-row\">\n <div className=\"fm-label\">{prop.name}</div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <span className=\"fm-dtype\">\n {prop.dataType}\n {prop.ref ? ` → ${prop.ref}` : ''}\n </span>\n {mapped && (\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label=\"Remove mapping for property\"\n onClick={(e) => {\n e.stopPropagation()\n mapper.removeRow(prop.name)\n }}\n >\n ×\n </Button>\n )}\n </div>\n </div>\n {mapped && (\n <div className=\"fm-value\">\n ← {mapped.sourceId}\n {mapped.resolve ? ` (${mapped.resolve})` : ''}\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {slots.lookups === 'section' &&\n renderLookup &&\n mapper.rows\n .filter((row) => row.mapping?.resolve === 'lookup')\n .map((row) => (\n <div\n key={row.id}\n className={slotClass('lookupEditor', classNames)}\n >\n {renderLookup({\n ...row,\n sampleValue: row.sampleValue ?? '',\n onLookupChange: (entries) =>\n mapper.setLookupEntries(row.id, entries),\n })}\n </div>\n ))}\n {slots.lookups === 'section' && !renderLookup && onLookupsChange && (\n <LookupEditor\n mode=\"section\"\n mappings={mappings}\n sources={sources}\n targets={targets}\n onLookupChange={(mapping, entries) => {\n const row = mapper.rows.find(\n (r) =>\n r.mapping?.sourceId === mapping.sourceId &&\n r.mapping?.propertyName === mapping.propertyName,\n )\n if (row) mapper.setLookupEntries(row.id, entries)\n }}\n classNames={classNames}\n />\n )}\n\n {jsonPreview && (\n <details\n className={slotClass('jsonPreview', classNames)}\n open={previewOpen}\n onToggle={(e) =>\n setPreviewOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>Preview JSON</summary>\n <pre className=\"fm-preview-body\">\n {JSON.stringify(preview, null, 2)}\n </pre>\n </details>\n )}\n </>\n )\n}\n","import React, { useMemo, useState, type ReactNode } from 'react'\nimport type {\n FieldMapping,\n MappingLookups,\n ResolveJob,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperSlot,\n ResolvedFieldMapperComponents,\n ResolvedFieldMapperSlots,\n} from './fieldMapperSlots'\nimport {\n showJsonPreview,\n showRowPreview,\n slotClass,\n} from './fieldMapperSlots'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport {\n buildSyncPreviewBag,\n filterPropertyNames,\n originSources,\n truncateSample,\n} from './fieldMapperCore'\nimport type {\n FieldMapperDefaultRows,\n FieldMapperLookupRow,\n FieldMapperRow,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\nimport { LookupEditor } from './LookupEditor'\n\nconst TRANSFORM_OPTIONS: { value: '' | ResolveJob; label: string }[] = [\n { value: '', label: 'copy' },\n { value: 'extract', label: 'extract' },\n { value: 'file', label: 'file' },\n { value: 'lookup', label: 'lookup' },\n]\n\nexport type PropertyRowsProps = {\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n mapper: UseFieldMapperResult\n defaultRows?: FieldMapperDefaultRows\n lookups?: MappingLookups\n onLookupsChange?: (lookups: MappingLookups) => void\n slots: ResolvedFieldMapperSlots\n classNames?: Partial<Record<FieldMapperSlot, string>>\n ui?: ResolvedFieldMapperComponents\n renderRowAccessory?: (row: FieldMapperRow) => ReactNode\n renderLookup?: (row: FieldMapperLookupRow) => ReactNode\n}\n\nexport function PropertyRows({\n sources,\n targets,\n mappings,\n mapper,\n defaultRows = 'requiredAndMapped',\n onLookupsChange,\n slots,\n classNames,\n ui = {\n Select: DefaultSelect,\n Button: DefaultButton,\n Pill: DefaultPill,\n },\n renderRowAccessory,\n renderLookup,\n}: PropertyRowsProps) {\n const Select = ui.Select\n const Button = ui.Button\n const Pill = ui.Pill\n\n const [filterMode, setFilterMode] =\n useState<FieldMapperDefaultRows>(defaultRows)\n const [extraNames, setExtraNames] = useState<Set<string>>(() => new Set())\n const [inspectorOpen, setInspectorOpen] = useState(false)\n const [adding, setAdding] = useState(false)\n const [pendingSourceId, setPendingSourceId] = useState<string | null>(null)\n const [previewOpen, setPreviewOpen] = useState(false)\n\n const visibleNames = useMemo(\n () => filterPropertyNames(targets, mappings, filterMode, extraNames),\n [targets, mappings, filterMode, extraNames],\n )\n\n const visibleRows = useMemo(() => {\n if (visibleNames == null) return mapper.rows\n return mapper.rows.filter((r) => visibleNames.has(r.id))\n }, [mapper.rows, visibleNames])\n\n const usageBySource = useMemo(() => {\n const map = new Map<string, string[]>()\n for (const m of mappings) {\n const list = map.get(m.sourceId) ?? []\n list.push(m.propertyName)\n map.set(m.sourceId, list)\n }\n return map\n }, [mappings])\n\n const syncPreview = useMemo(\n () => buildSyncPreviewBag(sources, mappings, targets),\n [sources, mappings, targets],\n )\n\n const { coverage, sourceOptions, addableProperties } = mapper\n const jsonPreview = showJsonPreview(slots.preview)\n const rowPreview = showRowPreview(slots.preview)\n const showRowLookups =\n slots.lookups === 'row' && (Boolean(renderLookup) || Boolean(onLookupsChange))\n const showSectionLookups =\n slots.lookups === 'section' &&\n !renderLookup &&\n Boolean(onLookupsChange)\n\n const handleAddProperty = (name: string) => {\n mapper.addRow(name)\n setExtraNames((prev) => new Set(prev).add(name))\n setAdding(false)\n }\n\n const mapThisSource = (sourceId: string) => {\n setPendingSourceId(sourceId)\n setAdding(true)\n }\n\n const onPickAddProperty = (name: string) => {\n handleAddProperty(name)\n if (pendingSourceId) {\n mapper.setSource(name, pendingSourceId)\n setPendingSourceId(null)\n }\n }\n\n return (\n <>\n <div className={slotClass('toolbar', classNames)}>\n {slots.autoMap && (\n <Button\n className={slotClass('autoMapButton', classNames)}\n onClick={() => mapper.autoMap()}\n >\n Auto-map\n </Button>\n )}\n <span className={slotClass('coverage', classNames)}>\n {coverage.mapped} of {coverage.total} properties mapped\n {coverage.missingRequired.length > 0\n ? ` · ${coverage.missingRequired.length} required missing`\n : ''}\n </span>\n </div>\n\n {slots.filter && (\n <div\n className={slotClass('filter', classNames)}\n role=\"group\"\n aria-label=\"Row filter\"\n >\n <Button\n className=\"fm-btn\"\n aria-pressed={filterMode === 'requiredAndMapped'}\n onClick={() => setFilterMode('requiredAndMapped')}\n >\n Mapped + required\n </Button>\n <Button\n className=\"fm-btn\"\n aria-pressed={filterMode === 'all'}\n onClick={() => setFilterMode('all')}\n >\n All {targets.length} properties\n </Button>\n </div>\n )}\n\n <div className={slotClass('rowList', classNames)}>\n {visibleRows.map((row) => {\n const resolveValue = (row.mapping?.resolve ?? '') as '' | ResolveJob\n return (\n <div\n key={row.id}\n className={slotClass('row', classNames)}\n data-state={row.state}\n data-property-name={row.id}\n data-required={row.target?.required ? 'true' : undefined}\n data-resolve={row.mapping?.resolve}\n data-source-kind={row.source?.kind}\n >\n <div className=\"fm-row-main\">\n <div className=\"fm-row-prop\">\n <div className={slotClass('propertyLabel', classNames)}>\n {row.target?.name}\n {row.target?.required ? ' *' : ''}\n </div>\n <Pill className={slotClass('dataType', classNames)}>\n {row.target?.dataType}\n </Pill>\n </div>\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label={`Source for ${row.id}`}\n value={row.mapping?.sourceId ?? ''}\n onChange={(v) => {\n mapper.setSource(row.id, v || null)\n }}\n >\n <option value=\"\">Choose a source field…</option>\n {sourceOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n {row.mapping?.sourceId ? (\n <Select\n className={slotClass('transformSelect', classNames)}\n aria-label={`Transform for ${row.id}`}\n value={resolveValue}\n onChange={(v) => {\n mapper.setTransform(row.id, (v as ResolveJob) || null)\n }}\n >\n {TRANSFORM_OPTIONS.map((opt) => (\n <option key={opt.label} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n ) : (\n <Pill className={slotClass('dataType', classNames)}>\n {row.target?.dataType}\n </Pill>\n )}\n <div className={slotClass('rowAccessory', classNames)}>\n {renderRowAccessory?.(row) ?? null}\n </div>\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label={`Remove mapping for ${row.id}`}\n onClick={() => mapper.removeRow(row.id)}\n >\n ×\n </Button>\n </div>\n {rowPreview && row.preview && (\n <div className={slotClass('preview', classNames)}>\n {row.preview}\n </div>\n )}\n {row.state === 'needsResolve' && row.requiredResolve && (\n <div className={slotClass('validation', classNames)}>\n needs {row.requiredResolve}\n </div>\n )}\n {row.state === 'needsLookup' && (\n <div className={slotClass('validation', classNames)}>\n needs lookup\n </div>\n )}\n {showRowLookups &&\n row.mapping?.resolve === 'lookup' &&\n row.mapping &&\n (renderLookup ? (\n <div className={slotClass('lookupEditor', classNames)}>\n {renderLookup({\n ...row,\n sampleValue: row.sampleValue ?? '',\n onLookupChange: (entries) =>\n mapper.setLookupEntries(row.id, entries),\n })}\n </div>\n ) : (\n <LookupEditor\n mode=\"row\"\n mappings={[row.mapping]}\n sources={sources}\n targets={targets}\n onLookupChange={(_mapping, entries) =>\n mapper.setLookupEntries(row.id, entries)\n }\n classNames={classNames}\n />\n ))}\n </div>\n )\n })}\n </div>\n\n <div style={{ marginTop: 10 }}>\n {adding ? (\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label=\"Add property mapping\"\n value=\"\"\n onChange={(name) => {\n if (name) onPickAddProperty(name)\n }}\n >\n <option value=\"\">Choose a property…</option>\n {addableProperties.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n {p.required ? ' *' : ''} ({p.dataType})\n </option>\n ))}\n </Select>\n ) : (\n <Button\n className={slotClass('addButton', classNames)}\n onClick={() => setAdding(true)}\n disabled={addableProperties.length === 0}\n >\n + Add mapping\n </Button>\n )}\n </div>\n\n {slots.inspector && (\n <details\n className={slotClass('inspector', classNames)}\n open={inspectorOpen}\n onToggle={(e) =>\n setInspectorOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>\n Source fields ({originSources(sources).length})\n </summary>\n {originSources(sources).map((source) => {\n const used = usageBySource.get(source.id) ?? []\n return (\n <div key={source.id} className=\"fm-inspector-row\">\n <div>\n <strong>{source.label}</strong>\n {source.subtitle ? (\n <div className=\"fm-value\">{source.subtitle}</div>\n ) : null}\n <div className=\"fm-value\">\n {truncateSample(source.value, 60)}\n </div>\n </div>\n <div className=\"fm-value\">\n {used.length > 0 ? `→ ${used.join(', ')}` : 'unused'}\n </div>\n <Button\n className=\"fm-btn\"\n onClick={() => mapThisSource(source.id)}\n >\n Map this\n </Button>\n </div>\n )\n })}\n </details>\n )}\n\n {showSectionLookups && (\n <LookupEditor\n mode=\"section\"\n mappings={mappings}\n sources={sources}\n targets={targets}\n onLookupChange={(mapping, entries) => {\n const row = mapper.rows.find(\n (r) =>\n r.mapping?.sourceId === mapping.sourceId &&\n r.mapping?.propertyName === mapping.propertyName,\n )\n if (row) mapper.setLookupEntries(row.id, entries)\n }}\n classNames={classNames}\n />\n )}\n\n {jsonPreview && (\n <details\n className={slotClass('jsonPreview', classNames)}\n open={previewOpen}\n onToggle={(e) =>\n setPreviewOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>Preview JSON</summary>\n <pre className=\"fm-preview-body\">\n {JSON.stringify(syncPreview, null, 2)}\n </pre>\n </details>\n )}\n </>\n )\n}\n","import React, { useMemo, useState, type ReactNode } from 'react'\nimport type {\n FieldMapping,\n MappingLookups,\n ResolveJob,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperSlot,\n ResolvedFieldMapperComponents,\n ResolvedFieldMapperSlots,\n} from './fieldMapperSlots'\nimport {\n showJsonPreview,\n showRowPreview,\n slotClass,\n} from './fieldMapperSlots'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport { buildSyncPreviewBag } from './fieldMapperCore'\nimport type {\n FieldMapperLookupRow,\n FieldMapperRow,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\nimport { LookupEditor } from './LookupEditor'\n\nconst TRANSFORM_OPTIONS: { value: '' | ResolveJob; label: string }[] = [\n { value: '', label: 'copy' },\n { value: 'extract', label: 'extract' },\n { value: 'file', label: 'file' },\n { value: 'lookup', label: 'lookup' },\n]\n\nexport type SourceRowsProps = {\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n mapper: UseFieldMapperResult\n lookups?: MappingLookups\n onLookupsChange?: (lookups: MappingLookups) => void\n slots: ResolvedFieldMapperSlots\n classNames?: Partial<Record<FieldMapperSlot, string>>\n ui?: ResolvedFieldMapperComponents\n renderRowAccessory?: (row: FieldMapperRow) => ReactNode\n renderLookup?: (row: FieldMapperLookupRow) => ReactNode\n}\n\nexport function SourceRows({\n sources,\n targets,\n mappings,\n mapper,\n onLookupsChange,\n slots,\n classNames,\n ui = {\n Select: DefaultSelect,\n Button: DefaultButton,\n Pill: DefaultPill,\n },\n renderRowAccessory,\n renderLookup,\n}: SourceRowsProps) {\n const Select = ui.Select\n const Button = ui.Button\n const [previewOpen, setPreviewOpen] = useState(false)\n const {\n rows,\n sourceOptions,\n propertyOptions,\n coverage,\n conflicts,\n setSource,\n setProperty,\n setTransform,\n addRow,\n removeRow,\n autoMap,\n } = mapper\n\n const syncPreview = useMemo(\n () => buildSyncPreviewBag(sources, mappings, targets),\n [sources, mappings, targets],\n )\n\n const jsonPreview = showJsonPreview(slots.preview)\n const rowPreview = showRowPreview(slots.preview)\n const showRowLookups =\n slots.lookups === 'row' && (Boolean(renderLookup) || Boolean(onLookupsChange))\n const showSectionLookups =\n slots.lookups === 'section' &&\n !renderLookup &&\n Boolean(onLookupsChange)\n\n return (\n <>\n <div className={slotClass('toolbar', classNames)}>\n {slots.autoMap && (\n <Button\n className={slotClass('autoMapButton', classNames)}\n onClick={() => autoMap()}\n >\n Auto-map\n </Button>\n )}\n <span className={slotClass('coverage', classNames)}>\n {coverage.mapped} of {coverage.total} mapped\n {coverage.missingRequired.length > 0\n ? ` · ${coverage.missingRequired.length} required missing: ${coverage.missingRequired.join(', ')}`\n : ''}\n </span>\n </div>\n\n {conflicts.size > 0 && (\n <div className=\"fm-banner fm-banner-danger\" role=\"alert\">\n {conflicts.size} row{conflicts.size === 1 ? '' : 's'} claim the same\n property — each property can only have one source.\n </div>\n )}\n\n {coverage.missingRequired.length > 0 && (\n <div className=\"fm-banner fm-banner-warn\" role=\"status\">\n Required missing: {coverage.missingRequired.join(', ')}\n </div>\n )}\n\n <div className={slotClass('rowList', classNames)}>\n {rows.map((row) => {\n const resolveValue = (row.mapping?.resolve ?? '') as '' | ResolveJob\n const sourceValue = row.source?.id ?? row.mapping?.sourceId ?? ''\n const propertyValue =\n row.target?.name ?? row.mapping?.propertyName ?? ''\n return (\n <div\n key={row.id}\n className={slotClass('row', classNames)}\n data-state={row.state}\n data-property-name={propertyValue || undefined}\n data-required={row.target?.required ? 'true' : undefined}\n data-resolve={row.mapping?.resolve}\n data-source-kind={row.source?.kind}\n >\n <div className=\"fm-row-main fm-row-main-source\">\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label=\"Source field\"\n value={sourceValue}\n onChange={(v) => {\n setSource(row.id, v || null)\n }}\n >\n <option value=\"\">Choose a source field…</option>\n {sourceOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n {sourceValue ? (\n <Select\n className={slotClass('transformSelect', classNames)}\n aria-label=\"Transform\"\n value={resolveValue}\n onChange={(v) => {\n setTransform(row.id, (v as ResolveJob) || null)\n }}\n >\n {TRANSFORM_OPTIONS.map((opt) => (\n <option key={opt.label} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n ) : (\n <span className=\"fm-into\" />\n )}\n <span className=\"fm-into\">into</span>\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label=\"Target property\"\n value={propertyValue}\n onChange={(v) => {\n if (v) setProperty(row.id, v)\n }}\n >\n <option value=\"\">Choose a property…</option>\n {propertyOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n <div className={slotClass('rowAccessory', classNames)}>\n {renderRowAccessory?.(row) ?? null}\n </div>\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label=\"Remove row\"\n onClick={() => removeRow(row.id)}\n >\n ×\n </Button>\n </div>\n {rowPreview && row.preview && (\n <div className={slotClass('preview', classNames)}>\n {row.preview}\n </div>\n )}\n {row.state === 'needsResolve' && row.requiredResolve && (\n <div className={slotClass('validation', classNames)}>\n needs {row.requiredResolve}\n </div>\n )}\n {row.state === 'needsLookup' && (\n <div className={slotClass('validation', classNames)}>\n needs lookup\n </div>\n )}\n {row.state === 'conflict' && (\n <div\n className={slotClass('validation', classNames)}\n style={{ color: 'var(--fm-danger)' }}\n >\n property already mapped by another row\n </div>\n )}\n {showRowLookups &&\n row.mapping?.resolve === 'lookup' &&\n row.mapping &&\n (renderLookup ? (\n <div className={slotClass('lookupEditor', classNames)}>\n {renderLookup({\n ...row,\n sampleValue: row.sampleValue ?? '',\n onLookupChange: (entries) =>\n mapper.setLookupEntries(row.id, entries),\n })}\n </div>\n ) : (\n <LookupEditor\n mode=\"row\"\n mappings={[row.mapping]}\n sources={sources}\n targets={targets}\n onLookupChange={(_mapping, entries) =>\n mapper.setLookupEntries(row.id, entries)\n }\n classNames={classNames}\n />\n ))}\n </div>\n )\n })}\n </div>\n\n <div style={{ marginTop: 10 }}>\n <Button\n className={slotClass('addButton', classNames)}\n onClick={() => addRow()}\n >\n + Add mapping\n </Button>\n </div>\n\n {showSectionLookups && (\n <LookupEditor\n mode=\"section\"\n mappings={mappings}\n sources={sources}\n targets={targets}\n onLookupChange={(mapping, entries) => {\n const match = mapper.rows.find(\n (r) =>\n r.mapping?.sourceId === mapping.sourceId &&\n r.mapping?.propertyName === mapping.propertyName,\n )\n if (match) mapper.setLookupEntries(match.id, entries)\n }}\n classNames={classNames}\n />\n )}\n\n {jsonPreview && (\n <details\n className={slotClass('jsonPreview', classNames)}\n open={previewOpen}\n onToggle={(e) =>\n setPreviewOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>Preview JSON</summary>\n <pre className=\"fm-preview-body\">\n {JSON.stringify(syncPreview, null, 2)}\n </pre>\n </details>\n )}\n </>\n )\n}\n","import { useCallback, useMemo, useRef, useState } from 'react'\nimport { autoMap as defaultAutoMap } from '../autoMap'\nimport { stripLookup } from '../relationLookup'\nimport type {\n FieldMapping,\n LookupEntry,\n ResolveJob,\n TargetProperty,\n} from '../types'\nimport {\n applyLookupEntriesToMappings,\n attachLookupIfNeeded,\n buildPropertyModeRows,\n buildPropertyOptions,\n buildSourceModeRows,\n buildSourceOptions,\n clearLookupsForProperties,\n computeCoverage,\n computeRequiredResolve,\n connectSourceToProperty,\n filterPropertyNames,\n newRowId,\n originSources,\n removeMappingsForSourceId,\n syncEdgeIds,\n type SourceModeDraft,\n upsertPropertyMapping,\n} from './fieldMapperCore'\nimport type {\n UseFieldMapperArgs,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\n\nexport function useFieldMapper({\n sources,\n targets,\n mappings,\n onChange,\n lookups = {},\n onLookupsChange,\n rowKey = 'property',\n onAutoMap,\n}: UseFieldMapperArgs): UseFieldMapperResult {\n const [extraPropertyNames, setExtraPropertyNames] = useState<Set<string>>(\n () => new Set(),\n )\n const [drafts, setDrafts] = useState<SourceModeDraft[]>([])\n const edgeIdsRef = useRef<string[]>([])\n edgeIdsRef.current = syncEdgeIds(edgeIdsRef.current, mappings.length)\n const edgeIds = edgeIdsRef.current\n\n const applyLookupClears = useCallback(\n (props: string[]) => {\n if (!onLookupsChange || props.length === 0) return\n const next = clearLookupsForProperties(lookups, props)\n if (next) onLookupsChange(next)\n },\n [lookups, onLookupsChange],\n )\n\n const sourceOptions = useMemo(() => buildSourceOptions(sources), [sources])\n const propertyOptions = useMemo(\n () => buildPropertyOptions(targets),\n [targets],\n )\n\n const coverage = useMemo(\n () => computeCoverage(targets, mappings),\n [targets, mappings],\n )\n\n const mappedProps = useMemo(\n () => new Set(mappings.map((m) => m.propertyName)),\n [mappings],\n )\n\n const addableProperties = useMemo(\n () =>\n targets.filter(\n (t) => !mappedProps.has(t.name) && !extraPropertyNames.has(t.name),\n ),\n [targets, mappedProps, extraPropertyNames],\n )\n\n const propertyRows = useMemo(() => {\n // Property mode always exposes the full target list to the hook;\n // UI filter is applied by the renderer via filterPropertyNames.\n return buildPropertyModeRows({ targets, mappings, sources, lookups })\n }, [targets, mappings, sources, lookups])\n\n const sourceBuilt = useMemo(() => {\n return buildSourceModeRows({\n mappings,\n edgeIds,\n drafts,\n sources,\n targets,\n lookups,\n })\n }, [mappings, edgeIds, drafts, sources, targets, lookups])\n\n const rows = rowKey === 'property' ? propertyRows : sourceBuilt.rows\n const conflicts =\n rowKey === 'property' ? new Set<string>() : sourceBuilt.conflicts\n\n const connect = useCallback(\n (sourceId: string, propertyName: string) => {\n const result = connectSourceToProperty(\n mappings,\n sources,\n targets,\n sourceId,\n propertyName,\n )\n onChange(result.mappings)\n applyLookupClears(result.clearedLookupProps)\n },\n [mappings, sources, targets, onChange, applyLookupClears],\n )\n\n const removeBySource = useCallback(\n (sourceId: string) => {\n const result = removeMappingsForSourceId(mappings, sourceId)\n onChange(result.mappings)\n applyLookupClears(result.clearedLookupProps)\n },\n [mappings, onChange, applyLookupClears],\n )\n\n const autoMap = useCallback(() => {\n const next = onAutoMap ? onAutoMap() : defaultAutoMap(sources, targets)\n onChange(next)\n setDrafts([])\n setExtraPropertyNames(new Set())\n }, [onAutoMap, sources, targets, onChange])\n\n const setSource = useCallback(\n (rowId: string, sourceId: string | null) => {\n if (rowKey === 'property') {\n if (!sourceId) {\n const prev = mappings.find((m) => m.propertyName === rowId)\n onChange(mappings.filter((m) => m.propertyName !== rowId))\n if (prev?.resolve === 'lookup') applyLookupClears([rowId])\n return\n }\n const result = connectSourceToProperty(\n mappings,\n sources,\n targets,\n sourceId,\n rowId,\n )\n // Pre-select required transform when connecting a plain origin source\n const target = targets.find((t) => t.name === rowId)\n const source = originSources(sources).find((s) => s.id === sourceId)\n let edge = result.mappings.find((m) => m.propertyName === rowId)!\n if (!edge.resolve) {\n const required = computeRequiredResolve(source, target)\n if (required) {\n edge = { ...edge, resolve: required }\n onChange(upsertPropertyMapping(result.mappings, edge))\n applyLookupClears(result.clearedLookupProps)\n return\n }\n }\n onChange(result.mappings)\n applyLookupClears(result.clearedLookupProps)\n return\n }\n\n // source mode\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex >= 0) {\n if (!sourceId) {\n const prev = mappings[edgeIndex]\n const next = mappings.filter((_, i) => i !== edgeIndex)\n onChange(next)\n if (prev?.resolve === 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n const prev = mappings[edgeIndex]!\n const target = targets.find((t) => t.name === prev.propertyName)\n let edge: FieldMapping = {\n sourceId,\n propertyName: prev.propertyName,\n }\n edge = attachLookupIfNeeded(edge, target)\n if (!edge.resolve) {\n const source = originSources(sources).find((s) => s.id === sourceId)\n const required = computeRequiredResolve(source, target)\n if (required) edge = { ...edge, resolve: required }\n }\n const next = [...mappings]\n next[edgeIndex] = edge\n onChange(next)\n if (prev.resolve === 'lookup' && edge.resolve !== 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) => {\n const updated = prev.map((d) => {\n if (d.id !== rowId) return d\n if (!sourceId) {\n return { id: d.id, propertyName: d.propertyName }\n }\n const target = d.propertyName\n ? targets.find((t) => t.name === d.propertyName)\n : undefined\n const source = originSources(sources).find((s) => s.id === sourceId)\n const required = computeRequiredResolve(source, target)\n const resolve =\n (target &&\n attachLookupIfNeeded(\n { sourceId, propertyName: d.propertyName ?? '' },\n target,\n ).resolve) ||\n required ||\n undefined\n return {\n id: d.id,\n sourceId,\n propertyName: d.propertyName,\n resolve,\n }\n })\n const complete = updated.filter((d) => d.sourceId && d.propertyName)\n const incomplete = updated.filter(\n (d) => !(d.sourceId && d.propertyName),\n )\n if (complete.length > 0) {\n onChange([\n ...mappings,\n ...complete.map((d) => ({\n sourceId: d.sourceId!,\n propertyName: d.propertyName!,\n ...(d.resolve ? { resolve: d.resolve } : {}),\n })),\n ])\n return incomplete\n }\n return updated\n })\n },\n [\n rowKey,\n mappings,\n sources,\n targets,\n onChange,\n applyLookupClears,\n edgeIds,\n ],\n )\n\n const setProperty = useCallback(\n (rowId: string, propertyName: string) => {\n if (rowKey === 'property') {\n // Property mode row ids are property names; renaming is add+remove.\n return\n }\n\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex >= 0) {\n const prev = mappings[edgeIndex]!\n const target = targets.find((t) => t.name === propertyName)\n const source = originSources(sources).find(\n (s) => s.id === prev.sourceId,\n )\n let edge: FieldMapping = {\n sourceId: prev.sourceId,\n propertyName,\n }\n edge = attachLookupIfNeeded(edge, target)\n if (!edge.resolve) {\n const required = computeRequiredResolve(source, target)\n if (required) edge = { ...edge, resolve: required }\n }\n const next = [...mappings]\n next[edgeIndex] = edge\n onChange(next)\n if (prev.resolve === 'lookup' && edge.resolve !== 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n if (\n prev.propertyName !== propertyName &&\n prev.resolve === 'lookup' &&\n edge.resolve === 'lookup'\n ) {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) => {\n const updated = prev.map((d) => {\n if (d.id !== rowId) return d\n const target = targets.find((t) => t.name === propertyName)\n const source = d.sourceId\n ? originSources(sources).find((s) => s.id === d.sourceId)\n : undefined\n let resolve = d.resolve\n if (d.sourceId && target) {\n const attached = attachLookupIfNeeded(\n { sourceId: d.sourceId, propertyName },\n target,\n )\n resolve =\n attached.resolve ??\n computeRequiredResolve(source, target) ??\n undefined\n }\n const nextDraft: SourceModeDraft = {\n id: d.id,\n sourceId: d.sourceId,\n propertyName,\n resolve,\n }\n // Promote complete drafts into mappings\n if (nextDraft.sourceId && nextDraft.propertyName) {\n return nextDraft\n }\n return nextDraft\n })\n\n const complete = updated.filter(\n (d) => d.sourceId && d.propertyName,\n )\n const incomplete = updated.filter(\n (d) => !(d.sourceId && d.propertyName),\n )\n\n if (complete.length > 0) {\n const promoted: FieldMapping[] = complete.map((d) => ({\n sourceId: d.sourceId!,\n propertyName: d.propertyName!,\n ...(d.resolve ? { resolve: d.resolve } : {}),\n }))\n onChange([...mappings, ...promoted])\n return incomplete\n }\n return updated\n })\n },\n [\n rowKey,\n edgeIds,\n mappings,\n targets,\n sources,\n onChange,\n applyLookupClears,\n ],\n )\n\n const setLookupEntries = useCallback(\n (rowId: string, entries: LookupEntry[]) => {\n const next = applyLookupEntriesToMappings(\n mappings,\n rowKey,\n rowId,\n edgeIds,\n entries,\n )\n if (!next) return\n onChange(next)\n if (!onLookupsChange) return\n const edge =\n rowKey === 'property'\n ? next.find((m) => m.propertyName === rowId)\n : next[edgeIds.indexOf(rowId)]\n if (!edge) return\n const table = Object.fromEntries(\n (edge.lookup?.entries ?? []).map((e) => [e.value, e.ref]),\n )\n const merged = { ...lookups }\n if (Object.keys(table).length === 0) {\n delete merged[edge.propertyName]\n } else {\n merged[edge.propertyName] = table\n }\n onLookupsChange(merged)\n },\n [mappings, rowKey, edgeIds, onChange, onLookupsChange, lookups],\n )\n\n const setTransform = useCallback(\n (rowId: string, resolve: ResolveJob | null) => {\n const nextEdge = (\n prev: FieldMapping,\n nextResolve: ResolveJob | null,\n ): FieldMapping => {\n if (!nextResolve) {\n return {\n sourceId: prev.sourceId,\n propertyName: prev.propertyName,\n }\n }\n if (nextResolve === 'lookup') {\n return { ...prev, resolve: nextResolve }\n }\n return stripLookup({\n sourceId: prev.sourceId,\n propertyName: prev.propertyName,\n resolve: nextResolve,\n })\n }\n\n if (rowKey === 'property') {\n const prev = mappings.find((m) => m.propertyName === rowId)\n if (!prev) return\n onChange(upsertPropertyMapping(mappings, nextEdge(prev, resolve)))\n if (prev.resolve === 'lookup' && resolve !== 'lookup') {\n applyLookupClears([rowId])\n }\n return\n }\n\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex >= 0) {\n const prev = mappings[edgeIndex]!\n const next = [...mappings]\n next[edgeIndex] = nextEdge(prev, resolve)\n onChange(next)\n if (prev.resolve === 'lookup' && resolve !== 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) =>\n prev.map((d) =>\n d.id === rowId\n ? { ...d, resolve: resolve ?? undefined }\n : d,\n ),\n )\n },\n [rowKey, mappings, edgeIds, onChange, applyLookupClears],\n )\n\n const addRow = useCallback(\n (propertyName?: string) => {\n if (rowKey === 'property') {\n if (propertyName) {\n setExtraPropertyNames((prev) => new Set(prev).add(propertyName))\n }\n return\n }\n setDrafts((prev) => [\n ...prev,\n {\n id: newRowId('draft'),\n ...(propertyName ? { propertyName } : {}),\n },\n ])\n },\n [rowKey],\n )\n\n const removeRow = useCallback(\n (rowId: string) => {\n if (rowKey === 'property') {\n const prev = mappings.find((m) => m.propertyName === rowId)\n onChange(mappings.filter((m) => m.propertyName !== rowId))\n if (prev?.resolve === 'lookup') applyLookupClears([rowId])\n setExtraPropertyNames((prevSet) => {\n if (!prevSet.has(rowId)) return prevSet\n const next = new Set(prevSet)\n next.delete(rowId)\n return next\n })\n return\n }\n\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex >= 0) {\n const prev = mappings[edgeIndex]\n onChange(mappings.filter((_, i) => i !== edgeIndex))\n if (prev?.resolve === 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) => prev.filter((d) => d.id !== rowId))\n },\n [rowKey, mappings, edgeIds, onChange, applyLookupClears],\n )\n\n return {\n rows,\n sourceOptions,\n propertyOptions,\n addableProperties,\n coverage,\n conflicts,\n setSource,\n setProperty,\n setTransform,\n setLookupEntries,\n addRow,\n removeRow,\n autoMap,\n connect,\n removeBySource,\n }\n}\n\n/** Re-export filter helper for row renderers. */\nexport { filterPropertyNames }\nexport type { TargetProperty }\n","import React, { useEffect, useMemo, type ReactNode } from 'react'\nimport type {\n FieldMapping,\n MappingLookups,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport type {\n FieldMapperComponents,\n FieldMapperSlot,\n FieldMapperSlots,\n} from './fieldMapperSlots'\nimport { resolveSlots, slotClass } from './fieldMapperSlots'\nimport { FieldMapperWires } from './FieldMapperWires'\nimport type {\n FieldMapperDefaultRows,\n FieldMapperLayout,\n FieldMapperLookupRow,\n FieldMapperRow,\n FieldMapperRowKey,\n} from './fieldMapperTypes'\nimport {\n ensureThemeInjected,\n resolveTheme,\n type FieldMapperTheme,\n} from './fieldMapperTheme'\nimport { PropertyRows } from './PropertyRows'\nimport { SourceRows } from './SourceRows'\nimport { useFieldMapper } from './useFieldMapper'\n\nexport {\n connectionStrokeForIndex,\n FIELD_MAPPER_PAIR_SLOTS,\n resolveTheme,\n ensureThemeInjected,\n buildThemeCss,\n wrapInThemeLayer,\n DEFAULT_THEME_CSS,\n STRUCTURAL_THEME_CSS,\n PAINT_THEME_CSS,\n THEME_STYLE_ID,\n resetThemeInjectionForTests,\n type FieldMapperTheme,\n type ResolvedFieldMapperTheme,\n} from './fieldMapperTheme'\n\nexport {\n slotClass,\n resolveSlots,\n showRowPreview,\n showJsonPreview,\n SLOT_BASE_CLASS,\n type FieldMapperSlot,\n type FieldMapperSlots,\n type ResolvedFieldMapperSlots,\n type FieldMapperComponents,\n type ResolvedFieldMapperComponents,\n type FieldMapperSelectProps,\n type FieldMapperButtonProps,\n type FieldMapperPillProps,\n} from './fieldMapperSlots'\n\nexport type { FieldMapperLayout, FieldMapperRowKey, FieldMapperDefaultRows }\n\nexport type FieldMapperProps = {\n /**\n * Source nodes to display. For `layout=\"rows\"` (default), pass origin\n * sources — transforms are chosen per row. For deprecated `layout=\"wires\"`,\n * pass `buildResolvedSourceNodes(sources)` to show extract/file candidates.\n */\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n onChange: (mappings: FieldMapping[]) => void\n /**\n * String → seed uid dictionaries for `resolve: 'lookup'` edges.\n * Host should persist alongside `MappingDocument.lookups`.\n */\n /**\n * @deprecated Prefer `FieldMapping.lookup.entries` + `renderLookup`.\n * Still accepted as a read fallback for preview / LookupEditor.\n */\n lookups?: MappingLookups\n /**\n * @deprecated Prefer `renderLookup`. Enables the package uid editor fallback.\n */\n onLookupsChange?: (lookups: MappingLookups) => void\n /** Override default autoMap heuristics. */\n onAutoMap?: () => FieldMapping[]\n className?: string\n /**\n * `default` injects structural + paint CSS.\n * `structural` injects layout/spacing only.\n * `none` skips injection (host styles structural classes / CSS vars).\n * `@deprecated` Prefer `none` — `unstyled` is a shim for `none`.\n */\n theme?: FieldMapperTheme\n /**\n * Optional connector stroke colors (wires layout). When omitted, strokes use\n * `var(--fm-map-N, var(--map-N, currentColor))` for N = 1…8.\n * @deprecated Prefer CSS `--sfm-map-*` / `--fm-map-*` / `--map-*` tokens.\n */\n connectionColors?: string[]\n /**\n * Show JSON preview. Default true.\n * @deprecated Prefer `slots.preview` (`'row' | 'json' | 'both' | false`).\n */\n showPreview?: boolean\n /**\n * Authoring surface. Defaults to `'rows'`.\n * `@deprecated` Prefer `'rows'` — `'wires'` remains supported for one minor.\n */\n layout?: FieldMapperLayout\n /**\n * Which side opens each row when `layout=\"rows\"`.\n * `'property'` (default) cannot represent an invalid state;\n * `'source'` matches the edge list and surfaces conflicts + coverage banners.\n */\n rowKey?: FieldMapperRowKey\n /** Rows shown before the filter is widened (property mode). */\n defaultRows?: FieldMapperDefaultRows\n /** Per-slot class injection; merged with package classes, never replacing them. */\n classNames?: Partial<Record<FieldMapperSlot, string>>\n /** Host design-system controls. Defaults are dependency-free natives. */\n components?: FieldMapperComponents\n /** Include / exclude structural pieces. Replaces `showPreview`. */\n slots?: FieldMapperSlots\n /**\n * Optional per-row host chrome (e.g. extract/file Preview). Rendered in\n * `.fm-row-accessory` after the transform control and before remove.\n * Return `null` when nothing to show. Package does not fetch or preview.\n */\n renderRowAccessory?: (row: FieldMapperRow) => ReactNode\n /**\n * Host lookup chrome on `resolve: 'lookup'` rows (Identity picker, etc.).\n * When set, the package uid editor is not mounted. Return `null` when idle.\n */\n renderLookup?: (row: FieldMapperLookupRow) => ReactNode\n}\n\n/**\n * Generic field mapper. Props-driven; no Seed hooks or routing.\n * Default layout is rows; pass `layout=\"wires\"` only if you still need the\n * two-pane connector UI (deprecated).\n */\nexport function FieldMapper({\n sources,\n targets,\n mappings,\n onChange,\n lookups = {},\n onLookupsChange,\n onAutoMap,\n className,\n theme = 'default',\n connectionColors,\n showPreview,\n layout = 'rows',\n rowKey = 'property',\n defaultRows = 'requiredAndMapped',\n classNames,\n components,\n slots,\n renderRowAccessory,\n renderLookup,\n}: FieldMapperProps) {\n const mapper = useFieldMapper({\n sources,\n targets,\n mappings,\n onChange,\n lookups,\n onLookupsChange,\n rowKey: layout === 'rows' ? rowKey : 'property',\n onAutoMap,\n })\n\n const resolvedTheme = resolveTheme(theme)\n const resolvedSlots = useMemo(\n () => resolveSlots(slots, showPreview, { layout }),\n [slots, showPreview, layout],\n )\n\n const ui = useMemo(\n () => ({\n Select: components?.Select ?? DefaultSelect,\n Button: components?.Button ?? DefaultButton,\n Pill: components?.Pill ?? DefaultPill,\n }),\n [components],\n )\n\n useEffect(() => {\n ensureThemeInjected(resolvedTheme)\n }, [resolvedTheme])\n\n const unstyled =\n resolvedTheme === 'none' || theme === 'unstyled' || theme === 'none'\n\n const rootClass = slotClass(\n 'root',\n classNames,\n [\n unstyled ? 'seed-field-mapper--unstyled' : null,\n layout === 'rows' ? 'seed-field-mapper--rows' : 'seed-field-mapper--wires',\n className,\n ]\n .filter(Boolean)\n .join(' ') || null,\n )\n\n return (\n <div\n className={rootClass}\n data-theme={resolvedTheme}\n data-layout={layout}\n data-row-key={layout === 'rows' ? rowKey : undefined}\n >\n {layout === 'wires' ? (\n <FieldMapperWires\n sources={sources}\n targets={targets}\n mappings={mappings}\n mapper={mapper}\n lookups={lookups}\n onLookupsChange={onLookupsChange}\n renderLookup={renderLookup}\n connectionColors={connectionColors}\n slots={resolvedSlots}\n classNames={classNames}\n ui={ui}\n />\n ) : rowKey === 'source' ? (\n <SourceRows\n sources={sources}\n targets={targets}\n mappings={mappings}\n mapper={mapper}\n lookups={lookups}\n onLookupsChange={onLookupsChange}\n slots={resolvedSlots}\n classNames={classNames}\n ui={ui}\n renderRowAccessory={renderRowAccessory}\n renderLookup={renderLookup}\n />\n ) : (\n <PropertyRows\n sources={sources}\n targets={targets}\n mappings={mappings}\n mapper={mapper}\n defaultRows={defaultRows}\n lookups={lookups}\n onLookupsChange={onLookupsChange}\n slots={resolvedSlots}\n classNames={classNames}\n ui={ui}\n renderRowAccessory={renderRowAccessory}\n renderLookup={renderLookup}\n />\n )}\n </div>\n )\n}\n\nexport default FieldMapper\n"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","names":[],"sources":["../src/react/fieldMapperControls.tsx","../src/react/fieldMapperSlots.ts","../src/react/fieldMapperCore.ts","../src/react/LookupEditor.tsx","../src/react/fieldMapperTheme.ts","../src/react/FieldMapperWires.tsx","../src/react/fieldMapperTransforms.ts","../src/react/PropertyRows.tsx","../src/react/SourceRows.tsx","../src/react/useFieldMapper.ts","../src/react/FieldMapper.tsx"],"sourcesContent":["import React from 'react'\nimport type {\n FieldMapperButtonProps,\n FieldMapperPillProps,\n FieldMapperSelectProps,\n} from './fieldMapperSlots'\n\n/** Default native select used when no `components.Select` is provided. */\nexport function DefaultSelect({\n className,\n value,\n onChange,\n children,\n disabled,\n 'aria-label': ariaLabel,\n}: FieldMapperSelectProps) {\n return (\n <select\n className={className}\n aria-label={ariaLabel}\n disabled={disabled}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n >\n {children}\n </select>\n )\n}\n\n/** Default native button used when no `components.Button` is provided. */\nexport function DefaultButton({\n className,\n type = 'button',\n onClick,\n children,\n disabled,\n 'aria-label': ariaLabel,\n 'aria-pressed': ariaPressed,\n}: FieldMapperButtonProps) {\n return (\n <button\n type={type}\n className={className}\n onClick={onClick}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-pressed={ariaPressed}\n >\n {children}\n </button>\n )\n}\n\n/** Default span pill used when no `components.Pill` is provided. */\nexport function DefaultPill({\n className,\n children,\n}: FieldMapperPillProps) {\n return <span className={className}>{children}</span>\n}\n","import type { ComponentType, MouseEvent, ReactNode } from 'react'\nimport type { FieldMapperLayout } from './fieldMapperTypes'\n\nexport type FieldMapperSlot =\n | 'root'\n | 'toolbar'\n | 'filter'\n | 'coverage'\n | 'autoMapButton'\n | 'rowList'\n | 'row'\n | 'propertyLabel'\n | 'dataType'\n | 'sourceSelect'\n | 'transformSelect'\n | 'rowAccessory'\n | 'preview'\n | 'validation'\n | 'removeButton'\n | 'addButton'\n | 'inspector'\n | 'lookupEditor'\n | 'rowExpansion'\n | 'jsonPreview'\n\nexport type FieldMapperSlots = {\n autoMap?: boolean\n filter?: boolean\n inspector?: boolean\n preview?: 'row' | 'json' | 'both' | false\n /**\n * Lookup editor placement.\n * Unspecified defaults to `'row'` when `layout === 'rows'`, otherwise `'section'`.\n */\n lookups?: 'row' | 'section' | false\n}\n\nexport type ResolvedFieldMapperSlots = {\n autoMap: boolean\n filter: boolean\n inspector: boolean\n preview: 'row' | 'json' | 'both' | false\n lookups: 'row' | 'section' | false\n}\n\nexport type ResolveSlotsOptions = {\n /** Used when `slots.lookups` is unspecified. */\n layout?: FieldMapperLayout\n}\n\nexport type FieldMapperSelectProps = {\n className?: string\n value: string\n onChange: (value: string) => void\n 'aria-label'?: string\n children: ReactNode\n disabled?: boolean\n}\n\nexport type FieldMapperButtonProps = {\n className?: string\n type?: 'button' | 'submit' | 'reset'\n onClick?: (e: MouseEvent<HTMLButtonElement>) => void\n children: ReactNode\n disabled?: boolean\n 'aria-label'?: string\n 'aria-pressed'?: boolean | 'true' | 'false'\n}\n\nexport type FieldMapperPillProps = {\n children: ReactNode\n className?: string\n}\n\nexport type FieldMapperComponents = {\n Select?: ComponentType<FieldMapperSelectProps>\n Button?: ComponentType<FieldMapperButtonProps>\n Pill?: ComponentType<FieldMapperPillProps>\n}\n\nexport type ResolvedFieldMapperComponents = {\n Select: ComponentType<FieldMapperSelectProps>\n Button: ComponentType<FieldMapperButtonProps>\n Pill: ComponentType<FieldMapperPillProps>\n}\n\n/** Package class names per slot (merged with host `classNames`). */\nexport const SLOT_BASE_CLASS: Record<FieldMapperSlot, string> = {\n root: 'seed-field-mapper',\n toolbar: 'fm-toolbar',\n filter: 'fm-filter',\n coverage: 'fm-meta',\n autoMapButton: 'fm-btn fm-btn-primary',\n rowList: 'fm-row-list',\n row: 'fm-row',\n propertyLabel: 'fm-row-prop-name',\n dataType: 'fm-dtype',\n sourceSelect: 'fm-select',\n transformSelect: 'fm-select',\n rowAccessory: 'fm-row-accessory',\n preview: 'fm-row-preview',\n validation: 'fm-row-flag',\n removeButton: 'fm-remove',\n addButton: 'fm-btn',\n inspector: 'fm-inspector',\n lookupEditor: 'fm-lookups',\n rowExpansion: 'fm-row-expansion',\n jsonPreview: 'fm-preview',\n}\n\n/** Merge package slot class with optional host classNames entry. */\nexport function slotClass(\n slot: FieldMapperSlot,\n classNames?: Partial<Record<FieldMapperSlot, string>>,\n extra?: string | null,\n): string {\n return [SLOT_BASE_CLASS[slot], classNames?.[slot], extra]\n .filter(Boolean)\n .join(' ')\n}\n\n/**\n * Resolve slots + deprecated `showPreview` shim.\n * Default preview is `'both'` (row preview + JSON disclosure) when unspecified.\n * Unspecified lookups: `'row'` for rows layout, `'section'` for wires.\n */\nexport function resolveSlots(\n slots?: FieldMapperSlots,\n showPreview?: boolean,\n options?: ResolveSlotsOptions,\n): ResolvedFieldMapperSlots {\n let preview: ResolvedFieldMapperSlots['preview']\n if (slots?.preview !== undefined) {\n preview = slots.preview\n } else if (showPreview === false) {\n preview = false\n } else {\n preview = 'both'\n }\n\n let lookups: ResolvedFieldMapperSlots['lookups']\n if (slots?.lookups === false) {\n lookups = false\n } else if (slots?.lookups === 'row' || slots?.lookups === 'section') {\n lookups = slots.lookups\n } else {\n lookups = options?.layout === 'rows' ? 'row' : 'section'\n }\n\n return {\n autoMap: slots?.autoMap ?? true,\n filter: slots?.filter ?? true,\n inspector: slots?.inspector ?? true,\n preview,\n lookups,\n }\n}\n\nexport function showRowPreview(\n preview: ResolvedFieldMapperSlots['preview'],\n): boolean {\n return preview === 'row' || preview === 'both'\n}\n\nexport function showJsonPreview(\n preview: ResolvedFieldMapperSlots['preview'],\n): boolean {\n return preview === 'json' || preview === 'both'\n}\n","import { applyMapping, coerceValue } from '../applyMapping'\nimport { looksLikeUrl } from '../classifyUrl'\nimport {\n isPresentEdge,\n withAssembleBlocks,\n withDeriveSpec,\n withPreservedExtras,\n} from '../edgeMapping'\nimport {\n isRelationLookupTarget,\n resolveLookupMapped,\n sampleValueFromSource,\n shapeLookupValue,\n stripLookup,\n withLookupEntries,\n} from '../relationLookup'\nimport {\n normalizeMappingFromSourceId,\n parseResolvedSourceId,\n} from '../resolvedSources'\nimport type {\n DeriveSpec,\n FieldMapping,\n LookupEntry,\n MappingLookups,\n ResolveJob,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperCoverage,\n FieldMapperOption,\n FieldMapperRow,\n FieldMapperRowState,\n} from './fieldMapperTypes'\n\nexport function truncateSample(s: string, n = 40): string {\n const t = s.replace(/\\s+/g, ' ').trim()\n if (t.length <= n) return t\n return `${t.slice(0, n)}…`\n}\n\nexport function formatSourceOptionLabel(source: SourceNode): string {\n const head = source.subtitle\n ? `${source.label} · ${source.subtitle}`\n : source.label\n const sample = truncateSample(source.value, 36)\n if (!sample) return head\n return `${head} · \"${sample}\"`\n}\n\n/** Origin sources only — rows UI does not list `@extract`/`@file` cards. */\nexport function originSources(sources: SourceNode[]): SourceNode[] {\n return sources.filter((s) => s.kind !== 'resolved')\n}\n\nexport function buildSourceOptions(sources: SourceNode[]): FieldMapperOption[] {\n return originSources(sources).map((s) => ({\n value: s.id,\n label: formatSourceOptionLabel(s),\n sample: s.value,\n kind: s.kind,\n }))\n}\n\nexport function buildPropertyOptions(\n targets: TargetProperty[],\n): FieldMapperOption[] {\n return targets.map((t) => ({\n value: t.name,\n label: t.required ? `${t.name} *` : t.name,\n dataType: t.dataType,\n }))\n}\n\nfunction sourceLooksLikeUrl(source: SourceNode): boolean {\n if (source.kind === 'full' || source.kind === 'section') return false\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n if (url.trim().includes('<')) return false\n return looksLikeUrl(url)\n}\n\n/**\n * Transform required for a usable apply — mirrors autoMap / applyMapping rules.\n */\nexport function computeRequiredResolve(\n source: SourceNode | undefined,\n target: TargetProperty | undefined,\n): ResolveJob | null {\n if (!source || !target) return null\n if (isRelationLookupTarget(target)) return 'lookup'\n if (sourceLooksLikeUrl(source)) {\n if (target.dataType === 'Image' || target.dataType === 'File') return 'file'\n if (target.dataType === 'Html') return 'extract'\n }\n return null\n}\n\nexport type PreviewForEdgeOptions = {\n target?: TargetProperty\n lookups?: MappingLookups\n propertyName?: string\n mapping?: FieldMapping\n}\n\n/**\n * Sync row preview aligned with `applyMapping` / lookup tables.\n * `extract`/`file` stay descriptive (sync apply skips them).\n * `lookup` shows a stored-entry hit when present; otherwise a pending placeholder.\n * Plain copy shows the coerced value when a target is known.\n */\nexport function previewForEdge(\n source: SourceNode | undefined,\n resolve: ResolveJob | undefined,\n options?: PreviewForEdgeOptions,\n): string {\n if (resolve === 'derive') {\n const from = options?.mapping?.derive?.from\n return from ? `‹derive from ${from}›` : '‹derive›'\n }\n if (resolve === 'assemble') {\n const blocks = options?.mapping?.assemble?.blocks\n if (blocks?.length) return `‹assemble ${blocks.join(', ')}›`\n return '‹assemble›'\n }\n if (!source) return ''\n if (resolve === 'extract') {\n return `‹extract HTML from ${truncateSample(source.value, 48)}›`\n }\n if (resolve === 'file') {\n return `‹file stored from ${truncateSample(source.value, 48)}›`\n }\n if (resolve === 'lookup') {\n const raw = source.value || source.label\n const mapping = options?.mapping ?? {\n sourceId: source.id,\n propertyName: options?.propertyName ?? options?.target?.name ?? '',\n resolve: 'lookup' as const,\n }\n const mapped = resolveLookupMapped(mapping, raw, options?.lookups)\n if (mapped !== undefined) {\n const shaped = options?.target\n ? shapeLookupValue(mapped, options.target)\n : mapped\n if (Array.isArray(shaped)) {\n return truncateSample(shaped.join(', '), 80)\n }\n return truncateSample(String(shaped), 80)\n }\n return `‹lookup ref for \"${truncateSample(source.value, 48)}\"›`\n }\n // Sync apply skips plain copies onto relation targets.\n if (options?.target && isRelationLookupTarget(options.target)) {\n return ''\n }\n if (options?.target) {\n const raw = source.value || source.label\n const coerced = coerceValue(raw, options.target.dataType)\n if (typeof coerced === 'string') return truncateSample(coerced, 80)\n if (typeof coerced === 'number' || typeof coerced === 'boolean') {\n return String(coerced)\n }\n try {\n return truncateSample(JSON.stringify(coerced), 80)\n } catch {\n return truncateSample(String(coerced), 80)\n }\n }\n return truncateSample(source.value, 80)\n}\n\n/**\n * JSON preview bag: sync `applyMapping` output plus `_pendingResolve` for\n * edges that require a host resolver (matches wires layout).\n */\nexport function buildSyncPreviewBag(\n sources: SourceNode[],\n mappings: FieldMapping[],\n targets: TargetProperty[],\n): Record<string, unknown> {\n const bag = applyMapping(sources, mappings, targets) as Record<\n string,\n unknown\n >\n const pendingResolve = mappings.filter(\n (m) => m.resolve && m.resolve !== 'lookup',\n )\n if (pendingResolve.length === 0) return bag\n return {\n ...bag,\n _pendingResolve: pendingResolve.map((m) => ({\n propertyName: m.propertyName,\n sourceId: m.sourceId,\n resolve: m.resolve,\n })),\n }\n}\n\nexport function rowState(args: {\n mapping?: FieldMapping\n requiredResolve: ResolveJob | null\n conflict?: boolean\n sampleValue?: string\n lookups?: MappingLookups\n}): FieldMapperRowState {\n if (args.conflict) return 'conflict'\n if (!args.mapping || !isPresentEdge(args.mapping)) return 'empty'\n const actual = args.mapping.resolve ?? null\n if (args.requiredResolve && actual !== args.requiredResolve) {\n if (!(actual === 'assemble' && args.requiredResolve === 'extract')) {\n return 'needsResolve'\n }\n }\n if (actual === 'lookup') {\n const sample = args.sampleValue ?? ''\n if (\n !sample ||\n resolveLookupMapped(args.mapping, sample, args.lookups) === undefined\n ) {\n return 'needsLookup'\n }\n }\n return 'mapped'\n}\n\n\nexport function computeCoverage(\n targets: TargetProperty[],\n mappings: FieldMapping[],\n): FieldMapperCoverage {\n const mappedProps = new Set(\n mappings.filter(isPresentEdge).map((m) => m.propertyName),\n )\n const missingRequired = targets\n .filter((t) => t.required && !mappedProps.has(t.name))\n .map((t) => t.name)\n return {\n mapped: mappedProps.size,\n total: targets.length,\n missingRequired,\n }\n}\n\nexport function findConflicts(rows: { id: string; propertyName?: string }[]): Set<string> {\n const seen = new Map<string, string>()\n const conflicts = new Set<string>()\n for (const row of rows) {\n const prop = row.propertyName\n if (!prop) continue\n const first = seen.get(prop)\n if (first) {\n conflicts.add(row.id)\n conflicts.add(first)\n } else {\n seen.set(prop, row.id)\n }\n }\n return conflicts\n}\n\nexport function attachLookupIfNeeded(\n edge: FieldMapping,\n target: TargetProperty | undefined,\n): FieldMapping {\n if (edge.resolve) {\n return edge.resolve === 'lookup' ? edge : stripLookup(edge)\n }\n if (target && isRelationLookupTarget(target)) {\n return { ...stripLookup(edge), resolve: 'lookup' }\n }\n return stripLookup(edge)\n}\n\nexport function applyAssembleBlocksToMappings(\n mappings: FieldMapping[],\n rowKey: 'property' | 'source',\n rowId: string,\n edgeIds: string[],\n blocks: string[],\n): FieldMapping[] | null {\n const index =\n rowKey === 'property'\n ? mappings.findIndex((m) => m.propertyName === rowId)\n : edgeIds.indexOf(rowId)\n if (index < 0) return null\n const prev = mappings[index]\n if (!prev || prev.resolve !== 'assemble') return null\n const next = [...mappings]\n next[index] = withAssembleBlocks(prev, blocks)\n return next\n}\n\nexport function applyDeriveToMappings(\n mappings: FieldMapping[],\n rowKey: 'property' | 'source',\n rowId: string,\n edgeIds: string[],\n spec: DeriveSpec | null,\n): FieldMapping[] | null {\n if (rowKey === 'property') {\n const index = mappings.findIndex((m) => m.propertyName === rowId)\n if (index >= 0) {\n const next = [...mappings]\n next[index] = withDeriveSpec(mappings[index]!, spec)\n return next\n }\n if (!spec) return null\n return upsertPropertyMapping(mappings, {\n propertyName: rowId,\n resolve: 'derive',\n derive: spec,\n })\n }\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex < 0) return null\n const prev = mappings[edgeIndex]\n if (!prev) return null\n const next = [...mappings]\n next[edgeIndex] = withDeriveSpec(prev, spec)\n return next\n}\n\nexport function applyLookupEntriesToMappings(\n mappings: FieldMapping[],\n rowKey: 'property' | 'source',\n rowId: string,\n edgeIds: string[],\n entries: LookupEntry[],\n): FieldMapping[] | null {\n if (rowKey === 'property') {\n const index = mappings.findIndex((m) => m.propertyName === rowId)\n if (index < 0) return null\n const prev = mappings[index]!\n if (prev.resolve !== 'lookup') return null\n const next = [...mappings]\n next[index] = withLookupEntries(prev, entries)\n return next\n }\n const edgeIndex = edgeIds.indexOf(rowId)\n if (edgeIndex < 0) return null\n const prev = mappings[edgeIndex]\n if (!prev || prev.resolve !== 'lookup') return null\n const next = [...mappings]\n next[edgeIndex] = withLookupEntries(prev, entries)\n return next\n}\n\nexport function upsertPropertyMapping(\n mappings: FieldMapping[],\n edge: FieldMapping,\n): FieldMapping[] {\n const next = mappings.filter((m) => m.propertyName !== edge.propertyName)\n next.push(edge)\n return next\n}\n\nexport function clearLookupsForProperties(\n lookups: MappingLookups,\n propertyNames: string[],\n): MappingLookups | null {\n if (propertyNames.length === 0) return null\n let changed = false\n const next = { ...lookups }\n for (const name of propertyNames) {\n if (name in next) {\n delete next[name]\n changed = true\n }\n }\n return changed ? next : null\n}\n\nexport function connectSourceToProperty(\n mappings: FieldMapping[],\n sources: SourceNode[],\n targets: TargetProperty[],\n sourceId: string,\n propertyName: string,\n): { mappings: FieldMapping[]; clearedLookupProps: string[] } {\n const targetsByName = new Map(targets.map((t) => [t.name, t]))\n let edge = normalizeMappingFromSourceId(sourceId, propertyName)\n edge = attachLookupIfNeeded(edge, targetsByName.get(propertyName))\n\n // Prefer origin source id even when host passed only resolved nodes\n if (edge.sourceId && !sources.some((s) => s.id === edge.sourceId)) {\n const origin = originSources(sources).find((s) => s.id === edge.sourceId)\n if (!origin && sources.some((s) => s.id === sourceId)) {\n // keep normalized edge as-is\n }\n }\n\n const prev = mappings.find((m) => m.propertyName === propertyName)\n edge = withPreservedExtras(edge, prev)\n const next = upsertPropertyMapping(mappings, edge)\n const clearedLookupProps: string[] = []\n if (prev?.resolve === 'lookup' && edge.resolve !== 'lookup') {\n clearedLookupProps.push(propertyName)\n }\n return { mappings: next, clearedLookupProps }\n}\n\nexport function removeMappingsForSourceId(\n mappings: FieldMapping[],\n sourceId: string,\n): { mappings: FieldMapping[]; clearedLookupProps: string[] } {\n const parsed = parseResolvedSourceId(sourceId)\n const clearedLookupProps: string[] = []\n const next = mappings.filter((c) => {\n let keep: boolean\n if (parsed) {\n keep = !(\n Boolean(c.sourceId) &&\n c.sourceId === parsed.originId &&\n c.resolve === parsed.resolve\n )\n } else {\n keep = c.sourceId !== sourceId\n }\n if (!keep && c.resolve === 'lookup') {\n clearedLookupProps.push(c.propertyName)\n }\n return keep\n })\n return { mappings: next, clearedLookupProps }\n}\n\nexport function buildPropertyModeRows(args: {\n targets: TargetProperty[]\n mappings: FieldMapping[]\n sources: SourceNode[]\n lookups?: MappingLookups\n /** When set, only these property names appear (add-flow extras). */\n visiblePropertyNames?: Set<string> | null\n}): FieldMapperRow[] {\n const { targets, mappings, sources, lookups } = args\n const byName = new Map(mappings.map((m) => [m.propertyName, m]))\n const sourceById = new Map(originSources(sources).map((s) => [s.id, s]))\n // Also index all sources for resolve edges that still point at origin\n for (const s of sources) {\n if (!sourceById.has(s.id)) sourceById.set(s.id, s)\n }\n\n const list =\n args.visiblePropertyNames == null\n ? targets\n : targets.filter((t) => args.visiblePropertyNames!.has(t.name))\n\n return list.map((target) => {\n const mapping = byName.get(target.name)\n const source = mapping?.sourceId\n ? sourceById.get(mapping.sourceId)\n : undefined\n const requiredResolve = computeRequiredResolve(source, target)\n const sampleValue = sampleValueFromSource(source)\n const state = rowState({ mapping, requiredResolve, sampleValue, lookups })\n return {\n id: target.name,\n target,\n mapping,\n source,\n sampleValue,\n preview: previewForEdge(source, mapping?.resolve, {\n target,\n lookups,\n propertyName: target.name,\n mapping,\n }),\n requiredResolve,\n state,\n }\n })\n}\n\nexport type SourceModeDraft = {\n id: string\n sourceId?: string\n propertyName?: string\n resolve?: ResolveJob\n}\n\nexport function buildSourceModeRows(args: {\n mappings: FieldMapping[]\n edgeIds: string[]\n drafts: SourceModeDraft[]\n sources: SourceNode[]\n targets: TargetProperty[]\n lookups?: MappingLookups\n}): { rows: FieldMapperRow[]; conflicts: Set<string> } {\n const { mappings, edgeIds, drafts, sources, targets, lookups } = args\n const sourceById = new Map(sources.map((s) => [s.id, s]))\n const targetsByName = new Map(targets.map((t) => [t.name, t]))\n\n const edgeRows: {\n id: string\n propertyName?: string\n mapping?: FieldMapping\n source?: SourceNode\n target?: TargetProperty\n }[] = []\n\n for (let i = 0; i < mappings.length; i++) {\n const mapping = mappings[i]!\n const id = edgeIds[i] ?? `edge-${i}`\n edgeRows.push({\n id,\n propertyName: mapping.propertyName,\n mapping,\n source: mapping.sourceId ? sourceById.get(mapping.sourceId) : undefined,\n target: targetsByName.get(mapping.propertyName),\n })\n }\n\n for (const draft of drafts) {\n edgeRows.push({\n id: draft.id,\n propertyName: draft.propertyName,\n mapping:\n draft.sourceId && draft.propertyName\n ? {\n sourceId: draft.sourceId,\n propertyName: draft.propertyName,\n ...(draft.resolve ? { resolve: draft.resolve } : {}),\n }\n : draft.sourceId || draft.propertyName\n ? {\n sourceId: draft.sourceId ?? '',\n propertyName: draft.propertyName ?? '',\n ...(draft.resolve ? { resolve: draft.resolve } : {}),\n }\n : undefined,\n source: draft.sourceId ? sourceById.get(draft.sourceId) : undefined,\n target: draft.propertyName\n ? targetsByName.get(draft.propertyName)\n : undefined,\n })\n }\n\n const conflicts = findConflicts(edgeRows)\n\n const rows: FieldMapperRow[] = edgeRows.map((r) => {\n const requiredResolve = computeRequiredResolve(r.source, r.target)\n const mapping =\n r.mapping && r.mapping.propertyName\n ? r.mapping\n : r.mapping\n const sampleValue = sampleValueFromSource(r.source)\n const complete =\n mapping && isPresentEdge(mapping) ? mapping : undefined\n const state = rowState({\n mapping: complete,\n requiredResolve,\n conflict: conflicts.has(r.id),\n sampleValue,\n lookups,\n })\n // Drafts with only source or only property stay empty\n const effectiveState =\n !complete\n ? conflicts.has(r.id)\n ? 'conflict'\n : 'empty'\n : state\n\n return {\n id: r.id,\n target: r.target,\n mapping: complete,\n source: r.source,\n sampleValue,\n preview: previewForEdge(r.source, complete?.resolve, {\n target: r.target,\n lookups,\n propertyName: complete?.propertyName,\n mapping: complete,\n }),\n requiredResolve,\n state: effectiveState,\n }\n })\n\n return { rows, conflicts }\n}\n\nexport function newRowId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 10)}`\n}\n\nexport function syncEdgeIds(\n prev: string[],\n mappingCount: number,\n): string[] {\n if (prev.length === mappingCount) return prev\n if (prev.length > mappingCount) return prev.slice(0, mappingCount)\n const next = [...prev]\n while (next.length < mappingCount) {\n next.push(newRowId('edge'))\n }\n return next\n}\n\nexport function filterPropertyNames(\n targets: TargetProperty[],\n mappings: FieldMapping[],\n mode: 'requiredAndMapped' | 'mapped' | 'all',\n extra: Set<string>,\n): Set<string> | null {\n if (mode === 'all') return null\n const mapped = new Set(mappings.map((m) => m.propertyName))\n const names = new Set<string>(extra)\n for (const t of targets) {\n if (mapped.has(t.name)) names.add(t.name)\n else if (mode === 'requiredAndMapped' && t.required) names.add(t.name)\n }\n return names\n}\n","import React, { useMemo } from 'react'\nimport { lookupEntriesFromMapping, normalizeLookupKey } from '../relationLookup'\nimport type {\n FieldMapping,\n LookupEntry,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type { FieldMapperSlot } from './fieldMapperSlots'\nimport { slotClass } from './fieldMapperSlots'\n\nfunction upsertEntry(\n entries: LookupEntry[],\n value: string,\n ref: string,\n): LookupEntry[] {\n const key = normalizeLookupKey(value)\n const trimmed = ref.trim()\n const next = entries.filter((e) => normalizeLookupKey(e.value) !== key)\n if (!trimmed) return next\n next.push({ value: key, ref: trimmed })\n return next\n}\n\nexport type LookupEditorProps = {\n mode: 'section' | 'row'\n /** Lookup edges to edit. Section: all lookup mappings; row: one property. */\n mappings: FieldMapping[]\n sources: SourceNode[]\n targets: TargetProperty[]\n onLookupChange: (mapping: FieldMapping, entries: LookupEntry[]) => void\n classNames?: Partial<Record<FieldMapperSlot, string>>\n /** Extra class on the root (e.g. nested-in-row modifier). */\n className?: string\n}\n\nfunction LookupBlock({\n mapping,\n sources,\n targetsByName,\n onLookupChange,\n compact,\n}: {\n mapping: FieldMapping\n sources: SourceNode[]\n targetsByName: Map<string, TargetProperty>\n onLookupChange: (mapping: FieldMapping, entries: LookupEntry[]) => void\n compact?: boolean\n}) {\n const source = sources.find((s) => s.id === mapping.sourceId)\n const sampleKey = normalizeLookupKey(source?.value || source?.label || '')\n const entries = lookupEntriesFromMapping(mapping)\n const keys = new Set<string>(\n entries.map((e) => normalizeLookupKey(e.value)).filter(Boolean),\n )\n if (sampleKey) keys.add(sampleKey)\n const keyList = [...keys]\n const target = targetsByName.get(mapping.propertyName)\n const refByKey = new Map(\n entries.map((e) => [normalizeLookupKey(e.value), e.ref]),\n )\n\n return (\n <div className=\"fm-lookup-block\">\n {!compact && (\n <h4>\n {mapping.propertyName}\n {target?.ref ? ` → ${target.ref}` : ''}\n </h4>\n )}\n <div className=\"fm-lookup-hint\">\n Map source strings to refs. Host owns Identity search/create.\n </div>\n {keyList.length === 0 ? (\n <div className=\"fm-lookup-hint\">\n No sample value yet — paste a source string key after connecting.\n </div>\n ) : (\n keyList.map((key) => (\n <div key={key} className=\"fm-lookup-row\">\n <div className=\"fm-lookup-key\" title={key}>\n {key || '(empty)'}\n </div>\n <input\n className=\"fm-lookup-input\"\n type=\"text\"\n placeholder=\"ref\"\n value={refByKey.get(key) ?? ''}\n onChange={(e) =>\n onLookupChange(mapping, upsertEntry(entries, key, e.target.value))\n }\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n ))\n )}\n </div>\n )\n}\n\n/**\n * Fallback string → ref editor when the host does not pass `renderLookup`.\n * Writes `FieldMapping.lookup.entries` via `onLookupChange`.\n */\nexport function LookupEditor({\n mode,\n mappings,\n sources,\n targets,\n onLookupChange,\n classNames,\n className,\n}: LookupEditorProps) {\n const lookupMappings = useMemo(\n () => mappings.filter((m) => m.resolve === 'lookup'),\n [mappings],\n )\n\n const targetsByName = useMemo(() => {\n const map = new Map<string, TargetProperty>()\n for (const t of targets) map.set(t.name, t)\n return map\n }, [targets])\n\n if (lookupMappings.length === 0) return null\n\n const rootClass = [\n slotClass('lookupEditor', classNames),\n mode === 'row' ? 'fm-lookups--row' : null,\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div className={rootClass}>\n {mode === 'section' && (\n <div className=\"fm-lookups-title\">Relation lookups</div>\n )}\n {lookupMappings.map((mapping) => (\n <LookupBlock\n key={`${mapping.sourceId}-${mapping.propertyName}`}\n mapping={mapping}\n sources={sources}\n targetsByName={targetsByName}\n onLookupChange={onLookupChange}\n compact={mode === 'row'}\n />\n ))}\n </div>\n )\n}\n","/** Number of cycling pair / map-color slots (`--fm-map-1` … `--fm-map-8`). */\nexport const FIELD_MAPPER_PAIR_SLOTS = 8\n\n/**\n * Theme modes for FieldMapper.\n * `'unstyled'` is a deprecated alias for `'none'` (kept for one minor).\n */\nexport type FieldMapperTheme = 'default' | 'structural' | 'none' | 'unstyled'\n\nexport type ResolvedFieldMapperTheme = 'default' | 'structural' | 'none'\n\nexport const THEME_STYLE_ID = 'seed-field-mapper-theme'\n\nfunction pairSlot(index: number): number {\n return index % FIELD_MAPPER_PAIR_SLOTS\n}\n\n/** Stroke for mapping index `i` — CSS vars by default so hosts can theme. */\nexport function connectionStrokeForIndex(\n index: number,\n connectionColors?: string[],\n): string {\n if (connectionColors && connectionColors.length > 0) {\n return connectionColors[index % connectionColors.length]!\n }\n const n = pairSlot(index) + 1\n return `var(--fm-map-${n}, var(--map-${n}, currentColor))`\n}\n\nexport { pairSlot }\n\n/** Map public theme prop (including deprecated `unstyled`) to a resolved mode. */\nexport function resolveTheme(\n theme: FieldMapperTheme = 'default',\n): ResolvedFieldMapperTheme {\n if (theme === 'unstyled') return 'none'\n return theme\n}\n\nconst PAINT_TOKENS = `\n --sfm-color-ground: #0f172a;\n --sfm-color-ink: #e2e8f0;\n --sfm-color-well: #1e293b;\n --sfm-color-line: #334155;\n --sfm-color-muted: #94a3b8;\n --sfm-color-faint: #64748b;\n --sfm-color-selection: #3b82f6;\n --sfm-color-warning: #fbbf24;\n --sfm-color-danger: #f87171;\n --sfm-color-highlight: #f59e0b;\n --sfm-map-1: #3b82f6;\n --sfm-map-2: #8b5cf6;\n --sfm-map-3: #ec4899;\n --sfm-map-4: #f59e0b;\n --sfm-map-5: #10b981;\n --sfm-map-6: #06b6d4;\n --sfm-map-7: #f97316;\n --sfm-map-8: #14b8a6;\n --fm-ground: var(--sfm-color-ground);\n --fm-ink: var(--sfm-color-ink);\n --fm-well: var(--sfm-color-well);\n --fm-line: var(--sfm-color-line);\n --fm-muted: var(--sfm-color-muted);\n --fm-faint: var(--sfm-color-faint);\n --fm-selection: var(--sfm-color-selection);\n --fm-highlight: var(--sfm-color-highlight);\n --fm-danger: var(--sfm-color-danger);\n --fm-warning: var(--sfm-color-warning);\n --fm-map-1: var(--sfm-map-1);\n --fm-map-2: var(--sfm-map-2);\n --fm-map-3: var(--sfm-map-3);\n --fm-map-4: var(--sfm-map-4);\n --fm-map-5: var(--sfm-map-5);\n --fm-map-6: var(--sfm-map-6);\n --fm-map-7: var(--sfm-map-7);\n --fm-map-8: var(--sfm-map-8);\n`\n\nconst STRUCTURAL_TOKENS = `\n --sfm-space-1: 4px;\n --sfm-space-2: 8px;\n --sfm-space-3: 12px;\n --sfm-space-4: 16px;\n --sfm-radius-sm: 4px;\n --sfm-radius-md: 8px;\n --sfm-radius-lg: 12px;\n --sfm-font-family: inherit;\n --sfm-font-mono: ui-monospace, monospace;\n --sfm-font-size-sm: 11px;\n --sfm-font-size-md: 13px;\n --sfm-control-height: 32px;\n --sfm-row-gap: var(--sfm-space-2);\n`\n\n/** Layout / spacing / display rules — no color paint. */\nexport const STRUCTURAL_THEME_CSS = `\n.seed-field-mapper {\n${STRUCTURAL_TOKENS}\n font-family: var(--sfm-font-family);\n border-radius: var(--sfm-radius-lg);\n padding: var(--sfm-space-4);\n}\n.seed-field-mapper * { box-sizing: border-box; }\n.seed-field-mapper .fm-toolbar {\n display: flex;\n gap: var(--sfm-space-2);\n align-items: center;\n margin-bottom: var(--sfm-space-3);\n flex-wrap: wrap;\n}\n.seed-field-mapper .fm-btn {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 6px var(--sfm-space-3);\n cursor: pointer;\n font-size: var(--sfm-font-size-md);\n min-height: var(--sfm-control-height);\n}\n.seed-field-mapper .fm-meta {\n font-size: 12px;\n margin-left: auto;\n}\n.seed-field-mapper .fm-banner {\n font-size: 12px;\n padding: var(--sfm-space-2) 10px;\n border-radius: var(--sfm-radius-md);\n margin-bottom: 10px;\n border: 1px solid;\n}\n.seed-field-mapper .fm-grid {\n position: relative;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 48px;\n min-height: 240px;\n}\n.seed-field-mapper .fm-col-title {\n font-size: var(--sfm-font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-card {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 10px var(--sfm-space-3);\n margin-bottom: var(--sfm-space-2);\n cursor: pointer;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n.seed-field-mapper .fm-label {\n font-weight: 600;\n font-size: var(--sfm-font-size-md);\n margin-bottom: var(--sfm-space-1);\n}\n.seed-field-mapper .fm-value {\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.seed-field-mapper .fm-kind {\n font-size: 10px;\n margin-left: 6px;\n}\n.seed-field-mapper .fm-prop-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-dtype {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: var(--sfm-radius-sm);\n border: 1px solid;\n}\n.seed-field-mapper .fm-remove {\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n padding: 0 var(--sfm-space-1);\n}\n.seed-field-mapper .fm-svg {\n position: absolute;\n inset: 0;\n pointer-events: none;\n overflow: visible;\n}\n.seed-field-mapper .fm-preview {\n margin-top: var(--sfm-space-3);\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: var(--sfm-space-3);\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n white-space: pre-wrap;\n max-height: 200px;\n overflow: auto;\n}\n.seed-field-mapper details.fm-preview {\n font-family: var(--sfm-font-family);\n white-space: normal;\n max-height: none;\n overflow: visible;\n padding: var(--sfm-space-2) var(--sfm-space-3);\n}\n.seed-field-mapper details.fm-preview > summary {\n cursor: pointer;\n font-size: var(--sfm-font-size-sm);\n list-style: disclosure-closed;\n}\n.seed-field-mapper details.fm-preview[open] > summary {\n list-style: disclosure-open;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-preview-body {\n margin: 0;\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n white-space: pre-wrap;\n max-height: 200px;\n overflow: auto;\n}\n.seed-field-mapper .fm-lookups {\n margin-top: var(--sfm-space-4);\n border-top: 1px solid;\n padding-top: var(--sfm-space-3);\n}\n.seed-field-mapper .fm-row .fm-lookups,\n.seed-field-mapper .fm-lookups--row {\n margin-top: var(--sfm-space-2);\n border-top: none;\n padding-top: 0;\n}\n.seed-field-mapper .fm-row .fm-lookup-block {\n margin-bottom: 0;\n padding: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookups-title {\n font-size: var(--sfm-font-size-sm);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-block {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 10px var(--sfm-space-3);\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-block h4 {\n margin: 0 0 var(--sfm-space-2);\n font-size: var(--sfm-font-size-md);\n font-weight: 600;\n}\n.seed-field-mapper .fm-lookup-hint {\n font-size: var(--sfm-font-size-sm);\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-row {\n display: grid;\n grid-template-columns: 1fr 1.4fr;\n gap: var(--sfm-space-2);\n align-items: center;\n margin-bottom: 6px;\n}\n.seed-field-mapper .fm-lookup-key {\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.seed-field-mapper .fm-lookup-input {\n width: 100%;\n border: 1px solid;\n border-radius: 6px;\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n padding: 6px var(--sfm-space-2);\n}\n.seed-field-mapper .fm-lookup-input:focus {\n outline: none;\n}\n.seed-field-mapper .fm-row-list {\n display: flex;\n flex-direction: column;\n gap: var(--sfm-row-gap);\n}\n.seed-field-mapper .fm-row {\n border: 1px solid;\n border-radius: var(--sfm-radius-md);\n padding: 10px var(--sfm-space-3);\n}\n.seed-field-mapper .fm-row-main {\n display: grid;\n grid-template-columns: minmax(100px, 140px) 1fr auto auto auto;\n gap: var(--sfm-space-2);\n align-items: center;\n}\n.seed-field-mapper .fm-row-main-source {\n grid-template-columns: 1fr auto auto 1fr auto auto;\n}\n.seed-field-mapper .fm-row-accessory {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n.seed-field-mapper .fm-row-accessory:empty {\n display: none;\n}\n.seed-field-mapper .fm-row-prop {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.seed-field-mapper .fm-row-prop-name {\n font-weight: 600;\n font-size: var(--sfm-font-size-md);\n}\n.seed-field-mapper .fm-row-preview {\n margin-top: 6px;\n font-family: var(--sfm-font-mono);\n font-size: var(--sfm-font-size-sm);\n}\n.seed-field-mapper .fm-row-expansion {\n margin-top: 8px;\n}\n.seed-field-mapper .fm-row-expansion:empty {\n display: none;\n}\n.seed-field-mapper .fm-row-flag {\n font-size: var(--sfm-font-size-sm);\n margin-top: var(--sfm-space-1);\n}\n.seed-field-mapper .fm-select {\n width: 100%;\n border: 1px solid;\n border-radius: 6px;\n font-size: 12px;\n padding: 6px var(--sfm-space-2);\n min-width: 0;\n min-height: var(--sfm-control-height);\n}\n.seed-field-mapper .fm-select:focus {\n outline: none;\n}\n.seed-field-mapper .fm-filter {\n display: flex;\n gap: 6px;\n margin-bottom: 10px;\n flex-wrap: wrap;\n}\n.seed-field-mapper .fm-inspector {\n margin-top: var(--sfm-space-3);\n border-top: 1px solid;\n padding-top: 10px;\n}\n.seed-field-mapper .fm-inspector summary {\n cursor: pointer;\n font-size: 12px;\n margin-bottom: var(--sfm-space-2);\n}\n.seed-field-mapper .fm-inspector-row {\n display: grid;\n grid-template-columns: 1fr 1.5fr auto;\n gap: var(--sfm-space-2);\n align-items: center;\n padding: 6px 0;\n border-bottom: 1px solid;\n font-size: 12px;\n}\n.seed-field-mapper .fm-into {\n font-size: var(--sfm-font-size-sm);\n}\n`\n\n/** Color / background / border-color paint on top of structural layout. */\nexport const PAINT_THEME_CSS = `\n.seed-field-mapper {\n${PAINT_TOKENS}\n color: var(--sfm-color-ink);\n background: var(--sfm-color-ground);\n}\n.seed-field-mapper .fm-btn {\n background: var(--sfm-color-well);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-btn:hover { border-color: var(--sfm-color-faint); }\n.seed-field-mapper .fm-btn-primary {\n background: var(--sfm-color-selection);\n border-color: var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-meta {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-banner {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-banner-warn {\n border-color: var(--sfm-color-warning);\n color: var(--sfm-color-warning);\n}\n.seed-field-mapper .fm-banner-danger {\n border-color: var(--sfm-color-danger);\n color: var(--sfm-color-danger);\n}\n.seed-field-mapper .fm-col-title {\n color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-card {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-card.active,\n.seed-field-mapper .fm-card.pending {\n border-color: var(--sfm-color-selection);\n box-shadow: 0 0 0 1px var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-card.mapped {\n border-color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-card.highlight {\n border-color: var(--sfm-color-highlight);\n}\n.seed-field-mapper .fm-value {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-kind {\n color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-dtype {\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-muted);\n background: transparent;\n}\n.seed-field-mapper .fm-remove {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-remove:hover { color: var(--sfm-color-danger); }\n.seed-field-mapper .fm-preview {\n background: color-mix(in srgb, var(--sfm-color-ground) 80%, black);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper details.fm-preview > summary {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-lookups {\n border-color: var(--sfm-color-line);\n}\n.seed-field-mapper .fm-lookups-title {\n color: var(--sfm-color-faint);\n}\n.seed-field-mapper .fm-lookup-block {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-lookup-hint {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-lookup-key {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-lookup-input {\n background: var(--sfm-color-ground);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-lookup-input:focus {\n border-color: var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-row {\n border-color: var(--sfm-color-line);\n background: var(--sfm-color-well);\n}\n.seed-field-mapper .fm-row[data-state=\"needsResolve\"] {\n border-color: var(--sfm-color-warning);\n}\n.seed-field-mapper .fm-row[data-state=\"conflict\"] {\n border-color: var(--sfm-color-danger);\n}\n.seed-field-mapper .fm-row-preview {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-row-flag {\n color: var(--sfm-color-warning);\n}\n.seed-field-mapper .fm-select {\n background: var(--sfm-color-ground);\n border-color: var(--sfm-color-line);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-select:focus {\n border-color: var(--sfm-color-selection);\n}\n.seed-field-mapper .fm-filter .fm-btn[aria-pressed=\"true\"] {\n border-color: var(--sfm-color-selection);\n color: var(--sfm-color-ink);\n}\n.seed-field-mapper .fm-inspector {\n border-color: var(--sfm-color-line);\n}\n.seed-field-mapper .fm-inspector summary {\n color: var(--sfm-color-muted);\n}\n.seed-field-mapper .fm-inspector-row {\n border-color: var(--sfm-color-line);\n}\n.seed-field-mapper .fm-into {\n color: var(--sfm-color-faint);\n}\n`\n\n/** Wrap CSS in the package cascade layer so host rules win without specificity fights. */\nexport function wrapInThemeLayer(css: string): string {\n return `@layer seed-field-mapper {\\n${css}\\n}`\n}\n\n/** Build the CSS string for a resolved theme mode (`none` → empty). */\nexport function buildThemeCss(theme: ResolvedFieldMapperTheme): string {\n if (theme === 'none') return ''\n if (theme === 'structural') {\n return wrapInThemeLayer(STRUCTURAL_THEME_CSS)\n }\n return wrapInThemeLayer(`${STRUCTURAL_THEME_CSS}\\n${PAINT_THEME_CSS}`)\n}\n\n/** Full default theme CSS (structural + paint, layered). Exported for tests / hosts. */\nexport const DEFAULT_THEME_CSS = buildThemeCss('default')\n\nlet injectedTheme: ResolvedFieldMapperTheme | null = null\n\n/**\n * Inject theme CSS once into `document.head`. Updates the existing style node\n * when the resolved theme changes. No-op when `document` is unavailable (SSR)\n * or when `theme === 'none'`.\n */\nexport function ensureThemeInjected(theme: ResolvedFieldMapperTheme): void {\n if (typeof document === 'undefined') return\n if (theme === 'none') return\n\n const css = buildThemeCss(theme)\n const existing = document.getElementById(\n THEME_STYLE_ID,\n ) as HTMLStyleElement | null\n\n if (existing) {\n if (injectedTheme !== theme) {\n existing.textContent = css\n injectedTheme = theme\n }\n return\n }\n\n const el = document.createElement('style')\n el.id = THEME_STYLE_ID\n el.textContent = css\n document.head.appendChild(el)\n injectedTheme = theme\n}\n\n/** Test helper: reset document-once injection bookkeeping. */\nexport function resetThemeInjectionForTests(): void {\n injectedTheme = null\n if (typeof document === 'undefined') return\n const el = document.getElementById(THEME_STYLE_ID)\n if (!el) return\n if (typeof el.remove === 'function') {\n el.remove()\n } else if (el.parentNode) {\n el.parentNode.removeChild(el)\n }\n}\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n parseResolvedSourceId,\n resolvedSourceId,\n} from '../resolvedSources'\nimport type {\n FieldMapping,\n MappingLookups,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperSlot,\n ResolvedFieldMapperComponents,\n ResolvedFieldMapperSlots,\n} from './fieldMapperSlots'\nimport { showJsonPreview, slotClass } from './fieldMapperSlots'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport { buildSyncPreviewBag } from './fieldMapperCore'\nimport type {\n FieldMapperLookupRow,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\nimport { LookupEditor } from './LookupEditor'\nimport {\n connectionStrokeForIndex,\n pairSlot,\n} from './fieldMapperTheme'\n\ntype ConnectorPoint = {\n x1: number\n y1: number\n x2: number\n y2: number\n stroke: string\n mappingIndex: number\n mapping: FieldMapping\n}\n\nfunction displaySourceIdForMapping(\n mapping: FieldMapping,\n sources: SourceNode[],\n): string {\n if (!mapping.sourceId) return ''\n if (!mapping.resolve) return mapping.sourceId\n const derived = resolvedSourceId(mapping.sourceId, mapping.resolve)\n if (sources.some((s) => s.id === derived)) return derived\n return mapping.sourceId\n}\n\nfunction truncate(s: string, n: number): string {\n const t = s.replace(/\\s+/g, ' ').trim()\n if (t.length <= n) return t\n return `${t.slice(0, n)}…`\n}\n\nexport type FieldMapperWiresProps = {\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n mapper: UseFieldMapperResult\n lookups?: MappingLookups\n onLookupsChange?: (lookups: MappingLookups) => void\n renderLookup?: (row: FieldMapperLookupRow) => React.ReactNode\n /** @deprecated Prefer CSS map tokens. */\n connectionColors?: string[]\n slots: ResolvedFieldMapperSlots\n classNames?: Partial<Record<FieldMapperSlot, string>>\n ui?: ResolvedFieldMapperComponents\n}\n\nexport function FieldMapperWires({\n sources,\n targets,\n mappings,\n mapper,\n onLookupsChange,\n renderLookup,\n connectionColors,\n slots,\n classNames,\n ui = {\n Select: DefaultSelect,\n Button: DefaultButton,\n Pill: DefaultPill,\n },\n}: FieldMapperWiresProps) {\n const Button = ui.Button\n const [activeSource, setActiveSource] = useState<string | null>(null)\n const [hoveredProp, setHoveredProp] = useState<string | null>(null)\n const [hoveredSource, setHoveredSource] = useState<string | null>(null)\n const [previewOpen, setPreviewOpen] = useState(false)\n const [svgDimensions, setSvgDimensions] = useState({ width: 0, height: 0 })\n const [connectorPoints, setConnectorPoints] = useState<ConnectorPoint[]>([])\n\n const containerRef = useRef<HTMLDivElement>(null)\n const sourceRefs = useRef<Record<string, HTMLDivElement | null>>({})\n const propRefs = useRef<Record<string, HTMLDivElement | null>>({})\n\n const mappingIndexByProp = useMemo(() => {\n const map = new Map<string, number>()\n mappings.forEach((m, i) => {\n map.set(m.propertyName, i)\n })\n return map\n }, [mappings])\n\n const mappingIndexesBySource = useMemo(() => {\n const map = new Map<string, number[]>()\n mappings.forEach((m, i) => {\n if (!m.sourceId) return\n const displayId = displaySourceIdForMapping(m, sources)\n for (const key of new Set([m.sourceId, displayId])) {\n const list = map.get(key) ?? []\n list.push(i)\n map.set(key, list)\n }\n })\n return map\n }, [mappings, sources])\n\n const getConnectorPoints = useCallback((): ConnectorPoint[] => {\n if (!containerRef.current) return []\n const containerRect = containerRef.current.getBoundingClientRect()\n return mappings\n .map((mapping, i) => {\n if (!mapping.sourceId) return null\n const displayId = displaySourceIdForMapping(mapping, sources)\n const sourceEl =\n sourceRefs.current[displayId] ?? sourceRefs.current[mapping.sourceId]\n const propEl = propRefs.current[mapping.propertyName]\n if (!sourceEl || !propEl) return null\n\n const sR = sourceEl.getBoundingClientRect()\n const pR = propEl.getBoundingClientRect()\n\n return {\n x1: sR.right - containerRect.left,\n y1: sR.top + sR.height / 2 - containerRect.top,\n x2: pR.left - containerRect.left,\n y2: pR.top + pR.height / 2 - containerRect.top,\n stroke: connectionStrokeForIndex(i, connectionColors),\n mappingIndex: i,\n mapping,\n }\n })\n .filter((pt): pt is ConnectorPoint => pt !== null)\n }, [mappings, connectionColors, sources])\n\n useEffect(() => {\n const update = () => {\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect()\n setSvgDimensions({ width: rect.width, height: rect.height })\n }\n setConnectorPoints(getConnectorPoints())\n }\n update()\n window.addEventListener('resize', update)\n const timer = setInterval(update, 200)\n return () => {\n window.removeEventListener('resize', update)\n clearInterval(timer)\n }\n }, [getConnectorPoints, mappings, sources, targets])\n\n const handleSourceClick = (sourceId: string) => {\n setActiveSource((prev) => (prev === sourceId ? null : sourceId))\n }\n\n const handlePropClick = (propertyName: string) => {\n if (!activeSource) return\n mapper.connect(activeSource, propertyName)\n }\n\n const sourceHasMapping = (sourceId: string) => {\n const parsed = parseResolvedSourceId(sourceId)\n if (parsed) {\n return mappings.some(\n (c) =>\n c.sourceId === parsed.originId && c.resolve === parsed.resolve,\n )\n }\n return mappings.some((c) => c.sourceId === sourceId)\n }\n const mappingForProp = (propName: string) =>\n mappings.find((c) => c.propertyName === propName)\n\n const isEdgeHighlighted = (mapping: FieldMapping) => {\n if (hoveredProp) return mapping.propertyName === hoveredProp\n if (hoveredSource) {\n const displayId = displaySourceIdForMapping(mapping, sources)\n return (\n mapping.sourceId === hoveredSource || displayId === hoveredSource\n )\n }\n return false\n }\n\n const anyEdgeHighlighted = hoveredProp != null || hoveredSource != null\n\n const preview = useMemo(\n () => buildSyncPreviewBag(sources, mappings, targets),\n [sources, mappings, targets],\n )\n\n const { coverage } = mapper\n const jsonPreview = showJsonPreview(slots.preview)\n\n return (\n <>\n <div className={slotClass('toolbar', classNames)}>\n {slots.autoMap && (\n <Button\n className={slotClass('autoMapButton', classNames)}\n onClick={() => mapper.autoMap()}\n >\n Auto-map\n </Button>\n )}\n <span className={slotClass('coverage', classNames)}>\n {coverage.mapped} / {coverage.total} mapped\n {coverage.missingRequired.length > 0\n ? ` · ${coverage.missingRequired.length} required missing`\n : ''}\n {activeSource\n ? ' · click properties (source stays selected)'\n : ' · click a source'}\n </span>\n </div>\n\n <div className=\"fm-grid\" ref={containerRef}>\n <svg\n className=\"fm-svg\"\n width={svgDimensions.width}\n height={svgDimensions.height}\n >\n {connectorPoints.map((pt) => {\n const isHi = isEdgeHighlighted(pt.mapping)\n const midX = (pt.x1 + pt.x2) / 2\n return (\n <path\n key={`${pt.mapping.sourceId}-${pt.mapping.propertyName}-${pt.mapping.resolve ?? 'copy'}`}\n className=\"fm-connector\"\n data-mapping-index={pt.mappingIndex}\n data-pair={pairSlot(pt.mappingIndex)}\n d={`M ${pt.x1} ${pt.y1} C ${midX} ${pt.y1}, ${midX} ${pt.y2}, ${pt.x2} ${pt.y2}`}\n stroke={pt.stroke}\n strokeWidth={isHi ? 3 : 2}\n fill=\"none\"\n opacity={anyEdgeHighlighted && !isHi ? 0.25 : 0.85}\n />\n )\n })}\n </svg>\n\n <div>\n <div className=\"fm-col-title\">Sources</div>\n {sources.map((source) => {\n const mapped = sourceHasMapping(source.id)\n const isPending = activeSource === source.id\n const indexes = mappingIndexesBySource.get(source.id) ?? []\n const firstIndex = indexes[0]\n const isHi =\n hoveredSource === source.id ||\n (hoveredProp != null &&\n mappings.some((m) => {\n const displayId = displaySourceIdForMapping(m, sources)\n return (\n (m.sourceId === source.id || displayId === source.id) &&\n m.propertyName === hoveredProp\n )\n }))\n return (\n <div\n key={source.id}\n ref={(el) => {\n sourceRefs.current[source.id] = el\n }}\n className={`fm-card${isPending ? ' active pending' : ''}${mapped ? ' mapped' : ''}${isHi ? ' highlight' : ''}`}\n data-source-id={source.id}\n {...(indexes.length > 0\n ? {\n 'data-mapping-index': indexes.join(' '),\n 'data-pair': String(pairSlot(firstIndex!)),\n }\n : {})}\n onClick={() => handleSourceClick(source.id)}\n onMouseEnter={() => setHoveredSource(source.id)}\n onMouseLeave={() => setHoveredSource(null)}\n >\n <div className=\"fm-prop-row\">\n <div className=\"fm-label\">\n {source.label}\n {source.subtitle ? (\n <span className=\"fm-kind\">{source.subtitle}</span>\n ) : null}\n <span className=\"fm-kind\">{source.kind}</span>\n </div>\n {mapped && (\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label=\"Remove all mappings for source\"\n onClick={(e) => {\n e.stopPropagation()\n mapper.removeBySource(source.id)\n }}\n >\n ×\n </Button>\n )}\n </div>\n <div className=\"fm-value\">{truncate(source.value, 80)}</div>\n </div>\n )\n })}\n </div>\n\n <div>\n <div className=\"fm-col-title\">Model properties</div>\n {targets.map((prop) => {\n const mapped = mappingForProp(prop.name)\n const mappingIndex = mappingIndexByProp.get(prop.name)\n const isHi =\n hoveredProp === prop.name ||\n (hoveredSource != null &&\n mapped != null &&\n (mapped.sourceId === hoveredSource ||\n displaySourceIdForMapping(mapped, sources) ===\n hoveredSource))\n return (\n <div\n key={prop.name}\n ref={(el) => {\n propRefs.current[prop.name] = el\n }}\n className={`fm-card${mapped ? ' mapped' : ''}${isHi ? ' highlight' : ''}`}\n data-property-name={prop.name}\n {...(mappingIndex != null\n ? {\n 'data-mapping-index': String(mappingIndex),\n 'data-pair': String(pairSlot(mappingIndex)),\n }\n : {})}\n onClick={() => handlePropClick(prop.name)}\n onMouseEnter={() => setHoveredProp(prop.name)}\n onMouseLeave={() => setHoveredProp(null)}\n >\n <div className=\"fm-prop-row\">\n <div className=\"fm-label\">{prop.name}</div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <span className=\"fm-dtype\">\n {prop.dataType}\n {prop.ref ? ` → ${prop.ref}` : ''}\n </span>\n {mapped && (\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label=\"Remove mapping for property\"\n onClick={(e) => {\n e.stopPropagation()\n mapper.removeRow(prop.name)\n }}\n >\n ×\n </Button>\n )}\n </div>\n </div>\n {mapped && (\n <div className=\"fm-value\">\n ← {mapped.sourceId}\n {mapped.resolve ? ` (${mapped.resolve})` : ''}\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {slots.lookups === 'section' &&\n renderLookup &&\n mapper.rows\n .filter((row) => row.mapping?.resolve === 'lookup')\n .map((row) => (\n <div\n key={row.id}\n className={slotClass('lookupEditor', classNames)}\n >\n {renderLookup({\n ...row,\n sampleValue: row.sampleValue ?? '',\n onLookupChange: (entries) =>\n mapper.setLookupEntries(row.id, entries),\n })}\n </div>\n ))}\n {slots.lookups === 'section' && !renderLookup && onLookupsChange && (\n <LookupEditor\n mode=\"section\"\n mappings={mappings}\n sources={sources}\n targets={targets}\n onLookupChange={(mapping, entries) => {\n const row = mapper.rows.find(\n (r) =>\n r.mapping?.sourceId === mapping.sourceId &&\n r.mapping?.propertyName === mapping.propertyName,\n )\n if (row) mapper.setLookupEntries(row.id, entries)\n }}\n classNames={classNames}\n />\n )}\n\n {jsonPreview && (\n <details\n className={slotClass('jsonPreview', classNames)}\n open={previewOpen}\n onToggle={(e) =>\n setPreviewOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>Preview JSON</summary>\n <pre className=\"fm-preview-body\">\n {JSON.stringify(preview, null, 2)}\n </pre>\n </details>\n )}\n </>\n )\n}\n","import type { FieldMapperRow, FieldMapperTransformOption } from './fieldMapperTypes'\n\nexport function defaultTransformOptions(\n row: FieldMapperRow,\n): FieldMapperTransformOption[] {\n const options: FieldMapperTransformOption[] = [\n { value: '', label: 'copy' },\n { value: 'extract', label: 'extract' },\n { value: 'file', label: 'file' },\n { value: 'lookup', label: 'lookup' },\n ]\n if (row.target?.dataType === 'Html') {\n options.push({ value: 'assemble', label: 'assemble' })\n }\n const current = row.mapping?.resolve\n if (current && !options.some((opt) => opt.value === current)) {\n options.push({ value: current, label: current })\n }\n return options\n}\n\nexport function resolveTransformOptions(\n row: FieldMapperRow,\n host?: (\n row: FieldMapperRow,\n defaults: FieldMapperTransformOption[],\n ) => FieldMapperTransformOption[],\n): FieldMapperTransformOption[] {\n const defaults = defaultTransformOptions(row)\n return host ? host(row, defaults) : defaults\n}\n\n/** Show the transform select for a mapped origin, source-less derive, or host derive option. */\nexport function showTransformSelect(\n row: FieldMapperRow,\n options: FieldMapperTransformOption[],\n): boolean {\n if (row.mapping?.sourceId) return true\n if (row.mapping?.resolve === 'derive') return true\n return options.some((opt) => opt.value === 'derive')\n}\n\nexport function isTransformSelectDisabled(row: FieldMapperRow): boolean {\n return !row.mapping?.sourceId && row.mapping?.resolve === 'derive'\n}\n","import React, { useMemo, useState, type ReactNode } from 'react'\nimport type {\n FieldMapping,\n MappingLookups,\n ResolveJob,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperSlot,\n ResolvedFieldMapperComponents,\n ResolvedFieldMapperSlots,\n} from './fieldMapperSlots'\nimport {\n showJsonPreview,\n showRowPreview,\n slotClass,\n} from './fieldMapperSlots'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport {\n buildSyncPreviewBag,\n filterPropertyNames,\n originSources,\n truncateSample,\n} from './fieldMapperCore'\nimport type {\n FieldMapperDefaultRows,\n FieldMapperLookupRow,\n FieldMapperRow,\n FieldMapperTransformOptions,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\nimport {\n isTransformSelectDisabled,\n resolveTransformOptions,\n showTransformSelect,\n} from './fieldMapperTransforms'\nimport { LookupEditor } from './LookupEditor'\n\nexport type PropertyRowsProps = {\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n mapper: UseFieldMapperResult\n defaultRows?: FieldMapperDefaultRows\n lookups?: MappingLookups\n onLookupsChange?: (lookups: MappingLookups) => void\n slots: ResolvedFieldMapperSlots\n classNames?: Partial<Record<FieldMapperSlot, string>>\n ui?: ResolvedFieldMapperComponents\n renderRowAccessory?: (row: FieldMapperRow) => ReactNode\n renderLookup?: (row: FieldMapperLookupRow) => ReactNode\n renderRowExpansion?: (row: FieldMapperRow) => ReactNode\n transformOptions?: FieldMapperTransformOptions\n}\n\nexport function PropertyRows({\n sources,\n targets,\n mappings,\n mapper,\n defaultRows = 'requiredAndMapped',\n onLookupsChange,\n slots,\n classNames,\n ui = {\n Select: DefaultSelect,\n Button: DefaultButton,\n Pill: DefaultPill,\n },\n renderRowAccessory,\n renderLookup,\n renderRowExpansion,\n transformOptions,\n}: PropertyRowsProps) {\n const Select = ui.Select\n const Button = ui.Button\n const Pill = ui.Pill\n\n const [filterMode, setFilterMode] =\n useState<FieldMapperDefaultRows>(defaultRows)\n const [extraNames, setExtraNames] = useState<Set<string>>(() => new Set())\n const [inspectorOpen, setInspectorOpen] = useState(false)\n const [adding, setAdding] = useState(false)\n const [pendingSourceId, setPendingSourceId] = useState<string | null>(null)\n const [previewOpen, setPreviewOpen] = useState(false)\n\n const visibleNames = useMemo(\n () => filterPropertyNames(targets, mappings, filterMode, extraNames),\n [targets, mappings, filterMode, extraNames],\n )\n\n const visibleRows = useMemo(() => {\n if (visibleNames == null) return mapper.rows\n return mapper.rows.filter((r) => visibleNames.has(r.id))\n }, [mapper.rows, visibleNames])\n\n const usageBySource = useMemo(() => {\n const map = new Map<string, string[]>()\n for (const m of mappings) {\n if (!m.sourceId) continue\n const list = map.get(m.sourceId) ?? []\n list.push(m.propertyName)\n map.set(m.sourceId, list)\n }\n return map\n }, [mappings])\n\n const syncPreview = useMemo(\n () => buildSyncPreviewBag(sources, mappings, targets),\n [sources, mappings, targets],\n )\n\n const { coverage, sourceOptions, addableProperties } = mapper\n const jsonPreview = showJsonPreview(slots.preview)\n const rowPreview = showRowPreview(slots.preview)\n const showRowLookups =\n slots.lookups === 'row' && (Boolean(renderLookup) || Boolean(onLookupsChange))\n const showSectionLookups =\n slots.lookups === 'section' &&\n !renderLookup &&\n Boolean(onLookupsChange)\n\n const handleAddProperty = (name: string) => {\n mapper.addRow(name)\n setExtraNames((prev) => new Set(prev).add(name))\n setAdding(false)\n }\n\n const handleRemoveRow = (rowId: string) => {\n mapper.removeRow(rowId)\n setExtraNames((prev) => {\n if (!prev.has(rowId)) return prev\n const next = new Set(prev)\n next.delete(rowId)\n return next\n })\n }\n\n const mapThisSource = (sourceId: string) => {\n setPendingSourceId(sourceId)\n setAdding(true)\n }\n\n const onPickAddProperty = (name: string) => {\n handleAddProperty(name)\n if (pendingSourceId) {\n mapper.setSource(name, pendingSourceId)\n setPendingSourceId(null)\n }\n }\n\n return (\n <>\n <div className={slotClass('toolbar', classNames)}>\n {slots.autoMap && (\n <Button\n className={slotClass('autoMapButton', classNames)}\n onClick={() => mapper.autoMap()}\n >\n Auto-map\n </Button>\n )}\n <span className={slotClass('coverage', classNames)}>\n {coverage.mapped} of {coverage.total} properties mapped\n {coverage.missingRequired.length > 0\n ? ` · ${coverage.missingRequired.length} required missing`\n : ''}\n </span>\n </div>\n\n {slots.filter && (\n <div\n className={slotClass('filter', classNames)}\n role=\"group\"\n aria-label=\"Row filter\"\n >\n <Button\n className=\"fm-btn\"\n aria-pressed={filterMode === 'requiredAndMapped'}\n onClick={() => setFilterMode('requiredAndMapped')}\n >\n Mapped + required\n </Button>\n <Button\n className=\"fm-btn\"\n aria-pressed={filterMode === 'all'}\n onClick={() => setFilterMode('all')}\n >\n All {targets.length} properties\n </Button>\n </div>\n )}\n\n <div className={slotClass('rowList', classNames)}>\n {visibleRows.map((row) => {\n const resolveValue = (row.mapping?.resolve ?? '') as '' | ResolveJob\n const transformOpts = resolveTransformOptions(row, transformOptions)\n const showTransform = showTransformSelect(row, transformOpts)\n return (\n <div\n key={row.id}\n className={slotClass('row', classNames)}\n data-state={row.state}\n data-property-name={row.id}\n data-required={row.target?.required ? 'true' : undefined}\n data-resolve={row.mapping?.resolve}\n data-source-kind={row.source?.kind}\n >\n <div className=\"fm-row-main\">\n <div className=\"fm-row-prop\">\n <div className={slotClass('propertyLabel', classNames)}>\n {row.target?.name}\n {row.target?.required ? ' *' : ''}\n </div>\n <Pill className={slotClass('dataType', classNames)}>\n {row.target?.dataType}\n </Pill>\n </div>\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label={`Source for ${row.id}`}\n value={row.mapping?.sourceId ?? ''}\n onChange={(v) => {\n mapper.setSource(row.id, v || null)\n }}\n >\n <option value=\"\">Choose a source field…</option>\n {sourceOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n {showTransform ? (\n <Select\n className={slotClass('transformSelect', classNames)}\n aria-label={`Transform for ${row.id}`}\n value={resolveValue}\n disabled={isTransformSelectDisabled(row)}\n onChange={(v) => {\n mapper.setTransform(row.id, (v as ResolveJob) || null)\n }}\n >\n {transformOpts.map((opt) => (\n <option\n key={opt.label}\n value={opt.value}\n disabled={opt.disabled}\n >\n {opt.label}\n </option>\n ))}\n </Select>\n ) : (\n <Pill className={slotClass('dataType', classNames)}>\n {row.target?.dataType}\n </Pill>\n )}\n <div className={slotClass('rowAccessory', classNames)}>\n {renderRowAccessory?.(row) ?? null}\n </div>\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label={`Remove mapping for ${row.id}`}\n onClick={() => handleRemoveRow(row.id)}\n >\n ×\n </Button>\n </div>\n {rowPreview && row.preview && (\n <div className={slotClass('preview', classNames)}>\n {row.preview}\n </div>\n )}\n {row.state === 'needsResolve' && row.requiredResolve && (\n <div className={slotClass('validation', classNames)}>\n needs {row.requiredResolve}\n </div>\n )}\n {row.state === 'needsLookup' && (\n <div className={slotClass('validation', classNames)}>\n needs lookup\n </div>\n )}\n {showRowLookups &&\n row.mapping?.resolve === 'lookup' &&\n row.mapping &&\n (renderLookup ? (\n <div className={slotClass('lookupEditor', classNames)}>\n {renderLookup({\n ...row,\n sampleValue: row.sampleValue ?? '',\n onLookupChange: (entries) =>\n mapper.setLookupEntries(row.id, entries),\n })}\n </div>\n ) : (\n <LookupEditor\n mode=\"row\"\n mappings={[row.mapping]}\n sources={sources}\n targets={targets}\n onLookupChange={(_mapping, entries) =>\n mapper.setLookupEntries(row.id, entries)\n }\n classNames={classNames}\n />\n ))}\n <div className={slotClass('rowExpansion', classNames)}>\n {renderRowExpansion?.(row) ?? null}\n </div>\n </div>\n )\n })}\n </div>\n\n <div style={{ marginTop: 10 }}>\n {adding ? (\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label=\"Add property mapping\"\n value=\"\"\n onChange={(name) => {\n if (name) onPickAddProperty(name)\n }}\n >\n <option value=\"\">Choose a property…</option>\n {addableProperties.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n {p.required ? ' *' : ''} ({p.dataType})\n </option>\n ))}\n </Select>\n ) : (\n <Button\n className={slotClass('addButton', classNames)}\n onClick={() => setAdding(true)}\n disabled={addableProperties.length === 0}\n >\n + Add mapping\n </Button>\n )}\n </div>\n\n {slots.inspector && (\n <details\n className={slotClass('inspector', classNames)}\n open={inspectorOpen}\n onToggle={(e) =>\n setInspectorOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>\n Source fields ({originSources(sources).length})\n </summary>\n {originSources(sources).map((source) => {\n const used = usageBySource.get(source.id) ?? []\n return (\n <div key={source.id} className=\"fm-inspector-row\">\n <div>\n <strong>{source.label}</strong>\n {source.subtitle ? (\n <div className=\"fm-value\">{source.subtitle}</div>\n ) : null}\n <div className=\"fm-value\">\n {truncateSample(source.value, 60)}\n </div>\n </div>\n <div className=\"fm-value\">\n {used.length > 0 ? `→ ${used.join(', ')}` : 'unused'}\n </div>\n <Button\n className=\"fm-btn\"\n onClick={() => mapThisSource(source.id)}\n >\n Map this\n </Button>\n </div>\n )\n })}\n </details>\n )}\n\n {showSectionLookups && (\n <LookupEditor\n mode=\"section\"\n mappings={mappings}\n sources={sources}\n targets={targets}\n onLookupChange={(mapping, entries) => {\n const row = mapper.rows.find(\n (r) =>\n r.mapping?.sourceId === mapping.sourceId &&\n r.mapping?.propertyName === mapping.propertyName,\n )\n if (row) mapper.setLookupEntries(row.id, entries)\n }}\n classNames={classNames}\n />\n )}\n\n {jsonPreview && (\n <details\n className={slotClass('jsonPreview', classNames)}\n open={previewOpen}\n onToggle={(e) =>\n setPreviewOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>Preview JSON</summary>\n <pre className=\"fm-preview-body\">\n {JSON.stringify(syncPreview, null, 2)}\n </pre>\n </details>\n )}\n </>\n )\n}\n","import React, { useMemo, useState, type ReactNode } from 'react'\nimport type {\n FieldMapping,\n MappingLookups,\n ResolveJob,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport type {\n FieldMapperSlot,\n ResolvedFieldMapperComponents,\n ResolvedFieldMapperSlots,\n} from './fieldMapperSlots'\nimport {\n showJsonPreview,\n showRowPreview,\n slotClass,\n} from './fieldMapperSlots'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport { buildSyncPreviewBag } from './fieldMapperCore'\nimport type {\n FieldMapperLookupRow,\n FieldMapperRow,\n FieldMapperTransformOptions,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\nimport {\n isTransformSelectDisabled,\n resolveTransformOptions,\n showTransformSelect,\n} from './fieldMapperTransforms'\nimport { LookupEditor } from './LookupEditor'\n\nexport type SourceRowsProps = {\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n mapper: UseFieldMapperResult\n lookups?: MappingLookups\n onLookupsChange?: (lookups: MappingLookups) => void\n slots: ResolvedFieldMapperSlots\n classNames?: Partial<Record<FieldMapperSlot, string>>\n ui?: ResolvedFieldMapperComponents\n renderRowAccessory?: (row: FieldMapperRow) => ReactNode\n renderLookup?: (row: FieldMapperLookupRow) => ReactNode\n renderRowExpansion?: (row: FieldMapperRow) => ReactNode\n transformOptions?: FieldMapperTransformOptions\n}\n\nexport function SourceRows({\n sources,\n targets,\n mappings,\n mapper,\n onLookupsChange,\n slots,\n classNames,\n ui = {\n Select: DefaultSelect,\n Button: DefaultButton,\n Pill: DefaultPill,\n },\n renderRowAccessory,\n renderLookup,\n renderRowExpansion,\n transformOptions,\n}: SourceRowsProps) {\n const Select = ui.Select\n const Button = ui.Button\n const [previewOpen, setPreviewOpen] = useState(false)\n const {\n rows,\n sourceOptions,\n propertyOptions,\n coverage,\n conflicts,\n setSource,\n setProperty,\n setTransform,\n addRow,\n removeRow,\n autoMap,\n } = mapper\n\n const syncPreview = useMemo(\n () => buildSyncPreviewBag(sources, mappings, targets),\n [sources, mappings, targets],\n )\n\n const jsonPreview = showJsonPreview(slots.preview)\n const rowPreview = showRowPreview(slots.preview)\n const showRowLookups =\n slots.lookups === 'row' && (Boolean(renderLookup) || Boolean(onLookupsChange))\n const showSectionLookups =\n slots.lookups === 'section' &&\n !renderLookup &&\n Boolean(onLookupsChange)\n\n return (\n <>\n <div className={slotClass('toolbar', classNames)}>\n {slots.autoMap && (\n <Button\n className={slotClass('autoMapButton', classNames)}\n onClick={() => autoMap()}\n >\n Auto-map\n </Button>\n )}\n <span className={slotClass('coverage', classNames)}>\n {coverage.mapped} of {coverage.total} mapped\n {coverage.missingRequired.length > 0\n ? ` · ${coverage.missingRequired.length} required missing: ${coverage.missingRequired.join(', ')}`\n : ''}\n </span>\n </div>\n\n {conflicts.size > 0 && (\n <div className=\"fm-banner fm-banner-danger\" role=\"alert\">\n {conflicts.size} row{conflicts.size === 1 ? '' : 's'} claim the same\n property — each property can only have one source.\n </div>\n )}\n\n {coverage.missingRequired.length > 0 && (\n <div className=\"fm-banner fm-banner-warn\" role=\"status\">\n Required missing: {coverage.missingRequired.join(', ')}\n </div>\n )}\n\n <div className={slotClass('rowList', classNames)}>\n {rows.map((row) => {\n const resolveValue = (row.mapping?.resolve ?? '') as '' | ResolveJob\n const sourceValue = row.source?.id ?? row.mapping?.sourceId ?? ''\n const propertyValue =\n row.target?.name ?? row.mapping?.propertyName ?? ''\n const transformOpts = resolveTransformOptions(row, transformOptions)\n const showTransform = showTransformSelect(row, transformOpts)\n return (\n <div\n key={row.id}\n className={slotClass('row', classNames)}\n data-state={row.state}\n data-property-name={propertyValue || undefined}\n data-required={row.target?.required ? 'true' : undefined}\n data-resolve={row.mapping?.resolve}\n data-source-kind={row.source?.kind}\n >\n <div className=\"fm-row-main fm-row-main-source\">\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label=\"Source field\"\n value={sourceValue}\n onChange={(v) => {\n setSource(row.id, v || null)\n }}\n >\n <option value=\"\">Choose a source field…</option>\n {sourceOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n {showTransform ? (\n <Select\n className={slotClass('transformSelect', classNames)}\n aria-label=\"Transform\"\n value={resolveValue}\n disabled={isTransformSelectDisabled(row)}\n onChange={(v) => {\n setTransform(row.id, (v as ResolveJob) || null)\n }}\n >\n {transformOpts.map((opt) => (\n <option\n key={opt.label}\n value={opt.value}\n disabled={opt.disabled}\n >\n {opt.label}\n </option>\n ))}\n </Select>\n ) : (\n <span className=\"fm-into\" />\n )}\n <span className=\"fm-into\">into</span>\n <Select\n className={slotClass('sourceSelect', classNames)}\n aria-label=\"Target property\"\n value={propertyValue}\n onChange={(v) => {\n if (v) setProperty(row.id, v)\n }}\n >\n <option value=\"\">Choose a property…</option>\n {propertyOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </Select>\n <div className={slotClass('rowAccessory', classNames)}>\n {renderRowAccessory?.(row) ?? null}\n </div>\n <Button\n className={slotClass('removeButton', classNames)}\n aria-label=\"Remove row\"\n onClick={() => removeRow(row.id)}\n >\n ×\n </Button>\n </div>\n {rowPreview && row.preview && (\n <div className={slotClass('preview', classNames)}>\n {row.preview}\n </div>\n )}\n {row.state === 'needsResolve' && row.requiredResolve && (\n <div className={slotClass('validation', classNames)}>\n needs {row.requiredResolve}\n </div>\n )}\n {row.state === 'needsLookup' && (\n <div className={slotClass('validation', classNames)}>\n needs lookup\n </div>\n )}\n {row.state === 'conflict' && (\n <div\n className={slotClass('validation', classNames)}\n style={{ color: 'var(--fm-danger)' }}\n >\n property already mapped by another row\n </div>\n )}\n {showRowLookups &&\n row.mapping?.resolve === 'lookup' &&\n row.mapping &&\n (renderLookup ? (\n <div className={slotClass('lookupEditor', classNames)}>\n {renderLookup({\n ...row,\n sampleValue: row.sampleValue ?? '',\n onLookupChange: (entries) =>\n mapper.setLookupEntries(row.id, entries),\n })}\n </div>\n ) : (\n <LookupEditor\n mode=\"row\"\n mappings={[row.mapping]}\n sources={sources}\n targets={targets}\n onLookupChange={(_mapping, entries) =>\n mapper.setLookupEntries(row.id, entries)\n }\n classNames={classNames}\n />\n ))}\n <div className={slotClass('rowExpansion', classNames)}>\n {renderRowExpansion?.(row) ?? null}\n </div>\n </div>\n )\n })}\n </div>\n\n <div style={{ marginTop: 10 }}>\n <Button\n className={slotClass('addButton', classNames)}\n onClick={() => addRow()}\n >\n + Add mapping\n </Button>\n </div>\n\n {showSectionLookups && (\n <LookupEditor\n mode=\"section\"\n mappings={mappings}\n sources={sources}\n targets={targets}\n onLookupChange={(mapping, entries) => {\n const match = mapper.rows.find(\n (r) =>\n r.mapping?.sourceId === mapping.sourceId &&\n r.mapping?.propertyName === mapping.propertyName,\n )\n if (match) mapper.setLookupEntries(match.id, entries)\n }}\n classNames={classNames}\n />\n )}\n\n {jsonPreview && (\n <details\n className={slotClass('jsonPreview', classNames)}\n open={previewOpen}\n onToggle={(e) =>\n setPreviewOpen((e.target as HTMLDetailsElement).open)\n }\n >\n <summary>Preview JSON</summary>\n <pre className=\"fm-preview-body\">\n {JSON.stringify(syncPreview, null, 2)}\n </pre>\n </details>\n )}\n </>\n )\n}\n","import { useCallback, useMemo, useRef, useState } from 'react'\nimport { autoMap as defaultAutoMap } from '../autoMap'\nimport {\n applyResolveToEdge,\n clearSourceKeepDerive,\n isDeriveKeepOnClear,\n withPreservedExtras,\n} from '../edgeMapping'\nimport type {\n DeriveSpec,\n FieldMapping,\n LookupEntry,\n ResolveJob,\n TargetProperty,\n} from '../types'\nimport {\n applyAssembleBlocksToMappings,\n applyDeriveToMappings,\n applyLookupEntriesToMappings,\n attachLookupIfNeeded,\n buildPropertyModeRows,\n buildPropertyOptions,\n buildSourceModeRows,\n buildSourceOptions,\n clearLookupsForProperties,\n computeCoverage,\n computeRequiredResolve,\n connectSourceToProperty,\n filterPropertyNames,\n newRowId,\n originSources,\n removeMappingsForSourceId,\n syncEdgeIds,\n type SourceModeDraft,\n upsertPropertyMapping,\n} from './fieldMapperCore'\nimport type {\n UseFieldMapperArgs,\n UseFieldMapperResult,\n} from './fieldMapperTypes'\n\nexport function useFieldMapper({\n sources,\n targets,\n mappings,\n onChange,\n lookups = {},\n onLookupsChange,\n rowKey = 'property',\n onAutoMap,\n}: UseFieldMapperArgs): UseFieldMapperResult {\n const [extraPropertyNames, setExtraPropertyNames] = useState<Set<string>>(\n () => new Set(),\n )\n const [drafts, setDrafts] = useState<SourceModeDraft[]>([])\n const mappingsRef = useRef(mappings)\n const mappingsPropRef = useRef(mappings)\n if (mappingsPropRef.current !== mappings) {\n mappingsPropRef.current = mappings\n mappingsRef.current = mappings\n }\n const edgeIdsRef = useRef<string[]>([])\n edgeIdsRef.current = syncEdgeIds(edgeIdsRef.current, mappingsRef.current.length)\n const edgeIds = edgeIdsRef.current\n\n const commitMappings = useCallback(\n (next: FieldMapping[]) => {\n mappingsRef.current = next\n edgeIdsRef.current = syncEdgeIds(edgeIdsRef.current, next.length)\n onChange(next)\n },\n [onChange],\n )\n\n const applyLookupClears = useCallback(\n (props: string[]) => {\n if (!onLookupsChange || props.length === 0) return\n const next = clearLookupsForProperties(lookups, props)\n if (next) onLookupsChange(next)\n },\n [lookups, onLookupsChange],\n )\n\n const sourceOptions = useMemo(() => buildSourceOptions(sources), [sources])\n const propertyOptions = useMemo(\n () => buildPropertyOptions(targets),\n [targets],\n )\n\n const coverage = useMemo(\n () => computeCoverage(targets, mappings),\n [targets, mappings],\n )\n\n const mappedProps = useMemo(\n () => new Set(mappings.map((m) => m.propertyName)),\n [mappings],\n )\n\n const addableProperties = useMemo(\n () =>\n targets.filter(\n (t) => !mappedProps.has(t.name) && !extraPropertyNames.has(t.name),\n ),\n [targets, mappedProps, extraPropertyNames],\n )\n\n const propertyRows = useMemo(() => {\n // Property mode always exposes the full target list to the hook;\n // UI filter is applied by the renderer via filterPropertyNames.\n return buildPropertyModeRows({ targets, mappings, sources, lookups })\n }, [targets, mappings, sources, lookups])\n\n const sourceBuilt = useMemo(() => {\n return buildSourceModeRows({\n mappings,\n edgeIds,\n drafts,\n sources,\n targets,\n lookups,\n })\n }, [mappings, edgeIds, drafts, sources, targets, lookups])\n\n const rows = rowKey === 'property' ? propertyRows : sourceBuilt.rows\n const conflicts =\n rowKey === 'property' ? new Set<string>() : sourceBuilt.conflicts\n\n const connect = useCallback(\n (sourceId: string, propertyName: string) => {\n const result = connectSourceToProperty(\n mappingsRef.current,\n sources,\n targets,\n sourceId,\n propertyName,\n )\n commitMappings(result.mappings)\n applyLookupClears(result.clearedLookupProps)\n },\n [sources, targets, commitMappings, applyLookupClears],\n )\n\n const removeBySource = useCallback(\n (sourceId: string) => {\n const result = removeMappingsForSourceId(mappingsRef.current, sourceId)\n commitMappings(result.mappings)\n applyLookupClears(result.clearedLookupProps)\n },\n [commitMappings, applyLookupClears],\n )\n\n const autoMap = useCallback(() => {\n const next = onAutoMap ? onAutoMap() : defaultAutoMap(sources, targets)\n commitMappings(next)\n setDrafts([])\n setExtraPropertyNames(new Set())\n }, [onAutoMap, sources, targets, commitMappings])\n\n const setSource = useCallback(\n (rowId: string, sourceId: string | null) => {\n const current = mappingsRef.current\n if (rowKey === 'property') {\n if (!sourceId) {\n const prev = current.find((m) => m.propertyName === rowId)\n if (prev && isDeriveKeepOnClear(prev)) {\n commitMappings(\n upsertPropertyMapping(current, clearSourceKeepDerive(prev)),\n )\n if (prev.resolve === 'lookup') applyLookupClears([rowId])\n return\n }\n commitMappings(current.filter((m) => m.propertyName !== rowId))\n if (prev?.resolve === 'lookup') applyLookupClears([rowId])\n return\n }\n const result = connectSourceToProperty(\n current,\n sources,\n targets,\n sourceId,\n rowId,\n )\n // Pre-select required transform when connecting a plain origin source\n const target = targets.find((t) => t.name === rowId)\n const source = originSources(sources).find((s) => s.id === sourceId)\n let edge = result.mappings.find((m) => m.propertyName === rowId)!\n if (!edge.resolve) {\n const required = computeRequiredResolve(source, target)\n if (required) {\n edge = { ...edge, resolve: required }\n commitMappings(upsertPropertyMapping(result.mappings, edge))\n applyLookupClears(result.clearedLookupProps)\n return\n }\n }\n commitMappings(result.mappings)\n applyLookupClears(result.clearedLookupProps)\n return\n }\n\n // source mode\n const edgeIndex = edgeIdsRef.current.indexOf(rowId)\n if (edgeIndex >= 0) {\n if (!sourceId) {\n const prev = current[edgeIndex]\n if (prev && isDeriveKeepOnClear(prev)) {\n const next = [...current]\n next[edgeIndex] = clearSourceKeepDerive(prev)\n commitMappings(next)\n if (prev.resolve === 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n const next = current.filter((_, i) => i !== edgeIndex)\n commitMappings(next)\n if (prev?.resolve === 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n const prev = current[edgeIndex]!\n const target = targets.find((t) => t.name === prev.propertyName)\n let edge: FieldMapping = {\n sourceId,\n propertyName: prev.propertyName,\n }\n edge = attachLookupIfNeeded(edge, target)\n edge = withPreservedExtras(edge, prev)\n if (!edge.resolve) {\n const source = originSources(sources).find((s) => s.id === sourceId)\n const required = computeRequiredResolve(source, target)\n if (required) edge = { ...edge, resolve: required }\n }\n const next = [...current]\n next[edgeIndex] = edge\n commitMappings(next)\n if (prev.resolve === 'lookup' && edge.resolve !== 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) => {\n const updated = prev.map((d) => {\n if (d.id !== rowId) return d\n if (!sourceId) {\n return { id: d.id, propertyName: d.propertyName }\n }\n const target = d.propertyName\n ? targets.find((t) => t.name === d.propertyName)\n : undefined\n const source = originSources(sources).find((s) => s.id === sourceId)\n const required = computeRequiredResolve(source, target)\n const resolve =\n (target &&\n attachLookupIfNeeded(\n { sourceId, propertyName: d.propertyName ?? '' },\n target,\n ).resolve) ||\n required ||\n undefined\n return {\n id: d.id,\n sourceId,\n propertyName: d.propertyName,\n resolve,\n }\n })\n const complete = updated.filter(\n (d) =>\n d.propertyName &&\n (d.sourceId || d.resolve === 'derive'),\n )\n const incomplete = updated.filter(\n (d) =>\n !(\n d.propertyName &&\n (d.sourceId || d.resolve === 'derive')\n ),\n )\n if (complete.length > 0) {\n commitMappings([\n ...mappingsRef.current,\n ...complete.map((d) => ({\n ...(d.sourceId ? { sourceId: d.sourceId } : {}),\n propertyName: d.propertyName!,\n ...(d.resolve ? { resolve: d.resolve } : {}),\n })),\n ])\n return incomplete\n }\n return updated\n })\n },\n [\n rowKey,\n sources,\n targets,\n commitMappings,\n applyLookupClears,\n ],\n )\n\n const setProperty = useCallback(\n (rowId: string, propertyName: string) => {\n if (rowKey === 'property') {\n // Property mode row ids are property names; renaming is add+remove.\n return\n }\n\n const current = mappingsRef.current\n const edgeIndex = edgeIdsRef.current.indexOf(rowId)\n if (edgeIndex >= 0) {\n const prev = current[edgeIndex]!\n const target = targets.find((t) => t.name === propertyName)\n const source = originSources(sources).find(\n (s) => s.id === prev.sourceId,\n )\n let edge: FieldMapping = {\n ...(prev.sourceId ? { sourceId: prev.sourceId } : {}),\n propertyName,\n }\n edge = attachLookupIfNeeded(edge, target)\n edge = withPreservedExtras(edge, prev)\n if (!edge.resolve) {\n const required = computeRequiredResolve(source, target)\n if (required) edge = { ...edge, resolve: required }\n }\n const next = [...current]\n next[edgeIndex] = edge\n commitMappings(next)\n if (prev.resolve === 'lookup' && edge.resolve !== 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n if (\n prev.propertyName !== propertyName &&\n prev.resolve === 'lookup' &&\n edge.resolve === 'lookup'\n ) {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) => {\n const updated = prev.map((d) => {\n if (d.id !== rowId) return d\n const target = targets.find((t) => t.name === propertyName)\n const source = d.sourceId\n ? originSources(sources).find((s) => s.id === d.sourceId)\n : undefined\n let resolve = d.resolve\n if (d.sourceId && target) {\n const attached = attachLookupIfNeeded(\n { sourceId: d.sourceId, propertyName },\n target,\n )\n resolve =\n attached.resolve ??\n computeRequiredResolve(source, target) ??\n undefined\n }\n const nextDraft: SourceModeDraft = {\n id: d.id,\n sourceId: d.sourceId,\n propertyName,\n resolve,\n }\n // Promote complete drafts into mappings\n if (nextDraft.sourceId && nextDraft.propertyName) {\n return nextDraft\n }\n return nextDraft\n })\n\n const complete = updated.filter(\n (d) =>\n d.propertyName &&\n (d.sourceId || d.resolve === 'derive'),\n )\n const incomplete = updated.filter(\n (d) =>\n !(\n d.propertyName &&\n (d.sourceId || d.resolve === 'derive')\n ),\n )\n\n if (complete.length > 0) {\n const promoted: FieldMapping[] = complete.map((d) => ({\n ...(d.sourceId ? { sourceId: d.sourceId } : {}),\n propertyName: d.propertyName!,\n ...(d.resolve ? { resolve: d.resolve } : {}),\n }))\n commitMappings([...mappingsRef.current, ...promoted])\n return incomplete\n }\n return updated\n })\n },\n [\n rowKey,\n targets,\n sources,\n commitMappings,\n applyLookupClears,\n ],\n )\n\n const setLookupEntries = useCallback(\n (rowId: string, entries: LookupEntry[]) => {\n const next = applyLookupEntriesToMappings(\n mappingsRef.current,\n rowKey,\n rowId,\n edgeIdsRef.current,\n entries,\n )\n if (!next) return\n commitMappings(next)\n if (!onLookupsChange) return\n const edge =\n rowKey === 'property'\n ? next.find((m) => m.propertyName === rowId)\n : next[edgeIdsRef.current.indexOf(rowId)]\n if (!edge) return\n const table = Object.fromEntries(\n (edge.lookup?.entries ?? []).map((e) => [e.value, e.ref]),\n )\n const merged = { ...lookups }\n if (Object.keys(table).length === 0) {\n delete merged[edge.propertyName]\n } else {\n merged[edge.propertyName] = table\n }\n onLookupsChange(merged)\n },\n [rowKey, commitMappings, onLookupsChange, lookups],\n )\n\n const setAssembleBlocks = useCallback(\n (rowId: string, blocks: string[]) => {\n const next = applyAssembleBlocksToMappings(\n mappingsRef.current,\n rowKey,\n rowId,\n edgeIdsRef.current,\n blocks,\n )\n if (next) commitMappings(next)\n },\n [rowKey, commitMappings],\n )\n\n const setDerive = useCallback(\n (rowId: string, spec: DeriveSpec | null) => {\n const next = applyDeriveToMappings(\n mappingsRef.current,\n rowKey,\n rowId,\n edgeIdsRef.current,\n spec,\n )\n if (next) commitMappings(next)\n },\n [rowKey, commitMappings],\n )\n\n const setTransform = useCallback(\n (rowId: string, resolve: ResolveJob | null) => {\n const current = mappingsRef.current\n if (rowKey === 'property') {\n const prev = current.find((m) => m.propertyName === rowId)\n if (!prev) {\n if (resolve === 'derive') {\n commitMappings(\n upsertPropertyMapping(current, {\n propertyName: rowId,\n resolve: 'derive',\n }),\n )\n }\n return\n }\n commitMappings(upsertPropertyMapping(current, applyResolveToEdge(prev, resolve)))\n if (prev.resolve === 'lookup' && resolve !== 'lookup') {\n applyLookupClears([rowId])\n }\n return\n }\n\n const edgeIndex = edgeIdsRef.current.indexOf(rowId)\n if (edgeIndex >= 0) {\n const prev = current[edgeIndex]!\n const next = [...current]\n next[edgeIndex] = applyResolveToEdge(prev, resolve)\n commitMappings(next)\n if (prev.resolve === 'lookup' && resolve !== 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prevDrafts) => {\n const updated = prevDrafts.map((d) =>\n d.id === rowId\n ? { ...d, resolve: resolve ?? undefined }\n : d,\n )\n const complete = updated.filter(\n (d) =>\n d.propertyName &&\n (d.sourceId || d.resolve === 'derive'),\n )\n const incomplete = updated.filter(\n (d) =>\n !(\n d.propertyName &&\n (d.sourceId || d.resolve === 'derive')\n ),\n )\n if (complete.length > 0) {\n commitMappings([\n ...mappingsRef.current,\n ...complete.map((d) => ({\n ...(d.sourceId ? { sourceId: d.sourceId } : {}),\n propertyName: d.propertyName!,\n ...(d.resolve ? { resolve: d.resolve } : {}),\n })),\n ])\n return incomplete\n }\n return updated\n })\n },\n [rowKey, commitMappings, applyLookupClears],\n )\n\n const addRow = useCallback(\n (propertyName?: string) => {\n if (rowKey === 'property') {\n if (propertyName) {\n setExtraPropertyNames((prev) => new Set(prev).add(propertyName))\n }\n return\n }\n setDrafts((prev) => [\n ...prev,\n {\n id: newRowId('draft'),\n ...(propertyName ? { propertyName } : {}),\n },\n ])\n },\n [rowKey],\n )\n\n const removeRow = useCallback(\n (rowId: string) => {\n const current = mappingsRef.current\n if (rowKey === 'property') {\n const prev = current.find((m) => m.propertyName === rowId)\n commitMappings(current.filter((m) => m.propertyName !== rowId))\n if (prev?.resolve === 'lookup') applyLookupClears([rowId])\n setExtraPropertyNames((prevSet) => {\n if (!prevSet.has(rowId)) return prevSet\n const next = new Set(prevSet)\n next.delete(rowId)\n return next\n })\n return\n }\n\n const edgeIndex = edgeIdsRef.current.indexOf(rowId)\n if (edgeIndex >= 0) {\n const prev = current[edgeIndex]\n commitMappings(current.filter((_, i) => i !== edgeIndex))\n if (prev?.resolve === 'lookup') {\n applyLookupClears([prev.propertyName])\n }\n return\n }\n\n setDrafts((prev) => prev.filter((d) => d.id !== rowId))\n },\n [rowKey, commitMappings, applyLookupClears],\n )\n\n return {\n rows,\n sourceOptions,\n propertyOptions,\n addableProperties,\n coverage,\n conflicts,\n setSource,\n setProperty,\n setTransform,\n setLookupEntries,\n setAssembleBlocks,\n setDerive,\n addRow,\n removeRow,\n autoMap,\n connect,\n removeBySource,\n }\n}\n\n/** Re-export filter helper for row renderers. */\nexport { filterPropertyNames }\nexport type { TargetProperty }\n","import React, { useEffect, useMemo, type ReactNode } from 'react'\nimport type {\n FieldMapping,\n MappingLookups,\n SourceNode,\n TargetProperty,\n} from '../types'\nimport {\n DefaultButton,\n DefaultPill,\n DefaultSelect,\n} from './fieldMapperControls'\nimport type {\n FieldMapperComponents,\n FieldMapperSlot,\n FieldMapperSlots,\n} from './fieldMapperSlots'\nimport { resolveSlots, slotClass } from './fieldMapperSlots'\nimport { FieldMapperWires } from './FieldMapperWires'\nimport type {\n FieldMapperDefaultRows,\n FieldMapperLayout,\n FieldMapperLookupRow,\n FieldMapperRow,\n FieldMapperRowKey,\n FieldMapperTransformOptions,\n} from './fieldMapperTypes'\nimport {\n ensureThemeInjected,\n resolveTheme,\n type FieldMapperTheme,\n} from './fieldMapperTheme'\nimport { PropertyRows } from './PropertyRows'\nimport { SourceRows } from './SourceRows'\nimport { useFieldMapper } from './useFieldMapper'\n\nexport {\n connectionStrokeForIndex,\n FIELD_MAPPER_PAIR_SLOTS,\n resolveTheme,\n ensureThemeInjected,\n buildThemeCss,\n wrapInThemeLayer,\n DEFAULT_THEME_CSS,\n STRUCTURAL_THEME_CSS,\n PAINT_THEME_CSS,\n THEME_STYLE_ID,\n resetThemeInjectionForTests,\n type FieldMapperTheme,\n type ResolvedFieldMapperTheme,\n} from './fieldMapperTheme'\n\nexport {\n slotClass,\n resolveSlots,\n showRowPreview,\n showJsonPreview,\n SLOT_BASE_CLASS,\n type FieldMapperSlot,\n type FieldMapperSlots,\n type ResolvedFieldMapperSlots,\n type FieldMapperComponents,\n type ResolvedFieldMapperComponents,\n type FieldMapperSelectProps,\n type FieldMapperButtonProps,\n type FieldMapperPillProps,\n} from './fieldMapperSlots'\n\nexport type { FieldMapperLayout, FieldMapperRowKey, FieldMapperDefaultRows }\n\nexport type FieldMapperProps = {\n /**\n * Source nodes to display. For `layout=\"rows\"` (default), pass origin\n * sources — transforms are chosen per row. For deprecated `layout=\"wires\"`,\n * pass `buildResolvedSourceNodes(sources)` to show extract/file candidates.\n */\n sources: SourceNode[]\n targets: TargetProperty[]\n mappings: FieldMapping[]\n onChange: (mappings: FieldMapping[]) => void\n /**\n * String → seed uid dictionaries for `resolve: 'lookup'` edges.\n * Host should persist alongside `MappingDocument.lookups`.\n */\n /**\n * @deprecated Prefer `FieldMapping.lookup.entries` + `renderLookup`.\n * Still accepted as a read fallback for preview / LookupEditor.\n */\n lookups?: MappingLookups\n /**\n * @deprecated Prefer `renderLookup`. Enables the package uid editor fallback.\n */\n onLookupsChange?: (lookups: MappingLookups) => void\n /** Override default autoMap heuristics. */\n onAutoMap?: () => FieldMapping[]\n className?: string\n /**\n * `default` injects structural + paint CSS.\n * `structural` injects layout/spacing only.\n * `none` skips injection (host styles structural classes / CSS vars).\n * `@deprecated` Prefer `none` — `unstyled` is a shim for `none`.\n */\n theme?: FieldMapperTheme\n /**\n * Optional connector stroke colors (wires layout). When omitted, strokes use\n * `var(--fm-map-N, var(--map-N, currentColor))` for N = 1…8.\n * @deprecated Prefer CSS `--sfm-map-*` / `--fm-map-*` / `--map-*` tokens.\n */\n connectionColors?: string[]\n /**\n * Show JSON preview. Default true.\n * @deprecated Prefer `slots.preview` (`'row' | 'json' | 'both' | false`).\n */\n showPreview?: boolean\n /**\n * Authoring surface. Defaults to `'rows'`.\n * `@deprecated` Prefer `'rows'` — `'wires'` remains supported for one minor.\n */\n layout?: FieldMapperLayout\n /**\n * Which side opens each row when `layout=\"rows\"`.\n * `'property'` (default) cannot represent an invalid state;\n * `'source'` matches the edge list and surfaces conflicts + coverage banners.\n */\n rowKey?: FieldMapperRowKey\n /** Rows shown before the filter is widened (property mode). */\n defaultRows?: FieldMapperDefaultRows\n /** Per-slot class injection; merged with package classes, never replacing them. */\n classNames?: Partial<Record<FieldMapperSlot, string>>\n /** Host design-system controls. Defaults are dependency-free natives. */\n components?: FieldMapperComponents\n /** Include / exclude structural pieces. Replaces `showPreview`. */\n slots?: FieldMapperSlots\n /**\n * Optional per-row host chrome (e.g. extract/file Preview). Rendered in\n * `.fm-row-accessory` after the transform control and before remove.\n * Return `null` when nothing to show. Package does not fetch or preview.\n */\n renderRowAccessory?: (row: FieldMapperRow) => ReactNode\n /**\n * Host lookup chrome on `resolve: 'lookup'` rows (Identity picker, etc.).\n * When set, the package uid editor is not mounted. Return `null` when idle.\n */\n renderLookup?: (row: FieldMapperLookupRow) => ReactNode\n /**\n * Host expansion under a row (e.g. assemble stack). Return `null` when idle.\n * Independent of `renderLookup` / `renderRowAccessory`.\n */\n renderRowExpansion?: (row: FieldMapperRow) => ReactNode\n /**\n * Override the per-row transform list. Defaults are copy / extract / file /\n * lookup, plus assemble on Html targets, plus the current resolve if missing.\n */\n transformOptions?: FieldMapperTransformOptions\n}\n\n/**\n * Generic field mapper. Props-driven; no Seed hooks or routing.\n * Default layout is rows; pass `layout=\"wires\"` only if you still need the\n * two-pane connector UI (deprecated).\n */\nexport function FieldMapper({\n sources,\n targets,\n mappings,\n onChange,\n lookups = {},\n onLookupsChange,\n onAutoMap,\n className,\n theme = 'default',\n connectionColors,\n showPreview,\n layout = 'rows',\n rowKey = 'property',\n defaultRows = 'requiredAndMapped',\n classNames,\n components,\n slots,\n renderRowAccessory,\n renderLookup,\n renderRowExpansion,\n transformOptions,\n}: FieldMapperProps) {\n const mapper = useFieldMapper({\n sources,\n targets,\n mappings,\n onChange,\n lookups,\n onLookupsChange,\n rowKey: layout === 'rows' ? rowKey : 'property',\n onAutoMap,\n })\n\n const resolvedTheme = resolveTheme(theme)\n const resolvedSlots = useMemo(\n () => resolveSlots(slots, showPreview, { layout }),\n [slots, showPreview, layout],\n )\n\n const ui = useMemo(\n () => ({\n Select: components?.Select ?? DefaultSelect,\n Button: components?.Button ?? DefaultButton,\n Pill: components?.Pill ?? DefaultPill,\n }),\n [components],\n )\n\n useEffect(() => {\n ensureThemeInjected(resolvedTheme)\n }, [resolvedTheme])\n\n const unstyled =\n resolvedTheme === 'none' || theme === 'unstyled' || theme === 'none'\n\n const rootClass = slotClass(\n 'root',\n classNames,\n [\n unstyled ? 'seed-field-mapper--unstyled' : null,\n layout === 'rows' ? 'seed-field-mapper--rows' : 'seed-field-mapper--wires',\n className,\n ]\n .filter(Boolean)\n .join(' ') || null,\n )\n\n return (\n <div\n className={rootClass}\n data-theme={resolvedTheme}\n data-layout={layout}\n data-row-key={layout === 'rows' ? rowKey : undefined}\n >\n {layout === 'wires' ? (\n <FieldMapperWires\n sources={sources}\n targets={targets}\n mappings={mappings}\n mapper={mapper}\n lookups={lookups}\n onLookupsChange={onLookupsChange}\n renderLookup={renderLookup}\n connectionColors={connectionColors}\n slots={resolvedSlots}\n classNames={classNames}\n ui={ui}\n />\n ) : rowKey === 'source' ? (\n <SourceRows\n sources={sources}\n targets={targets}\n mappings={mappings}\n mapper={mapper}\n lookups={lookups}\n onLookupsChange={onLookupsChange}\n slots={resolvedSlots}\n classNames={classNames}\n ui={ui}\n renderRowAccessory={renderRowAccessory}\n renderLookup={renderLookup}\n renderRowExpansion={renderRowExpansion}\n transformOptions={transformOptions}\n />\n ) : (\n <PropertyRows\n sources={sources}\n targets={targets}\n mappings={mappings}\n mapper={mapper}\n defaultRows={defaultRows}\n lookups={lookups}\n onLookupsChange={onLookupsChange}\n slots={resolvedSlots}\n classNames={classNames}\n ui={ui}\n renderRowAccessory={renderRowAccessory}\n renderLookup={renderLookup}\n renderRowExpansion={renderRowExpansion}\n transformOptions={transformOptions}\n />\n )}\n </div>\n )\n}\n\nexport default FieldMapper\n"],"mappings":"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"}