25 lines
1.7 KiB
JavaScript
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')
|