UNPKG

@drangis-tech/file-writer

Version:

TSX file writer utility using ts-morph

89 lines 2.87 kB
// src/writer.ts import { Project, SyntaxKind } from "ts-morph"; var FileWriter = class { constructor() { this.project = new Project({ skipFileDependencyResolution: true }); } /** * Apply a change to a TSX file based on the design map. */ async applyChange(change, designMap, projectRoot) { const entry = designMap[change.id]; if (!entry) { throw new Error(`No mapping found for id: ${change.id}`); } const filePath = `${projectRoot}/${entry.file}`; const sourceFile = this.project.addSourceFileAtPath(filePath); const jsxElements = sourceFile.getDescendantsOfKind( SyntaxKind.JsxSelfClosingElement ); const jsxOpeningElements = sourceFile.getDescendantsOfKind( SyntaxKind.JsxOpeningElement ); let targetElement = null; for (const el of jsxElements) { const attr = el.getAttribute("data-edit-id"); if (attr && attr.getText().includes(`"${change.id}"`)) { targetElement = el; break; } } if (!targetElement) { for (const el of jsxOpeningElements) { const attr = el.getAttribute("data-edit-id"); if (attr && attr.getText().includes(`"${change.id}"`)) { targetElement = el; break; } } } if (!targetElement) { throw new Error( `Could not find JSX element with data-edit-id="${change.id}" in ${entry.file}` ); } if (change.kind === "text") { const parent = targetElement.getParent(); if (parent && parent.getKind() === SyntaxKind.JsxElement) { const jsxElement = parent; const children = jsxElement.getJsxChildren(); const textNode = children.find( (child) => child.getKind() === SyntaxKind.JsxText ); if (textNode) { textNode.replaceWithText(change.value); } else { const openingElement = jsxElement.getOpeningElement(); openingElement.insertText(openingElement.getEnd(), change.value); } } else { throw new Error( `Element with data-edit-id="${change.id}" is self-closing and cannot contain text. Please use a non-self-closing element.` ); } } else if (change.kind === "classes") { let classNameAttr = targetElement.getAttribute("className"); if (classNameAttr) { const initializer = classNameAttr.getInitializer(); if (initializer) { initializer.replaceWithText(`"${change.value}"`); } else { classNameAttr.setInitializer(`"${change.value}"`); } } else { targetElement.addAttribute({ name: "className", initializer: `"${change.value}"` }); } } await sourceFile.save(); this.project.removeSourceFile(sourceFile); } }; export { FileWriter }; //# sourceMappingURL=index.mjs.map