prompt-helper
Version:
A CLI tool to help you create and manage prompts for AI models.
160 lines • 5.95 kB
JavaScript
;
// src/collectors/codeCollector.ts
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.collectCode = collectCode;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const micromatch = __importStar(require("micromatch")); // Import micromatch
/**
* Recursively finds files with the exact name under the given directory.
*
* @param dir - Directory to search within.
* @param name - Filename to match.
* @param results - Accumulator for results (used during recursion).
* @returns An array of absolute file paths that match the given name.
*/
function findFilesByName(dir, name, results = []) {
for (const entry of fs.readdirSync(dir)) {
const fullPath = path.join(dir, entry);
let stat;
try {
stat = fs.statSync(fullPath);
}
catch {
continue;
}
if (stat.isDirectory()) {
findFilesByName(fullPath, name, results);
}
else if (entry === name) {
results.push(fullPath);
}
}
return results;
}
/**
* Recursively collects all file paths under a directory.
*
* @param dir - Directory to search.
* @param results - Accumulator for file paths.
* @returns A flat list of all file paths found under the directory.
*/
function findAllFiles(dir, results = []) {
for (const entry of fs.readdirSync(dir)) {
const fullPath = path.join(dir, entry);
let stat;
try {
stat = fs.statSync(fullPath);
}
catch {
continue;
}
if (stat.isDirectory()) {
findAllFiles(fullPath, results);
}
else {
results.push(fullPath);
}
}
return results;
}
/**
* Collects code snippets from user-specified file or directory paths,
* respecting ignore patterns.
*
* @param baseDir - Root directory used for resolving relative paths.
* @param projectInfo - The project info object to populate with code snippets.
* @param codePaths - A list of file or directory names/paths to collect code from.
* @param ignorePatterns - A list of glob patterns to exclude files.
*/
function collectCode(baseDir, projectInfo, codePaths, ignorePatterns // Added ignorePatterns parameter
) {
if (codePaths.length === 0) {
return;
}
const snippets = [];
// Ensure ignorePatterns are valid and non-empty for micromatch
const validIgnorePatterns = ignorePatterns.filter(p => p && p.trim() !== '');
for (const cp of codePaths) {
let resolvedPath;
const candidate = path.isAbsolute(cp) ? cp : path.join(baseDir, cp);
if (fs.existsSync(candidate)) {
resolvedPath = candidate;
}
else if (!cp.includes(path.sep)) {
const matches = findFilesByName(baseDir, cp);
if (matches.length === 1) {
resolvedPath = matches[0];
}
else if (matches.length === 0) {
throw new Error(`Code file or directory "${cp}" not found.`);
}
else {
throw new Error(`Ambiguous code path "${cp}" found in multiple locations.`);
}
}
else {
throw new Error(`Code path "${cp}" not found at resolved path "${candidate}".`);
}
if (!resolvedPath) {
continue;
}
const stat = fs.statSync(resolvedPath);
let filesToRead = stat.isDirectory() ? findAllFiles(resolvedPath) : [resolvedPath];
// Filter files based on ignore patterns
if (validIgnorePatterns.length > 0) {
filesToRead = filesToRead.filter(filePath => {
const relativeFilePath = path.relative(baseDir, filePath).replace(/\\/g, '/');
// micromatch.isMatch returns true if the path matches ANY of the patterns.
// We want to exclude if it matches, so we negate the result.
return !micromatch.isMatch(relativeFilePath, validIgnorePatterns, { dot: true });
});
}
for (const filePath of filesToRead) {
const rel = path.relative(baseDir, filePath).replace(/\\/g, '/');
let code;
try {
code = fs.readFileSync(filePath, 'utf8');
}
catch (err) {
throw new Error(`Error reading code file "${filePath}": ${err}`);
}
snippets.push({ file: rel, code });
}
}
projectInfo.codeSnippets = snippets;
}
//# sourceMappingURL=codeCollector.js.map