@pedroab0/skills 1.1.0 → 1.2.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/bin/cli.js +23 -3
- package/figma-extractor/figma-plugin/code.js +461 -87
- package/figma-extractor/figma-plugin/ui.html +76 -23
- package/figma-extractor/scripts/fetch_figma.js +285 -35
- package/figma-to-code/scripts/fetch_figma.js +285 -35
- package/package.json +7 -2
- package/figma-extractor/demo/desktop_home.json +0 -2434
- package/figma-extractor/demo/dt_money_desktop_home.png +0 -0
- package/figma-extractor/demo/dt_money_preview.png +0 -0
- package/figma-extractor/demo/dt_money_selection.json +0 -472
- package/figma-extractor/demo/index.html +0 -188
- package/figma-extractor/demo/style.css +0 -360
- package/figma-extractor/figma-plugin/assets/cover-1920.png +0 -0
- package/figma-extractor/figma-plugin/assets/cover.jpg +0 -0
- package/figma-extractor/figma-plugin/assets/cover.png +0 -0
- package/figma-extractor/figma-plugin/assets/icon-128.png +0 -0
- package/figma-extractor/figma-plugin/assets/icon.png +0 -0
- package/figma-extractor/scripts/test_fetch_figma.js +0 -687
- package/figma-node-builder/scripts/test_inspect_spec.js +0 -163
- package/figma-to-code/scripts/test_fetch_figma.js +0 -660
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const assert = require('assert');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const os = require('os');
|
|
7
|
-
const { execSync } = require('child_process');
|
|
8
|
-
const {
|
|
9
|
-
decodeTextBuffer,
|
|
10
|
-
resolveSpecPath,
|
|
11
|
-
inspectSpec,
|
|
12
|
-
formatTerminalReport,
|
|
13
|
-
formatMarkdownReport,
|
|
14
|
-
} = require('./inspect_spec.js');
|
|
15
|
-
|
|
16
|
-
console.log('--- Running Spec Inspector Unit Tests ---');
|
|
17
|
-
|
|
18
|
-
// Mock Node AST tree
|
|
19
|
-
const mockSpec = {
|
|
20
|
-
name: 'Product Card',
|
|
21
|
-
type: 'FRAME',
|
|
22
|
-
bounds: { width: 360, height: 480 },
|
|
23
|
-
layoutMode: 'VERTICAL',
|
|
24
|
-
itemSpacing: 16,
|
|
25
|
-
itemSpacingToken: 'spacing/md',
|
|
26
|
-
padding: { top: 24, right: 24, bottom: 24, left: 24 },
|
|
27
|
-
paddingToken: 'spacing/lg',
|
|
28
|
-
cornerRadius: 12,
|
|
29
|
-
cornerRadiusToken: 'radii/lg',
|
|
30
|
-
fills: [{ type: 'SOLID', color: '#FFFFFF', token: 'color/surface' }],
|
|
31
|
-
children: [
|
|
32
|
-
{
|
|
33
|
-
name: 'Badge Instance',
|
|
34
|
-
type: 'INSTANCE',
|
|
35
|
-
component: { name: 'Badge' },
|
|
36
|
-
props: { variant: 'success', label: 'In Stock' },
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: 'Title',
|
|
40
|
-
type: 'TEXT',
|
|
41
|
-
characters: 'Wireless Noise-Canceling Headphones',
|
|
42
|
-
style: {
|
|
43
|
-
fontFamily: 'Inter',
|
|
44
|
-
fontSize: 20,
|
|
45
|
-
fontWeight: 700,
|
|
46
|
-
},
|
|
47
|
-
fills: [{ type: 'SOLID', color: '#111827', token: 'color/text-primary' }],
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: 'Description',
|
|
51
|
-
type: 'TEXT',
|
|
52
|
-
characters: 'Premium audio experience with active noise cancellation.',
|
|
53
|
-
style: {
|
|
54
|
-
fontFamily: 'Inter',
|
|
55
|
-
fontSize: 14,
|
|
56
|
-
fontWeight: 400,
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'Action Button',
|
|
61
|
-
type: 'INSTANCE',
|
|
62
|
-
component: { name: 'Button' },
|
|
63
|
-
props: { variant: 'primary', size: 'md', hasIcon: true },
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name: 'Secondary Button',
|
|
67
|
-
type: 'INSTANCE',
|
|
68
|
-
component: { name: 'Button' },
|
|
69
|
-
props: { variant: 'outline', size: 'md' },
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
// 1. inspectSpec: dimensions and layout
|
|
75
|
-
const report = inspectSpec(mockSpec, '/mock/.specs/card.json');
|
|
76
|
-
assert.strictEqual(report.rootLayout.name, 'Product Card');
|
|
77
|
-
assert.strictEqual(report.rootLayout.width, 360);
|
|
78
|
-
assert.strictEqual(report.rootLayout.height, 480);
|
|
79
|
-
assert.strictEqual(report.rootLayout.layoutMode, 'VERTICAL');
|
|
80
|
-
assert.strictEqual(report.rootLayout.itemSpacing, 16);
|
|
81
|
-
assert.strictEqual(report.rootLayout.itemSpacingToken, 'spacing/md');
|
|
82
|
-
assert.strictEqual(report.rootLayout.paddingToken, 'spacing/lg');
|
|
83
|
-
console.log(' ✓ inspectSpec: correctly extracts root dimensions and auto-layout metrics');
|
|
84
|
-
|
|
85
|
-
// 2. inspectSpec: tokens
|
|
86
|
-
assert.ok(report.tokens.colors.has('color/surface'), 'Includes surface color token');
|
|
87
|
-
assert.ok(report.tokens.colors.has('color/text-primary'), 'Includes text color token');
|
|
88
|
-
assert.ok(report.tokens.spacing.has('spacing/md'), 'Includes spacing/md token');
|
|
89
|
-
assert.ok(report.tokens.radii.has('radii/lg'), 'Includes radii/lg token');
|
|
90
|
-
console.log(' ✓ inspectSpec: aggregates design tokens across colors, spacing, and radii');
|
|
91
|
-
|
|
92
|
-
// 3. inspectSpec: component instances & gaps
|
|
93
|
-
assert.strictEqual(report.instances.size, 2, 'Detects 2 distinct components');
|
|
94
|
-
assert.strictEqual(report.instances.get('Button').length, 2, 'Detects 2 Button instances');
|
|
95
|
-
assert.strictEqual(report.instances.get('Badge').length, 1, 'Detects 1 Badge instance');
|
|
96
|
-
assert.strictEqual(report.instances.get('Button')[0].variant, 'primary');
|
|
97
|
-
assert.strictEqual(report.instances.get('Button')[1].variant, 'outline');
|
|
98
|
-
console.log(' ✓ inspectSpec: aggregates component instances and variant prop shapes');
|
|
99
|
-
|
|
100
|
-
// 4. inspectSpec: typography
|
|
101
|
-
assert.strictEqual(report.typography.totalTextLayers, 2);
|
|
102
|
-
assert.ok(report.typography.fontFamilies.has('Inter'));
|
|
103
|
-
assert.ok(report.typography.fontSizes.has(20));
|
|
104
|
-
assert.ok(report.typography.fontSizes.has(14));
|
|
105
|
-
assert.ok(report.typography.fontWeights.has(700));
|
|
106
|
-
console.log(' ✓ inspectSpec: extracts font families, sizes, weights, and text samples');
|
|
107
|
-
|
|
108
|
-
// 5. formatTerminalReport & formatMarkdownReport
|
|
109
|
-
const terminalText = formatTerminalReport(report);
|
|
110
|
-
assert.ok(terminalText.includes('Product Card'));
|
|
111
|
-
assert.ok(terminalText.includes('Vertical Flex (Column)'));
|
|
112
|
-
assert.ok(terminalText.includes('<Button />'));
|
|
113
|
-
assert.ok(terminalText.includes('<Badge />'));
|
|
114
|
-
assert.ok(terminalText.includes('Component Gaps & Codebase Checklist'));
|
|
115
|
-
console.log(' ✓ formatTerminalReport: formats clean box-drawing terminal report');
|
|
116
|
-
|
|
117
|
-
const markdownText = formatMarkdownReport(report);
|
|
118
|
-
assert.ok(markdownText.includes('### 📐 Figma Spec Summary: `card.json`'));
|
|
119
|
-
assert.ok(markdownText.includes('`<Button />`'));
|
|
120
|
-
assert.ok(markdownText.includes('`spacing/md`'));
|
|
121
|
-
console.log(' ✓ formatMarkdownReport: formats Markdown table and component checklist');
|
|
122
|
-
|
|
123
|
-
// 6. resolveSpecPath: resolution from disk
|
|
124
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'spec-test-'));
|
|
125
|
-
try {
|
|
126
|
-
const specsSubdir = path.join(tmpDir, '.specs');
|
|
127
|
-
fs.mkdirSync(specsSubdir, { recursive: true });
|
|
128
|
-
const testFile = path.join(specsSubdir, 'product.json');
|
|
129
|
-
fs.writeFileSync(testFile, JSON.stringify(mockSpec), 'utf8');
|
|
130
|
-
|
|
131
|
-
// Direct path
|
|
132
|
-
assert.strictEqual(resolveSpecPath(testFile), testFile);
|
|
133
|
-
|
|
134
|
-
// Shorthand in cwd
|
|
135
|
-
const origCwd = process.cwd();
|
|
136
|
-
try {
|
|
137
|
-
process.chdir(tmpDir);
|
|
138
|
-
const expected = fs.realpathSync(path.resolve(specsSubdir, 'product.json'));
|
|
139
|
-
assert.strictEqual(fs.realpathSync(resolveSpecPath('product')), expected);
|
|
140
|
-
assert.strictEqual(fs.realpathSync(resolveSpecPath('.specs/product')), expected);
|
|
141
|
-
assert.strictEqual(fs.realpathSync(resolveSpecPath('.specs/product.json')), expected);
|
|
142
|
-
console.log(' ✓ resolveSpecPath: resolves direct files, shorthand names, and .specs/ subdirectories');
|
|
143
|
-
} finally {
|
|
144
|
-
process.chdir(origCwd);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// 7. decodeTextBuffer & CLI UTF-8 BOM / UTF-16LE BOM resilience (Windows PowerShell 5.1 & Notepad)
|
|
148
|
-
const utf8BomFile = path.join(specsSubdir, 'utf8bom.json');
|
|
149
|
-
fs.writeFileSync(utf8BomFile, '\uFEFF' + JSON.stringify(mockSpec), 'utf8');
|
|
150
|
-
const utf16BomFile = path.join(specsSubdir, 'utf16le.json');
|
|
151
|
-
const utf16Buf = Buffer.concat([Buffer.from([0xff, 0xfe]), Buffer.from(JSON.stringify(mockSpec), 'utf16le')]);
|
|
152
|
-
fs.writeFileSync(utf16BomFile, utf16Buf);
|
|
153
|
-
|
|
154
|
-
assert.strictEqual(JSON.parse(decodeTextBuffer(fs.readFileSync(utf8BomFile))).name, 'Product Card');
|
|
155
|
-
assert.strictEqual(JSON.parse(decodeTextBuffer(fs.readFileSync(utf16BomFile))).name, 'Product Card');
|
|
156
|
-
const cliOut = execSync(`node "${path.join(__dirname, 'inspect_spec.js')}" "${utf16BomFile}" --markdown`, { encoding: 'utf8' });
|
|
157
|
-
assert.ok(cliOut.includes('Product Card'));
|
|
158
|
-
console.log(' ✓ decodeTextBuffer & CLI: parses UTF-8 BOM and UTF-16LE BOM specs cleanly');
|
|
159
|
-
} finally {
|
|
160
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
console.log('\nResults: 7/7 Spec Inspector tests passed.\n');
|