Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/scripts/validate-interaction-contracts.mjs
T

47 lines
3.3 KiB
JavaScript

import fs from 'node:fs'
const failures=[]
const read=p=>fs.readFileSync(p,'utf8')
const ui=read('packages/kbx-contracts/src/ui.ts')
for(const token of ["'changed'","'warning'","'ai-suggested'","'application'","'page'","'grid'","'dialog'","'editor'"])if(!ui.includes(token))failures.push(`ui interaction contract missing ${token}`)
const stateful=[
'KbxInput.vue','KbxNumberField.vue','KbxDateField.vue','KbxDateRange.vue','KbxSelect.vue','KbxTextarea.vue','KbxLookup.vue','KbxCheckbox.vue','KbxRadio.vue','KbxTextField.vue','KbxBarcodeField.vue','KbxMoneyField.vue','KbxQuantityField.vue',
]
for(const file of stateful){
const text=read(`packages/kbx-ui/src/components/${file}`)
if(!text.includes('KbxFieldState'))failures.push(`${file} must consume KbxFieldState`)
}
const searchContract=read('packages/kbx-contracts/src/search.ts')
if(!searchContract.includes("'checkbox'"))failures.push('KbxSearchFieldType must include checkbox')
const search=read('packages/kbx-ui/src/components/KbxSearchPanel.vue')
for(const token of ['rememberChecked','savedSearchRequested',"field.type==='checkbox'",'field.defaultValue'])if(!search.includes(token))failures.push(`KbxSearchPanel missing ${token}`)
const grid=read('packages/kbx-ui/src/components/KbxDataGrid.vue')
for(const token of ['KbxDataState','changedCells','personalization','savedPreference','preferenceChanged','exportable','emptyText','errorText','savePreference','KbxSummaryBar'])if(!grid.includes(token))failures.push(`KbxDataGrid missing ${token}`)
const keyboard=read('packages/kbx-ui/src/keyboard/manager.ts')
for(const token of ['scopeRank','protectedBrowserShortcuts','F5','CTRL+L','CTRL+T','CTRL+W','CTRL+R','registerKbxShortcuts'])if(!keyboard.includes(token))failures.push(`keyboard manager missing ${token}`)
const composable=read('packages/kbx-ui/src/composables/useKbxShortcuts.ts')
if(!composable.includes('registerKbxShortcuts'))failures.push('useKbxShortcuts must delegate to central keyboard manager')
for(const file of ['apps/web/src/shell/KbxAppFrame.vue','packages/kbx-ui/src/components/KbxExceptionDetailDrawer.vue']){
if(read(file).includes("addEventListener('keydown'"))failures.push(`${file} bypasses central keyboard manager`)
}
const tabs=read('packages/kbx-ui/src/components/KbxTabs.vue')
for(const token of ['ArrowRight','ArrowLeft','Home','End','aria-controls','tabpanel'])if(!tabs.includes(token))failures.push(`KbxTabs missing ${token}`)
const index=read('packages/kbx-ui/src/index.ts')
if(!index.includes('KbxDataState'))failures.push('public API missing KbxDataState')
const manifest=read('packages/kbx-ui/src/registry/componentManifest.ts')
if(!manifest.includes("name: 'KbxDataState'"))failures.push('component manifest missing KbxDataState')
const catalog=read('packages/kbx-ui/src/catalog/componentCatalog.ts')
if(!catalog.includes("component:'KbxDataState'"))failures.push('component catalog missing KbxDataState')
for(const state of ["state:'changed'","state:'warning'","state:'ai-suggested'","state:'empty'"])if(!catalog.includes(state))failures.push(`component catalog missing ${state}`)
if(failures.length){console.error('KBX interaction contract validation failed:\n- '+failures.join('\n- '));process.exit(1)}
console.log(`Interaction contracts PASS: ${stateful.length} stateful inputs, SearchPanel, DataGrid runtime states, scoped keyboard manager, accessible Tabs.`)