import fs from 'node:fs' import path from 'node:path' const root = process.cwd() const sourceRoot = path.join(root, 'apps/web/src/modules') const out = path.join(root, 'generated/screen-manifest.json') function files(dir) { return fs.readdirSync(dir, { withFileTypes: true }).flatMap(entry => { const full = path.join(dir, entry.name) return entry.isDirectory() ? files(full) : [full] }) } const definitions = files(sourceRoot).filter(f => /definition\.ts$/.test(f)) const screens = [] for (const file of definitions) { const text = fs.readFileSync(file, 'utf8') const start = text.search(/defineKbxScreen\s*\(/) if (start < 0) continue const block = text.slice(start) const get = key => block.match(new RegExp(`\\b${key}:\\s*['\"]([^'\"]+)['\"]`))?.[1] const id = get('id') if (!id) continue const permissionsRaw = block.match(/permissions:\s*\[([^\]]*)\]/)?.[1] ?? '' const requiredPermissions = [...permissionsRaw.matchAll(/['"]([^'"]+)['"]/g)].map(m => m[1]) screens.push({ id, version: get('version') ?? 'unknown', module: get('module') ?? 'unknown', type: get('type') ?? 'unknown', templateCode: get('templateCode') ?? null, title: get('title') ?? id, helpKey: get('helpKey') ?? null, requiredPermissions, source: path.relative(root, file).replaceAll('\\\\','/'), }) } screens.sort((a,b) => a.id.localeCompare(b.id)) fs.mkdirSync(path.dirname(out), { recursive: true }) fs.writeFileSync(out, JSON.stringify(screens, null, 2) + '\n') console.log(`generated ${screens.length} screen definitions -> ${path.relative(root,out)}`)