@auto-engineer/design-system-importer 0.4.8 → 0.4.9
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/.turbo/turbo-build.log +6 -5
- package/.turbo/turbo-format.log +8 -7
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +14 -12
- package/.turbo/turbo-type-check.log +5 -4
- package/DEBUG.md +195 -0
- package/dist/FigmaComponentsBuilder.d.ts +1 -0
- package/dist/FigmaComponentsBuilder.d.ts.map +1 -1
- package/dist/FigmaComponentsBuilder.js +103 -22
- package/dist/FigmaComponentsBuilder.js.map +1 -1
- package/dist/commands/import-design-system.d.ts.map +1 -1
- package/dist/commands/import-design-system.js +39 -3
- package/dist/commands/import-design-system.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -16
- package/dist/index.js.map +1 -1
- package/dist/utils/FilterLoader.d.ts.map +1 -1
- package/dist/utils/FilterLoader.js +84 -4
- package/dist/utils/FilterLoader.js.map +1 -1
- package/package.json +2 -2
- package/src/FigmaComponentsBuilder.ts +106 -23
- package/src/commands/import-design-system.ts +41 -3
- package/src/index.ts +118 -15
- package/src/utils/FilterLoader.ts +85 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -3,78 +3,113 @@ import { pathToFileURL, fileURLToPath } from 'url';
|
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync, mkdtempSync, rmSync } from 'fs';
|
|
4
4
|
import { spawnSync } from 'child_process';
|
|
5
5
|
import { tmpdir } from 'os';
|
|
6
|
+
import createDebug from 'debug';
|
|
7
|
+
const debug = createDebug('design-system-importer:filter-loader');
|
|
8
|
+
const debugLoad = createDebug('design-system-importer:filter-loader:load');
|
|
9
|
+
const debugTS = createDebug('design-system-importer:filter-loader:typescript');
|
|
10
|
+
const debugStrategy = createDebug('design-system-importer:filter-loader:strategy');
|
|
11
|
+
const debugTemplate = createDebug('design-system-importer:filter-loader:template');
|
|
6
12
|
export class FilterLoader {
|
|
7
13
|
constructor() {
|
|
14
|
+
debug('FilterLoader instance created');
|
|
8
15
|
// Get the directory where template files are stored
|
|
9
16
|
const currentFile = fileURLToPath(import.meta.url);
|
|
10
17
|
this.templatesDir = join(dirname(currentFile), 'templates');
|
|
18
|
+
debug('Templates directory: %s', this.templatesDir);
|
|
11
19
|
}
|
|
12
20
|
async loadFilter(filePath) {
|
|
21
|
+
debugLoad('Loading filter from: %s', filePath);
|
|
13
22
|
if (typeof filePath !== 'string' || filePath.trim().length === 0) {
|
|
23
|
+
debugLoad('ERROR: Invalid filter path provided');
|
|
14
24
|
throw new Error('Filter file path is required');
|
|
15
25
|
}
|
|
16
26
|
const absolutePath = resolvePath(process.cwd(), filePath);
|
|
27
|
+
debugLoad('Resolved absolute path: %s', absolutePath);
|
|
17
28
|
if (!existsSync(absolutePath)) {
|
|
29
|
+
debugLoad('ERROR: Filter file not found at %s', absolutePath);
|
|
18
30
|
throw new Error(`Filter file not found: ${absolutePath}`);
|
|
19
31
|
}
|
|
20
32
|
const ext = extname(absolutePath).toLowerCase();
|
|
33
|
+
debugLoad('File extension: %s', ext);
|
|
21
34
|
// For TypeScript files, use tsx to load them
|
|
22
35
|
if (ext === '.ts' || ext === '.tsx') {
|
|
36
|
+
debugLoad('Detected TypeScript file, using TypeScript loader');
|
|
23
37
|
return this.loadTypeScriptFilter(absolutePath);
|
|
24
38
|
}
|
|
25
39
|
// For JavaScript files, load directly
|
|
40
|
+
debugLoad('Loading JavaScript file directly');
|
|
26
41
|
const fileUrl = pathToFileURL(absolutePath).href;
|
|
42
|
+
debugLoad('File URL: %s', fileUrl);
|
|
27
43
|
const loadedUnknown = await import(fileUrl);
|
|
28
44
|
const loadedModule = loadedUnknown;
|
|
45
|
+
debugLoad('Module loaded, checking for filter function');
|
|
29
46
|
if (typeof loadedModule.filter === 'function') {
|
|
47
|
+
debugLoad('Found named export "filter"');
|
|
30
48
|
return loadedModule.filter;
|
|
31
49
|
}
|
|
32
50
|
if (typeof loadedModule.default === 'function') {
|
|
51
|
+
debugLoad('Found default export, using as filter');
|
|
33
52
|
console.warn('Using default export from filter module. Prefer a named export "filter".');
|
|
34
53
|
return loadedModule.default;
|
|
35
54
|
}
|
|
55
|
+
debugLoad('ERROR: No filter function found in module');
|
|
36
56
|
throw new Error('No filter function found. Export a function named "filter" or as a default export from the file.');
|
|
37
57
|
}
|
|
38
58
|
async loadTypeScriptFilter(filePath) {
|
|
59
|
+
debugTS('Loading TypeScript filter from: %s', filePath);
|
|
39
60
|
// Create a temporary directory for our scripts
|
|
40
61
|
const tempDir = mkdtempSync(join(tmpdir(), 'tsx-filter-'));
|
|
62
|
+
debugTS('Created temp directory: %s', tempDir);
|
|
41
63
|
try {
|
|
42
64
|
const filterUrl = pathToFileURL(filePath).href;
|
|
65
|
+
debugTS('Filter URL: %s', filterUrl);
|
|
43
66
|
// Try different loading strategies in order
|
|
44
67
|
const strategies = [
|
|
45
68
|
() => this.tryNodeDirectLoad(tempDir, filterUrl),
|
|
46
69
|
() => this.tryNpxTsxExport(tempDir, filterUrl),
|
|
47
70
|
() => this.tryNodeLoaderOptions(tempDir, filterUrl),
|
|
48
71
|
];
|
|
49
|
-
|
|
50
|
-
|
|
72
|
+
debugTS('Will try %d loading strategies', strategies.length);
|
|
73
|
+
for (let i = 0; i < strategies.length; i++) {
|
|
74
|
+
debugTS('Trying strategy %d/%d', i + 1, strategies.length);
|
|
75
|
+
const result = await strategies[i]();
|
|
51
76
|
if (result) {
|
|
77
|
+
debugTS('Strategy %d succeeded!', i + 1);
|
|
52
78
|
return result;
|
|
53
79
|
}
|
|
80
|
+
debugTS('Strategy %d failed, trying next...', i + 1);
|
|
54
81
|
}
|
|
82
|
+
debugTS('ERROR: All strategies failed to load TypeScript filter');
|
|
55
83
|
throw new Error(`TypeScript filter cannot be loaded. ` +
|
|
56
84
|
`Please ensure tsx is installed in your project:\n` +
|
|
57
85
|
` npm install -D tsx\n` +
|
|
58
86
|
`Or provide a JavaScript version of your filter.`);
|
|
59
87
|
}
|
|
60
88
|
catch (error) {
|
|
89
|
+
debugTS('ERROR: Failed to load TypeScript filter: %O', error);
|
|
61
90
|
throw new Error(`Failed to load TypeScript filter.\n` +
|
|
62
91
|
`Error: ${error instanceof Error ? error.message : String(error)}\n` +
|
|
63
92
|
`Please ensure tsx is installed locally: npm install -D tsx`);
|
|
64
93
|
}
|
|
65
94
|
finally {
|
|
95
|
+
debugTS('Cleaning up temp directory: %s', tempDir);
|
|
66
96
|
// Clean up temp files
|
|
67
97
|
try {
|
|
68
98
|
rmSync(tempDir, { recursive: true, force: true });
|
|
99
|
+
debugTS('Temp directory cleaned up successfully');
|
|
69
100
|
}
|
|
70
|
-
catch {
|
|
101
|
+
catch (cleanupError) {
|
|
102
|
+
debugTS('Warning: Failed to clean up temp directory: %O', cleanupError);
|
|
71
103
|
// Ignore cleanup errors
|
|
72
104
|
}
|
|
73
105
|
}
|
|
74
106
|
}
|
|
75
107
|
async tryNodeDirectLoad(tempDir, filterUrl) {
|
|
108
|
+
debugStrategy('Strategy: Node direct load');
|
|
76
109
|
// First attempt: Try to run the loader script with Node.js directly
|
|
77
110
|
const loaderFile = this.prepareTemplate(tempDir, 'tsx-loader.mjs', filterUrl);
|
|
111
|
+
debugStrategy('Prepared loader file: %s', loaderFile);
|
|
112
|
+
debugStrategy('Spawning node with experimental loader...');
|
|
78
113
|
const result = spawnSync('node', [loaderFile], {
|
|
79
114
|
cwd: process.cwd(),
|
|
80
115
|
encoding: 'utf-8',
|
|
@@ -83,40 +118,64 @@ export class FilterLoader {
|
|
|
83
118
|
NODE_OPTIONS: '--experimental-loader tsx',
|
|
84
119
|
},
|
|
85
120
|
});
|
|
121
|
+
debugStrategy('Node process exit code: %d', result.status);
|
|
86
122
|
if (result.status === 0) {
|
|
123
|
+
debugStrategy('Node direct load succeeded, importing module');
|
|
87
124
|
// Success! Now import the loader module to get the filter
|
|
88
125
|
const loaderModule = (await import(pathToFileURL(loaderFile).href));
|
|
126
|
+
debugStrategy('Filter function retrieved from module');
|
|
89
127
|
return loaderModule.filter;
|
|
90
128
|
}
|
|
129
|
+
debugStrategy('Node direct load failed');
|
|
130
|
+
if (result.stderr) {
|
|
131
|
+
debugStrategy('Error output: %s', result.stderr);
|
|
132
|
+
}
|
|
91
133
|
return null;
|
|
92
134
|
}
|
|
93
135
|
async tryNpxTsxExport(tempDir, filterUrl) {
|
|
136
|
+
debugStrategy('Strategy: npx tsx export');
|
|
94
137
|
// Second attempt: Use npx tsx to run a script that exports the filter
|
|
95
138
|
const exportFile = this.prepareTemplate(tempDir, 'tsx-export.mjs', filterUrl);
|
|
139
|
+
debugStrategy('Prepared export file: %s', exportFile);
|
|
140
|
+
debugStrategy('Spawning npx tsx...');
|
|
96
141
|
const npxResult = spawnSync('npx', ['tsx', exportFile], {
|
|
97
142
|
cwd: process.cwd(),
|
|
98
143
|
encoding: 'utf-8',
|
|
99
144
|
shell: true,
|
|
100
145
|
});
|
|
146
|
+
debugStrategy('npx process exit code: %d', npxResult.status);
|
|
101
147
|
if (npxResult.status === 0 && npxResult.stdout) {
|
|
148
|
+
debugStrategy('npx tsx succeeded, parsing output');
|
|
102
149
|
try {
|
|
103
150
|
const output = JSON.parse(npxResult.stdout);
|
|
104
151
|
if (output.success === true && typeof output.filterCode === 'string' && output.filterCode.length > 0) {
|
|
152
|
+
debugStrategy('Successfully parsed filter code, creating function');
|
|
105
153
|
// Create a function from the filter code
|
|
106
154
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval, @typescript-eslint/no-unsafe-call
|
|
107
155
|
const filter = new Function('return ' + output.filterCode)();
|
|
156
|
+
debugStrategy('Filter function created successfully');
|
|
108
157
|
return filter;
|
|
109
158
|
}
|
|
159
|
+
debugStrategy('Output missing success flag or filter code');
|
|
110
160
|
}
|
|
111
|
-
catch {
|
|
161
|
+
catch (parseError) {
|
|
162
|
+
debugStrategy('Failed to parse npx output: %O', parseError);
|
|
112
163
|
// JSON parse failed, try another approach
|
|
113
164
|
}
|
|
114
165
|
}
|
|
166
|
+
else {
|
|
167
|
+
debugStrategy('npx tsx failed or no output');
|
|
168
|
+
if (npxResult.stderr) {
|
|
169
|
+
debugStrategy('Error output: %s', npxResult.stderr);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
115
172
|
return null;
|
|
116
173
|
}
|
|
117
174
|
async tryNodeLoaderOptions(tempDir, filterUrl) {
|
|
175
|
+
debugStrategy('Strategy: Node loader options');
|
|
118
176
|
// Third attempt: Create a wrapper that uses dynamic import with tsx
|
|
119
177
|
const wrapperFile = this.prepareTemplate(tempDir, 'tsx-wrapper.mjs', filterUrl);
|
|
178
|
+
debugStrategy('Prepared wrapper file: %s', wrapperFile);
|
|
120
179
|
// Try with various Node.js loader configurations
|
|
121
180
|
const loaderOptions = [
|
|
122
181
|
['--loader', 'tsx'],
|
|
@@ -124,46 +183,67 @@ export class FilterLoader {
|
|
|
124
183
|
['--require', 'tsx'],
|
|
125
184
|
['--import', 'tsx'],
|
|
126
185
|
];
|
|
186
|
+
debugStrategy('Will try %d loader configurations', loaderOptions.length);
|
|
127
187
|
for (const options of loaderOptions) {
|
|
188
|
+
debugStrategy('Trying loader options: %s', options.join(' '));
|
|
128
189
|
const testResult = spawnSync('node', [...options, wrapperFile], {
|
|
129
190
|
cwd: process.cwd(),
|
|
130
191
|
encoding: 'utf-8',
|
|
131
192
|
env: { ...process.env },
|
|
132
193
|
});
|
|
194
|
+
debugStrategy('Exit code: %d', testResult.status);
|
|
133
195
|
if (testResult.status === 0) {
|
|
196
|
+
debugStrategy('Configuration works! Loading final filter');
|
|
134
197
|
// This configuration works! Use it to load the actual filter
|
|
135
198
|
const finalFile = this.prepareTemplate(tempDir, 'tsx-final-loader.mjs', filterUrl);
|
|
136
199
|
const finalModule = (await import(pathToFileURL(finalFile).href));
|
|
200
|
+
debugStrategy('Filter loaded successfully with options: %s', options.join(' '));
|
|
137
201
|
return finalModule.filter;
|
|
138
202
|
}
|
|
203
|
+
else if (testResult.stderr) {
|
|
204
|
+
debugStrategy('Error with %s: %s', options.join(' '), testResult.stderr);
|
|
205
|
+
}
|
|
139
206
|
}
|
|
207
|
+
debugStrategy('All loader options failed');
|
|
140
208
|
return null;
|
|
141
209
|
}
|
|
142
210
|
prepareTemplate(tempDir, templateName, filterPath) {
|
|
211
|
+
debugTemplate('Preparing template: %s', templateName);
|
|
212
|
+
debugTemplate('Filter path: %s', filterPath);
|
|
143
213
|
const templatePath = join(this.templatesDir, templateName);
|
|
144
214
|
const outputPath = join(tempDir, templateName);
|
|
215
|
+
debugTemplate('Template path: %s', templatePath);
|
|
216
|
+
debugTemplate('Output path: %s', outputPath);
|
|
145
217
|
// Read the template
|
|
146
218
|
let content;
|
|
147
219
|
if (existsSync(templatePath)) {
|
|
220
|
+
debugTemplate('Reading template from source');
|
|
148
221
|
content = readFileSync(templatePath, 'utf-8');
|
|
149
222
|
}
|
|
150
223
|
else {
|
|
224
|
+
debugTemplate('Template not in source, checking dist');
|
|
151
225
|
// Fallback to dist directory if running from compiled code
|
|
152
226
|
const distTemplatePath = templatePath.replace('/src/', '/dist/');
|
|
227
|
+
debugTemplate('Checking dist path: %s', distTemplatePath);
|
|
153
228
|
if (existsSync(distTemplatePath)) {
|
|
229
|
+
debugTemplate('Reading template from dist');
|
|
154
230
|
content = readFileSync(distTemplatePath, 'utf-8');
|
|
155
231
|
}
|
|
156
232
|
else {
|
|
233
|
+
debugTemplate('ERROR: Template not found in source or dist');
|
|
157
234
|
throw new Error(`Template not found: ${templateName}`);
|
|
158
235
|
}
|
|
159
236
|
}
|
|
160
237
|
// Replace the placeholder with the actual filter path
|
|
161
238
|
content = content.replace(/__FILTER_PATH__/g, filterPath);
|
|
239
|
+
debugTemplate('Replaced filter path placeholder');
|
|
162
240
|
// Write the prepared script
|
|
163
241
|
writeFileSync(outputPath, content);
|
|
242
|
+
debugTemplate('Written prepared script to: %s', outputPath);
|
|
164
243
|
return outputPath;
|
|
165
244
|
}
|
|
166
245
|
cleanup() {
|
|
246
|
+
debug('FilterLoader cleanup called');
|
|
167
247
|
// No cleanup needed
|
|
168
248
|
}
|
|
169
249
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterLoader.js","sourceRoot":"","sources":["../../src/utils/FilterLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"FilterLoader.js","sourceRoot":"","sources":["../../src/utils/FilterLoader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auto-engineer/design-system-importer",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@auto-engineer/message-bus": "^0.3.
|
|
21
|
+
"@auto-engineer/message-bus": "^0.3.4",
|
|
22
22
|
"figma-api": "2.0.2-beta",
|
|
23
23
|
"tsx": "^3.12.7"
|
|
24
24
|
},
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import * as dotenv from 'dotenv';
|
|
2
2
|
import * as Figma from 'figma-api';
|
|
3
|
+
import createDebug from 'debug';
|
|
4
|
+
|
|
5
|
+
const debug = createDebug('design-system-importer:figma-builder');
|
|
6
|
+
const debugComponents = createDebug('design-system-importer:figma-builder:components');
|
|
7
|
+
const debugFilters = createDebug('design-system-importer:figma-builder:filters');
|
|
8
|
+
const debugAPI = createDebug('design-system-importer:figma-builder:api');
|
|
9
|
+
const debugTree = createDebug('design-system-importer:figma-builder:tree');
|
|
3
10
|
|
|
4
11
|
dotenv.config();
|
|
5
12
|
|
|
13
|
+
debug('Initializing FigmaComponentsBuilder module');
|
|
6
14
|
const figmaApi = new Figma.Api({
|
|
7
15
|
personalAccessToken: process.env.FIGMA_PERSONAL_TOKEN as string,
|
|
8
16
|
});
|
|
17
|
+
debug('Figma API initialized with personal access token');
|
|
9
18
|
|
|
10
19
|
export interface FigmaComponent {
|
|
11
20
|
name: string;
|
|
@@ -26,47 +35,79 @@ interface FigmaNode {
|
|
|
26
35
|
export class FigmaComponentsBuilder {
|
|
27
36
|
components: FigmaComponent[] = [];
|
|
28
37
|
|
|
38
|
+
constructor() {
|
|
39
|
+
debug('FigmaComponentsBuilder instance created');
|
|
40
|
+
debugComponents('Initial components array: empty');
|
|
41
|
+
}
|
|
42
|
+
|
|
29
43
|
async withFigmaComponents() {
|
|
44
|
+
debugAPI('Fetching Figma components from file: %s', process.env.FIGMA_FILE_ID);
|
|
30
45
|
try {
|
|
46
|
+
debugAPI('Making API call to getFileComponents...');
|
|
31
47
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
32
48
|
const response = await figmaApi.getFileComponents({ file_key: process.env.FIGMA_FILE_ID });
|
|
49
|
+
debugAPI('API response received');
|
|
33
50
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
34
51
|
if (response.meta.components.length > 0) {
|
|
35
52
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
36
|
-
|
|
53
|
+
debugComponents('Found %d components in Figma file', response.meta.components.length);
|
|
37
54
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
38
55
|
this.components = response.meta.components.map(
|
|
39
|
-
(component: { name: string; description: string; thumbnail_url: string }) =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
(component: { name: string; description: string; thumbnail_url: string }) => {
|
|
57
|
+
debugComponents('Processing component: %s', component.name);
|
|
58
|
+
return {
|
|
59
|
+
name: component.name,
|
|
60
|
+
description: component.description,
|
|
61
|
+
thumbnail: component.thumbnail_url,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
44
64
|
);
|
|
65
|
+
debugComponents('Successfully mapped %d components', this.components.length);
|
|
66
|
+
} else {
|
|
67
|
+
debugComponents('No components found in Figma file');
|
|
45
68
|
}
|
|
46
69
|
} catch (e) {
|
|
47
|
-
|
|
70
|
+
debugAPI('ERROR: Failed to fetch Figma components: %O', e);
|
|
71
|
+
console.error('Failed to fetch Figma components:', e);
|
|
48
72
|
}
|
|
73
|
+
debugComponents('withFigmaComponents complete, total components: %d', this.components.length);
|
|
49
74
|
return this;
|
|
50
75
|
}
|
|
51
76
|
|
|
52
77
|
async withFigmaComponentSets() {
|
|
78
|
+
debugAPI('Fetching Figma component sets from file: %s', process.env.FIGMA_FILE_ID);
|
|
53
79
|
try {
|
|
80
|
+
debugAPI('Making API call to getFileComponentSets...');
|
|
54
81
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
55
82
|
const response = await figmaApi.getFileComponentSets({ file_key: process.env.FIGMA_FILE_ID });
|
|
83
|
+
debugAPI('API response received');
|
|
56
84
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
57
85
|
if (response.meta.component_sets.length > 0) {
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
87
|
+
debugComponents('Found %d component sets in Figma file', response.meta.component_sets.length);
|
|
58
88
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
59
89
|
this.components = response.meta.component_sets.map(
|
|
60
|
-
(component: { name: string; description: string; thumbnail_url: string }) =>
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
90
|
+
(component: { name: string; description: string; thumbnail_url: string }) => {
|
|
91
|
+
debugComponents('Processing component set: %s', component.name);
|
|
92
|
+
const mapped = {
|
|
93
|
+
name: component.name,
|
|
94
|
+
description: component.description ?? 'N/A',
|
|
95
|
+
thumbnail: component.thumbnail_url ?? 'N/A',
|
|
96
|
+
};
|
|
97
|
+
debugComponents(' - Description: %s', mapped.description.substring(0, 50));
|
|
98
|
+
debugComponents(' - Has thumbnail: %s', mapped.thumbnail !== 'N/A');
|
|
99
|
+
return mapped;
|
|
100
|
+
},
|
|
65
101
|
);
|
|
102
|
+
debugComponents('Successfully mapped %d component sets', this.components.length);
|
|
103
|
+
} else {
|
|
104
|
+
debugComponents('No component sets found in Figma file');
|
|
66
105
|
}
|
|
67
106
|
} catch (e) {
|
|
68
|
-
|
|
107
|
+
debugAPI('ERROR: Failed to fetch Figma component sets: %O', e);
|
|
108
|
+
console.error('Failed to fetch Figma component sets:', e);
|
|
69
109
|
}
|
|
110
|
+
debugComponents('withFigmaComponentSets complete, total components: %d', this.components.length);
|
|
70
111
|
return this;
|
|
71
112
|
}
|
|
72
113
|
|
|
@@ -81,73 +122,107 @@ export class FigmaComponentsBuilder {
|
|
|
81
122
|
// }
|
|
82
123
|
|
|
83
124
|
withFilteredNamesForShadcn(): void {
|
|
125
|
+
debugFilters('Applying Shadcn name filter to %d components', this.components.length);
|
|
126
|
+
const originalCount = this.components.length;
|
|
84
127
|
this.components = this.components
|
|
85
128
|
.map((comp: FigmaComponent): FigmaComponent | null => {
|
|
86
|
-
if (!comp?.name)
|
|
129
|
+
if (!comp?.name) {
|
|
130
|
+
debugFilters('Skipping component with no name');
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
87
133
|
|
|
88
134
|
let str = comp.name.trim();
|
|
135
|
+
debugFilters('Processing component name: %s', str);
|
|
89
136
|
|
|
90
137
|
if (str.includes('/')) {
|
|
138
|
+
const original = str;
|
|
91
139
|
str = str.split('/')[0].trim();
|
|
140
|
+
debugFilters(' Split by /: %s -> %s', original, str);
|
|
92
141
|
} else {
|
|
142
|
+
const original = str;
|
|
93
143
|
str = str.split(' ')[0].trim();
|
|
144
|
+
debugFilters(' Split by space: %s -> %s', original, str);
|
|
94
145
|
}
|
|
95
146
|
|
|
96
147
|
if (str.length > 0) {
|
|
97
|
-
|
|
148
|
+
const capitalized = str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
149
|
+
const final = capitalized.toLowerCase();
|
|
150
|
+
debugFilters(' Normalized: %s -> %s', str, final);
|
|
151
|
+
return {
|
|
152
|
+
...comp,
|
|
153
|
+
name: final,
|
|
154
|
+
};
|
|
98
155
|
} else {
|
|
156
|
+
debugFilters(' Empty string after processing, skipping');
|
|
99
157
|
return null;
|
|
100
158
|
}
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
...comp,
|
|
104
|
-
name: str.toLowerCase(),
|
|
105
|
-
};
|
|
106
159
|
})
|
|
107
160
|
.filter((c: FigmaComponent | null): c is FigmaComponent => Boolean(c));
|
|
161
|
+
debugFilters('Shadcn filter complete: %d -> %d components', originalCount, this.components.length);
|
|
108
162
|
}
|
|
109
163
|
|
|
110
164
|
withFilter(filter: FilterFunctionType): void {
|
|
165
|
+
debugFilters('Applying custom filter function to %d components', this.components.length);
|
|
166
|
+
const originalCount = this.components.length;
|
|
111
167
|
try {
|
|
112
168
|
this.components = filter(this.components);
|
|
169
|
+
debugFilters('Custom filter applied successfully: %d -> %d components', originalCount, this.components.length);
|
|
113
170
|
} catch (e) {
|
|
171
|
+
debugFilters('ERROR: Failed to apply custom filter: %O', e);
|
|
114
172
|
console.error('Error applying custom filter:', e);
|
|
115
173
|
}
|
|
116
174
|
}
|
|
117
175
|
|
|
118
176
|
async withAllFigmaInstanceNames() {
|
|
177
|
+
debugAPI('Fetching all Figma instance names from file: %s', process.env.FIGMA_FILE_ID);
|
|
119
178
|
try {
|
|
120
179
|
/// ----
|
|
121
180
|
const usedComponentMap = new Map<string, { name: string; description: string; thumbnail: string }>();
|
|
181
|
+
debugTree('Created component map for tracking unique instances');
|
|
122
182
|
|
|
183
|
+
debugAPI('Making API call to getFile with depth: 1...');
|
|
123
184
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
124
185
|
const { document } = await figmaApi.getFile({
|
|
125
186
|
file_key: process.env.FIGMA_FILE_ID,
|
|
126
187
|
depth: 1,
|
|
127
188
|
});
|
|
189
|
+
debugAPI('File document received, starting tree walk');
|
|
190
|
+
|
|
191
|
+
// eslint-disable-next-line complexity
|
|
192
|
+
function walkTree(node: FigmaNode, depth: number = 0) {
|
|
193
|
+
const indent = ' '.repeat(depth);
|
|
194
|
+
debugTree('%sVisiting node: %s (type: %s)', indent, node.name, node.type);
|
|
128
195
|
|
|
129
|
-
function walkTree(node: FigmaNode) {
|
|
130
196
|
if (node.type === 'INSTANCE' && Boolean(node.name)) {
|
|
131
197
|
if (!usedComponentMap.has(node.name)) {
|
|
198
|
+
debugTree('%s -> Found new instance: %s', indent, node.name);
|
|
132
199
|
usedComponentMap.set(node.name, {
|
|
133
200
|
name: node.name,
|
|
134
201
|
description: node.description ?? '',
|
|
135
202
|
thumbnail: node.thumbnail_url ?? '',
|
|
136
203
|
});
|
|
204
|
+
debugTree('%s Description: %s', indent, node.description ? 'present' : 'empty');
|
|
205
|
+
debugTree('%s Thumbnail: %s', indent, node.thumbnail_url ? 'present' : 'missing');
|
|
206
|
+
} else {
|
|
207
|
+
debugTree('%s -> Instance already tracked: %s', indent, node.name);
|
|
137
208
|
}
|
|
138
209
|
}
|
|
139
210
|
|
|
140
211
|
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
141
212
|
if (node.children) {
|
|
213
|
+
debugTree('%s Has %d children', indent, node.children.length);
|
|
142
214
|
for (const child of node.children) {
|
|
143
|
-
walkTree(child);
|
|
215
|
+
walkTree(child, depth + 1);
|
|
144
216
|
}
|
|
145
217
|
}
|
|
146
218
|
}
|
|
147
219
|
|
|
220
|
+
debugTree('Starting tree walk from document root');
|
|
148
221
|
walkTree(document);
|
|
222
|
+
debugTree('Tree walk complete');
|
|
149
223
|
|
|
150
224
|
this.components = Array.from(usedComponentMap.values());
|
|
225
|
+
debugComponents('Extracted %d unique component instances', this.components.length);
|
|
151
226
|
|
|
152
227
|
/// ----
|
|
153
228
|
|
|
@@ -196,12 +271,20 @@ export class FigmaComponentsBuilder {
|
|
|
196
271
|
// );
|
|
197
272
|
// }
|
|
198
273
|
} catch (e) {
|
|
199
|
-
|
|
274
|
+
debugAPI('ERROR: Failed to fetch Figma instance names: %O', e);
|
|
275
|
+
console.error('Failed to fetch Figma instance names:', e);
|
|
200
276
|
}
|
|
277
|
+
debugComponents('withAllFigmaInstanceNames complete, total components: %d', this.components.length);
|
|
201
278
|
return this;
|
|
202
279
|
}
|
|
203
280
|
|
|
204
281
|
build() {
|
|
282
|
+
debug('Building final component list');
|
|
283
|
+
debugComponents('Returning %d components', this.components.length);
|
|
284
|
+
if (this.components.length > 0) {
|
|
285
|
+
debugComponents('First component: %s', this.components[0].name);
|
|
286
|
+
debugComponents('Last component: %s', this.components[this.components.length - 1].name);
|
|
287
|
+
}
|
|
205
288
|
return this.components;
|
|
206
289
|
}
|
|
207
290
|
}
|