@johnlindquist/file-forge
Version:
File Forge is a powerful CLI tool for deep analysis of codebases, generating markdown reports to feed AI reasoning models.
105 lines • 3.67 kB
JavaScript
// src/utils.ts
import { promises as fsPromises, readFileSync, accessSync } from "node:fs";
import { createHash } from "node:crypto";
import * as path from "node:path";
import { parse } from "jsonc-parser";
/** Asynchronously check if a file/directory exists */
export async function fileExists(path) {
try {
await fsPromises.access(path);
return true;
}
catch {
return false;
}
}
/** Parse comma‑separated and repeated patterns into an array */
export function parsePatterns(input) {
if (!input || input.length === 0)
return [];
const splitted = [];
for (const val of input) {
const strVal = String(val);
if (strVal.includes(",")) {
splitted.push(...strVal
.split(",")
.map((s) => s.trim())
.filter(Boolean));
}
else {
splitted.push(strVal.trim());
}
}
return splitted.filter(Boolean);
}
/** Get a hashed version of a source string */
export function getHashedSource(source) {
return createHash("md5").update(String(source)).digest("hex").slice(0, 6);
}
/** Load ffg.config.jsonc or ffg.config.json from the cwd */
export function loadFfgConfig(cwd) {
// Check for test environment variable first
if (process.env["FFG_TEST_CONFIG"]) {
try {
return JSON.parse(process.env["FFG_TEST_CONFIG"]);
}
catch (error) {
console.warn(`Warning: Could not parse FFG_TEST_CONFIG: ${error instanceof Error ? error.message : String(error)}`);
// Continue to file-based loading if parsing fails
}
}
const jsoncPath = path.join(cwd, "ffg.config.jsonc");
const jsonPath = path.join(cwd, "ffg.config.json");
let configContent = null;
let configPath = "";
try {
if (fileExistsSync(jsoncPath)) {
configContent = readFileSync(jsoncPath, "utf8");
configPath = jsoncPath;
}
else if (fileExistsSync(jsonPath)) {
configContent = readFileSync(jsonPath, "utf8");
configPath = jsonPath;
}
}
catch (error) {
console.warn(`Warning: Could not read config file at ${configPath || 'ffg.config.json(c)'}: ${error instanceof Error ? error.message : String(error)}`);
return null;
}
if (!configContent)
return null;
try {
// Use jsonc-parser to handle comments
return parse(configContent);
}
catch (error) {
console.error(`Error parsing config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
return null;
}
}
// Helper sync function to check file existence (used only within loadFfgConfig)
function fileExistsSync(filePath) {
try {
accessSync(filePath);
return true;
}
catch {
return false;
}
}
/** Writes the FfgConfig object to ffg.config.jsonc in the specified directory */
export async function writeFfgConfig(configData, cwd) {
const configPath = path.join(cwd, "ffg.config.jsonc"); // Always write to .jsonc
try {
const configString = JSON.stringify(configData, null, 2); // Pretty print JSON
await fsPromises.writeFile(configPath, configString, "utf8");
if (process.env['DEBUG']) { // Use DEBUG env var check
console.log(`[DEBUG] Successfully wrote config to ${configPath}`);
}
}
catch (error) {
console.error(`Error writing config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
throw error; // Re-throw to indicate failure
}
}
//# sourceMappingURL=utils.js.map