@defai.digital/ax-cli 3.14.9 → 3.14.11
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/README.md +17 -2
- package/dist/agent/execution/tool-executor.d.ts +6 -0
- package/dist/agent/execution/tool-executor.js +72 -0
- package/dist/agent/execution/tool-executor.js.map +1 -1
- package/dist/commands/design.d.ts +18 -0
- package/dist/commands/design.js +495 -0
- package/dist/commands/design.js.map +1 -0
- package/dist/commands/vscode.js +1 -1
- package/dist/commands/vscode.js.map +1 -1
- package/dist/design/figma-alias.d.ts +88 -0
- package/dist/design/figma-alias.js +324 -0
- package/dist/design/figma-alias.js.map +1 -0
- package/dist/design/figma-audit.d.ts +40 -0
- package/dist/design/figma-audit.js +375 -0
- package/dist/design/figma-audit.js.map +1 -0
- package/dist/design/figma-client.d.ts +123 -0
- package/dist/design/figma-client.js +316 -0
- package/dist/design/figma-client.js.map +1 -0
- package/dist/design/figma-map.d.ts +29 -0
- package/dist/design/figma-map.js +274 -0
- package/dist/design/figma-map.js.map +1 -0
- package/dist/design/figma-tokens.d.ts +73 -0
- package/dist/design/figma-tokens.js +431 -0
- package/dist/design/figma-tokens.js.map +1 -0
- package/dist/design/index.d.ts +13 -0
- package/dist/design/index.js +18 -0
- package/dist/design/index.js.map +1 -0
- package/dist/design/types.d.ts +89 -0
- package/dist/design/types.js +9 -0
- package/dist/design/types.js.map +1 -0
- package/dist/hooks/hook-runner.js +2 -2
- package/dist/hooks/hook-runner.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/ipc/vscode-client.js +1 -1
- package/dist/ipc/vscode-client.js.map +1 -1
- package/dist/llm/tools.js +170 -0
- package/dist/llm/tools.js.map +1 -1
- package/dist/mcp/client-v2.js +1 -1
- package/dist/mcp/client-v2.js.map +1 -1
- package/dist/mcp/validation.js +1 -1
- package/dist/mcp/validation.js.map +1 -1
- package/dist/permissions/permission-manager.js +2 -2
- package/dist/permissions/permission-manager.js.map +1 -1
- package/dist/tools/design-tool.d.ts +59 -0
- package/dist/tools/design-tool.js +258 -0
- package/dist/tools/design-tool.js.map +1 -0
- package/dist/ui/hooks/use-input-history.js +1 -1
- package/dist/ui/hooks/use-input-history.js.map +1 -1
- package/dist/ui/utils/image-handler.js +1 -1
- package/dist/ui/utils/image-handler.js.map +1 -1
- package/dist/utils/path-security.js +2 -2
- package/dist/utils/path-security.js.map +1 -1
- package/dist/utils/progress-tracker.js +1 -1
- package/dist/utils/progress-tracker.js.map +1 -1
- package/dist/utils/settings-manager.js +8 -3
- package/dist/utils/settings-manager.js.map +1 -1
- package/node_modules/@ax-cli/schemas/dist/index.d.ts +1 -0
- package/node_modules/@ax-cli/schemas/dist/index.d.ts.map +1 -1
- package/node_modules/@ax-cli/schemas/dist/index.js +2 -2
- package/node_modules/@ax-cli/schemas/dist/index.js.map +1 -1
- package/node_modules/@ax-cli/schemas/dist/public/design/alias-types.d.ts +346 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/alias-types.d.ts.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/alias-types.js +171 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/alias-types.js.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/audit-types.d.ts +545 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/audit-types.d.ts.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/audit-types.js +307 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/audit-types.js.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/figma-types.d.ts +1306 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/figma-types.d.ts.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/figma-types.js +428 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/figma-types.js.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/index.d.ts +13 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/index.d.ts.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/index.js +82 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/index.js.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/token-types.d.ts +1245 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/token-types.d.ts.map +1 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/token-types.js +282 -0
- package/node_modules/@ax-cli/schemas/dist/public/design/token-types.js.map +1 -0
- package/package.json +2 -2
- package/packages/schemas/dist/index.d.ts +1 -0
- package/packages/schemas/dist/index.d.ts.map +1 -1
- package/packages/schemas/dist/index.js +2 -2
- package/packages/schemas/dist/index.js.map +1 -1
- package/packages/schemas/dist/public/design/alias-types.d.ts +346 -0
- package/packages/schemas/dist/public/design/alias-types.d.ts.map +1 -0
- package/packages/schemas/dist/public/design/alias-types.js +171 -0
- package/packages/schemas/dist/public/design/alias-types.js.map +1 -0
- package/packages/schemas/dist/public/design/audit-types.d.ts +545 -0
- package/packages/schemas/dist/public/design/audit-types.d.ts.map +1 -0
- package/packages/schemas/dist/public/design/audit-types.js +307 -0
- package/packages/schemas/dist/public/design/audit-types.js.map +1 -0
- package/packages/schemas/dist/public/design/figma-types.d.ts +1306 -0
- package/packages/schemas/dist/public/design/figma-types.d.ts.map +1 -0
- package/packages/schemas/dist/public/design/figma-types.js +428 -0
- package/packages/schemas/dist/public/design/figma-types.js.map +1 -0
- package/packages/schemas/dist/public/design/index.d.ts +13 -0
- package/packages/schemas/dist/public/design/index.d.ts.map +1 -0
- package/packages/schemas/dist/public/design/index.js +82 -0
- package/packages/schemas/dist/public/design/index.js.map +1 -0
- package/packages/schemas/dist/public/design/token-types.d.ts +1245 -0
- package/packages/schemas/dist/public/design/token-types.d.ts.map +1 -0
- package/packages/schemas/dist/public/design/token-types.js +282 -0
- package/packages/schemas/dist/public/design/token-types.js.map +1 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma REST API Client
|
|
3
|
+
*
|
|
4
|
+
* Provides a type-safe interface to the Figma REST API.
|
|
5
|
+
* Includes caching, rate limiting, and error handling.
|
|
6
|
+
*
|
|
7
|
+
* @module design/figma-client
|
|
8
|
+
*/
|
|
9
|
+
import { FigmaFileResponseSchema, FigmaNodesResponseSchema, FigmaVariablesResponseSchema, FigmaImagesResponseSchema, } from '@ax-cli/schemas';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Rate Limiter
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Simple rate limiter for Figma API (60 req/min for Professional)
|
|
15
|
+
*/
|
|
16
|
+
class RateLimiter {
|
|
17
|
+
requests = [];
|
|
18
|
+
maxRequests;
|
|
19
|
+
windowMs;
|
|
20
|
+
constructor(maxRequests = 60, windowMs = 60000) {
|
|
21
|
+
this.maxRequests = maxRequests;
|
|
22
|
+
this.windowMs = windowMs;
|
|
23
|
+
}
|
|
24
|
+
async waitForSlot() {
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
// Remove old requests
|
|
27
|
+
this.requests = this.requests.filter((t) => now - t < this.windowMs);
|
|
28
|
+
if (this.requests.length >= this.maxRequests) {
|
|
29
|
+
// Wait until oldest request expires
|
|
30
|
+
const oldestRequest = this.requests[0];
|
|
31
|
+
const waitTime = this.windowMs - (now - oldestRequest) + 100;
|
|
32
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
33
|
+
return this.waitForSlot();
|
|
34
|
+
}
|
|
35
|
+
this.requests.push(now);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Response Cache
|
|
40
|
+
// =============================================================================
|
|
41
|
+
class ResponseCache {
|
|
42
|
+
cache = new Map();
|
|
43
|
+
defaultTtl;
|
|
44
|
+
constructor(defaultTtl = 60000) {
|
|
45
|
+
this.defaultTtl = defaultTtl;
|
|
46
|
+
}
|
|
47
|
+
get(key) {
|
|
48
|
+
const entry = this.cache.get(key);
|
|
49
|
+
if (!entry)
|
|
50
|
+
return undefined;
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
if (now - entry.timestamp > entry.ttl) {
|
|
53
|
+
this.cache.delete(key);
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return entry.data;
|
|
57
|
+
}
|
|
58
|
+
set(key, data, ttl) {
|
|
59
|
+
this.cache.set(key, {
|
|
60
|
+
data,
|
|
61
|
+
timestamp: Date.now(),
|
|
62
|
+
ttl: ttl ?? this.defaultTtl,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
delete(key) {
|
|
66
|
+
this.cache.delete(key);
|
|
67
|
+
}
|
|
68
|
+
clear() {
|
|
69
|
+
this.cache.clear();
|
|
70
|
+
}
|
|
71
|
+
/** Get cache key for a request */
|
|
72
|
+
static makeKey(endpoint, params) {
|
|
73
|
+
const paramStr = params ? JSON.stringify(params) : '';
|
|
74
|
+
return `${endpoint}:${paramStr}`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// =============================================================================
|
|
78
|
+
// Figma Client
|
|
79
|
+
// =============================================================================
|
|
80
|
+
export class FigmaClient {
|
|
81
|
+
accessToken;
|
|
82
|
+
baseUrl;
|
|
83
|
+
timeout;
|
|
84
|
+
cache;
|
|
85
|
+
cacheEnabled;
|
|
86
|
+
rateLimiter;
|
|
87
|
+
constructor(config) {
|
|
88
|
+
this.accessToken = config.accessToken;
|
|
89
|
+
this.baseUrl = config.baseUrl ?? 'https://api.figma.com';
|
|
90
|
+
this.timeout = config.timeout ?? 30000;
|
|
91
|
+
this.cacheEnabled = config.cacheEnabled ?? true;
|
|
92
|
+
this.cache = new ResponseCache(config.cacheTtl ?? 60000);
|
|
93
|
+
this.rateLimiter = new RateLimiter();
|
|
94
|
+
}
|
|
95
|
+
// ===========================================================================
|
|
96
|
+
// Core Request Method
|
|
97
|
+
// ===========================================================================
|
|
98
|
+
async request(endpoint, options) {
|
|
99
|
+
const { params, skipCache, cacheTtl } = options ?? {};
|
|
100
|
+
// Build URL with query params
|
|
101
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
102
|
+
if (params) {
|
|
103
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
104
|
+
if (value !== undefined) {
|
|
105
|
+
url.searchParams.set(key, String(value));
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Check cache
|
|
110
|
+
const cacheKey = ResponseCache.makeKey(endpoint, params);
|
|
111
|
+
if (this.cacheEnabled && !skipCache) {
|
|
112
|
+
const cached = this.cache.get(cacheKey);
|
|
113
|
+
if (cached) {
|
|
114
|
+
return cached;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Rate limit
|
|
118
|
+
await this.rateLimiter.waitForSlot();
|
|
119
|
+
// Make request
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
122
|
+
try {
|
|
123
|
+
const response = await fetch(url.toString(), {
|
|
124
|
+
method: 'GET',
|
|
125
|
+
headers: {
|
|
126
|
+
'X-Figma-Token': this.accessToken,
|
|
127
|
+
'Content-Type': 'application/json',
|
|
128
|
+
},
|
|
129
|
+
signal: controller.signal,
|
|
130
|
+
});
|
|
131
|
+
clearTimeout(timeoutId);
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
const errorBody = await response.text().catch(() => '');
|
|
134
|
+
const error = new Error(`Figma API error: ${response.statusText}`);
|
|
135
|
+
error.status = response.status;
|
|
136
|
+
error.endpoint = endpoint;
|
|
137
|
+
error.figmaError = errorBody;
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
const data = await response.json();
|
|
141
|
+
// Cache response
|
|
142
|
+
if (this.cacheEnabled) {
|
|
143
|
+
this.cache.set(cacheKey, data, cacheTtl);
|
|
144
|
+
}
|
|
145
|
+
return data;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
clearTimeout(timeoutId);
|
|
149
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
150
|
+
const timeoutError = new Error(`Figma API request timed out after ${this.timeout}ms`);
|
|
151
|
+
timeoutError.status = 408;
|
|
152
|
+
timeoutError.endpoint = endpoint;
|
|
153
|
+
throw timeoutError;
|
|
154
|
+
}
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// ===========================================================================
|
|
159
|
+
// Public API Methods
|
|
160
|
+
// ===========================================================================
|
|
161
|
+
/**
|
|
162
|
+
* Get a Figma file
|
|
163
|
+
*
|
|
164
|
+
* @param fileKey - The file key from the Figma URL
|
|
165
|
+
* @param options - Optional parameters (depth, geometry, etc.)
|
|
166
|
+
* @returns Validated FigmaFileResponse
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const file = await client.getFile('abc123xyz', { depth: 2 });
|
|
171
|
+
* console.log(file.name);
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
async getFile(fileKey, options) {
|
|
175
|
+
const params = {
|
|
176
|
+
depth: options?.depth,
|
|
177
|
+
geometry: options?.geometry,
|
|
178
|
+
plugin_data: options?.plugin_data,
|
|
179
|
+
branch_data: options?.branch_data,
|
|
180
|
+
};
|
|
181
|
+
if (options?.version) {
|
|
182
|
+
params.version = options.version;
|
|
183
|
+
}
|
|
184
|
+
const response = await this.request(`/v1/files/${fileKey}`, { params });
|
|
185
|
+
return FigmaFileResponseSchema.parse(response);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get specific nodes from a Figma file
|
|
189
|
+
*
|
|
190
|
+
* @param fileKey - The file key from the Figma URL
|
|
191
|
+
* @param nodeIds - Array of node IDs to fetch
|
|
192
|
+
* @returns Validated FigmaNodesResponse
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const nodes = await client.getFileNodes('abc123xyz', ['1:2', '3:4']);
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
async getFileNodes(fileKey, nodeIds) {
|
|
200
|
+
const params = {
|
|
201
|
+
ids: nodeIds.join(','),
|
|
202
|
+
};
|
|
203
|
+
const response = await this.request(`/v1/files/${fileKey}/nodes`, { params });
|
|
204
|
+
return FigmaNodesResponseSchema.parse(response);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get local variables (design tokens) from a Figma file
|
|
208
|
+
*
|
|
209
|
+
* @param fileKey - The file key from the Figma URL
|
|
210
|
+
* @returns Validated FigmaVariablesResponse
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const variables = await client.getLocalVariables('abc123xyz');
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
async getLocalVariables(fileKey) {
|
|
218
|
+
const response = await this.request(`/v1/files/${fileKey}/variables/local`);
|
|
219
|
+
return FigmaVariablesResponseSchema.parse(response);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Get images for specific nodes
|
|
223
|
+
*
|
|
224
|
+
* @param fileKey - The file key from the Figma URL
|
|
225
|
+
* @param nodeIds - Array of node IDs to export
|
|
226
|
+
* @param options - Export options (scale, format)
|
|
227
|
+
* @returns Validated FigmaImagesResponse with URLs
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* const images = await client.getImages('abc123xyz', ['1:2'], { format: 'png', scale: 2 });
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
async getImages(fileKey, nodeIds, options) {
|
|
235
|
+
const params = {
|
|
236
|
+
ids: nodeIds.join(','),
|
|
237
|
+
scale: options?.scale,
|
|
238
|
+
format: options?.format,
|
|
239
|
+
svg_include_id: options?.svg_include_id,
|
|
240
|
+
svg_simplify_stroke: options?.svg_simplify_stroke,
|
|
241
|
+
use_absolute_bounds: options?.use_absolute_bounds,
|
|
242
|
+
};
|
|
243
|
+
const response = await this.request(`/v1/images/${fileKey}`, {
|
|
244
|
+
params,
|
|
245
|
+
skipCache: true, // Image URLs are time-limited
|
|
246
|
+
});
|
|
247
|
+
return FigmaImagesResponseSchema.parse(response);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get file metadata without the full document tree
|
|
251
|
+
*
|
|
252
|
+
* @param fileKey - The file key from the Figma URL
|
|
253
|
+
* @returns Basic file info (name, lastModified, etc.)
|
|
254
|
+
*/
|
|
255
|
+
async getFileMetadata(fileKey) {
|
|
256
|
+
// Use depth=0 to get minimal data
|
|
257
|
+
const response = await this.getFile(fileKey, { depth: 1 });
|
|
258
|
+
return {
|
|
259
|
+
name: response.name,
|
|
260
|
+
lastModified: response.lastModified,
|
|
261
|
+
version: response.version,
|
|
262
|
+
thumbnailUrl: response.thumbnailUrl,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// ===========================================================================
|
|
266
|
+
// Cache Management
|
|
267
|
+
// ===========================================================================
|
|
268
|
+
/**
|
|
269
|
+
* Clear the response cache
|
|
270
|
+
*/
|
|
271
|
+
clearCache() {
|
|
272
|
+
this.cache.clear();
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Invalidate cache for a specific file
|
|
276
|
+
*/
|
|
277
|
+
invalidateFile(fileKey) {
|
|
278
|
+
// Clear all cached entries for this file
|
|
279
|
+
this.cache.delete(ResponseCache.makeKey(`/v1/files/${fileKey}`));
|
|
280
|
+
this.cache.delete(ResponseCache.makeKey(`/v1/files/${fileKey}/nodes`));
|
|
281
|
+
this.cache.delete(ResponseCache.makeKey(`/v1/files/${fileKey}/variables/local`));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// =============================================================================
|
|
285
|
+
// Factory Functions
|
|
286
|
+
// =============================================================================
|
|
287
|
+
let defaultClient = null;
|
|
288
|
+
/**
|
|
289
|
+
* Create a new Figma client instance
|
|
290
|
+
*/
|
|
291
|
+
export function createFigmaClient(config) {
|
|
292
|
+
return new FigmaClient(config);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Get the default Figma client (creates one if needed)
|
|
296
|
+
*
|
|
297
|
+
* Uses FIGMA_ACCESS_TOKEN environment variable if no token provided.
|
|
298
|
+
*/
|
|
299
|
+
export function getFigmaClient(accessToken) {
|
|
300
|
+
if (defaultClient) {
|
|
301
|
+
return defaultClient;
|
|
302
|
+
}
|
|
303
|
+
const token = accessToken ?? process.env.FIGMA_ACCESS_TOKEN;
|
|
304
|
+
if (!token) {
|
|
305
|
+
throw new Error('Figma access token required. Set FIGMA_ACCESS_TOKEN environment variable or pass token to createFigmaClient().');
|
|
306
|
+
}
|
|
307
|
+
defaultClient = createFigmaClient({ accessToken: token });
|
|
308
|
+
return defaultClient;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Reset the default client (useful for testing)
|
|
312
|
+
*/
|
|
313
|
+
export function resetFigmaClient() {
|
|
314
|
+
defaultClient = null;
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=figma-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figma-client.js","sourceRoot":"","sources":["../../src/design/figma-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma File Mapping
|
|
3
|
+
*
|
|
4
|
+
* Converts Figma file structure to a human-readable/machine-readable format.
|
|
5
|
+
*
|
|
6
|
+
* @module design/figma-map
|
|
7
|
+
*/
|
|
8
|
+
import type { FigmaFileResponse } from '@ax-cli/schemas';
|
|
9
|
+
import type { SimplifiedNode, MapResult, TreeDisplayOptions, MapOutputFormat } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Map a Figma file to a simplified structure
|
|
12
|
+
*/
|
|
13
|
+
export declare function mapFigmaFile(response: FigmaFileResponse, fileKey: string, options?: TreeDisplayOptions): MapResult;
|
|
14
|
+
/**
|
|
15
|
+
* Format map result as string
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatMapResult(result: MapResult, format: MapOutputFormat, options?: TreeDisplayOptions): string;
|
|
18
|
+
/**
|
|
19
|
+
* Find a node by ID in the simplified tree
|
|
20
|
+
*/
|
|
21
|
+
export declare function findNodeById(root: SimplifiedNode, nodeId: string): SimplifiedNode | null;
|
|
22
|
+
/**
|
|
23
|
+
* Find nodes matching a predicate
|
|
24
|
+
*/
|
|
25
|
+
export declare function findNodes(root: SimplifiedNode, predicate: (node: SimplifiedNode) => boolean, limit?: number): SimplifiedNode[];
|
|
26
|
+
/**
|
|
27
|
+
* Get path to a node
|
|
28
|
+
*/
|
|
29
|
+
export declare function getNodePath(root: SimplifiedNode, nodeId: string): string[] | null;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma File Mapping
|
|
3
|
+
*
|
|
4
|
+
* Converts Figma file structure to a human-readable/machine-readable format.
|
|
5
|
+
*
|
|
6
|
+
* @module design/figma-map
|
|
7
|
+
*/
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Node Simplification
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Simplify a Figma node to essential properties
|
|
13
|
+
*/
|
|
14
|
+
function simplifyNode(node, options, depth = 0) {
|
|
15
|
+
// Check depth limit
|
|
16
|
+
if (options.maxDepth !== undefined && depth > options.maxDepth) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
// Filter by type
|
|
20
|
+
if (options.filterTypes && !options.filterTypes.includes(node.type)) {
|
|
21
|
+
// Still process children to find matching nodes
|
|
22
|
+
if ('children' in node && node.children) {
|
|
23
|
+
const children = node.children
|
|
24
|
+
.map((child) => simplifyNode(child, options, depth + 1))
|
|
25
|
+
.filter((n) => n !== null);
|
|
26
|
+
if (children.length > 0) {
|
|
27
|
+
return {
|
|
28
|
+
id: node.id,
|
|
29
|
+
name: node.name,
|
|
30
|
+
type: node.type,
|
|
31
|
+
children,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
// Frames only filter
|
|
38
|
+
if (options.framesOnly) {
|
|
39
|
+
const frameTypes = ['FRAME', 'COMPONENT', 'COMPONENT_SET', 'SECTION', 'CANVAS'];
|
|
40
|
+
if (!frameTypes.includes(node.type)) {
|
|
41
|
+
// Still process children
|
|
42
|
+
if ('children' in node && node.children) {
|
|
43
|
+
const children = node.children
|
|
44
|
+
.map((child) => simplifyNode(child, options, depth + 1))
|
|
45
|
+
.filter((n) => n !== null);
|
|
46
|
+
if (children.length > 0) {
|
|
47
|
+
return {
|
|
48
|
+
id: node.id,
|
|
49
|
+
name: node.name,
|
|
50
|
+
type: node.type,
|
|
51
|
+
children,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const simplified = {
|
|
59
|
+
id: node.id,
|
|
60
|
+
name: node.name,
|
|
61
|
+
type: node.type,
|
|
62
|
+
};
|
|
63
|
+
// Add optional metadata based on node type
|
|
64
|
+
if ('componentId' in node && node.componentId) {
|
|
65
|
+
simplified.componentKey = node.componentId;
|
|
66
|
+
}
|
|
67
|
+
if ('characters' in node && node.characters) {
|
|
68
|
+
// Truncate long text
|
|
69
|
+
simplified.characters = node.characters.length > 50
|
|
70
|
+
? node.characters.slice(0, 50) + '...'
|
|
71
|
+
: node.characters;
|
|
72
|
+
}
|
|
73
|
+
if ('layoutMode' in node && node.layoutMode && node.layoutMode !== 'NONE') {
|
|
74
|
+
simplified.hasAutoLayout = true;
|
|
75
|
+
}
|
|
76
|
+
if ('fills' in node && Array.isArray(node.fills)) {
|
|
77
|
+
simplified.fillCount = node.fills.length;
|
|
78
|
+
}
|
|
79
|
+
// Process children
|
|
80
|
+
if ('children' in node && node.children) {
|
|
81
|
+
const children = node.children
|
|
82
|
+
.map((child) => simplifyNode(child, options, depth + 1))
|
|
83
|
+
.filter((n) => n !== null);
|
|
84
|
+
if (children.length > 0) {
|
|
85
|
+
simplified.children = children;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return simplified;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Count nodes recursively
|
|
92
|
+
*/
|
|
93
|
+
function countNodes(node) {
|
|
94
|
+
let count = 1;
|
|
95
|
+
if (node.children) {
|
|
96
|
+
for (const child of node.children) {
|
|
97
|
+
count += countNodes(child);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return count;
|
|
101
|
+
}
|
|
102
|
+
// =============================================================================
|
|
103
|
+
// Tree Formatting
|
|
104
|
+
// =============================================================================
|
|
105
|
+
/**
|
|
106
|
+
* Format node as tree string with box-drawing characters
|
|
107
|
+
*/
|
|
108
|
+
function formatNodeAsTree(node, options, prefix = '', isLast = true, depth = 0) {
|
|
109
|
+
const lines = [];
|
|
110
|
+
// Build the connector
|
|
111
|
+
const connector = isLast ? '└─' : '├─';
|
|
112
|
+
const nodePrefix = depth === 0 ? '' : prefix + connector;
|
|
113
|
+
// Build node label
|
|
114
|
+
let label = node.name;
|
|
115
|
+
if (options.showTypes) {
|
|
116
|
+
label = `[${node.type}] ${label}`;
|
|
117
|
+
}
|
|
118
|
+
if (options.showIds) {
|
|
119
|
+
label = `${label} (${node.id})`;
|
|
120
|
+
}
|
|
121
|
+
// Add metadata hints
|
|
122
|
+
const hints = [];
|
|
123
|
+
if (node.hasAutoLayout)
|
|
124
|
+
hints.push('auto-layout');
|
|
125
|
+
if (node.componentKey)
|
|
126
|
+
hints.push('instance');
|
|
127
|
+
if (node.characters)
|
|
128
|
+
hints.push(`"${node.characters}"`);
|
|
129
|
+
if (hints.length > 0) {
|
|
130
|
+
label += ` ${hints.join(', ')}`;
|
|
131
|
+
}
|
|
132
|
+
lines.push(nodePrefix + label);
|
|
133
|
+
// Process children
|
|
134
|
+
if (node.children && node.children.length > 0) {
|
|
135
|
+
const childPrefix = depth === 0 ? '' : prefix + (isLast ? ' ' : '│ ');
|
|
136
|
+
const childCount = node.children.length;
|
|
137
|
+
node.children.forEach((child, index) => {
|
|
138
|
+
const isChildLast = index === childCount - 1;
|
|
139
|
+
lines.push(...formatNodeAsTree(child, options, childPrefix, isChildLast, depth + 1));
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return lines;
|
|
143
|
+
}
|
|
144
|
+
// =============================================================================
|
|
145
|
+
// Flat List Formatting
|
|
146
|
+
// =============================================================================
|
|
147
|
+
/**
|
|
148
|
+
* Flatten node tree to a list with paths
|
|
149
|
+
*/
|
|
150
|
+
function flattenNodes(node, path = [], results = []) {
|
|
151
|
+
const currentPath = [...path, node.name];
|
|
152
|
+
results.push({
|
|
153
|
+
path: currentPath.join(' > '),
|
|
154
|
+
id: node.id,
|
|
155
|
+
type: node.type,
|
|
156
|
+
name: node.name,
|
|
157
|
+
});
|
|
158
|
+
if (node.children) {
|
|
159
|
+
for (const child of node.children) {
|
|
160
|
+
flattenNodes(child, currentPath, results);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return results;
|
|
164
|
+
}
|
|
165
|
+
// =============================================================================
|
|
166
|
+
// Public API
|
|
167
|
+
// =============================================================================
|
|
168
|
+
/**
|
|
169
|
+
* Map a Figma file to a simplified structure
|
|
170
|
+
*/
|
|
171
|
+
export function mapFigmaFile(response, fileKey, options = {}) {
|
|
172
|
+
const rootNode = simplifyNode(response.document, options);
|
|
173
|
+
if (!rootNode) {
|
|
174
|
+
throw new Error('Failed to simplify document node');
|
|
175
|
+
}
|
|
176
|
+
const nodeCount = countNodes(rootNode);
|
|
177
|
+
const pageCount = rootNode.children?.length ?? 0;
|
|
178
|
+
const componentCount = response.components ? Object.keys(response.components).length : 0;
|
|
179
|
+
const styleCount = response.styles ? Object.keys(response.styles).length : 0;
|
|
180
|
+
return {
|
|
181
|
+
fileKey,
|
|
182
|
+
fileName: response.name,
|
|
183
|
+
lastModified: response.lastModified,
|
|
184
|
+
pageCount,
|
|
185
|
+
nodeCount,
|
|
186
|
+
componentCount,
|
|
187
|
+
styleCount,
|
|
188
|
+
root: rootNode,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Format map result as string
|
|
193
|
+
*/
|
|
194
|
+
export function formatMapResult(result, format, options = {}) {
|
|
195
|
+
switch (format) {
|
|
196
|
+
case 'json':
|
|
197
|
+
return JSON.stringify(result, null, 2);
|
|
198
|
+
case 'flat': {
|
|
199
|
+
const flat = flattenNodes(result.root);
|
|
200
|
+
return flat.map((n) => `${n.path} [${n.type}] (${n.id})`).join('\n');
|
|
201
|
+
}
|
|
202
|
+
case 'tree':
|
|
203
|
+
default: {
|
|
204
|
+
const header = [
|
|
205
|
+
`File: ${result.fileName}`,
|
|
206
|
+
`Last Modified: ${result.lastModified}`,
|
|
207
|
+
`Pages: ${result.pageCount} | Nodes: ${result.nodeCount} | Components: ${result.componentCount} | Styles: ${result.styleCount}`,
|
|
208
|
+
'',
|
|
209
|
+
];
|
|
210
|
+
const tree = formatNodeAsTree(result.root, options);
|
|
211
|
+
return [...header, ...tree].join('\n');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Find a node by ID in the simplified tree
|
|
217
|
+
*/
|
|
218
|
+
export function findNodeById(root, nodeId) {
|
|
219
|
+
if (root.id === nodeId) {
|
|
220
|
+
return root;
|
|
221
|
+
}
|
|
222
|
+
if (root.children) {
|
|
223
|
+
for (const child of root.children) {
|
|
224
|
+
const found = findNodeById(child, nodeId);
|
|
225
|
+
if (found)
|
|
226
|
+
return found;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Find nodes matching a predicate
|
|
233
|
+
*/
|
|
234
|
+
export function findNodes(root, predicate, limit) {
|
|
235
|
+
const results = [];
|
|
236
|
+
function search(node) {
|
|
237
|
+
if (limit !== undefined && results.length >= limit) {
|
|
238
|
+
return true; // Stop searching
|
|
239
|
+
}
|
|
240
|
+
if (predicate(node)) {
|
|
241
|
+
results.push(node);
|
|
242
|
+
}
|
|
243
|
+
if (node.children) {
|
|
244
|
+
for (const child of node.children) {
|
|
245
|
+
if (search(child))
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
search(root);
|
|
252
|
+
return results;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get path to a node
|
|
256
|
+
*/
|
|
257
|
+
export function getNodePath(root, nodeId) {
|
|
258
|
+
function findPath(node, path) {
|
|
259
|
+
const currentPath = [...path, node.name];
|
|
260
|
+
if (node.id === nodeId) {
|
|
261
|
+
return currentPath;
|
|
262
|
+
}
|
|
263
|
+
if (node.children) {
|
|
264
|
+
for (const child of node.children) {
|
|
265
|
+
const found = findPath(child, currentPath);
|
|
266
|
+
if (found)
|
|
267
|
+
return found;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
return findPath(root, []);
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=figma-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figma-map.js","sourceRoot":"","sources":["../../src/design/figma-map.ts"],"names":[],"mappings":"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"}
|