44 lines
2.7 KiB
JavaScript
44 lines
2.7 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
const root=process.cwd()
|
|
const base=path.join(root,'apps/web/fe-reference')
|
|
const required=['index.html','kbx-fe.css','kbx-fe.js','README.md']
|
|
const errors=[]
|
|
for(const file of required){if(!fs.existsSync(path.join(base,file)))errors.push(`missing ${file}`)}
|
|
|
|
if(!errors.length){
|
|
const html=fs.readFileSync(path.join(base,'index.html'),'utf8')
|
|
const css=fs.readFileSync(path.join(base,'kbx-fe.css'),'utf8')
|
|
const js=fs.readFileSync(path.join(base,'kbx-fe.js'),'utf8')
|
|
|
|
for(const token of ['global-header','side-nav','workspaceTabs','menuSearchDialog','lookupDialog','unsavedDialog','quantityDialog','exceptionDialog','drawerBackdrop','Content-Security-Policy']){
|
|
if(!html.includes(token))errors.push(`html missing ${token}`)
|
|
}
|
|
for(const token of ['--header-h:56px','--nav-w:220px','--nav-collapsed:56px','--control-h:34px','.wms-phone','.data-state','.confirm-dialog','.cell-editor','.scan-box.scan-error','.validation-summary','.action-result']){
|
|
if(!css.includes(token))errors.push(`css missing ${token}`)
|
|
}
|
|
for(const template of ['T01','T02','T03','T04','T05','T06','T07','T08','T09']){
|
|
if(!js.includes(template))errors.push(`js missing ${template}`)
|
|
}
|
|
for(const behavior of ['requestCloseTab','pendingNavigationId','openLookup','bindLookups','showUtilityPanel','applyIntent','orderQuickFilter','orderDataState','fastRows','inventoryItemId','queueFilter','mismatchOnly','importStep','importJobStatus','startImportJob','applyScan','lastScanValue','networkStatus','selectedOrders','toggleFavorite','orderSearch','captureOrderSearch','masterDraft','validateMasterDraft','transactionHeader','validateTransaction','selectedQueueRows','selectedReconcileRows','trySaveDirtyScreen','beforeunload']){
|
|
if(!js.includes(behavior))errors.push(`js missing behavior ${behavior}`)
|
|
}
|
|
for(const security of ["const esc =",'knownIds','try{ localStorage.setItem','localStorage.getItem']){
|
|
if(!js.includes(security))errors.push(`security/stability contract missing ${security}`)
|
|
}
|
|
for(const forbidden of ['prompt(','eval(','document.write(']){
|
|
if(js.includes(forbidden))errors.push(`forbidden FE pattern ${forbidden}`)
|
|
}
|
|
if(!js.includes("selection===0"))errors.push('selection-dependent command disabling missing')
|
|
if(!js.includes("e.key==='Enter'"))errors.push('keyboard Enter flow missing')
|
|
if(!js.includes("e.key==='Escape'"))errors.push('Escape recovery flow missing')
|
|
}
|
|
|
|
if(errors.length){
|
|
console.error('FE reference validation failed')
|
|
for(const error of errors)console.error(`- ${error}`)
|
|
process.exit(1)
|
|
}
|
|
console.log('FE reference validation passed: v44 completion loops + themed state/recovery + non-modal runtime center + secure shell + async import + WMS guards')
|