UNPKG

embedded-typescript

Version:
98 lines (96 loc) 3.58 kB
import { format } from "prettier"; import { trimLeadingIndentation, getLeadingIndentation, trimLaggingNewline, sanitizeString, removeFinalNewline, } from "./utils/index.js"; import { parse, isParseError } from "../parser/index.js"; const RESULT = "result"; function compile(nodes) { let compiled = ""; let indent = ""; let hasPreserveIndentation = false; function write(text) { compiled += indent + text; } nodes.forEach((node, idx) => { const prevNode = nodes[idx - 1]; const nextNode = nodes[idx + 1]; switch (node.type) { case "header": { const props = /(interface|type) Props/.test(node.content) ? "Props" : "unknown"; write(`${node.content}\n\n`); write(`export default function (props: ${props}): string {\n`); indent += " "; write(`let ${RESULT} = '';\n`); break; } case "text": { let content = node.content; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (prevNode?.type === "statement" || prevNode?.type === "header") { content = trimLaggingNewline(content); } // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (nextNode?.type === "statement") { content = trimLeadingIndentation(content); } // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!nextNode) { content = removeFinalNewline(content); } if (content) { write(`${RESULT} += '${sanitizeString(content)}';\n`); } break; } case "expression": { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const indentation = getLeadingIndentation(prevNode.content ?? ""); if (!indentation) { write(`${RESULT} += ${node.content};\n`); } else { hasPreserveIndentation = true; write(`${RESULT} += preserveIndentation(${node.content}, '${indentation}');\n`); } break; } case "statement": { write(`${node.content}\n`); break; } default: { const exhaust = node.type; return exhaust; } } }); write(`return ${RESULT};\n`); indent = ""; write(`}\n`); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (hasPreserveIndentation) { write(`\nfunction preserveIndentation(text: string, indentation: string): string { return text .split("\\n") .map((line, idx) => (idx === 0 ? line : indentation + line)) .join("\\n"); }`); } return compiled; } export function compiler(template, templatePath) { const parsed = parse(template); if (isParseError(parsed)) { return parsed; } const heading = `/* * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * * Run \`npx ets\` or \`yarn ets\` to regenerate this file. * Source: ${templatePath} */ /* eslint-disable */ `; const file = heading + compile(parsed); return format(file, { parser: "typescript" }); }