import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import ts from '../../web/node_modules/typescript/lib/typescript.js'; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); const file = 'web/app/src/app/App.tsx'; const labels = process.argv.slice(2); if (!labels.length || labels.length > 8 || labels.some(label => label.length > 100)) { throw new Error('Provide one to eight exact workflow aria-labels'); } const tree = ts.createSourceFile(file, fs.readFileSync(path.join(root, file), 'utf8'), ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX); const results = []; function inspect(node) { if (ts.isJsxElement(node)) { const attribute = node.openingElement.attributes.properties.find(item => ts.isJsxAttribute(item) && item.name.text === 'aria-label' && item.initializer && ts.isStringLiteral(item.initializer) && labels.includes(item.initializer.text)); if (attribute) { const record = { workflow: attribute.initializer.text, file, line: tree.getLineAndCharacterOfPosition(node.getStart(tree)).line + 1, controls: [], buttons: [] }; function visit(child) { if (ts.isJsxAttribute(child) && ['aria-label', 'data-testid'].includes(child.name.text) && child.initializer && ts.isStringLiteral(child.initializer)) { record.controls.push({ attribute: child.name.text, value: child.initializer.text }); } if (ts.isJsxElement(child) && ts.isIdentifier(child.openingElement.tagName) && child.openingElement.tagName.text === 'button') { record.buttons.push(child.children.filter(ts.isJsxText).map(text => text.text.trim()).filter(Boolean).join(' ')); } ts.forEachChild(child, visit); } visit(node); results.push(record); } } ts.forEachChild(node, inspect); } inspect(tree); console.log(JSON.stringify({ results, missing: labels.filter(label => !results.some(result => result.workflow === label)) }));