Skip to content

Commit 10bb7eb

Browse files
authored
Merge pull request #18 from dev-five-git/fix-assets-issue
Fix assets issue
2 parents a694142 + 1583391 commit 10bb7eb

36 files changed

+4588
-449
lines changed

.husky/pre-commit

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env sh
2-
3-
bun run lint
4-
bun run test
1+
#!/usr/bin/env sh
2+
3+
bun run lint
4+
bun run test

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"dev": "rspack dev",
88
"build": "rspack build",
99
"watch": "rspack build --watch",
10-
"test": "bun test --coverage",
10+
"test": "tsc --noEmit && bun test --coverage",
1111
"lint": "biome check --error-on-warnings",
1212
"lint:fix": "biome check --fix",
1313
"prepare": "husky"
Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,55 @@
1-
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots
2-
3-
exports[`registerCodegen should register codegen 1`] = `
4-
[
5-
{
6-
"code":
7-
"export function Test() {
8-
return <Box boxSize="100%" />
9-
}"
10-
,
11-
"language": "TYPESCRIPT",
12-
"title": "Test - Components",
13-
},
14-
{
15-
"code":
16-
"echo 'export function Test() {
17-
return <Box boxSize="100%" />
18-
}' > Test.tsx"
19-
,
20-
"language": "BASH",
21-
"title": "Test - Components CLI",
22-
},
23-
]
24-
`;
25-
26-
exports[`registerCodegen should register codegen 2`] = `
27-
[
28-
{
29-
"code": "<Box boxSize="100%" />",
30-
"language": "TYPESCRIPT",
31-
"title": "Main",
32-
},
33-
]
34-
`;
35-
36-
exports[`registerCodegen should register codegen 3`] = `[]`;
1+
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots
2+
3+
exports[`registerCodegen should register codegen 1`] = `
4+
[
5+
{
6+
"code":
7+
"export function Test() {
8+
return <Box boxSize="100%" />
9+
}"
10+
,
11+
"language": "TYPESCRIPT",
12+
"title": "Test - Components",
13+
},
14+
{
15+
"code":
16+
"mkdir -p src/components
17+
18+
echo 'import { Box } from \\'@devup-ui/react\\'
19+
20+
export function Test() {
21+
return <Box boxSize="100%" />
22+
}' > src/components/Test.tsx"
23+
,
24+
"language": "BASH",
25+
"title": "Test - Components CLI (Bash)",
26+
},
27+
{
28+
"code":
29+
"New-Item -ItemType Directory -Force -Path src\\components | Out-Null
30+
31+
@'
32+
import { Box } from '@devup-ui/react'
33+
34+
export function Test() {
35+
return <Box boxSize="100%" />
36+
}
37+
'@ | Out-File -FilePath src\\components\\Test.tsx -Encoding UTF8"
38+
,
39+
"language": "BASH",
40+
"title": "Test - Components CLI (PowerShell)",
41+
},
42+
]
43+
`;
44+
45+
exports[`registerCodegen should register codegen 2`] = `
46+
[
47+
{
48+
"code": "<Box boxSize="100%" />",
49+
"language": "TYPESCRIPT",
50+
"title": "Main",
51+
},
52+
]
53+
`;
54+
55+
exports[`registerCodegen should register codegen 3`] = `[]`;

src/__tests__/code-responsive.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const originalGenerateResponsiveCode =
2525

