39 lines
3.0 KiB
JavaScript
39 lines
3.0 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
const requiredCore=[
|
|
'KbxButton','KbxInput','KbxNumberField','KbxMoneyField','KbxQuantityField','KbxDateField','KbxDateRange','KbxSelect','KbxLookup',
|
|
'KbxPageHeader','KbxCommandBar','KbxSearchPanel','KbxFormSection','KbxDataGrid','KbxBulkActionBar','KbxStatus',
|
|
'KbxDialog','KbxDrawer','KbxToast','KbxConfirm','KbxExcelMenu','KbxExcelImport','KbxJobProgress','KbxAuditTrail','KbxHelpPanel','KbxAiPanel','KbxProposalPanel',
|
|
'KbxListPage','KbxMasterPage','KbxTransactionPage','KbxMasterDetailPage','KbxQueuePage','KbxReconcilePage','KbxWmsMobilePage',
|
|
]
|
|
const manifest=fs.readFileSync('packages/kbx-ui/src/registry/componentManifest.ts','utf8')
|
|
const index=fs.readFileSync('packages/kbx-ui/src/index.ts','utf8')
|
|
const catalog=JSON.parse(fs.readFileSync('generated/catalog-manifest.json','utf8'))
|
|
const generatedComponents=JSON.parse(fs.readFileSync('generated/component-manifest.json','utf8'))
|
|
const failures=[]
|
|
for(const entry of generatedComponents){ if(!/^\d+\.\d+\.\d+$/.test(entry.version)) failures.push(`invalid component semver ${entry.name}: ${entry.version}`) }
|
|
for(const name of requiredCore){
|
|
if(!manifest.includes(`name: '${name}'`)) failures.push(`component manifest missing ${name}`)
|
|
if(!generatedComponents.some(x=>x.name===name)) failures.push(`generated component manifest missing ${name}`)
|
|
if(!index.includes(`as ${name} }`) && !index.includes(`as ${name} } from`) && !index.includes(`default as ${name}`)) failures.push(`public API missing ${name}`)
|
|
}
|
|
for(const name of ['KbxInput','KbxLookup','KbxDataGrid','KbxCommandBar','KbxExcelImport','KbxWmsMobilePage','KbxApplicationShell']){
|
|
if(!catalog.some(x=>x.component===name)) failures.push(`catalog missing critical component ${name}`)
|
|
}
|
|
const css=fs.readFileSync('packages/kbx-ui/src/tokens/kbx.css','utf8')
|
|
if(!css.includes(':focus-visible')) failures.push('global focus-visible contract missing')
|
|
const uiFiles=[]
|
|
function walk(dir){for(const e of fs.readdirSync(dir,{withFileTypes:true})){const f=path.join(dir,e.name);e.isDirectory()?walk(f):uiFiles.push(f)}}
|
|
walk('packages/kbx-ui/src')
|
|
for(const file of uiFiles.filter(x=>x.endsWith('.vue'))){
|
|
const text=fs.readFileSync(file,'utf8')
|
|
if(/outline\s*:\s*none/i.test(text)) failures.push(`${file}: outline:none is forbidden`)
|
|
}
|
|
const visual=fs.readFileSync('tests/e2e/kbx-component-catalog.visual.spec.ts','utf8')
|
|
for(const d of ['compact','comfortable','touch']) if(!visual.includes(`density:'${d}'`)) failures.push(`visual regression missing ${d} density`)
|
|
const keyboard=fs.readFileSync('tests/e2e/kbx-keyboard-regression.spec.ts','utf8')
|
|
for(const key of ['F2','F3','F8','Tab','Shift+Tab','Enter','Escape']) if(!keyboard.includes(`'${key}'`) && !keyboard.includes(`('${key}')`)) failures.push(`keyboard regression missing ${key}`)
|
|
if(failures.length){console.error('KBX component catalog validation failed:\n- '+failures.join('\n- '));process.exit(1)}
|
|
console.log(`KBX component catalog validation passed: ${requiredCore.length} core APIs, ${catalog.length} catalog entries.`)
|