import type { ControlComponentBinding, ControlComponentBindingConfig, ControlComponentBindingRecordConfig, ControlComponentBindingsById, ControlComponentBindingsConfig, ControlComponentPropsMap, ControlComponentPropSource, } from './controlSchemaTypes' /** Map control workspace values into component props for direct `v-bind` usage. */ export function controlValuesToComponentProps>( values: TValues, mapping?: ControlComponentPropsMap, ): Record { if (mapping === undefined) return { ...values } if (Array.isArray(mapping)) { const props: Record = {} for (const key of mapping) { props[key] = values[key] } return props } const props: Record = {} for (const [prop, source] of Object.entries(mapping) as Array<[string, ControlComponentPropSource]>) { props[prop] = typeof source === 'function' ? source(values) : values[source] } return props } /** Map control workspace values into named SDK component bindings for direct slot rendering. */ export function controlValuesToComponentBindings>( values: TValues, bindings?: ControlComponentBindingsConfig, ): ControlComponentBinding[] { if (bindings === undefined) return [] return normalizeControlComponentBindingConfigs(bindings).map(binding => ({ id: binding.id, component: binding.component, props: controlValuesToComponentProps(values, binding.props), })) } /** Map control workspace values into SDK component bindings keyed by binding id. */ export function controlValuesToComponentBindingsById>( values: TValues, bindings?: ControlComponentBindingsConfig, ): ControlComponentBindingsById { return Object.fromEntries( controlValuesToComponentBindings(values, bindings).map(binding => [binding.id, binding]), ) } function normalizeControlComponentBindingConfigs>( bindings: ControlComponentBindingsConfig, ): Array, 'id' | 'component'>> & Pick, 'props'>> { if (Array.isArray(bindings)) { const usedIds = new Map() return bindings.map(binding => ({ id: uniqueComponentBindingId(binding.id ?? binding.component, usedIds), component: binding.component, props: binding.props, })) } return Object.entries(bindings).map(([id, binding]: [string, ControlComponentBindingRecordConfig]) => ({ id, component: binding.component, props: binding.props, })) } function uniqueComponentBindingId(id: string, usedIds: Map): string { const count = usedIds.get(id) ?? 0 usedIds.set(id, count + 1) return count === 0 ? id : `${id}-${count + 1}` }