| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import * as fs from "node:fs";
- import * as path from "node:path";
- import nunjucks, { ConfigureOptions } from "nunjucks";
- import { RenderContext } from "./getRenderContext";
- import { deepMerge, sortDependencies } from "./objectHelpers";
- import {
- camelCase,
- kebabCase,
- pascalCase,
- snakeCase,
- titleCase,
- } from "./stringHelpers";
- /**
- * Renders a template folder/file to the provided destination,
- * by recursively copying all files under the source directory,
- * with the following exception:
- * - `_filename` are renamed to `.filename`.
- * - `package.json` files are merged.
- * - `.gitignore` files are concatenated.
- * - `.njk` files are rendered as nunjucks templates
- * and saved without the `.njk` extension.
- */
- export function renderTemplate(ctx: RenderContext, src: string, dest: string) {
- const stats = fs.statSync(src);
- // Recursively render directories.
- if (stats.isDirectory()) {
- // Skip node_module.
- if (path.basename(src) === "node_modules") return;
- // Render its subdirectories and files recursively.
- fs.mkdirSync(dest, { recursive: true });
- for (const file of fs.readdirSync(src)) {
- renderTemplate(ctx, path.resolve(src, file), path.resolve(dest, file));
- }
- return;
- }
- const filename = path.basename(src);
- // Merge package.json files.
- if (filename === "package.json" && fs.existsSync(dest)) {
- const existing = JSON.parse(fs.readFileSync(dest, "utf8"));
- const newPackage = JSON.parse(fs.readFileSync(src, "utf8"));
- const pkg = sortDependencies(deepMerge(existing, newPackage));
- fs.writeFileSync(dest, JSON.stringify(pkg, null, 2) + "\n");
- return;
- }
- // Append to existing .gitignore.
- if (filename === ".gitignore" && fs.existsSync(dest)) {
- const existing = fs.readFileSync(dest, "utf8");
- const newGitignore = fs.readFileSync(src, "utf8");
- fs.writeFileSync(dest, existing + "\n" + newGitignore);
- return;
- }
- // Render nunjucks templates.
- if (filename.endsWith(".njk")) {
- dest = dest.replace(/\.njk$/, "");
- fs.writeFileSync(dest, resolveNunjunksTemplate(src, ctx));
- fs.chmodSync(dest, stats.mode);
- return;
- }
- fs.copyFileSync(src, dest);
- }
- function resolveNunjunksTemplate(
- file: string,
- context?: object,
- options?: ConfigureOptions
- ): string {
- const directory = path.dirname(file);
- const filename = path.basename(file);
- const env = nunjucks.configure(directory, {
- trimBlocks: true,
- autoescape: false,
- ...options,
- });
- env.addFilter("pascalCase", pascalCase);
- env.addFilter("camelCase", camelCase);
- env.addFilter("snakeCase", snakeCase);
- env.addFilter("kebabCase", kebabCase);
- env.addFilter("titleCase", titleCase);
- return env.render(filename, context);
- }
|