ai-code-to-project-files
Version:
A CLI tool to convert AI code responses with multiple file sections into organized project files
127 lines (111 loc) • 4.33 kB
JavaScript
const fs = require('fs').promises;
const path = require('path');
/**
* Parse artifact content and extract files
* @param {string} artifactContent - The content to parse
* @returns {Promise<Array>} Array of file objects with path and content
*/
async function parseArtifactContent(artifactContent) {
try {
const files = [];
// Split by '\n\n# ' to separate file sections, filter out empty sections
const fileSections = artifactContent.split('\n# ').filter(Boolean);
for (let section of fileSections) {
// Ensure section starts with '# ' for consistency
if (!section.startsWith('# ')) {
section = '# ' + section;
}
const lines = section.split('\n');
// Extract file path from the first line (remove '# ' prefix)
const filePath = lines[0].replace(/^# /, '').trim();
// Join remaining lines as content
const content = lines.slice(1).join('\n').trim();
if (filePath && content) {
// Validate file path to prevent invalid characters
if (/[<>:"\\|?*\x00-\x1f]/.test(filePath)) {
console.warn(`Skipping invalid file path: ${filePath}`);
continue;
}
files.push({ path: filePath, content });
}
}
if (files.length === 0) {
throw new Error('No valid files found in the input content.');
}
return files;
} catch (error) {
throw new Error(`Failed to parse artifact content: ${error.message}`);
}
}
/**
* Create directories and files from parsed data
* @param {Array} files - Array of file objects
* @param {string} baseDir - Base directory to create files in
* @returns {Promise<void>}
*/
async function createFileStructure(files, baseDir) {
try {
for (const file of files) {
const fullPath = path.join(baseDir, file.path);
const dir = path.dirname(fullPath);
// Create directory if it doesn't exist
await fs.mkdir(dir, { recursive: true });
// Write file content
await fs.writeFile(fullPath, file.content);
console.log(`Created file: ${fullPath}`);
}
console.log('Project structure created successfully.');
} catch (error) {
throw new Error(`Error creating project structure: ${error.message}`);
}
}
/**
* Generate project structure from AI artifact content
* @param {string} inputFilePath - Path to input file
* @param {string} outputDir - Output directory (default: './generated_project')
* @returns {Promise<Object>} Result object with success status
*/
async function generateFromFile(inputFilePath, outputDir = './generated_project') {
try {
// Validate input file path
if (!inputFilePath || !inputFilePath.endsWith('.txt')) {
throw new Error('Input file must be a .txt file.');
}
// Read the input file
const artifactContent = await fs.readFile(inputFilePath, 'utf8');
// Parse the artifact content
const files = await parseArtifactContent(artifactContent);
// Create the output directory
await fs.mkdir(outputDir, { recursive: true });
// Create the file structure
await createFileStructure(files, outputDir);
return { success: true, message: 'Project structure generated successfully', files: files.length };
} catch (error) {
return { success: false, error: error.message };
}
}
/**
* Generate project structure from content string
* @param {string} content - The artifact content as string
* @param {string} outputDir - Output directory (default: './generated_project')
* @returns {Promise<Object>} Result object with success status
*/
async function generateFromContent(content, outputDir = './generated_project') {
try {
// Parse the artifact content
const files = await parseArtifactContent(content);
// Create the output directory
await fs.mkdir(outputDir, { recursive: true });
// Create the file structure
await createFileStructure(files, outputDir);
return { success: true, message: 'Project structure generated successfully', files: files.length };
} catch (error) {
return { success: false, error: error.message };
}
}
module.exports = {
generateFromFile,
generateFromContent,
parseArtifactContent,
createFileStructure
};