Files
ycode/scripts/rea/recover-project-icon.cjs
T

25 lines
1.7 KiB
JavaScript

const fs = require('node:fs')
const assert = require('node:assert/strict')
const evidence = JSON.parse(fs.readFileSync('.tmp/rea-todo20-project-page.json', 'utf8').replace(/^\uFEFF/, ''))
assert.equal(evidence.evidence_id, 'ev_89843a8b67f411d3297b5f3e428830393cd0fe8712603816cf8b7bbe442064d9')
const document = evidence.normalized_result.visuals.layout.documents[0]
const parent = document.nodes.find(node => node.attributes.class === 'landing-template-icon')
const svg = document.svg_nodes.find(node => node.parent_index === parent.node_index)
assert.equal(svg.node_name, 'svg')
const names = { 'clip-path': 'clipPath', 'fill-rule': 'fillRule', 'class': 'className' }
function jsx(node) {
assert.ok(['svg', 'clipPath', 'path', 'g'].includes(node.node_name))
const attrs = Object.entries(node.attributes).map(([key, value]) => {
if (key === 'id') return 'id={clipId}'
if (key === 'clip-path') return 'clipPath={`url(#${clipId})`}'
return `${names[key] || key}=${JSON.stringify(value)}`
}).join(' ')
const children = document.svg_nodes.filter(child => child.parent_index === node.node_index).map(jsx).join('')
return `<${node.node_name} ${attrs}>${children}</${node.node_name}>`
}
const output = `// WorkBuddy 5.8.3, REA ${evidence.evidence_id}; literal SVG recovery.\nimport { useId } from 'react'\nexport default function ProjectIcon(): React.JSX.Element {\nconst clipId = useId()\nreturn ${jsx(svg)}\n}\n`
const destination = 'src/renderer/src/projects/ProjectIcon.tsx'
if (process.argv.includes('--check')) assert.equal(fs.readFileSync(destination, 'utf8'), output)
else fs.writeFileSync(destination, output)
console.log('PASS project SVG recovery, per-instance clip ID')