Skip to content

Commit 8d31698

Browse files
committed
fix: resolve build error and audit findings from simplify review
- Add BUILT_IN_TOOL_TYPES export to blocks/utils.ts (was removed from tool-input.tsx but never added to the new import target — caused build error "Export BUILT_IN_TOOL_TYPES doesn't exist in target module") - Export Wordmark from emcn icons barrel (index.ts) - Derive isDragging from dragCounter in skill-import.tsx instead of maintaining redundant state that could desync - Replace manual AbortController/setTimeout with AbortSignal.timeout() in skills import API route (Node 17.3+ supported, cleaner no-cleanup) - Use useId() for SVG gradient ID in wordmark.tsx to prevent duplicate ID collisions if rendered multiple times on the same page
1 parent 722b6ad commit 8d31698

File tree

5 files changed

+53
-42
lines changed

5 files changed

+53
-42
lines changed

apps/sim/app/api/skills/import/route.ts

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -64,42 +64,35 @@ export async function POST(req: NextRequest) {
6464
return NextResponse.json({ error: message }, { status: 400 })
6565
}
6666

67-
const controller = new AbortController()
68-
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS)
69-
70-
try {
71-
const response = await fetch(rawUrl, {
72-
signal: controller.signal,
73-
headers: { Accept: 'text/plain' },
67+
const response = await fetch(rawUrl, {
68+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
69+
headers: { Accept: 'text/plain' },
70+
})
71+
72+
if (!response.ok) {
73+
logger.warn(`[${requestId}] GitHub fetch failed`, {
74+
status: response.status,
75+
url: rawUrl,
7476
})
77+
return NextResponse.json(
78+
{ error: `Failed to fetch file (HTTP ${response.status}). Is the repository public?` },
79+
{ status: 502 }
80+
)
81+
}
7582

76-
if (!response.ok) {
77-
logger.warn(`[${requestId}] GitHub fetch failed`, {
78-
status: response.status,
79-
url: rawUrl,
80-
})
81-
return NextResponse.json(
82-
{ error: `Failed to fetch file (HTTP ${response.status}). Is the repository public?` },
83-
{ status: 502 }
84-
)
85-
}
86-
87-
const content = await response.text()
88-
89-
if (content.length > 100_000) {
90-
return NextResponse.json({ error: 'File is too large (max 100KB)' }, { status: 400 })
91-
}
92-
93-
return NextResponse.json({ content })
94-
} finally {
95-
clearTimeout(timeout)
83+
const content = await response.text()
84+
85+
if (content.length > 100_000) {
86+
return NextResponse.json({ error: 'File is too large (max 100KB)' }, { status: 400 })
9687
}
88+
89+
return NextResponse.json({ content })
9790
} catch (error) {
9891
if (error instanceof z.ZodError) {
9992
return NextResponse.json({ error: 'Invalid request', details: error.errors }, { status: 400 })
10093
}
10194

102-
if (error instanceof Error && error.name === 'AbortError') {
95+
if (error instanceof Error && (error.name === 'AbortError' || error.name === 'TimeoutError')) {
10396
logger.warn(`[${requestId}] GitHub fetch timed out`)
10497
return NextResponse.json({ error: 'Request timed out' }, { status: 504 })
10598
}

apps/sim/app/workspace/[workspaceId]/settings/components/skills/components/skill-import.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ function isAcceptedFile(file: File): boolean {
3030
export function SkillImport({ onImport }: SkillImportProps) {
3131
const fileInputRef = useRef<HTMLInputElement>(null)
3232

33-
const [isDragging, setIsDragging] = useState(false)
3433
const [dragCounter, setDragCounter] = useState(0)
34+
const isDragging = dragCounter > 0
3535
const [fileState, setFileState] = useState<ImportState>('idle')
3636
const [fileError, setFileError] = useState('')
3737

@@ -86,21 +86,13 @@ export function SkillImport({ onImport }: SkillImportProps) {
8686
const handleDragEnter = useCallback((e: React.DragEvent) => {
8787
e.preventDefault()
8888
e.stopPropagation()
89-
setDragCounter((prev) => {
90-
const next = prev + 1
91-
if (next === 1) setIsDragging(true)
92-
return next
93-
})
89+
setDragCounter((prev) => prev + 1)
9490
}, [])
9591

9692
const handleDragLeave = useCallback((e: React.DragEvent) => {
9793
e.preventDefault()
9894
e.stopPropagation()
99-
setDragCounter((prev) => {
100-
const next = prev - 1
101-
if (next === 0) setIsDragging(false)
102-
return next
103-
})
95+
setDragCounter((prev) => prev - 1)
10496
}, [])
10597

10698
const handleDragOver = useCallback((e: React.DragEvent) => {
@@ -113,7 +105,6 @@ export function SkillImport({ onImport }: SkillImportProps) {
113105
(e: React.DragEvent) => {
114106
e.preventDefault()
115107
e.stopPropagation()
116-
setIsDragging(false)
117108
setDragCounter(0)
118109

119110
const file = e.dataTransfer.files?.[0]

apps/sim/blocks/utils.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,29 @@ export function normalizeFileInput(
365365
return files
366366
}
367367

368+
/**
369+
* Block types that are built-in to the platform (as opposed to third-party integrations).
370+
* Used to categorize tools in the tool selection dropdown.
371+
*/
372+
export const BUILT_IN_TOOL_TYPES = new Set([
373+
'api',
374+
'file',
375+
'function',
376+
'knowledge',
377+
'search',
378+
'thinking',
379+
'image_generator',
380+
'video_generator',
381+
'vision',
382+
'translate',
383+
'tts',
384+
'stt',
385+
'memory',
386+
'table',
387+
'webhook_request',
388+
'workflow',
389+
])
390+
368391
/**
369392
* Shared wand configuration for the Response Format code subblock.
370393
* Used by Agent and Mothership blocks.

apps/sim/components/emcn/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export { Upload } from './upload'
8484
export { User } from './user'
8585
export { UserPlus } from './user-plus'
8686
export { Users } from './users'
87+
export { Wordmark } from './wordmark'
8788
export { WorkflowX } from './workflow-x'
8889
export { Wrap } from './wrap'
8990
export { Wrench } from './wrench'

apps/sim/components/emcn/icons/wordmark.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import type { SVGProps } from 'react'
2+
import { useId } from 'react'
23

34
/**
45
* Sim brand wordmark — icon (green) + "Sim" text as a single SVG.
56
* Use when expanded; use the plain `Sim` icon when collapsed.
67
* @param props - SVG properties including className, style, etc.
78
*/
89
export function Wordmark(props: SVGProps<SVGSVGElement>) {
10+
const gradientId = useId()
11+
912
return (
1013
<svg
1114
fill='none'
@@ -28,12 +31,12 @@ export function Wordmark(props: SVGProps<SVGSVGElement>) {
2831
/>
2932
<path
3033
d='m275.293 171.18h-85.187c-10.327 0-18.7 8.432-18.7 18.834v84.749c0 10.402 8.373 18.833 18.7 18.833h85.187c10.328 0 18.701-8.431 18.701-18.833v-84.749c0-10.402-8.373-18.834-18.701-18.834z'
31-
fill='url(#sim-wordmark-gradient)'
34+
fill={`url(#${gradientId})`}
3235
fillOpacity='.2'
3336
/>
3437
<defs>
3538
<linearGradient
36-
id='sim-wordmark-gradient'
39+
id={gradientId}
3740
gradientUnits='userSpaceOnUse'
3841
x1='171.406'
3942
x2='245.831'

0 commit comments

Comments
 (0)