@drangis-tech/file-writer
Version:
TSX file writer utility using ts-morph
89 lines • 2.87 kB
JavaScript
// 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