UNPKG

dynamate-design-to-code

Version:

A powerful tool for converting Figma designs into high-quality, production-ready code with built-in best practices and customizable rulesets

147 lines 5.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateRuleset = void 0; const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const glob_promise_1 = __importDefault(require("glob-promise")); /** * Generates a project-specific ruleset based on configuration */ async function generateRuleset(config) { // Analyze existing project code const analysis = await analyzeProject(config.projectRoot); const rules = []; const examples = {}; // Generate naming convention rules based on analysis if (config.conventions.naming?.components) { rules.push({ name: 'component-naming', description: 'Component names should follow project conventions', pattern: analysis.componentPatterns.naming[0] || '[A-Z][a-zA-Z]+', severity: 'error', category: 'naming' }); } // Generate structure rules based on analysis if (config.conventions.structure?.imports) { rules.push({ name: 'import-structure', description: 'Import statements should follow project conventions', pattern: analysis.componentPatterns.imports[0] || '^import.*from', severity: 'warning', category: 'structure' }); } // Generate documentation rules based on analysis if (config.conventions.documentation?.jsdoc) { rules.push({ name: 'jsdoc-required', description: 'Components should have JSDoc documentation', pattern: analysis.documentationPatterns.jsdoc[0] || '/\\*\\*[\\s\\S]*?\\*/', severity: 'warning', category: 'documentation' }); } // Add example based on analyzed patterns const exampleComponent = await findBestExampleComponent(config.projectRoot, config.framework); if (exampleComponent) { examples[`${config.framework}-component`] = exampleComponent; } return { name: `${config.projectName}-ruleset`, rules, examples }; } exports.generateRuleset = generateRuleset; async function analyzeProject(projectRoot) { const analysis = { componentPatterns: { naming: [], structure: [], imports: [], exports: [] }, stylePatterns: { naming: [], structure: [] }, documentationPatterns: { jsdoc: [], examples: [] } }; try { // Find all TypeScript/JavaScript files const files = await (0, glob_promise_1.default)('**/*.{ts,tsx,js,jsx}', { cwd: projectRoot, ignore: ['**/node_modules/**', '**/dist/**', '**/__tests__/**'] }); for (const file of files) { const content = await fs_1.promises.readFile(path_1.default.join(projectRoot, file), 'utf-8'); // Analyze component naming patterns const componentNameMatch = content.match(/(?:class|interface|function)\s+([A-Z][a-zA-Z]+)/g); if (componentNameMatch) { analysis.componentPatterns.naming.push(...componentNameMatch); } // Analyze import patterns const importMatches = content.match(/import\s+.*\s+from\s+['"][^'"]+['"];?/g); if (importMatches) { analysis.componentPatterns.imports.push(...importMatches); } // Analyze JSDoc patterns const jsdocMatches = content.match(/\/\*\*[\s\S]*?\*\//g); if (jsdocMatches) { analysis.documentationPatterns.jsdoc.push(...jsdocMatches); } } // Find all style files const styleFiles = await (0, glob_promise_1.default)('**/*.{css,scss,less,styled.{ts,js}}', { cwd: projectRoot, ignore: ['**/node_modules/**', '**/dist/**'] }); for (const file of styleFiles) { const content = await fs_1.promises.readFile(path_1.default.join(projectRoot, file), 'utf-8'); // Analyze style naming patterns const classMatches = content.match(/\.[a-zA-Z][a-zA-Z0-9-_]*/g); if (classMatches) { analysis.stylePatterns.naming.push(...classMatches); } } } catch (error) { console.error('Error analyzing project:', error); } return analysis; } async function findBestExampleComponent(projectRoot, framework) { try { // Find component files based on framework const extension = framework === 'react' ? '{tsx,jsx}' : framework === 'vue' ? 'vue' : framework === 'svelte' ? 'svelte' : 'ts'; const files = await (0, glob_promise_1.default)(`**/*.${extension}`, { cwd: projectRoot, ignore: ['**/node_modules/**', '**/dist/**', '**/__tests__/**'] }); // Find the most representative component for (const file of files) { const content = await fs_1.promises.readFile(path_1.default.join(projectRoot, file), 'utf-8'); // Look for components with props, state, and documentation if (content.includes('props') && content.includes('export') && content.includes('/**')) { return content; } } return null; } catch (error) { console.error('Error finding example component:', error); return null; } } //# sourceMappingURL=ruleset-generator.js.map