#!/usr/bin/env node import fs from "fs"; import path from "path"; import indentString from "indent-string"; import chokidar from "chokidar"; import chalk from "chalk"; import { Command } from "commander"; import glob from "glob"; const processFile = (fileName, seen = []) => { const normalizedFileName = path.resolve(fileName); if (seen.includes(normalizedFileName)) { throw new Error(`Recursive dependency for file ${fileName}`); } const fileContents = fs.readFileSync(fileName, "utf-8"); if (!fileName.endsWith(".squiggleU")) { return fileContents; } const regex = /\@import\(\s*([^)]+?)\s*\)/g; const matches = Array.from(fileContents.matchAll(regex)).map((r) => r[1].split(/\s*,\s*/) ); const newContent = fileContents.replaceAll(regex, ""); const appendings = []; matches.forEach((r) => { const importFileName = r[0]; const rename = r[1]; const item = fs.statSync(importFileName); if (item.isFile()) { const data = processFile(importFileName, [...seen, normalizedFileName]); if (data) { const importString = `${rename} = {\n${indentString(data, 2)}\n}\n`; appendings.push(importString); } } else { console.log( chalk.red(`Import Error`) + `: ` + chalk.cyan(importFileName) + ` not found in file ` + chalk.cyan(fileName) + `. Make sure the @import file names all exist in this repo.` ); } }); const imports = appendings.join("\n"); const newerContent = imports.concat(newContent); return newerContent; }; const run = (fileName) => { const content = processFile(fileName); const parsedPath = path.parse(path.resolve(fileName)); const newFilename = `${parsedPath.dir}/${parsedPath.name}.squiggle`; fs.writeFileSync(newFilename, content); console.log(chalk.cyan(`Updated ${fileName} -> ${newFilename}`)); }; const compile = () => { glob("**/*.squiggleU", (_err, files) => { files.forEach(run); }); }; const watch = () => { chokidar .watch("**.squiggleU") .on("ready", () => console.log(chalk.green("Ready!"))) .on("change", (event, _) => { run(event); }); }; const program = new Command(); program .name("squiggle-utils") .description("CLI to transform squiggle files with @imports") .version("0.0.1"); program .command("watch") .description("watch files and compile on the fly") .action(watch); program .command("compile") .description("compile all .squiggleU files into .squiggle files") .action(compile); program.parse();