figma-console-mcp 0.1.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/LICENSE +21 -0
- package/README.md +328 -0
- package/dist/browser/base.d.ts +50 -0
- package/dist/browser/base.d.ts.map +1 -0
- package/dist/browser/base.js +6 -0
- package/dist/browser/base.js.map +1 -0
- package/dist/browser/local.d.ts +66 -0
- package/dist/browser/local.d.ts.map +1 -0
- package/dist/browser/local.js +223 -0
- package/dist/browser/local.js.map +1 -0
- package/dist/cloudflare/browser/base.js +5 -0
- package/dist/cloudflare/browser/cloudflare.js +156 -0
- package/dist/cloudflare/browser-manager.js +157 -0
- package/dist/cloudflare/core/config.js +161 -0
- package/dist/cloudflare/core/console-monitor.js +382 -0
- package/dist/cloudflare/core/enrichment/enrichment-service.js +272 -0
- package/dist/cloudflare/core/enrichment/index.js +7 -0
- package/dist/cloudflare/core/enrichment/relationship-mapper.js +351 -0
- package/dist/cloudflare/core/enrichment/style-resolver.js +326 -0
- package/dist/cloudflare/core/figma-api.js +273 -0
- package/dist/cloudflare/core/figma-desktop-connector.js +383 -0
- package/dist/cloudflare/core/figma-style-extractor.js +311 -0
- package/dist/cloudflare/core/figma-tools.js +2299 -0
- package/dist/cloudflare/core/logger.js +53 -0
- package/dist/cloudflare/core/snippet-injector.js +96 -0
- package/dist/cloudflare/core/types/enriched.js +5 -0
- package/dist/cloudflare/core/types/index.js +4 -0
- package/dist/cloudflare/index.js +1059 -0
- package/dist/cloudflare/test-browser.js +88 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +141 -0
- package/dist/config.js.map +1 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +162 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/console-monitor.d.ts +81 -0
- package/dist/core/console-monitor.d.ts.map +1 -0
- package/dist/core/console-monitor.js +383 -0
- package/dist/core/console-monitor.js.map +1 -0
- package/dist/core/enrichment/enrichment-service.d.ts +52 -0
- package/dist/core/enrichment/enrichment-service.d.ts.map +1 -0
- package/dist/core/enrichment/enrichment-service.js +273 -0
- package/dist/core/enrichment/enrichment-service.js.map +1 -0
- package/dist/core/enrichment/index.d.ts +8 -0
- package/dist/core/enrichment/index.d.ts.map +1 -0
- package/dist/core/enrichment/index.js +8 -0
- package/dist/core/enrichment/index.js.map +1 -0
- package/dist/core/enrichment/relationship-mapper.d.ts +106 -0
- package/dist/core/enrichment/relationship-mapper.d.ts.map +1 -0
- package/dist/core/enrichment/relationship-mapper.js +352 -0
- package/dist/core/enrichment/relationship-mapper.js.map +1 -0
- package/dist/core/enrichment/style-resolver.d.ts +80 -0
- package/dist/core/enrichment/style-resolver.d.ts.map +1 -0
- package/dist/core/enrichment/style-resolver.js +327 -0
- package/dist/core/enrichment/style-resolver.js.map +1 -0
- package/dist/core/figma-api.d.ts +137 -0
- package/dist/core/figma-api.d.ts.map +1 -0
- package/dist/core/figma-api.js +274 -0
- package/dist/core/figma-api.js.map +1 -0
- package/dist/core/figma-desktop-connector.d.ts +52 -0
- package/dist/core/figma-desktop-connector.d.ts.map +1 -0
- package/dist/core/figma-desktop-connector.js +384 -0
- package/dist/core/figma-desktop-connector.js.map +1 -0
- package/dist/core/figma-style-extractor.d.ts +76 -0
- package/dist/core/figma-style-extractor.d.ts.map +1 -0
- package/dist/core/figma-style-extractor.js +312 -0
- package/dist/core/figma-style-extractor.js.map +1 -0
- package/dist/core/figma-tools.d.ts +15 -0
- package/dist/core/figma-tools.d.ts.map +1 -0
- package/dist/core/figma-tools.js +2300 -0
- package/dist/core/figma-tools.js.map +1 -0
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +54 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/snippet-injector.d.ts +24 -0
- package/dist/core/snippet-injector.d.ts.map +1 -0
- package/dist/core/snippet-injector.js +97 -0
- package/dist/core/snippet-injector.js.map +1 -0
- package/dist/core/types/enriched.d.ts +213 -0
- package/dist/core/types/enriched.d.ts.map +1 -0
- package/dist/core/types/enriched.js +6 -0
- package/dist/core/types/enriched.js.map +1 -0
- package/dist/core/types/index.d.ts +112 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +5 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +57 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +668 -0
- package/dist/local.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +45 -0
- package/dist/logger.js.map +1 -0
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +99 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/index.d.ts +15 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +184 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types/index.d.ts +102 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/figma-desktop-bridge/README.md +232 -0
- package/figma-desktop-bridge/code.js +133 -0
- package/figma-desktop-bridge/manifest.json +13 -0
- package/figma-desktop-bridge/ui.html +200 -0
- package/package.json +77 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Desktop Connector
|
|
3
|
+
*
|
|
4
|
+
* This service connects directly to Figma Desktop's plugin context
|
|
5
|
+
* to execute code with access to the full Figma Plugin API,
|
|
6
|
+
* including variables without Enterprise access.
|
|
7
|
+
*
|
|
8
|
+
* Uses Puppeteer's Worker API to directly access plugin workers,
|
|
9
|
+
* bypassing CDP context enumeration limitations.
|
|
10
|
+
*/
|
|
11
|
+
import { logger } from './logger.js';
|
|
12
|
+
export class FigmaDesktopConnector {
|
|
13
|
+
constructor(page) {
|
|
14
|
+
this.page = page;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initialize connection to Figma Desktop's plugin context
|
|
18
|
+
* No setup needed - Puppeteer handles worker access automatically
|
|
19
|
+
*/
|
|
20
|
+
async initialize() {
|
|
21
|
+
logger.info('Figma Desktop connector initialized (using Puppeteer Worker API)');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Execute code in Figma's plugin context where the figma API is available
|
|
25
|
+
* Uses Puppeteer's direct worker access instead of CDP context enumeration
|
|
26
|
+
*/
|
|
27
|
+
async executeInPluginContext(code) {
|
|
28
|
+
try {
|
|
29
|
+
// Use Puppeteer's worker API directly - this can access plugin workers
|
|
30
|
+
// that CDP's Runtime.getExecutionContexts cannot enumerate
|
|
31
|
+
const workers = this.page.workers();
|
|
32
|
+
// Log to browser console so MCP can capture it
|
|
33
|
+
await this.page.evaluate((count, urls) => {
|
|
34
|
+
console.log(`[DESKTOP_CONNECTOR] Found ${count} workers via Puppeteer API:`, urls);
|
|
35
|
+
}, workers.length, workers.map(w => w.url()));
|
|
36
|
+
logger.info({
|
|
37
|
+
workerCount: workers.length,
|
|
38
|
+
workerUrls: workers.map(w => w.url())
|
|
39
|
+
}, 'Found workers via Puppeteer API');
|
|
40
|
+
// Try each worker to find one with figma API
|
|
41
|
+
for (const worker of workers) {
|
|
42
|
+
try {
|
|
43
|
+
// Log to browser console
|
|
44
|
+
await this.page.evaluate((url) => {
|
|
45
|
+
console.log(`[DESKTOP_CONNECTOR] Checking worker: ${url}`);
|
|
46
|
+
}, worker.url());
|
|
47
|
+
// Check if this worker has the figma API
|
|
48
|
+
// Use string evaluation to avoid TypeScript errors about figma global
|
|
49
|
+
const hasFigmaApi = await worker.evaluate('typeof figma !== "undefined"');
|
|
50
|
+
// Log result to browser console
|
|
51
|
+
await this.page.evaluate((url, hasApi) => {
|
|
52
|
+
console.log(`[DESKTOP_CONNECTOR] Worker ${url} has figma API: ${hasApi}`);
|
|
53
|
+
}, worker.url(), hasFigmaApi);
|
|
54
|
+
if (hasFigmaApi) {
|
|
55
|
+
logger.info({ workerUrl: worker.url() }, 'Found worker with Figma API');
|
|
56
|
+
await this.page.evaluate((url) => {
|
|
57
|
+
console.log(`[DESKTOP_CONNECTOR] ✅ SUCCESS! Found worker with Figma API: ${url}`);
|
|
58
|
+
}, worker.url());
|
|
59
|
+
// Execute the code in this worker context
|
|
60
|
+
// Wrap the code in a function to ensure proper evaluation
|
|
61
|
+
const wrappedCode = `(${code})`;
|
|
62
|
+
const result = await worker.evaluate(wrappedCode);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (workerError) {
|
|
67
|
+
// This worker doesn't have figma API or evaluation failed, try next
|
|
68
|
+
await this.page.evaluate((url, err) => {
|
|
69
|
+
console.error(`[DESKTOP_CONNECTOR] ❌ Worker ${url} check failed:`, err);
|
|
70
|
+
}, worker.url(), workerError instanceof Error ? workerError.message : String(workerError));
|
|
71
|
+
logger.error({ error: workerError, workerUrl: worker.url() }, 'Worker check failed, trying next');
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// If no worker found with figma API, throw error
|
|
76
|
+
throw new Error('No plugin worker found with Figma API. Make sure a plugin is running in Figma Desktop.');
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger.error({ error, code: code.substring(0, 200) }, 'Failed to execute in plugin context');
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get Figma variables from plugin UI window object
|
|
85
|
+
* This bypasses Figma's plugin sandbox security restrictions
|
|
86
|
+
* by accessing data that the plugin posted to its UI iframe
|
|
87
|
+
*/
|
|
88
|
+
async getVariablesFromPluginUI(fileKey) {
|
|
89
|
+
try {
|
|
90
|
+
// Log to browser console
|
|
91
|
+
await this.page.evaluate((key) => {
|
|
92
|
+
console.log(`[DESKTOP_CONNECTOR] 🚀 getVariablesFromPluginUI() called, fileKey: ${key}`);
|
|
93
|
+
}, fileKey);
|
|
94
|
+
logger.info({ fileKey }, 'Getting variables from plugin UI iframe');
|
|
95
|
+
// Get all frames (iframes) in the page
|
|
96
|
+
const frames = this.page.frames();
|
|
97
|
+
await this.page.evaluate((count) => {
|
|
98
|
+
console.log(`[DESKTOP_CONNECTOR] Found ${count} frames (iframes)`);
|
|
99
|
+
}, frames.length);
|
|
100
|
+
logger.info({ frameCount: frames.length }, 'Found frames in page');
|
|
101
|
+
// Try to find plugin UI iframe with variables data
|
|
102
|
+
for (const frame of frames) {
|
|
103
|
+
try {
|
|
104
|
+
const frameUrl = frame.url();
|
|
105
|
+
await this.page.evaluate((url) => {
|
|
106
|
+
console.log(`[DESKTOP_CONNECTOR] Checking frame: ${url}`);
|
|
107
|
+
}, frameUrl);
|
|
108
|
+
// Check if this frame has our variables data
|
|
109
|
+
const hasData = await frame.evaluate('typeof window.__figmaVariablesData !== "undefined" && window.__figmaVariablesReady === true');
|
|
110
|
+
await this.page.evaluate((url, has) => {
|
|
111
|
+
console.log(`[DESKTOP_CONNECTOR] Frame ${url} has variables data: ${has}`);
|
|
112
|
+
}, frameUrl, hasData);
|
|
113
|
+
if (hasData) {
|
|
114
|
+
logger.info({ frameUrl }, 'Found frame with variables data');
|
|
115
|
+
await this.page.evaluate((url) => {
|
|
116
|
+
console.log(`[DESKTOP_CONNECTOR] ✅ SUCCESS! Found plugin UI with variables data: ${url}`);
|
|
117
|
+
}, frameUrl);
|
|
118
|
+
// Get the data from window object
|
|
119
|
+
const result = await frame.evaluate('window.__figmaVariablesData');
|
|
120
|
+
logger.info({
|
|
121
|
+
variableCount: result.variables?.length,
|
|
122
|
+
collectionCount: result.variableCollections?.length
|
|
123
|
+
}, 'Successfully retrieved variables from plugin UI');
|
|
124
|
+
await this.page.evaluate((varCount, collCount) => {
|
|
125
|
+
console.log(`[DESKTOP_CONNECTOR] ✅ Retrieved ${varCount} variables in ${collCount} collections`);
|
|
126
|
+
}, result.variables?.length || 0, result.variableCollections?.length || 0);
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (frameError) {
|
|
131
|
+
await this.page.evaluate((url, err) => {
|
|
132
|
+
console.log(`[DESKTOP_CONNECTOR] Frame ${url} check failed: ${err}`);
|
|
133
|
+
}, frame.url(), frameError instanceof Error ? frameError.message : String(frameError));
|
|
134
|
+
logger.debug({ error: frameError, frameUrl: frame.url() }, 'Frame check failed, trying next');
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// If no frame found with data, throw error
|
|
139
|
+
throw new Error('No plugin UI found with variables data. Make sure the Variables Exporter (Persistent) plugin is running.');
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
logger.error({ error }, 'Failed to get variables from plugin UI');
|
|
143
|
+
await this.page.evaluate((msg) => {
|
|
144
|
+
console.error('[DESKTOP_CONNECTOR] ❌ getVariablesFromPluginUI failed:', msg);
|
|
145
|
+
}, error instanceof Error ? error.message : String(error));
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get component data by node ID from plugin UI window object
|
|
151
|
+
* This bypasses the REST API bug where descriptions are missing
|
|
152
|
+
* by accessing data from the Desktop Bridge plugin via its UI iframe
|
|
153
|
+
*/
|
|
154
|
+
async getComponentFromPluginUI(nodeId) {
|
|
155
|
+
try {
|
|
156
|
+
// Log to browser console
|
|
157
|
+
await this.page.evaluate((id) => {
|
|
158
|
+
console.log(`[DESKTOP_CONNECTOR] 🎯 getComponentFromPluginUI() called, nodeId: ${id}`);
|
|
159
|
+
}, nodeId);
|
|
160
|
+
logger.info({ nodeId }, 'Getting component from plugin UI iframe');
|
|
161
|
+
// Get all frames (iframes) in the page
|
|
162
|
+
const frames = this.page.frames();
|
|
163
|
+
await this.page.evaluate((count) => {
|
|
164
|
+
console.log(`[DESKTOP_CONNECTOR] Found ${count} frames (iframes)`);
|
|
165
|
+
}, frames.length);
|
|
166
|
+
logger.info({ frameCount: frames.length }, 'Found frames in page');
|
|
167
|
+
// Try to find plugin UI iframe with requestComponentData function
|
|
168
|
+
for (const frame of frames) {
|
|
169
|
+
try {
|
|
170
|
+
const frameUrl = frame.url();
|
|
171
|
+
await this.page.evaluate((url) => {
|
|
172
|
+
console.log(`[DESKTOP_CONNECTOR] Checking frame: ${url}`);
|
|
173
|
+
}, frameUrl);
|
|
174
|
+
// Check if this frame has our requestComponentData function
|
|
175
|
+
const hasFunction = await frame.evaluate('typeof window.requestComponentData === "function"');
|
|
176
|
+
await this.page.evaluate((url, has) => {
|
|
177
|
+
console.log(`[DESKTOP_CONNECTOR] Frame ${url} has requestComponentData: ${has}`);
|
|
178
|
+
}, frameUrl, hasFunction);
|
|
179
|
+
if (hasFunction) {
|
|
180
|
+
logger.info({ frameUrl }, 'Found frame with requestComponentData function');
|
|
181
|
+
await this.page.evaluate((url) => {
|
|
182
|
+
console.log(`[DESKTOP_CONNECTOR] ✅ SUCCESS! Found plugin UI with requestComponentData: ${url}`);
|
|
183
|
+
}, frameUrl);
|
|
184
|
+
// Call the function with the nodeId - it returns a Promise
|
|
185
|
+
// Use JSON.stringify to safely pass the nodeId as a string literal
|
|
186
|
+
const result = await frame.evaluate(`window.requestComponentData(${JSON.stringify(nodeId)})`);
|
|
187
|
+
logger.info({
|
|
188
|
+
nodeId,
|
|
189
|
+
componentName: result.component?.name,
|
|
190
|
+
hasDescription: !!result.component?.description
|
|
191
|
+
}, 'Successfully retrieved component from plugin UI');
|
|
192
|
+
await this.page.evaluate((name, hasDesc) => {
|
|
193
|
+
console.log(`[DESKTOP_CONNECTOR] ✅ Retrieved component "${name}", has description: ${hasDesc}`);
|
|
194
|
+
}, result.component?.name, !!result.component?.description);
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (frameError) {
|
|
199
|
+
await this.page.evaluate((url, err) => {
|
|
200
|
+
console.log(`[DESKTOP_CONNECTOR] Frame ${url} check failed: ${err}`);
|
|
201
|
+
}, frame.url(), frameError instanceof Error ? frameError.message : String(frameError));
|
|
202
|
+
logger.debug({ error: frameError, frameUrl: frame.url() }, 'Frame check failed, trying next');
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// If no frame found with function, throw error
|
|
207
|
+
throw new Error('No plugin UI found with requestComponentData function. Make sure the Desktop Bridge plugin is running.');
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
logger.error({ error, nodeId }, 'Failed to get component from plugin UI');
|
|
211
|
+
await this.page.evaluate((msg) => {
|
|
212
|
+
console.error('[DESKTOP_CONNECTOR] ❌ getComponentFromPluginUI failed:', msg);
|
|
213
|
+
}, error instanceof Error ? error.message : String(error));
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get Figma variables using the desktop connection
|
|
219
|
+
* This bypasses the Enterprise requirement!
|
|
220
|
+
*/
|
|
221
|
+
async getVariables(fileKey) {
|
|
222
|
+
// Log to browser console
|
|
223
|
+
await this.page.evaluate((key) => {
|
|
224
|
+
console.log(`[DESKTOP_CONNECTOR] 🚀 getVariables() called, fileKey: ${key}`);
|
|
225
|
+
}, fileKey);
|
|
226
|
+
logger.info({ fileKey }, 'Getting variables via Desktop connection');
|
|
227
|
+
const code = `
|
|
228
|
+
(async () => {
|
|
229
|
+
try {
|
|
230
|
+
// Check if we're in the right context
|
|
231
|
+
if (typeof figma === 'undefined') {
|
|
232
|
+
throw new Error('Figma API not available in this context');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Get variables just like the official MCP does
|
|
236
|
+
const variables = await figma.variables.getLocalVariablesAsync();
|
|
237
|
+
const collections = await figma.variables.getLocalVariableCollectionsAsync();
|
|
238
|
+
|
|
239
|
+
// Format the response
|
|
240
|
+
const result = {
|
|
241
|
+
success: true,
|
|
242
|
+
timestamp: Date.now(),
|
|
243
|
+
variables: variables.map(v => ({
|
|
244
|
+
id: v.id,
|
|
245
|
+
name: v.name,
|
|
246
|
+
key: v.key,
|
|
247
|
+
resolvedType: v.resolvedType,
|
|
248
|
+
valuesByMode: v.valuesByMode,
|
|
249
|
+
variableCollectionId: v.variableCollectionId,
|
|
250
|
+
scopes: v.scopes,
|
|
251
|
+
description: v.description,
|
|
252
|
+
hiddenFromPublishing: v.hiddenFromPublishing
|
|
253
|
+
})),
|
|
254
|
+
variableCollections: collections.map(c => ({
|
|
255
|
+
id: c.id,
|
|
256
|
+
name: c.name,
|
|
257
|
+
key: c.key,
|
|
258
|
+
modes: c.modes,
|
|
259
|
+
defaultModeId: c.defaultModeId,
|
|
260
|
+
variableIds: c.variableIds
|
|
261
|
+
}))
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
return result;
|
|
265
|
+
} catch (error) {
|
|
266
|
+
return {
|
|
267
|
+
success: false,
|
|
268
|
+
error: error.message
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
})()
|
|
272
|
+
`;
|
|
273
|
+
try {
|
|
274
|
+
const result = await this.executeInPluginContext(code);
|
|
275
|
+
if (!result.success) {
|
|
276
|
+
throw new Error(result.error || 'Failed to get variables');
|
|
277
|
+
}
|
|
278
|
+
logger.info({
|
|
279
|
+
variableCount: result.variables?.length,
|
|
280
|
+
collectionCount: result.variableCollections?.length
|
|
281
|
+
}, 'Successfully retrieved variables via Desktop');
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
logger.error({ error }, 'Failed to get variables via Desktop');
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Clean up resources (no-op since we use Puppeteer's built-in worker management)
|
|
291
|
+
*/
|
|
292
|
+
/**
|
|
293
|
+
* Get component data by node ID using Plugin API
|
|
294
|
+
* This bypasses the REST API bug where descriptions are missing
|
|
295
|
+
*/
|
|
296
|
+
async getComponentByNodeId(nodeId) {
|
|
297
|
+
await this.page.evaluate((id) => {
|
|
298
|
+
console.log(`[DESKTOP_CONNECTOR] 🎯 getComponentByNodeId() called, nodeId: ${id}`);
|
|
299
|
+
}, nodeId);
|
|
300
|
+
logger.info({ nodeId }, 'Getting component via Desktop Plugin API');
|
|
301
|
+
const code = `
|
|
302
|
+
(async () => {
|
|
303
|
+
try {
|
|
304
|
+
// Check if we're in the right context
|
|
305
|
+
if (typeof figma === 'undefined') {
|
|
306
|
+
throw new Error('Figma API not available in this context');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Get the node by ID
|
|
310
|
+
const node = figma.getNodeById('${nodeId}');
|
|
311
|
+
|
|
312
|
+
if (!node) {
|
|
313
|
+
throw new Error('Node not found with ID: ${nodeId}');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Check if it's a component-like node
|
|
317
|
+
if (node.type !== 'COMPONENT' && node.type !== 'COMPONENT_SET' && node.type !== 'INSTANCE') {
|
|
318
|
+
throw new Error('Node is not a component, component set, or instance. Type: ' + node.type);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Extract component data including description fields
|
|
322
|
+
const result = {
|
|
323
|
+
success: true,
|
|
324
|
+
timestamp: Date.now(),
|
|
325
|
+
component: {
|
|
326
|
+
id: node.id,
|
|
327
|
+
name: node.name,
|
|
328
|
+
type: node.type,
|
|
329
|
+
description: node.description || null,
|
|
330
|
+
descriptionMarkdown: node.descriptionMarkdown || null,
|
|
331
|
+
// Include other useful properties
|
|
332
|
+
visible: node.visible,
|
|
333
|
+
locked: node.locked,
|
|
334
|
+
// For components with properties
|
|
335
|
+
componentPropertyDefinitions: node.type === 'COMPONENT' || node.type === 'COMPONENT_SET'
|
|
336
|
+
? node.componentPropertyDefinitions
|
|
337
|
+
: undefined,
|
|
338
|
+
// Get children info (lightweight)
|
|
339
|
+
children: node.children ? node.children.map(child => ({
|
|
340
|
+
id: child.id,
|
|
341
|
+
name: child.name,
|
|
342
|
+
type: child.type
|
|
343
|
+
})) : undefined
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
return result;
|
|
348
|
+
} catch (error) {
|
|
349
|
+
return {
|
|
350
|
+
success: false,
|
|
351
|
+
error: error.message,
|
|
352
|
+
stack: error.stack
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
})()
|
|
356
|
+
`;
|
|
357
|
+
try {
|
|
358
|
+
const result = await this.executeInPluginContext(code);
|
|
359
|
+
if (!result.success) {
|
|
360
|
+
throw new Error(result.error || 'Failed to get component data');
|
|
361
|
+
}
|
|
362
|
+
logger.info({
|
|
363
|
+
nodeId,
|
|
364
|
+
componentName: result.component?.name,
|
|
365
|
+
hasDescription: !!result.component?.description
|
|
366
|
+
}, 'Successfully retrieved component via Desktop Plugin API');
|
|
367
|
+
await this.page.evaluate((name, hasDesc) => {
|
|
368
|
+
console.log(`[DESKTOP_CONNECTOR] ✅ Retrieved component "${name}", has description: ${hasDesc}`);
|
|
369
|
+
}, result.component?.name, !!result.component?.description);
|
|
370
|
+
return result;
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
logger.error({ error, nodeId }, 'Failed to get component via Desktop Plugin API');
|
|
374
|
+
await this.page.evaluate((id, err) => {
|
|
375
|
+
console.error(`[DESKTOP_CONNECTOR] ❌ getComponentByNodeId failed for ${id}:`, err);
|
|
376
|
+
}, nodeId, error instanceof Error ? error.message : String(error));
|
|
377
|
+
throw error;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async dispose() {
|
|
381
|
+
logger.info('Figma Desktop connector disposed');
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=figma-desktop-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figma-desktop-connector.js","sourceRoot":"","sources":["../../src/core/figma-desktop-connector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,qBAAqB;IAGhC,YAAY,IAAU;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAClF,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,sBAAsB,CAAU,IAAY;QAChD,IAAI,CAAC;YACH,uEAAuE;YACvE,2DAA2D;YAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAEpC,+CAA+C;YAC/C,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;gBACvC,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,6BAA6B,EAAE,IAAI,CAAC,CAAC;YACrF,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAE9C,MAAM,CAAC,IAAI,CAAC;gBACV,WAAW,EAAE,OAAO,CAAC,MAAM;gBAC3B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;aACtC,EAAE,iCAAiC,CAAC,CAAC;YAEtC,6CAA6C;YAC7C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC;oBACH,yBAAyB;oBACzB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;wBAC/B,OAAO,CAAC,GAAG,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;oBAC7D,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;oBAEjB,yCAAyC;oBACzC,sEAAsE;oBACtE,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC;oBAE1E,gCAAgC;oBAChC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;wBACvC,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,mBAAmB,MAAM,EAAE,CAAC,CAAC;oBAC5E,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;oBAE9B,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,6BAA6B,CAAC,CAAC;wBAExE,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;4BAC/B,OAAO,CAAC,GAAG,CAAC,+DAA+D,GAAG,EAAE,CAAC,CAAC;wBACpF,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;wBAEjB,0CAA0C;wBAC1C,0DAA0D;wBAC1D,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC;wBAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;wBAClD,OAAO,MAAW,CAAC;oBACrB,CAAC;gBACH,CAAC;gBAAC,OAAO,WAAW,EAAE,CAAC;oBACrB,oEAAoE;oBACpE,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBACpC,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,gBAAgB,EAAE,GAAG,CAAC,CAAC;oBAC1E,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;oBAE3F,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,kCAAkC,CAAC,CAAC;oBAClG,SAAS;gBACX,CAAC;YACH,CAAC;YAED,iDAAiD;YACjD,MAAM,IAAI,KAAK,CAAC,wFAAwF,CAAC,CAAC;QAC5G,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,qCAAqC,CAAC,CAAC;YAC7F,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAGD;;;;OAIG;IACH,KAAK,CAAC,wBAAwB,CAAC,OAAgB;QAC7C,IAAI,CAAC;YACH,yBAAyB;YACzB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC/B,OAAO,CAAC,GAAG,CAAC,sEAAsE,GAAG,EAAE,CAAC,CAAC;YAC3F,CAAC,EAAE,OAAO,CAAC,CAAC;YAEZ,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,yCAAyC,CAAC,CAAC;YAEpE,uCAAuC;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAElC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;gBACjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,mBAAmB,CAAC,CAAC;YACrE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAElB,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAEnE,mDAAmD;YACnD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;oBAE7B,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;wBAC/B,OAAO,CAAC,GAAG,CAAC,uCAAuC,GAAG,EAAE,CAAC,CAAC;oBAC5D,CAAC,EAAE,QAAQ,CAAC,CAAC;oBAEb,6CAA6C;oBAC7C,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,6FAA6F,CAAC,CAAC;oBAEpI,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBACpC,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,wBAAwB,GAAG,EAAE,CAAC,CAAC;oBAC7E,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAEtB,IAAI,OAAO,EAAE,CAAC;wBACZ,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,iCAAiC,CAAC,CAAC;wBAE7D,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;4BAC/B,OAAO,CAAC,GAAG,CAAC,uEAAuE,GAAG,EAAE,CAAC,CAAC;wBAC5F,CAAC,EAAE,QAAQ,CAAC,CAAC;wBAEb,kCAAkC;wBAClC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,6BAA6B,CAAQ,CAAC;wBAE1E,MAAM,CAAC,IAAI,CACT;4BACE,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM;4BACvC,eAAe,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM;yBACpD,EACD,iDAAiD,CAClD,CAAC;wBAEF,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE;4BAC/C,OAAO,CAAC,GAAG,CAAC,mCAAmC,QAAQ,iBAAiB,SAAS,cAAc,CAAC,CAAC;wBACnG,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;wBAE3E,OAAO,MAAM,CAAC;oBAChB,CAAC;gBACH,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBACpC,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,kBAAkB,GAAG,EAAE,CAAC,CAAC;oBACvE,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;oBAEvF,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,iCAAiC,CAAC,CAAC;oBAC9F,SAAS;gBACX,CAAC;YACH,CAAC;YAED,2CAA2C;YAC3C,MAAM,IAAI,KAAK,CAAC,0GAA0G,CAAC,CAAC;QAC9H,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,wCAAwC,CAAC,CAAC;YAElE,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC/B,OAAO,CAAC,KAAK,CAAC,wDAAwD,EAAE,GAAG,CAAC,CAAC;YAC/E,CAAC,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAE3D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,wBAAwB,CAAC,MAAc;QAC3C,IAAI,CAAC;YACH,yBAAyB;YACzB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE;gBAC9B,OAAO,CAAC,GAAG,CAAC,qEAAqE,EAAE,EAAE,CAAC,CAAC;YACzF,CAAC,EAAE,MAAM,CAAC,CAAC;YAEX,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,yCAAyC,CAAC,CAAC;YAEnE,uCAAuC;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAElC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;gBACjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,mBAAmB,CAAC,CAAC;YACrE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAElB,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAEnE,kEAAkE;YAClE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;oBAE7B,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;wBAC/B,OAAO,CAAC,GAAG,CAAC,uCAAuC,GAAG,EAAE,CAAC,CAAC;oBAC5D,CAAC,EAAE,QAAQ,CAAC,CAAC;oBAEb,4DAA4D;oBAC5D,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,mDAAmD,CAAC,CAAC;oBAE9F,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBACpC,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,8BAA8B,GAAG,EAAE,CAAC,CAAC;oBACnF,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;oBAE1B,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,gDAAgD,CAAC,CAAC;wBAE5E,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;4BAC/B,OAAO,CAAC,GAAG,CAAC,6EAA6E,GAAG,EAAE,CAAC,CAAC;wBAClG,CAAC,EAAE,QAAQ,CAAC,CAAC;wBAEb,2DAA2D;wBAC3D,mEAAmE;wBACnE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAQ,CAAC;wBAErG,MAAM,CAAC,IAAI,CACT;4BACE,MAAM;4BACN,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI;4BACrC,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW;yBAChD,EACD,iDAAiD,CAClD,CAAC;wBAEF,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;4BACzC,OAAO,CAAC,GAAG,CAAC,8CAA8C,IAAI,uBAAuB,OAAO,EAAE,CAAC,CAAC;wBAClG,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;wBAE5D,OAAO,MAAM,CAAC;oBAChB,CAAC;gBACH,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBACpC,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,kBAAkB,GAAG,EAAE,CAAC,CAAC;oBACvE,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;oBAEvF,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,iCAAiC,CAAC,CAAC;oBAC9F,SAAS;gBACX,CAAC;YACH,CAAC;YAED,+CAA+C;YAC/C,MAAM,IAAI,KAAK,CAAC,wGAAwG,CAAC,CAAC;QAC5H,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,wCAAwC,CAAC,CAAC;YAE1E,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC/B,OAAO,CAAC,KAAK,CAAC,wDAAwD,EAAE,GAAG,CAAC,CAAC;YAC/E,CAAC,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAE3D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,OAAgB;QACjC,yBAAyB;QACzB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,0DAA0D,GAAG,EAAE,CAAC,CAAC;QAC/E,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,0CAA0C,CAAC,CAAC;QAErE,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6CZ,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAEvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,yBAAyB,CAAC,CAAC;YAC7D,CAAC;YAED,MAAM,CAAC,IAAI,CACT;gBACE,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM;gBACvC,eAAe,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM;aACpD,EACD,8CAA8C,CAC/C,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,qCAAqC,CAAC,CAAC;YAC/D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IAEH;;;OAGG;IACH,KAAK,CAAC,oBAAoB,CAAC,MAAc;QACvC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE;YAC9B,OAAO,CAAC,GAAG,CAAC,iEAAiE,EAAE,EAAE,CAAC,CAAC;QACrF,CAAC,EAAE,MAAM,CAAC,CAAC;QAEX,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,0CAA0C,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAG;;;;;;;;;4CAS2B,MAAM;;;uDAGK,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2CxD,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAEvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,8BAA8B,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,CAAC,IAAI,CACT;gBACE,MAAM;gBACN,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI;gBACrC,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW;aAChD,EACD,yDAAyD,CAC1D,CAAC;YAEF,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;gBACzC,OAAO,CAAC,GAAG,CAAC,8CAA8C,IAAI,uBAAuB,OAAO,EAAE,CAAC,CAAC;YAClG,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAE5D,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gDAAgD,CAAC,CAAC;YAElF,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE;gBACnC,OAAO,CAAC,KAAK,CAAC,yDAAyD,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACrF,CAAC,EAAE,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAEnE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAClD,CAAC;CACF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Style Extractor
|
|
3
|
+
*
|
|
4
|
+
* Extracts style information (colors, typography, spacing) from Figma files
|
|
5
|
+
* using the REST API /files endpoint. This provides an alternative to the
|
|
6
|
+
* Enterprise-only Variables API by parsing style data directly from nodes.
|
|
7
|
+
*
|
|
8
|
+
* Based on the approach used by Figma-Context-MCP
|
|
9
|
+
*/
|
|
10
|
+
interface ExtractedVariable {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
value: string;
|
|
14
|
+
type: 'COLOR' | 'TYPOGRAPHY' | 'SPACING' | 'RADIUS' | 'EFFECT';
|
|
15
|
+
category?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
nodeId?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class FigmaStyleExtractor {
|
|
20
|
+
private extractedVariables;
|
|
21
|
+
private colorIndex;
|
|
22
|
+
private typographyIndex;
|
|
23
|
+
private spacingIndex;
|
|
24
|
+
private radiusIndex;
|
|
25
|
+
/**
|
|
26
|
+
* Extract style "variables" from Figma file data
|
|
27
|
+
* This mimics what users would see as variables in Figma
|
|
28
|
+
*/
|
|
29
|
+
extractStylesFromFile(fileData: any): Promise<ExtractedVariable[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Process a single node and extract style information
|
|
32
|
+
*/
|
|
33
|
+
private processNode;
|
|
34
|
+
/**
|
|
35
|
+
* Extract color variable
|
|
36
|
+
*/
|
|
37
|
+
private extractColor;
|
|
38
|
+
/**
|
|
39
|
+
* Extract typography variable
|
|
40
|
+
*/
|
|
41
|
+
private extractTypography;
|
|
42
|
+
/**
|
|
43
|
+
* Extract spacing variable
|
|
44
|
+
*/
|
|
45
|
+
private extractSpacing;
|
|
46
|
+
/**
|
|
47
|
+
* Extract radius variable
|
|
48
|
+
*/
|
|
49
|
+
private extractRadius;
|
|
50
|
+
/**
|
|
51
|
+
* Process Figma styles object
|
|
52
|
+
*/
|
|
53
|
+
private processStyles;
|
|
54
|
+
/**
|
|
55
|
+
* Helper to infer color category from node name
|
|
56
|
+
*/
|
|
57
|
+
private inferColorCategory;
|
|
58
|
+
/**
|
|
59
|
+
* Generate a meaningful color name
|
|
60
|
+
*/
|
|
61
|
+
private generateColorName;
|
|
62
|
+
/**
|
|
63
|
+
* Generate a meaningful typography name
|
|
64
|
+
*/
|
|
65
|
+
private generateTypographyName;
|
|
66
|
+
/**
|
|
67
|
+
* Categorize radius values
|
|
68
|
+
*/
|
|
69
|
+
private categorizeRadius;
|
|
70
|
+
/**
|
|
71
|
+
* Format the extracted variables for output
|
|
72
|
+
*/
|
|
73
|
+
formatVariablesAsOutput(variables: ExtractedVariable[]): any;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=figma-style-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figma-style-extractor.d.ts","sourceRoot":"","sources":["../../src/core/figma-style-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAqDH,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAK;IAExB;;;OAGG;IACG,qBAAqB,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAiDxE;;OAEG;IACH,OAAO,CAAC,WAAW;IAwDnB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,uBAAuB,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,GAAG;CAyB7D"}
|