2626
describe('registerCodegen responsive error handling', () => {
2727
beforeEach(() => {
28-
Codegen.prototype.run = runMock
28+
Codegen.prototype.run = runMock as unknown as typeof Codegen.prototype.run
2929
Codegen.prototype.getComponentsCodes = getComponentsCodesMock
3030
Codegen.prototype.getCode = getCodeMock
3131
ResponsiveCodegen.prototype.generateResponsiveCode =
@@ -48,9 +48,8 @@ describe('registerCodegen responsive error handling', () => {
4848
})
4949

5050
test('swallows responsive errors and still returns base code', async () => {
51-
const handlerCalls: Parameters<
52-
Parameters<typeof registerCodegen>[0]['codegen']['on']
53-
>[1][] = []
51+
const handlerCalls: ((event: CodegenEvent) => Promise<CodegenResult[]>)[] =
52+
[]
5453
const ctx = {
5554
editorType: 'dev',
5655
mode: 'codegen',

src/__tests__/code.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ describe('registerCodegen', () => {
9595
node: {
9696
type: 'COMPONENT',
9797
name: 'Test',
98+
visible: true,
9899
},
99100
language: 'devup-ui',
100101
},
@@ -109,6 +110,7 @@ describe('registerCodegen', () => {
109110
node: {
110111
type: 'FRAME',
111112
name: 'Main',
113+
visible: true,
112114
},
113115
language: 'devup-ui',
114116
},
@@ -123,6 +125,7 @@ describe('registerCodegen', () => {
123125
node: {
124126
type: 'FRAME',
125127
name: 'Other',
128+
visible: true,
126129
},
127130
language: 'other',
128131
},
@@ -182,3 +185,32 @@ it('auto-runs on module load when figma is present', async () => {
182185

183186
expect(codegenOn).toHaveBeenCalledWith('generate', expect.any(Function))
184187
})
188+
189+
describe('extractImports', () => {
190+
it('should extract keyframes import when code contains keyframes(', () => {
191+
const result = codeModule.extractImports([
192+
[
193+
'AnimatedBox',
194+
'<Box animationName={keyframes({ "0%": { opacity: 0 } })} />',
195+
],
196+
])
197+
expect(result).toContain('keyframes')
198+
expect(result).toContain('Box')
199+
})
200+
201+
it('should extract keyframes import when code contains keyframes`', () => {
202+
const result = codeModule.extractImports([
203+
['AnimatedBox', '<Box animationName={keyframes`from { opacity: 0 }`} />'],
204+
])
205+
expect(result).toContain('keyframes')
206+
expect(result).toContain('Box')
207+
})
208+
209+
it('should not extract keyframes when not present', () => {
210+
const result = codeModule.extractImports([
211+
['SimpleBox', '<Box w="100px" />'],
212+
])
213+
expect(result).not.toContain('keyframes')
214+
expect(result).toContain('Box')
215+
})
216+
})

src/code-impl.ts

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,80 @@ import { exportDevup, importDevup } from './commands/devup'
44
import { exportAssets } from './commands/exportAssets'
55
import { exportComponents } from './commands/exportComponents'
66

7+
export function extractImports(
8+
componentsCodes: ReadonlyArray<readonly [string, string]>,
9+
): string[] {
10+
const allCode = componentsCodes.map(([_, code]) => code).join('\n')
11+
const imports = new Set<string>()
12+
13+
const devupComponents = [
14+
'Center',
15+
'VStack',
16+
'Flex',
17+
'Grid',
18+
'Box',
19+
'Text',
20+
'Image',
21+
]
22+
23+
for (const component of devupComponents) {
24+
const regex = new RegExp(`<${component}[\\s/>]`, 'g')
25+
if (regex.test(allCode)) {
26+
imports.add(component)
27+
}
28+
}
29+
30+
// keyframes 함수 체크
31+
if (/keyframes\s*\(|keyframes`/.test(allCode)) {
32+
imports.add('keyframes')
33+
}
34+
35+
return Array.from(imports).sort()
36+
}
37+
38+
function generateBashCLI(
39+
componentsCodes: ReadonlyArray<readonly [string, string]>,
40+
): string {
41+
const imports = extractImports(componentsCodes)
42+
const importStatement =
43+
imports.length > 0
44+
? `import { ${imports.join(', ')} } from '@devup-ui/react'\n\n`
45+
: ''
46+
47+
const commands = [
48+
'mkdir -p src/components',
49+
'',
50+
...componentsCodes.map(([componentName, code]) => {
51+
const fullCode = importStatement + code
52+
const escapedCode = fullCode.replace(/'/g, "\\'")
53+
return `echo '${escapedCode}' > src/components/${componentName}.tsx`
54+
}),
55+
]
56+
57+
return commands.join('\n')
58+
}
59+
60+
function generatePowerShellCLI(
61+
componentsCodes: ReadonlyArray<readonly [string, string]>,
62+
): string {
63+
const imports = extractImports(componentsCodes)
64+
const importStatement =
65+
imports.length > 0
66+
? `import { ${imports.join(', ')} } from '@devup-ui/react'\n\n`
67+
: ''
68+
69+
const commands = [
70+
'New-Item -ItemType Directory -Force -Path src\\components | Out-Null',
71+
'',
72+
...componentsCodes.map(([componentName, code]) => {
73+
const fullCode = importStatement + code
74+
return `@'\n${fullCode}\n'@ | Out-File -FilePath src\\components\\${componentName}.tsx -Encoding UTF8`
75+
}),
76+
]
77+
78+
return commands.join('\n')
79+
}
80+
781
export function registerCodegen(ctx: typeof figma) {
882
if (ctx.editorType === 'dev' && ctx.mode === 'codegen') {
983
ctx.codegen.on('generate', async ({ node, language }) => {
@@ -15,7 +89,6 @@ export function registerCodegen(ctx: typeof figma) {
1589
const componentsCodes = codegen.getComponentsCodes()
1690
console.info(`[benchmark] devup-ui end ${Date.now() - time}ms`)
1791

18-
// 반응형 코드 생성 (부모가 Section인 경우)
1992
const parentSection = ResponsiveCodegen.hasParentSection(node)
2093
let responsiveResult: {
2194
title: string
@@ -60,14 +133,14 @@ export function registerCodegen(ctx: typeof figma) {
60133
code: componentsCodes.map((code) => code[1]).join('\n\n'),
61134
},
62135
{
63-
title: `${node.name} - Components CLI`,
136+
title: `${node.name} - Components CLI (Bash)`,
137+
language: 'BASH',
138+
code: generateBashCLI(componentsCodes),
139+
},
140+
{
141+
title: `${node.name} - Components CLI (PowerShell)`,
64142
language: 'BASH',
65-
code: componentsCodes
66-
.map(
67-
([componentName, code]) =>
68-
`echo '${code}' > ${componentName}.tsx`,
69-
)
70-
.join('\n'),
143+
code: generatePowerShellCLI(componentsCodes),
71144
},
72145
] as const)
73146
: []),

0 commit comments

Comments
 (0)