@meldscience/meld
Version:
pipeable one-shot prompt scripting toolkit
145 lines • 5.63 kB
JavaScript
;
/**
* codeImporter.ts
*
* Extracts code symbols (functions, classes, interfaces, etc.) from a TypeScript/JavaScript file.
* Supports extracting multiple symbols and adjusting the heading level and text.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.importCodeSymbols = importCodeSymbols;
const fs_1 = require("fs");
function importCodeSymbols(options) {
const { filePath, symbolList, headingLevelOverride, headingTextOverride } = options;
try {
const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
const lines = content.split('\n');
const result = {
content: '',
symbolsFound: false,
duplicateSymbols: false
};
// Track found symbols and their locations
const foundSymbols = new Map();
let inComment = false;
let inString = false;
let stringChar = '';
// Find all symbol locations
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
// Skip empty lines
if (!line)
continue;
// Handle multi-line comments
if (line.includes('/*'))
inComment = true;
if (line.includes('*/'))
inComment = false;
// Handle strings
if (!inComment) {
for (let j = 0; j < line.length; j++) {
const char = line[j];
if (inString) {
if (char === stringChar && line[j - 1] !== '\\') {
inString = false;
}
}
else if (char === '"' || char === "'") {
inString = true;
stringChar = char;
}
}
}
// Skip comments and strings
if (inComment || inString)
continue;
// Look for symbol declarations
for (const symbol of symbolList) {
if (line.includes(symbol)) {
const locations = foundSymbols.get(symbol) || [];
locations.push(i);
foundSymbols.set(symbol, locations);
}
}
}
// Check for duplicates and missing symbols
result.symbolsFound = symbolList.every(symbol => foundSymbols.has(symbol));
result.duplicateSymbols = Array.from(foundSymbols.values()).some(locations => locations.length > 1);
if (!result.symbolsFound || result.duplicateSymbols) {
return result;
}
// Extract symbols
const extractedContent = [];
// Add heading by default unless skipHeading is true
if (!options.skipHeading) {
const heading = headingLevelOverride ?? '#';
const text = headingTextOverride ?? 'Code Symbols';
extractedContent.push(`${heading} ${text}`);
extractedContent.push('');
}
// Add code fence
extractedContent.push('```typescript');
// Add each symbol's code
for (const symbol of symbolList) {
const locations = foundSymbols.get(symbol);
const location = locations[0];
let start = location;
let end = location;
// Find the start of the symbol (include JSDoc comments)
while (start > 0 && (lines[start - 1].trim().startsWith('*') || lines[start - 1].trim().startsWith('/'))) {
start--;
}
// Find the end of the symbol (include the entire block)
let braceCount = 0;
let foundFirstBrace = false;
for (let i = location; i < lines.length; i++) {
const line = lines[i];
for (const char of line) {
if (char === '{') {
foundFirstBrace = true;
braceCount++;
}
else if (char === '}') {
braceCount--;
}
}
end = i;
if (foundFirstBrace && braceCount === 0)
break;
if (!foundFirstBrace && (line.trim().endsWith(';') || line.trim().endsWith('}'))) {
break;
}
}
// Add the symbol's code
for (let i = start; i <= end; i++) {
const line = lines[i];
if (i === end && symbol === symbolList[symbolList.length - 1]) {
const trimmedLine = line.trimEnd();
if (trimmedLine.endsWith(';') || trimmedLine.endsWith('}')) {
extractedContent.push(trimmedLine);
extractedContent.push('```');
}
else {
extractedContent.push(trimmedLine);
extractedContent.push('```');
}
}
else {
extractedContent.push(line);
}
}
// Add newline between symbols
if (symbol !== symbolList[symbolList.length - 1]) {
extractedContent.push('');
}
}
result.content = extractedContent.join('\n');
return result;
}
catch (error) {
if (error.code === 'ENOENT') {
throw new Error('File not found');
}
throw error;
}
}
//# sourceMappingURL=codeImporter.js.map