import type { Component } from 'vue' import type { UiAdapter, UiAdapterCapability } from './contracts' export interface UiAdapterCompatibilityIssue { code: 'CONTRACT_VERSION' | 'MISSING_CAPABILITY' | 'MISSING_COMPONENT' | 'PRODUCTION_INELIGIBLE' severity: 'ERROR' | 'WARNING' detail: string } export interface UiAdapterCompatibilityReport { adapterId: string contractVersion: string compatible: boolean issues: readonly UiAdapterCompatibilityIssue[] } const componentByCapability: Readonly> = { 'button': 'Button', 'text-field': 'TextField', 'text-area': 'TextArea', 'select': 'Select', 'multi-select': 'MultiSelect', 'checkbox': 'Checkbox', 'date-field': 'DateField', 'number-field': 'NumberField', 'dialog': 'Dialog', 'status-tag': 'StatusTag', 'inline-message': 'InlineMessage', 'paginator': 'Paginator', 'tabs': 'Tabs', 'data-grid': 'DataGrid' } export function evaluateUiAdapterCompatibility( adapter: UiAdapter, requiredCapabilities: readonly UiAdapterCapability[], requireProductionEligible = false ): UiAdapterCompatibilityReport { const issues: UiAdapterCompatibilityIssue[] = [] if (adapter.descriptor.contractVersion !== '4.0') { issues.push({ code: 'CONTRACT_VERSION', severity: 'ERROR', detail: `Expected 4.0, got ${adapter.descriptor.contractVersion}` }) } for (const capability of requiredCapabilities) { if (!adapter.descriptor.capabilities.has(capability)) { issues.push({ code: 'MISSING_CAPABILITY', severity: 'ERROR', detail: capability }) continue } const component = adapter.components[componentByCapability[capability]] as Component | undefined if (!component) issues.push({ code: 'MISSING_COMPONENT', severity: 'ERROR', detail: capability }) } if (requireProductionEligible && !adapter.descriptor.productionEligible) { issues.push({ code: 'PRODUCTION_INELIGIBLE', severity: 'ERROR', detail: adapter.descriptor.id }) } return { adapterId: adapter.descriptor.id, contractVersion: adapter.descriptor.contractVersion, compatible: !issues.some(x => x.severity === 'ERROR'), issues } } export function assertUiAdapterCompatibility(report: UiAdapterCompatibilityReport): void { if (!report.compatible) throw new Error(`UI adapter ${report.adapterId} is incompatible: ${report.issues.map(x => `${x.code}:${x.detail}`).join(', ')}`) }