rollup-plugin-caveman
Version:
Converts Caveman templates to ES6 modules
107 lines (104 loc) • 3.23 kB
JavaScript
// index.ts
import camelCase from "lodash.camelcase";
import cavemanLib from "caveman";
import { access, readFile } from "fs/promises";
import { createFilter } from "@rollup/pluginutils";
import { dirname, extname, join } from "path";
function toES6Module(content) {
return `
import Caveman from "caveman"
export function render(d = {}) {
${content}
}
export default { render };
`;
}
async function getValidPath(path) {
await access(path);
return path;
}
function getPartialPath(fileName, paths) {
return Promise.any(paths.map((path) => getValidPath(join(path, fileName))));
}
function caveman({
include = "**/*.html?caveman",
exclude,
partialPaths = []
} = {}) {
const filter = createFilter(include, exclude);
const postfixRE = /[?#].*$/s;
const partialNameMap = /* @__PURE__ */ new Map();
const partialPathCache = /* @__PURE__ */ new Map();
return {
name: "caveman",
async resolveId(id, importer) {
const extension = extname(id);
if (!extension.includes(".html"))
return null;
const postfix = id.match(postfixRE)?.[0] ?? "";
const filePath = id.replace(postfixRE, "");
const result = await this.resolve(filePath, importer);
if (!result)
return result;
return result.id + postfix;
},
async load(id) {
const filePath = id.replace(postfixRE, "");
const extension = extname(filePath);
if (extension !== ".html" || !filter(id))
return;
const code = await readFile(filePath, "utf8");
let compiled = toES6Module(cavemanLib.compile(code));
const hasPartials = /\b_Cr\('/.test(compiled);
if (!hasPartials) {
return {
code: compiled,
map: { mappings: "" }
};
}
compiled = compiled.replace(
/\b_Cr\('([^']+)',/g,
(match, partialName) => {
if (!partialName)
return match;
const importName = camelCase(partialName);
partialNameMap.set(partialName, importName);
return `${importName}.render(`;
}
);
const postfix = id.match(postfixRE)?.[0] ?? "";
const partialLookupPaths = [
dirname(filePath),
// Always look for partials in the same directory as the template
...partialPaths
];
let partialImports = [];
try {
partialImports = await Promise.all(
Array.from(partialNameMap, async ([partialName, importName]) => {
let partialPath = partialPathCache.get(partialName);
if (!partialPath) {
partialPath = await getPartialPath(
partialName + extension,
partialLookupPaths
);
partialPathCache.set(partialName, partialPath);
}
return `import ${importName} from "${partialPath}${postfix}"`;
})
);
} catch (e) {
this.error({ message: "Unable to find caveman partial", cause: e });
}
const importBlock = partialImports.join("\n\n");
let output = importBlock + "\n\n" + compiled;
return {
code: output,
map: { mappings: "" }
};
}
};
}
export {
caveman as default
};