import { readFile, readdir } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import { join } from "node:path"; import type { RuleSetId } from "./detect-project.js"; export const ECC_COMMIT = "623f2c020f052319657674e4e6c29ab5d0ad566b"; export const ECC_REPOSITORY_URL = "https://github.com/affaan-m/ECC"; export type RuleSource = "ecc" | "pi"; export interface RuleDocument { ruleSet: RuleSetId; relativePath: string; content: string; source: RuleSource; } const ECC_RULES_DIRECTORY = fileURLToPath(new URL("../rules/ecc/", import.meta.url)); const PI_RULES_DIRECTORY = fileURLToPath(new URL("../rules/pi/", import.meta.url)); async function readRuleContent( ruleSet: RuleSetId, filename: string, ): Promise<{ content: string; source: RuleSource }> { try { return { content: await readFile(join(PI_RULES_DIRECTORY, ruleSet, filename), "utf8"), source: "pi", }; } catch (error: unknown) { if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error; } return { content: await readFile(join(ECC_RULES_DIRECTORY, ruleSet, filename), "utf8"), source: "ecc", }; } export async function loadRuleDocuments(ruleSets: readonly RuleSetId[]): Promise { const documents: RuleDocument[] = []; for (const ruleSet of ruleSets) { const directory = join(ECC_RULES_DIRECTORY, ruleSet); const filenames = (await readdir(directory, { withFileTypes: true })) .filter((entry) => entry.isFile() && entry.name.endsWith(".md")) .map((entry) => entry.name) .sort((left, right) => left.localeCompare(right)); const loadedRules = await Promise.all( filenames.map((filename) => readRuleContent(ruleSet, filename)), ); documents.push( ...filenames.map((filename, index) => ({ ruleSet, relativePath: `${ruleSet}/${filename}`, content: loadedRules[index]?.content ?? "", source: loadedRules[index]?.source ?? "ecc", })), ); } return documents; }