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,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Figma API Client
|
|
4
|
+
* Handles communication with Figma REST API
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.FigmaAPIClient = void 0;
|
|
44
|
+
const axios_1 = __importDefault(require("axios"));
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const FigmaCache_1 = require("./FigmaCache");
|
|
48
|
+
class FigmaAPIClient {
|
|
49
|
+
constructor(accessToken, enableCache = true) {
|
|
50
|
+
this.accessToken = accessToken;
|
|
51
|
+
this.baseURL = 'https://api.figma.com/v1';
|
|
52
|
+
this.maxRetries = 3;
|
|
53
|
+
this.baseRetryDelay = 1000; // milliseconds
|
|
54
|
+
this.cacheMaxAge = 24 * 60 * 60 * 1000; // 24 hours (increased from 5 minutes)
|
|
55
|
+
if (!accessToken) {
|
|
56
|
+
throw new Error('Figma access token is required');
|
|
57
|
+
}
|
|
58
|
+
this.cache = enableCache ? new FigmaCache_1.FigmaCache() : null;
|
|
59
|
+
this.axiosInstance = axios_1.default.create({
|
|
60
|
+
baseURL: this.baseURL,
|
|
61
|
+
headers: {
|
|
62
|
+
'X-Figma-Token': this.accessToken,
|
|
63
|
+
},
|
|
64
|
+
timeout: 60000, // Increased to 60 seconds
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get file's complete design data
|
|
69
|
+
* @param fileKey - Figma file ID
|
|
70
|
+
* @param options - Optional query parameters
|
|
71
|
+
* @returns Design file data
|
|
72
|
+
*/
|
|
73
|
+
async getFile(fileKey, options) {
|
|
74
|
+
if (!fileKey) {
|
|
75
|
+
throw new Error('File key is required');
|
|
76
|
+
}
|
|
77
|
+
// Check cache first
|
|
78
|
+
const cacheKey = `file:${fileKey}:${JSON.stringify(options || {})}`;
|
|
79
|
+
if (this.cache) {
|
|
80
|
+
const cached = this.cache.get(cacheKey, this.cacheMaxAge);
|
|
81
|
+
if (cached) {
|
|
82
|
+
console.log('✓ Using cached Figma file data (cache hit)');
|
|
83
|
+
return cached;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
console.log('Fetching from Figma API (this may take a moment)...');
|
|
87
|
+
try {
|
|
88
|
+
const response = await this.retryRequest(async () => {
|
|
89
|
+
return await this.axiosInstance.get(`/files/${fileKey}`, {
|
|
90
|
+
params: options,
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
console.log('✓ Successfully fetched from Figma API');
|
|
94
|
+
// Cache the result
|
|
95
|
+
if (this.cache) {
|
|
96
|
+
this.cache.set(cacheKey, response.data);
|
|
97
|
+
console.log('✓ Cached for future use');
|
|
98
|
+
}
|
|
99
|
+
return response.data;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw this.handleError(error, 'Failed to fetch Figma file');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get image resource URLs from file
|
|
107
|
+
* @param fileKey - Figma file ID
|
|
108
|
+
* @param nodeIds - List of node IDs to export
|
|
109
|
+
* @param format - Image format (png, jpg, svg, pdf)
|
|
110
|
+
* @returns Image URL mapping
|
|
111
|
+
*/
|
|
112
|
+
async getImages(fileKey, nodeIds, format = 'png') {
|
|
113
|
+
if (!fileKey) {
|
|
114
|
+
throw new Error('File key is required');
|
|
115
|
+
}
|
|
116
|
+
if (!nodeIds || nodeIds.length === 0) {
|
|
117
|
+
throw new Error('At least one node ID is required');
|
|
118
|
+
}
|
|
119
|
+
// Check cache first
|
|
120
|
+
const cacheKey = `images:${fileKey}:${nodeIds.join(',')}:${format}`;
|
|
121
|
+
if (this.cache) {
|
|
122
|
+
const cached = this.cache.get(cacheKey, this.cacheMaxAge);
|
|
123
|
+
if (cached) {
|
|
124
|
+
console.log('✓ Using cached image URLs');
|
|
125
|
+
return cached;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const response = await this.retryRequest(async () => {
|
|
130
|
+
return await this.axiosInstance.get(`/images/${fileKey}`, {
|
|
131
|
+
params: {
|
|
132
|
+
ids: nodeIds.join(','),
|
|
133
|
+
format,
|
|
134
|
+
scale: 2,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
if (response.data.err) {
|
|
139
|
+
throw new Error(`Figma API error: ${response.data.err}`);
|
|
140
|
+
}
|
|
141
|
+
// Cache the result
|
|
142
|
+
if (this.cache) {
|
|
143
|
+
this.cache.set(cacheKey, response.data);
|
|
144
|
+
console.log('✓ Cached image URLs');
|
|
145
|
+
}
|
|
146
|
+
return response.data;
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
throw this.handleError(error, 'Failed to fetch images');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Download image resource to local file
|
|
154
|
+
* @param imageUrl - Image URL
|
|
155
|
+
* @param outputPath - Save path
|
|
156
|
+
*/
|
|
157
|
+
async downloadImage(imageUrl, outputPath) {
|
|
158
|
+
if (!imageUrl) {
|
|
159
|
+
throw new Error('Image URL is required');
|
|
160
|
+
}
|
|
161
|
+
if (!outputPath) {
|
|
162
|
+
throw new Error('Output path is required');
|
|
163
|
+
}
|
|
164
|
+
// Check if file already exists (cached locally)
|
|
165
|
+
if (fs.existsSync(outputPath)) {
|
|
166
|
+
console.log(`✓ Using cached image: ${path.basename(outputPath)}`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
// Ensure directory exists
|
|
171
|
+
const dir = path.dirname(outputPath);
|
|
172
|
+
if (!fs.existsSync(dir)) {
|
|
173
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
174
|
+
}
|
|
175
|
+
console.log(`Downloading image: ${path.basename(outputPath)}...`);
|
|
176
|
+
const response = await this.retryRequest(async () => {
|
|
177
|
+
return await axios_1.default.get(imageUrl, {
|
|
178
|
+
responseType: 'arraybuffer',
|
|
179
|
+
timeout: 60000, // 60 seconds for image download
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
fs.writeFileSync(outputPath, response.data);
|
|
183
|
+
console.log(`✓ Downloaded: ${path.basename(outputPath)}`);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
throw this.handleError(error, 'Failed to download image');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Retry request with exponential backoff and Retry-After header support
|
|
191
|
+
*/
|
|
192
|
+
async retryRequest(requestFn, retries = this.maxRetries) {
|
|
193
|
+
try {
|
|
194
|
+
return await requestFn();
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
if (retries > 0 && this.isRetryableError(error)) {
|
|
198
|
+
// Check for Retry-After header (429 rate limit)
|
|
199
|
+
let delay = this.baseRetryDelay * (this.maxRetries - retries + 1);
|
|
200
|
+
if (axios_1.default.isAxiosError(error) && error.response?.status === 429) {
|
|
201
|
+
const retryAfter = error.response.headers['retry-after'];
|
|
202
|
+
if (retryAfter) {
|
|
203
|
+
const retryAfterSeconds = parseInt(retryAfter);
|
|
204
|
+
const retryAfterMs = retryAfterSeconds * 1000;
|
|
205
|
+
// If rate limit is more than 1 minute, don't retry
|
|
206
|
+
if (retryAfterSeconds > 60) {
|
|
207
|
+
const hours = Math.floor(retryAfterSeconds / 3600);
|
|
208
|
+
const minutes = Math.floor((retryAfterSeconds % 3600) / 60);
|
|
209
|
+
throw new Error(`Figma API rate limit exceeded. Please try again in ${hours}h ${minutes}m. ` +
|
|
210
|
+
`Tip: Use a different Figma token or wait for the rate limit to reset.`);
|
|
211
|
+
}
|
|
212
|
+
delay = retryAfterMs;
|
|
213
|
+
console.log(`Rate limited. Waiting ${retryAfterSeconds}s before retry...`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
await this.sleep(delay);
|
|
217
|
+
return this.retryRequest(requestFn, retries - 1);
|
|
218
|
+
}
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check if error is retryable (network errors, rate limits, server errors)
|
|
224
|
+
*/
|
|
225
|
+
isRetryableError(error) {
|
|
226
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
227
|
+
const axiosError = error;
|
|
228
|
+
// Retry on network errors or 5xx server errors or 429 rate limit
|
|
229
|
+
return (!axiosError.response ||
|
|
230
|
+
axiosError.response.status >= 500 ||
|
|
231
|
+
axiosError.response.status === 429);
|
|
232
|
+
}
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Sleep for specified milliseconds
|
|
237
|
+
*/
|
|
238
|
+
sleep(ms) {
|
|
239
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Handle and format errors
|
|
243
|
+
*/
|
|
244
|
+
handleError(error, message) {
|
|
245
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
246
|
+
const axiosError = error;
|
|
247
|
+
// Authentication error
|
|
248
|
+
if (axiosError.response?.status === 403) {
|
|
249
|
+
return new Error('Authentication failed. Please check your Figma access token.');
|
|
250
|
+
}
|
|
251
|
+
// Not found error
|
|
252
|
+
if (axiosError.response?.status === 404) {
|
|
253
|
+
return new Error('File not found. Please check the file key and ensure you have access to the file.');
|
|
254
|
+
}
|
|
255
|
+
// Rate limit error
|
|
256
|
+
if (axiosError.response?.status === 429) {
|
|
257
|
+
return new Error('Rate limit exceeded. Please try again later.');
|
|
258
|
+
}
|
|
259
|
+
// Other API errors
|
|
260
|
+
if (axiosError.response) {
|
|
261
|
+
const errorData = axiosError.response.data;
|
|
262
|
+
const errorMessage = errorData?.err || errorData?.message || 'Unknown API error';
|
|
263
|
+
return new Error(`${message}: ${errorMessage}`);
|
|
264
|
+
}
|
|
265
|
+
// Network errors
|
|
266
|
+
if (axiosError.request) {
|
|
267
|
+
return new Error(`${message}: Network error. Please check your internet connection.`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Generic error
|
|
271
|
+
return new Error(`${message}: ${error.message || 'Unknown error'}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
exports.FigmaAPIClient = FigmaAPIClient;
|
|
275
|
+
//# sourceMappingURL=FigmaAPIClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaAPIClient.js","sourceRoot":"","sources":["../../src/extraction/FigmaAPIClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple file-based cache for Figma API responses
|
|
3
|
+
* Reduces API calls and avoids rate limiting
|
|
4
|
+
*/
|
|
5
|
+
export declare class FigmaCache {
|
|
6
|
+
private cacheDir;
|
|
7
|
+
constructor(cacheDir?: string);
|
|
8
|
+
private ensureCacheDir;
|
|
9
|
+
private getCacheKey;
|
|
10
|
+
private getCachePath;
|
|
11
|
+
/**
|
|
12
|
+
* Get cached data if exists and not expired
|
|
13
|
+
*/
|
|
14
|
+
get<T>(key: string, maxAge?: number): T | null;
|
|
15
|
+
/**
|
|
16
|
+
* Set cache data
|
|
17
|
+
*/
|
|
18
|
+
set<T>(key: string, value: T): void;
|
|
19
|
+
/**
|
|
20
|
+
* Delete cache entry
|
|
21
|
+
*/
|
|
22
|
+
delete(key: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Clear all cache
|
|
25
|
+
*/
|
|
26
|
+
clear(): void;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=FigmaCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaCache.d.ts","sourceRoot":"","sources":["../../src/extraction/FigmaCache.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,SAAiB;IAKrC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IA2B9C;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAUnC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOzB;;OAEG;IACH,KAAK,IAAI,IAAI;CAQd"}
|
|
@@ -0,0 +1,120 @@
|
|
|
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.FigmaCache = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const crypto = __importStar(require("crypto"));
|
|
40
|
+
/**
|
|
41
|
+
* Simple file-based cache for Figma API responses
|
|
42
|
+
* Reduces API calls and avoids rate limiting
|
|
43
|
+
*/
|
|
44
|
+
class FigmaCache {
|
|
45
|
+
constructor(cacheDir = '.figma-cache') {
|
|
46
|
+
this.cacheDir = path.resolve(process.cwd(), cacheDir);
|
|
47
|
+
this.ensureCacheDir();
|
|
48
|
+
}
|
|
49
|
+
ensureCacheDir() {
|
|
50
|
+
if (!fs.existsSync(this.cacheDir)) {
|
|
51
|
+
fs.mkdirSync(this.cacheDir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
getCacheKey(key) {
|
|
55
|
+
return crypto.createHash('md5').update(key).digest('hex');
|
|
56
|
+
}
|
|
57
|
+
getCachePath(key) {
|
|
58
|
+
const hash = this.getCacheKey(key);
|
|
59
|
+
return path.join(this.cacheDir, `${hash}.json`);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get cached data if exists and not expired
|
|
63
|
+
*/
|
|
64
|
+
get(key, maxAge) {
|
|
65
|
+
const cachePath = this.getCachePath(key);
|
|
66
|
+
if (!fs.existsSync(cachePath)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const data = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
|
|
71
|
+
// Check expiration
|
|
72
|
+
if (maxAge && data.timestamp) {
|
|
73
|
+
const age = Date.now() - data.timestamp;
|
|
74
|
+
if (age > maxAge) {
|
|
75
|
+
this.delete(key);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return data.value;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
// Invalid cache, delete it
|
|
83
|
+
this.delete(key);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Set cache data
|
|
89
|
+
*/
|
|
90
|
+
set(key, value) {
|
|
91
|
+
const cachePath = this.getCachePath(key);
|
|
92
|
+
const data = {
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
value,
|
|
95
|
+
};
|
|
96
|
+
fs.writeFileSync(cachePath, JSON.stringify(data), 'utf-8');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Delete cache entry
|
|
100
|
+
*/
|
|
101
|
+
delete(key) {
|
|
102
|
+
const cachePath = this.getCachePath(key);
|
|
103
|
+
if (fs.existsSync(cachePath)) {
|
|
104
|
+
fs.unlinkSync(cachePath);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Clear all cache
|
|
109
|
+
*/
|
|
110
|
+
clear() {
|
|
111
|
+
if (fs.existsSync(this.cacheDir)) {
|
|
112
|
+
const files = fs.readdirSync(this.cacheDir);
|
|
113
|
+
for (const file of files) {
|
|
114
|
+
fs.unlinkSync(path.join(this.cacheDir, file));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.FigmaCache = FigmaCache;
|
|
120
|
+
//# sourceMappingURL=FigmaCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaCache.js","sourceRoot":"","sources":["../../src/extraction/FigmaCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP (Model Context Protocol) Client
|
|
3
|
+
* Handles direct communication with Figma Desktop via WebSocket
|
|
4
|
+
*/
|
|
5
|
+
import { FigmaFile } from './types';
|
|
6
|
+
export interface ConnectionStatus {
|
|
7
|
+
connected: boolean;
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface DesignChanges {
|
|
11
|
+
type: 'node_added' | 'node_removed' | 'node_modified';
|
|
12
|
+
nodeId: string;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
data?: any;
|
|
15
|
+
}
|
|
16
|
+
export declare class MCPClient {
|
|
17
|
+
private readonly wsUrl;
|
|
18
|
+
private ws;
|
|
19
|
+
private connected;
|
|
20
|
+
private messageId;
|
|
21
|
+
private pendingRequests;
|
|
22
|
+
private changeCallbacks;
|
|
23
|
+
private reconnectAttempts;
|
|
24
|
+
private readonly maxReconnectAttempts;
|
|
25
|
+
private readonly reconnectDelay;
|
|
26
|
+
constructor(wsUrl?: string);
|
|
27
|
+
/**
|
|
28
|
+
* Connect to Figma Desktop
|
|
29
|
+
* @returns Connection status
|
|
30
|
+
*/
|
|
31
|
+
connect(): Promise<ConnectionStatus>;
|
|
32
|
+
/**
|
|
33
|
+
* Get current open file data
|
|
34
|
+
* @returns Design file data
|
|
35
|
+
*/
|
|
36
|
+
getCurrentFile(): Promise<FigmaFile>;
|
|
37
|
+
/**
|
|
38
|
+
* Watch for design file changes
|
|
39
|
+
* @param callback - Change callback function
|
|
40
|
+
*/
|
|
41
|
+
watchChanges(callback: (changes: DesignChanges) => void): void;
|
|
42
|
+
/**
|
|
43
|
+
* Disconnect from Figma Desktop
|
|
44
|
+
*/
|
|
45
|
+
disconnect(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Send a request and wait for response
|
|
48
|
+
*/
|
|
49
|
+
private sendRequest;
|
|
50
|
+
/**
|
|
51
|
+
* Send a notification (no response expected)
|
|
52
|
+
*/
|
|
53
|
+
private sendNotification;
|
|
54
|
+
/**
|
|
55
|
+
* Handle incoming WebSocket messages
|
|
56
|
+
*/
|
|
57
|
+
private handleMessage;
|
|
58
|
+
/**
|
|
59
|
+
* Handle disconnection and attempt reconnection
|
|
60
|
+
*/
|
|
61
|
+
private handleDisconnect;
|
|
62
|
+
/**
|
|
63
|
+
* Notify all change callbacks
|
|
64
|
+
*/
|
|
65
|
+
private notifyChangeCallbacks;
|
|
66
|
+
/**
|
|
67
|
+
* Generate unique message ID
|
|
68
|
+
*/
|
|
69
|
+
private generateMessageId;
|
|
70
|
+
/**
|
|
71
|
+
* Check if currently connected
|
|
72
|
+
*/
|
|
73
|
+
isConnected(): boolean;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=MCPClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MCPClient.d.ts","sourceRoot":"","sources":["../../src/extraction/MCPClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,CAAC;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAcD,qBAAa,SAAS;IAgBR,OAAO,CAAC,QAAQ,CAAC,KAAK;IAflC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,eAAe,CAMnB;IACJ,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAK;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;gBAEV,KAAK,GAAE,MAA8B;IAMlE;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAiD1C;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,SAAS,CAAC;IAkB1C;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAmB9D;;OAEG;IACH,UAAU,IAAI,IAAI;IAkBlB;;OAEG;YACW,WAAW;IAiCzB;;OAEG;YACW,gBAAgB;IAe9B;;OAEG;IACH,OAAO,CAAC,aAAa;IA2BrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,WAAW,IAAI,OAAO;CAGvB"}
|