buildmd/src/index.ts
2025-06-07 13:13:18 -04:00

68 lines
1.6 KiB
TypeScript

import { Glob } from "bun";
import { buildFile } from "./build";
import { CLIError } from "./error";
import { getOutputFile, isDirectory } from "./file-util";
import { type CLIOptions, USAGE, parseCLIArgs } from "./options";
async function processStdin(options: CLIOptions): Promise<void> {
const outfile = options.outfile ? Bun.file(options.outfile) : Bun.stdout;
const renderedHTML = await buildFile(Bun.stdin, options);
await Bun.write(outfile, renderedHTML);
}
async function processFileAtPath(
filePath: string,
options: CLIOptions,
): Promise<void> {
console.log(`Building ${filePath}...`);
const file = Bun.file(filePath);
// Ensure input files exist
if (!(await file.exists())) {
throw new CLIError(`File ${filePath} does not exist.`);
}
const outfile = await getOutputFile(filePath, options);
const renderedHTML = await buildFile(file, options);
await Bun.write(outfile, renderedHTML);
}
async function main() {
const { options, args } = parseCLIArgs();
if (options.help) {
console.log(USAGE);
return;
}
// stdin mode
if (args.length === 0) {
return processStdin(options);
}
// file mode
for (const inputPath of args) {
const isDir = await isDirectory(inputPath);
if (isDir) {
const dirGlob = new Glob(`${inputPath}/**/*.md`);
for await (const file of dirGlob.scan()) {
await processFileAtPath(file, options);
}
} else {
await processFileAtPath(inputPath, options);
}
}
}
try {
await main();
process.exit(0);
} catch (error) {
if (error instanceof CLIError) {
console.error(error.message);
process.exit(1);
}
throw error;
}