Files
KArtSell.Aegis/frontend/src/shared/ui/adapter/compatibility.ts
T
kjh2064 dcd1322d41
ci / backend (push) Failing after 12s
ci / frontend (push) Failing after 19s
ci / static (push) Failing after 45s
Initial commit: Add project files
2026-08-02 05:15:36 +09:00

50 lines
2.3 KiB
TypeScript

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<Record<UiAdapterCapability, keyof UiAdapter['components']>> = {
'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(', ')}`)
}