figma-to-code-agent 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/LICENSE +21 -0
- package/QUICKSTART.md +198 -0
- package/README.md +149 -0
- package/dist/FigmaToCodeAgent.d.ts +55 -0
- package/dist/FigmaToCodeAgent.d.ts.map +1 -0
- package/dist/FigmaToCodeAgent.js +251 -0
- package/dist/FigmaToCodeAgent.js.map +1 -0
- package/dist/assets/index.d.ts +6 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/assets/index.js +7 -0
- package/dist/assets/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +261 -0
- package/dist/cli.js.map +1 -0
- package/dist/extraction/FigmaAPIClient.d.ts +53 -0
- package/dist/extraction/FigmaAPIClient.d.ts.map +1 -0
- package/dist/extraction/FigmaAPIClient.js +275 -0
- package/dist/extraction/FigmaAPIClient.js.map +1 -0
- package/dist/extraction/FigmaCache.d.ts +28 -0
- package/dist/extraction/FigmaCache.d.ts.map +1 -0
- package/dist/extraction/FigmaCache.js +120 -0
- package/dist/extraction/FigmaCache.js.map +1 -0
- package/dist/extraction/MCPClient.d.ts +75 -0
- package/dist/extraction/MCPClient.d.ts.map +1 -0
- package/dist/extraction/MCPClient.js +254 -0
- package/dist/extraction/MCPClient.js.map +1 -0
- package/dist/extraction/index.d.ts +9 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +27 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/extraction/types.d.ts +122 -0
- package/dist/extraction/types.d.ts.map +1 -0
- package/dist/extraction/types.js +6 -0
- package/dist/extraction/types.js.map +1 -0
- package/dist/generation/AICodeOptimizer.d.ts +10 -0
- package/dist/generation/AICodeOptimizer.d.ts.map +1 -0
- package/dist/generation/AICodeOptimizer.js +33 -0
- package/dist/generation/AICodeOptimizer.js.map +1 -0
- package/dist/generation/ReactGenerator.d.ts +27 -0
- package/dist/generation/ReactGenerator.d.ts.map +1 -0
- package/dist/generation/ReactGenerator.js +423 -0
- package/dist/generation/ReactGenerator.js.map +1 -0
- package/dist/generation/VueGenerator.d.ts +23 -0
- package/dist/generation/VueGenerator.d.ts.map +1 -0
- package/dist/generation/VueGenerator.js +337 -0
- package/dist/generation/VueGenerator.js.map +1 -0
- package/dist/generation/index.d.ts +6 -0
- package/dist/generation/index.d.ts.map +1 -0
- package/dist/generation/index.js +7 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/generation/types.d.ts +24 -0
- package/dist/generation/types.d.ts.map +1 -0
- package/dist/generation/types.js +3 -0
- package/dist/generation/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/BedrockProvider.d.ts +8 -0
- package/dist/llm/BedrockProvider.d.ts.map +1 -0
- package/dist/llm/BedrockProvider.js +34 -0
- package/dist/llm/BedrockProvider.js.map +1 -0
- package/dist/llm/LLMFactory.d.ts +5 -0
- package/dist/llm/LLMFactory.d.ts.map +1 -0
- package/dist/llm/LLMFactory.js +21 -0
- package/dist/llm/LLMFactory.js.map +1 -0
- package/dist/llm/OpenAIProvider.d.ts +7 -0
- package/dist/llm/OpenAIProvider.d.ts.map +1 -0
- package/dist/llm/OpenAIProvider.js +34 -0
- package/dist/llm/OpenAIProvider.js.map +1 -0
- package/dist/llm/index.d.ts +5 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +21 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/types.d.ts +23 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +3 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/transformation/ASTFactory.d.ts +92 -0
- package/dist/transformation/ASTFactory.d.ts.map +1 -0
- package/dist/transformation/ASTFactory.js +240 -0
- package/dist/transformation/ASTFactory.js.map +1 -0
- package/dist/transformation/ASTParser.d.ts +13 -0
- package/dist/transformation/ASTParser.d.ts.map +1 -0
- package/dist/transformation/ASTParser.js +177 -0
- package/dist/transformation/ASTParser.js.map +1 -0
- package/dist/transformation/TransformationPipeline.d.ts +31 -0
- package/dist/transformation/TransformationPipeline.d.ts.map +1 -0
- package/dist/transformation/TransformationPipeline.js +42 -0
- package/dist/transformation/TransformationPipeline.js.map +1 -0
- package/dist/transformation/index.d.ts +7 -0
- package/dist/transformation/index.d.ts.map +1 -0
- package/dist/transformation/index.js +25 -0
- package/dist/transformation/index.js.map +1 -0
- package/dist/transformation/transformers/AIComponentSplitter.d.ts +14 -0
- package/dist/transformation/transformers/AIComponentSplitter.d.ts.map +1 -0
- package/dist/transformation/transformers/AIComponentSplitter.js +71 -0
- package/dist/transformation/transformers/AIComponentSplitter.js.map +1 -0
- package/dist/transformation/transformers/AILayoutAnalyzer.d.ts +18 -0
- package/dist/transformation/transformers/AILayoutAnalyzer.d.ts.map +1 -0
- package/dist/transformation/transformers/AILayoutAnalyzer.js +125 -0
- package/dist/transformation/transformers/AILayoutAnalyzer.js.map +1 -0
- package/dist/transformation/transformers/AISemanticNamer.d.ts +12 -0
- package/dist/transformation/transformers/AISemanticNamer.d.ts.map +1 -0
- package/dist/transformation/transformers/AISemanticNamer.js +50 -0
- package/dist/transformation/transformers/AISemanticNamer.js.map +1 -0
- package/dist/transformation/transformers/ComponentExtractor.d.ts +16 -0
- package/dist/transformation/transformers/ComponentExtractor.d.ts.map +1 -0
- package/dist/transformation/transformers/ComponentExtractor.js +91 -0
- package/dist/transformation/transformers/ComponentExtractor.js.map +1 -0
- package/dist/transformation/transformers/FigmaLayerPreserver.d.ts +14 -0
- package/dist/transformation/transformers/FigmaLayerPreserver.d.ts.map +1 -0
- package/dist/transformation/transformers/FigmaLayerPreserver.js +48 -0
- package/dist/transformation/transformers/FigmaLayerPreserver.js.map +1 -0
- package/dist/transformation/transformers/FigmaStructureOptimizer.d.ts +16 -0
- package/dist/transformation/transformers/FigmaStructureOptimizer.d.ts.map +1 -0
- package/dist/transformation/transformers/FigmaStructureOptimizer.js +65 -0
- package/dist/transformation/transformers/FigmaStructureOptimizer.js.map +1 -0
- package/dist/transformation/transformers/FlattenTransformer.d.ts +15 -0
- package/dist/transformation/transformers/FlattenTransformer.d.ts.map +1 -0
- package/dist/transformation/transformers/FlattenTransformer.js +69 -0
- package/dist/transformation/transformers/FlattenTransformer.js.map +1 -0
- package/dist/transformation/transformers/LayoutOptimizer.d.ts +15 -0
- package/dist/transformation/transformers/LayoutOptimizer.d.ts.map +1 -0
- package/dist/transformation/transformers/LayoutOptimizer.js +63 -0
- package/dist/transformation/transformers/LayoutOptimizer.js.map +1 -0
- package/dist/transformation/transformers/SemanticNamer.d.ts +14 -0
- package/dist/transformation/transformers/SemanticNamer.d.ts.map +1 -0
- package/dist/transformation/transformers/SemanticNamer.js +65 -0
- package/dist/transformation/transformers/SemanticNamer.js.map +1 -0
- package/dist/transformation/transformers/SimplifyTransformer.d.ts +23 -0
- package/dist/transformation/transformers/SimplifyTransformer.d.ts.map +1 -0
- package/dist/transformation/transformers/SimplifyTransformer.js +138 -0
- package/dist/transformation/transformers/SimplifyTransformer.js.map +1 -0
- package/dist/transformation/types.d.ts +129 -0
- package/dist/transformation/types.d.ts.map +1 -0
- package/dist/transformation/types.js +7 -0
- package/dist/transformation/types.js.map +1 -0
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +7 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +81 -0
- package/test-app/test-react/index.html +19 -0
- package/test-app/test-react/package.json +16 -0
- package/test-app/test-react/src/Component.jsx +146 -0
- package/test-app/test-react/src/Component.module.css +572 -0
- package/test-app/test-react/src/Homepage.jsx +53 -0
- package/test-app/test-react/src/Homepage.module.css +218 -0
- package/test-app/test-react/src/ProductPage.jsx +74 -0
- package/test-app/test-react/src/ProductPage.module.css +357 -0
- package/test-app/test-react/src/ShoppingCart.jsx +151 -0
- package/test-app/test-react/src/ShoppingCart.module.css +739 -0
- package/test-app/test-react/src/main.jsx +9 -0
- package/test-app/test-react/vite.config.js +6 -0
- package/test-app/test-vue/index.html +19 -0
- package/test-app/test-vue/package.json +15 -0
- package/test-app/test-vue/src/App.vue +16 -0
- package/test-app/test-vue/src/Component.vue +723 -0
- package/test-app/test-vue/src/Homepage.vue +271 -0
- package/test-app/test-vue/src/ProductPage.vue +431 -0
- package/test-app/test-vue/src/ShoppingCart.vue +890 -0
- package/test-app/test-vue/src/main.js +4 -0
- package/test-app/test-vue/vite.config.js +6 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FigmaToCodeAgent = void 0;
|
|
37
|
+
const FigmaAPIClient_1 = require("./extraction/FigmaAPIClient");
|
|
38
|
+
const ASTParser_1 = require("./transformation/ASTParser");
|
|
39
|
+
const TransformationPipeline_1 = require("./transformation/TransformationPipeline");
|
|
40
|
+
const FigmaStructureOptimizer_1 = require("./transformation/transformers/FigmaStructureOptimizer");
|
|
41
|
+
const ComponentExtractor_1 = require("./transformation/transformers/ComponentExtractor");
|
|
42
|
+
const LayoutOptimizer_1 = require("./transformation/transformers/LayoutOptimizer");
|
|
43
|
+
const SemanticNamer_1 = require("./transformation/transformers/SemanticNamer");
|
|
44
|
+
const AILayoutAnalyzer_1 = require("./transformation/transformers/AILayoutAnalyzer");
|
|
45
|
+
const ReactGenerator_1 = require("./generation/ReactGenerator");
|
|
46
|
+
const VueGenerator_1 = require("./generation/VueGenerator");
|
|
47
|
+
const llm_1 = require("./llm");
|
|
48
|
+
const AISemanticNamer_1 = require("./transformation/transformers/AISemanticNamer");
|
|
49
|
+
const AIComponentSplitter_1 = require("./transformation/transformers/AIComponentSplitter");
|
|
50
|
+
const AICodeOptimizer_1 = require("./generation/AICodeOptimizer");
|
|
51
|
+
class FigmaToCodeAgent {
|
|
52
|
+
constructor(config) {
|
|
53
|
+
this.config = config;
|
|
54
|
+
this.figmaClient = new FigmaAPIClient_1.FigmaAPIClient(config.figmaToken);
|
|
55
|
+
this.parser = new ASTParser_1.ASTParser();
|
|
56
|
+
this.pipeline = new TransformationPipeline_1.TransformationPipeline();
|
|
57
|
+
// Initialize LLM if configured
|
|
58
|
+
if (config.llm) {
|
|
59
|
+
this.llm = llm_1.LLMFactory.create(config.llm);
|
|
60
|
+
if (config.llm.enableAIOptimization) {
|
|
61
|
+
this.aiOptimizer = new AICodeOptimizer_1.AICodeOptimizer(this.llm);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Register transformers (order matters!)
|
|
65
|
+
// NOTE: Use FigmaStructureOptimizer instead of aggressive SimplifyTransformer/FlattenTransformer
|
|
66
|
+
// to preserve Figma layer structure for better readability
|
|
67
|
+
this.pipeline.register(new FigmaStructureOptimizer_1.FigmaStructureOptimizer()); // 1. Light optimization, preserve structure
|
|
68
|
+
// AI layout analysis (before component extraction)
|
|
69
|
+
if (config.llm?.enableAILayout && this.llm) {
|
|
70
|
+
this.pipeline.register(new AILayoutAnalyzer_1.AILayoutAnalyzer(this.llm)); // 2. AI semantic analysis
|
|
71
|
+
}
|
|
72
|
+
this.pipeline
|
|
73
|
+
.register(new ComponentExtractor_1.ComponentExtractor()) // 3. Extract components
|
|
74
|
+
.register(new LayoutOptimizer_1.LayoutOptimizer()); // 4. Optimize layout
|
|
75
|
+
// Use AI or rule-based naming
|
|
76
|
+
if (config.llm?.enableAINaming && this.llm) {
|
|
77
|
+
this.pipeline.register(new AISemanticNamer_1.AISemanticNamer(this.llm)); // 5. AI naming
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.pipeline.register(new SemanticNamer_1.SemanticNamer()); // 5. Rule-based naming
|
|
81
|
+
}
|
|
82
|
+
// Add AI component splitting if enabled
|
|
83
|
+
if (config.llm?.enableAISplitting && this.llm) {
|
|
84
|
+
this.pipeline.register(new AIComponentSplitter_1.AIComponentSplitter(this.llm)); // 6. AI splitting
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async convert() {
|
|
88
|
+
// Step 1: Extract design from Figma
|
|
89
|
+
const figmaFile = await this.figmaClient.getFile(this.config.fileKey);
|
|
90
|
+
// Step 2: Find target node(s) or use entire document
|
|
91
|
+
let targetNode = figmaFile.document;
|
|
92
|
+
if (this.config.nodeIds && this.config.nodeIds.length > 0) {
|
|
93
|
+
const nodeId = this.config.nodeIds[0].replace('-', ':');
|
|
94
|
+
const found = this.findNodeById(figmaFile.document, nodeId);
|
|
95
|
+
if (found) {
|
|
96
|
+
targetNode = found;
|
|
97
|
+
console.log(`✓ Found target node: ${found.name} (${found.type})`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.log(`⚠ Node ${nodeId} not found, using entire document`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Step 3: Parse to AST
|
|
104
|
+
const ast = this.parser.parse(targetNode);
|
|
105
|
+
// Step 4: Download images for Image nodes
|
|
106
|
+
await this.downloadImages(ast);
|
|
107
|
+
// Step 5: Transform AST
|
|
108
|
+
const transformedAst = await this.pipeline.execute(ast);
|
|
109
|
+
// Step 6: Generate code
|
|
110
|
+
const generator = this.config.framework === 'react' ? new ReactGenerator_1.ReactGenerator() : new VueGenerator_1.VueGenerator();
|
|
111
|
+
const generatorConfig = {
|
|
112
|
+
framework: this.config.framework,
|
|
113
|
+
styleMode: this.config.styleMode,
|
|
114
|
+
typescript: this.config.typescript,
|
|
115
|
+
outputDir: this.config.outputDir,
|
|
116
|
+
};
|
|
117
|
+
let files = generator.generate(transformedAst, generatorConfig);
|
|
118
|
+
// Step 7: AI optimization (optional)
|
|
119
|
+
if (this.aiOptimizer) {
|
|
120
|
+
files = await this.aiOptimizer.optimize(files);
|
|
121
|
+
}
|
|
122
|
+
return files;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Download images for all Image nodes in the AST
|
|
126
|
+
*/
|
|
127
|
+
async downloadImages(ast) {
|
|
128
|
+
const imageNodes = [];
|
|
129
|
+
this.collectImageNodes(ast, imageNodes);
|
|
130
|
+
this.collectIconNodes(ast, imageNodes);
|
|
131
|
+
if (imageNodes.length === 0)
|
|
132
|
+
return;
|
|
133
|
+
console.log(`Found ${imageNodes.length} image(s) to download...`);
|
|
134
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
135
|
+
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
136
|
+
const assetsDir = path.join(this.config.outputDir, 'assets');
|
|
137
|
+
// Try to use locally cached files first before hitting API
|
|
138
|
+
const nodesNeedingDownload = [];
|
|
139
|
+
for (const node of imageNodes) {
|
|
140
|
+
const fileName = this.sanitizeFileName(node.name) + '.png';
|
|
141
|
+
const filePath = path.join(assetsDir, fileName);
|
|
142
|
+
if (fs.existsSync(filePath)) {
|
|
143
|
+
console.log(`✓ Using cached image: ${fileName}`);
|
|
144
|
+
node.metadata.imageRef = `./assets/${fileName}`;
|
|
145
|
+
if (node.type !== 'Image') {
|
|
146
|
+
node.type = 'Image';
|
|
147
|
+
node.children = [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
nodesNeedingDownload.push(node);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (nodesNeedingDownload.length === 0)
|
|
155
|
+
return;
|
|
156
|
+
const nodeIds = nodesNeedingDownload.map((n) => n.metadata.figmaId);
|
|
157
|
+
try {
|
|
158
|
+
const imageMap = await this.figmaClient.getImages(this.config.fileKey, nodeIds, 'png');
|
|
159
|
+
if (imageMap.images) {
|
|
160
|
+
if (!fs.existsSync(assetsDir)) {
|
|
161
|
+
fs.mkdirSync(assetsDir, { recursive: true });
|
|
162
|
+
}
|
|
163
|
+
for (const node of nodesNeedingDownload) {
|
|
164
|
+
const imageUrl = imageMap.images[node.metadata.figmaId];
|
|
165
|
+
if (imageUrl) {
|
|
166
|
+
const fileName = this.sanitizeFileName(node.name) + '.png';
|
|
167
|
+
const filePath = path.join(assetsDir, fileName);
|
|
168
|
+
try {
|
|
169
|
+
await this.figmaClient.downloadImage(imageUrl, filePath);
|
|
170
|
+
node.metadata.imageRef = `./assets/${fileName}`;
|
|
171
|
+
if (node.type !== 'Image') {
|
|
172
|
+
node.type = 'Image';
|
|
173
|
+
node.children = [];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
console.log(`⚠ Failed to download image: ${node.name}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
console.log(`⚠ Failed to fetch image URLs, using placeholders`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
collectImageNodes(node, result) {
|
|
188
|
+
if (node.type === 'Image') {
|
|
189
|
+
result.push(node);
|
|
190
|
+
}
|
|
191
|
+
node.children.forEach((child) => this.collectImageNodes(child, result));
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Find containers whose children are all Shape/Vector nodes (icons).
|
|
195
|
+
* These should be exported as images since CSS can't render SVG paths.
|
|
196
|
+
*/
|
|
197
|
+
/**
|
|
198
|
+
* Find containers whose children are all Shape/Vector nodes (icons).
|
|
199
|
+
* These should be exported as images since CSS can't render SVG paths.
|
|
200
|
+
* Only matches small containers (< 200px) to avoid exporting large sections.
|
|
201
|
+
*/
|
|
202
|
+
/**
|
|
203
|
+
* Find containers whose descendants are all Shape/Vector nodes.
|
|
204
|
+
* These should be exported as images since CSS can't render SVG paths.
|
|
205
|
+
* Skips containers that also have Text or Image children (mixed content).
|
|
206
|
+
*/
|
|
207
|
+
collectIconNodes(node, result) {
|
|
208
|
+
if (node.type === 'Container' && node.children.length > 0) {
|
|
209
|
+
const hasShape = this.hasShapeDescendant(node);
|
|
210
|
+
const hasTextOrImage = this.hasTextOrImageDescendant(node);
|
|
211
|
+
if (hasShape && !hasTextOrImage) {
|
|
212
|
+
result.push(node);
|
|
213
|
+
return; // Don't recurse — export this whole container
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
node.children.forEach((child) => this.collectIconNodes(child, result));
|
|
217
|
+
}
|
|
218
|
+
hasShapeDescendant(node) {
|
|
219
|
+
if (node.type === 'Shape')
|
|
220
|
+
return true;
|
|
221
|
+
return node.children.some((c) => this.hasShapeDescendant(c));
|
|
222
|
+
}
|
|
223
|
+
hasTextOrImageDescendant(node) {
|
|
224
|
+
if (node.type === 'Text' || node.type === 'Image')
|
|
225
|
+
return true;
|
|
226
|
+
return node.children.some((c) => this.hasTextOrImageDescendant(c));
|
|
227
|
+
}
|
|
228
|
+
sanitizeFileName(name) {
|
|
229
|
+
return (name
|
|
230
|
+
// eslint-disable-next-line no-control-regex
|
|
231
|
+
.replace(/[^\x00-\x7F]/g, '') // Remove non-ASCII (Chinese, etc.)
|
|
232
|
+
.replace(/[^\w\s-]/g, '')
|
|
233
|
+
.replace(/\s+/g, '-')
|
|
234
|
+
.toLowerCase()
|
|
235
|
+
.substring(0, 50) || 'icon');
|
|
236
|
+
}
|
|
237
|
+
findNodeById(node, id) {
|
|
238
|
+
if (node.id === id)
|
|
239
|
+
return node;
|
|
240
|
+
if (node.children) {
|
|
241
|
+
for (const child of node.children) {
|
|
242
|
+
const found = this.findNodeById(child, id);
|
|
243
|
+
if (found)
|
|
244
|
+
return found;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.FigmaToCodeAgent = FigmaToCodeAgent;
|
|
251
|
+
//# sourceMappingURL=FigmaToCodeAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaToCodeAgent.js","sourceRoot":"","sources":["../src/FigmaToCodeAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const FigmaToCodeAgent_1 = require("./FigmaToCodeAgent");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
async function main() {
|
|
42
|
+
const args = process.argv.slice(2);
|
|
43
|
+
if (args.length === 0 || args.includes('--help')) {
|
|
44
|
+
console.log(`
|
|
45
|
+
Figma-to-Code AI Agent
|
|
46
|
+
|
|
47
|
+
Usage:
|
|
48
|
+
figma-to-code --token <token> --file <fileKey> [options]
|
|
49
|
+
|
|
50
|
+
Options:
|
|
51
|
+
--token <token> Figma API token (required)
|
|
52
|
+
--file <fileKey> Figma file key (required)
|
|
53
|
+
--node <nodeId> Specific node ID to convert
|
|
54
|
+
--framework <name> Framework: react or vue (default: react)
|
|
55
|
+
--style <mode> Style mode: css-modules, tailwind, or css (default: css-modules)
|
|
56
|
+
--typescript Enable TypeScript output (default: false)
|
|
57
|
+
--output <dir> Output directory (default: ./output)
|
|
58
|
+
--preview Preview in browser after generation
|
|
59
|
+
|
|
60
|
+
AI Options:
|
|
61
|
+
--llm-provider <name> LLM provider: bedrock, openai, anthropic
|
|
62
|
+
--llm-model <model> Model name
|
|
63
|
+
--llm-region <region> AWS region for Bedrock (default: us-east-1)
|
|
64
|
+
--llm-api-key <key> API key for OpenAI/Anthropic
|
|
65
|
+
--ai-naming Enable AI-powered component naming
|
|
66
|
+
--ai-splitting Enable AI-powered component splitting
|
|
67
|
+
--ai-optimization Enable AI-powered code optimization
|
|
68
|
+
--ai-layout Enable AI-powered layout analysis
|
|
69
|
+
|
|
70
|
+
--help Show this help message
|
|
71
|
+
|
|
72
|
+
Example:
|
|
73
|
+
figma-to-code --token abc123 --file xyz789 --framework react --output ./src/components
|
|
74
|
+
figma-to-code --token abc123 --file xyz789 --framework react --preview
|
|
75
|
+
`);
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
const preview = args.includes('--preview');
|
|
79
|
+
const config = {
|
|
80
|
+
figmaToken: getArg('--token', args) || process.env.FIGMA_TOKEN || '',
|
|
81
|
+
fileKey: getArg('--file', args) || '',
|
|
82
|
+
nodeIds: getArgs('--node', args),
|
|
83
|
+
framework: (getArg('--framework', args) || 'react'),
|
|
84
|
+
styleMode: (getArg('--style', args) || 'css-modules'),
|
|
85
|
+
typescript: args.includes('--typescript'),
|
|
86
|
+
outputDir: getArg('--output', args) || './output',
|
|
87
|
+
llm: getArg('--llm-provider', args)
|
|
88
|
+
? {
|
|
89
|
+
provider: getArg('--llm-provider', args),
|
|
90
|
+
model: getArg('--llm-model', args) || '',
|
|
91
|
+
region: getArg('--llm-region', args),
|
|
92
|
+
apiKey: getArg('--llm-api-key', args) || process.env.LLM_API_KEY,
|
|
93
|
+
enableAINaming: args.includes('--ai-naming'),
|
|
94
|
+
enableAISplitting: args.includes('--ai-splitting'),
|
|
95
|
+
enableAIOptimization: args.includes('--ai-optimization'),
|
|
96
|
+
enableAILayout: args.includes('--ai-layout'),
|
|
97
|
+
}
|
|
98
|
+
: undefined,
|
|
99
|
+
};
|
|
100
|
+
if (!config.figmaToken) {
|
|
101
|
+
console.error('Error: Figma token is required. Use --token or set FIGMA_TOKEN environment variable.');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
if (!config.fileKey) {
|
|
105
|
+
console.error('Error: Figma file key is required. Use --file option.');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
console.log('Starting Figma-to-Code conversion...');
|
|
109
|
+
console.log(`Framework: ${config.framework}`);
|
|
110
|
+
console.log(`Style mode: ${config.styleMode}`);
|
|
111
|
+
console.log(`TypeScript: ${config.typescript}`);
|
|
112
|
+
console.log(`Output: ${config.outputDir}`);
|
|
113
|
+
console.log('');
|
|
114
|
+
try {
|
|
115
|
+
console.log('Step 1/4: Extracting design from Figma...');
|
|
116
|
+
const agent = new FigmaToCodeAgent_1.FigmaToCodeAgent(config);
|
|
117
|
+
const files = await agent.convert();
|
|
118
|
+
console.log('\nStep 4/4: Writing files...');
|
|
119
|
+
// Create output directory
|
|
120
|
+
if (!fs.existsSync(config.outputDir)) {
|
|
121
|
+
fs.mkdirSync(config.outputDir, { recursive: true });
|
|
122
|
+
}
|
|
123
|
+
// Write generated files to output directory
|
|
124
|
+
for (const file of files) {
|
|
125
|
+
const filePath = path.join(process.cwd(), file.path);
|
|
126
|
+
const dir = path.dirname(filePath);
|
|
127
|
+
if (!fs.existsSync(dir)) {
|
|
128
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
fs.writeFileSync(filePath, file.content, 'utf-8');
|
|
131
|
+
console.log(`✓ Generated: ${file.path}`);
|
|
132
|
+
}
|
|
133
|
+
console.log(`\n✓ Successfully generated ${files.length} file(s)`);
|
|
134
|
+
// Preview mode: copy to test-app and launch Vite
|
|
135
|
+
if (preview) {
|
|
136
|
+
await startPreview(config.framework, config.outputDir, files);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function startPreview(framework, outputDir, files) {
|
|
145
|
+
const cliDir = path.dirname(path.dirname(path.resolve(__filename)));
|
|
146
|
+
const testAppDir = framework === 'react'
|
|
147
|
+
? path.join(cliDir, 'test-app', 'test-react')
|
|
148
|
+
: path.join(cliDir, 'test-app', 'test-vue');
|
|
149
|
+
const srcDir = path.join(testAppDir, 'src');
|
|
150
|
+
if (!fs.existsSync(testAppDir)) {
|
|
151
|
+
console.error('Error: test-app directory not found at', testAppDir);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
console.log('\n🔍 Starting preview...');
|
|
155
|
+
// Copy generated files and assets to test-app/src
|
|
156
|
+
const outputAbsolute = path.resolve(outputDir);
|
|
157
|
+
const copiedFiles = [];
|
|
158
|
+
for (const file of files) {
|
|
159
|
+
const srcPath = path.join(process.cwd(), file.path);
|
|
160
|
+
const fileName = path.basename(file.path);
|
|
161
|
+
const destPath = path.join(srcDir, fileName);
|
|
162
|
+
fs.copyFileSync(srcPath, destPath);
|
|
163
|
+
copiedFiles.push(destPath);
|
|
164
|
+
}
|
|
165
|
+
// Copy assets directory if it exists in output
|
|
166
|
+
const outputAssetsDir = path.join(outputAbsolute, 'assets');
|
|
167
|
+
const destAssetsDir = path.join(srcDir, 'assets');
|
|
168
|
+
if (fs.existsSync(outputAssetsDir)) {
|
|
169
|
+
if (!fs.existsSync(destAssetsDir)) {
|
|
170
|
+
fs.mkdirSync(destAssetsDir, { recursive: true });
|
|
171
|
+
}
|
|
172
|
+
for (const assetFile of fs.readdirSync(outputAssetsDir)) {
|
|
173
|
+
const assetSrc = path.join(outputAssetsDir, assetFile);
|
|
174
|
+
const assetDest = path.join(destAssetsDir, assetFile);
|
|
175
|
+
if (fs.statSync(assetSrc).isFile()) {
|
|
176
|
+
fs.copyFileSync(assetSrc, assetDest);
|
|
177
|
+
copiedFiles.push(assetDest);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Find the main component file name
|
|
182
|
+
const componentFile = files.find((f) => framework === 'react'
|
|
183
|
+
? f.path.endsWith('.jsx') || f.path.endsWith('.tsx')
|
|
184
|
+
: f.path.endsWith('.vue'));
|
|
185
|
+
if (!componentFile) {
|
|
186
|
+
console.error('Error: No component file found in generated output');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const componentFileName = path.basename(componentFile.path);
|
|
190
|
+
const componentName = componentFileName.replace(/\.(jsx|tsx|vue)$/, '');
|
|
191
|
+
// Update entry file to import the generated component
|
|
192
|
+
if (framework === 'react') {
|
|
193
|
+
const ext = componentFileName.endsWith('.tsx') ? '.tsx' : '.jsx';
|
|
194
|
+
const entryContent = `import React from 'react'
|
|
195
|
+
import ReactDOM from 'react-dom/client'
|
|
196
|
+
import { ${componentName} } from './${componentName}${ext}'
|
|
197
|
+
|
|
198
|
+
ReactDOM.createRoot(document.getElementById('root')).render(
|
|
199
|
+
<React.StrictMode>
|
|
200
|
+
<${componentName} />
|
|
201
|
+
</React.StrictMode>
|
|
202
|
+
)
|
|
203
|
+
`;
|
|
204
|
+
fs.writeFileSync(path.join(srcDir, 'main.jsx'), entryContent, 'utf-8');
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
const entryContent = `import { createApp } from 'vue'
|
|
208
|
+
import ${componentName} from './${componentName}.vue'
|
|
209
|
+
|
|
210
|
+
createApp(${componentName}).mount('#app')
|
|
211
|
+
`;
|
|
212
|
+
fs.writeFileSync(path.join(srcDir, 'main.js'), entryContent, 'utf-8');
|
|
213
|
+
}
|
|
214
|
+
console.log(`✓ Copied files to ${testAppDir}`);
|
|
215
|
+
console.log(`✓ Starting Vite dev server...\n`);
|
|
216
|
+
// Launch Vite with --open
|
|
217
|
+
const viteProcess = (0, child_process_1.spawn)('npx', ['vite', '--open'], {
|
|
218
|
+
cwd: testAppDir,
|
|
219
|
+
stdio: 'inherit',
|
|
220
|
+
shell: true,
|
|
221
|
+
});
|
|
222
|
+
// Cleanup on exit: remove copied files
|
|
223
|
+
const cleanup = () => {
|
|
224
|
+
console.log('\n🧹 Cleaning up preview files...');
|
|
225
|
+
for (const f of copiedFiles) {
|
|
226
|
+
try {
|
|
227
|
+
fs.unlinkSync(f);
|
|
228
|
+
}
|
|
229
|
+
catch { /* ignore cleanup errors */ }
|
|
230
|
+
}
|
|
231
|
+
viteProcess.kill();
|
|
232
|
+
process.exit(0);
|
|
233
|
+
};
|
|
234
|
+
process.on('SIGINT', cleanup);
|
|
235
|
+
process.on('SIGTERM', cleanup);
|
|
236
|
+
viteProcess.on('close', (code) => {
|
|
237
|
+
// Clean up when Vite exits
|
|
238
|
+
for (const f of copiedFiles) {
|
|
239
|
+
try {
|
|
240
|
+
fs.unlinkSync(f);
|
|
241
|
+
}
|
|
242
|
+
catch { /* ignore cleanup errors */ }
|
|
243
|
+
}
|
|
244
|
+
process.exit(code ?? 0);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function getArg(flag, args) {
|
|
248
|
+
const index = args.indexOf(flag);
|
|
249
|
+
return index !== -1 && index + 1 < args.length ? args[index + 1] : undefined;
|
|
250
|
+
}
|
|
251
|
+
function getArgs(flag, args) {
|
|
252
|
+
const values = [];
|
|
253
|
+
for (let i = 0; i < args.length; i++) {
|
|
254
|
+
if (args[i] === flag && i + 1 < args.length) {
|
|
255
|
+
values.push(args[i + 1]);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return values.length > 0 ? values : undefined;
|
|
259
|
+
}
|
|
260
|
+
main();
|
|
261
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma API Client
|
|
3
|
+
* Handles communication with Figma REST API
|
|
4
|
+
*/
|
|
5
|
+
import { FigmaFile, GetFileOptions, ImageFormat, ImageMap } from './types';
|
|
6
|
+
export declare class FigmaAPIClient {
|
|
7
|
+
private readonly accessToken;
|
|
8
|
+
private readonly baseURL;
|
|
9
|
+
private readonly axiosInstance;
|
|
10
|
+
private readonly maxRetries;
|
|
11
|
+
private readonly baseRetryDelay;
|
|
12
|
+
private readonly cache;
|
|
13
|
+
private readonly cacheMaxAge;
|
|
14
|
+
constructor(accessToken: string, enableCache?: boolean);
|
|
15
|
+
/**
|
|
16
|
+
* Get file's complete design data
|
|
17
|
+
* @param fileKey - Figma file ID
|
|
18
|
+
* @param options - Optional query parameters
|
|
19
|
+
* @returns Design file data
|
|
20
|
+
*/
|
|
21
|
+
getFile(fileKey: string, options?: GetFileOptions): Promise<FigmaFile>;
|
|
22
|
+
/**
|
|
23
|
+
* Get image resource URLs from file
|
|
24
|
+
* @param fileKey - Figma file ID
|
|
25
|
+
* @param nodeIds - List of node IDs to export
|
|
26
|
+
* @param format - Image format (png, jpg, svg, pdf)
|
|
27
|
+
* @returns Image URL mapping
|
|
28
|
+
*/
|
|
29
|
+
getImages(fileKey: string, nodeIds: string[], format?: ImageFormat): Promise<ImageMap>;
|
|
30
|
+
/**
|
|
31
|
+
* Download image resource to local file
|
|
32
|
+
* @param imageUrl - Image URL
|
|
33
|
+
* @param outputPath - Save path
|
|
34
|
+
*/
|
|
35
|
+
downloadImage(imageUrl: string, outputPath: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Retry request with exponential backoff and Retry-After header support
|
|
38
|
+
*/
|
|
39
|
+
private retryRequest;
|
|
40
|
+
/**
|
|
41
|
+
* Check if error is retryable (network errors, rate limits, server errors)
|
|
42
|
+
*/
|
|
43
|
+
private isRetryableError;
|
|
44
|
+
/**
|
|
45
|
+
* Sleep for specified milliseconds
|
|
46
|
+
*/
|
|
47
|
+
private sleep;
|
|
48
|
+
/**
|
|
49
|
+
* Handle and format errors
|
|
50
|
+
*/
|
|
51
|
+
private handleError;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=FigmaAPIClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaAPIClient.d.ts","sourceRoot":"","sources":["../../src/extraction/FigmaAPIClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG3E,qBAAa,cAAc;IASvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAGhC,WAAW,EAAE,MAAM,EACpC,WAAW,UAAO;IAiBpB;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IAqC5E;;;;;;OAMG;IACG,SAAS,CACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,GAAE,WAAmB,GAC1B,OAAO,CAAC,QAAQ,CAAC;IA8CpB;;;;OAIG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCxE;;OAEG;YACW,YAAY;IAuC1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;OAEG;IACH,OAAO,CAAC,KAAK;IAIb;;OAEG;IACH,OAAO,CAAC,WAAW;CAqCpB"}
|