markdown-code
Version:
Keep code examples in Markdown synchronized with actual source files
155 lines (150 loc) • 4.22 kB
JavaScript
// src/config.ts
import { readFile } from "fs/promises";
import { resolve } from "path";
// src/utils.ts
import { access } from "fs/promises";
async function fileExists(path) {
try {
await access(path);
return true;
} catch {
return false;
}
}
// src/config.ts
var DEFAULT_CONFIG = {
snippetRoot: ".",
markdownGlob: "**/*.md",
excludeGlob: [
"node_modules/**",
".git/**",
"dist/**",
"build/**",
"coverage/**",
".next/**",
".nuxt/**",
"out/**",
"target/**",
"vendor/**"
],
includeExtensions: [
".ts",
".js",
".py",
".java",
".cpp",
".c",
".go",
".rs",
".php",
".rb",
".swift",
".kt"
]
};
async function configExists(configPath) {
const defaultPath = resolve(".markdown-coderc.json");
const pathToCheck = configPath ? resolve(configPath) : defaultPath;
if (!await fileExists(pathToCheck)) {
return false;
}
try {
const content = await readFile(pathToCheck, "utf-8");
return content.length > 0;
} catch {
return false;
}
}
async function loadConfig(configPath, overrides = {}) {
let config = { ...DEFAULT_CONFIG };
if (!configPath) {
const defaultPath = resolve(".markdown-coderc.json");
try {
const content = await readFile(defaultPath, "utf-8");
config = { ...config, ...JSON.parse(content) };
} catch {
}
} else {
try {
const content = await readFile(resolve(configPath), "utf-8");
config = { ...config, ...JSON.parse(content) };
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
if (errorMessage.includes("ENOENT")) {
throw new Error(`Config file not found: ${configPath}`);
}
throw new Error(
`Failed to load config from ${configPath}: ${errorMessage}`
);
}
}
if (overrides.snippetRoot) {
config.snippetRoot = overrides.snippetRoot;
}
if (overrides.markdownGlob) {
config.markdownGlob = overrides.markdownGlob;
}
if (overrides.excludeGlob) {
config.excludeGlob = overrides.excludeGlob.split(",").map((pattern) => pattern.trim()).filter((pattern) => pattern.length > 0);
}
if (overrides.includeExtensions) {
config.includeExtensions = overrides.includeExtensions.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
}
return config;
}
function validateConfig(config) {
if (!config.snippetRoot || typeof config.snippetRoot !== "string") {
throw new Error("Config: snippetRoot must be a non-empty string");
}
if (!config.markdownGlob || typeof config.markdownGlob !== "string") {
throw new Error("Config: markdownGlob must be a non-empty string");
}
if (!Array.isArray(config.excludeGlob)) {
throw new Error("Config: excludeGlob must be an array");
}
if (!Array.isArray(config.includeExtensions)) {
throw new Error("Config: includeExtensions must be an array");
}
}
// src/commands/shared.ts
function buildConfigOverrides(argv) {
const overrides = {};
if (argv.snippetRoot) overrides.snippetRoot = argv.snippetRoot;
if (argv.markdownGlob) overrides.markdownGlob = argv.markdownGlob;
if (argv.excludeGlob) overrides.excludeGlob = argv.excludeGlob;
if (argv.includeExtensions)
overrides.includeExtensions = argv.includeExtensions;
return overrides;
}
async function getValidatedConfig(argv) {
const overrides = buildConfigOverrides(argv);
const config = await loadConfig(argv.config, overrides);
validateConfig(config);
return config;
}
function handleError(error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error(errorMessage);
process.exit(1);
}
function logWarningsAndErrors(warnings, errors) {
if (warnings.length > 0) {
console.log("Warnings:");
warnings.forEach((warning) => console.log(` ${warning}`));
}
if (errors.length > 0) {
console.error("Errors:");
errors.forEach((error) => console.error(` ${error}`));
process.exit(1);
}
return warnings.length > 0 || errors.length > 0;
}
export {
fileExists,
DEFAULT_CONFIG,
configExists,
buildConfigOverrides,
getValidatedConfig,
handleError,
logWarningsAndErrors
};