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
JavaScript
;
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