From e58be35cee814c9f6d66be888467f60b54f6831a Mon Sep 17 00:00:00 2001 From: clawdbot Date: Tue, 27 Jan 2026 23:32:45 +0800 Subject: [PATCH] fix(sdk): improve goView video/iframe import heuristics --- packages/sdk/src/core/goview/convert.ts | 40 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/sdk/src/core/goview/convert.ts b/packages/sdk/src/core/goview/convert.ts index ea670c8..9be5eb0 100644 --- a/packages/sdk/src/core/goview/convert.ts +++ b/packages/sdk/src/core/goview/convert.ts @@ -168,7 +168,10 @@ function looksLikeIframeOption(option: unknown): boolean { return ( (/^https?:\/\//i.test(url) || /^data:text\/html/i.test(url)) && !/\.(png|jpe?g|gif|webp|bmp|svg)(\?|#|$)/i.test(url) && - !/\.(mp4|m3u8|flv|webm|mov|m4v|ogv)(\?|#|$)/i.test(url) + // Avoid misclassifying video streams as iframes. + !/\.(mp4|m3u8|flv|webm|mov|m4v|ogv)(\?|#|$)/i.test(url) && + !/\bm3u8\b/i.test(url) && + !/^(rtsp|rtmp):\/\//i.test(url) ); } @@ -360,7 +363,8 @@ export function convertGoViewProjectToScreen(input: GoViewProjectLike | GoViewSt continue; } - if (isIframe(c) || looksLikeIframeOption(option)) { + // Prefer explicit component keys over heuristics. + if (isIframe(c)) { const props = convertGoViewIframeOptionToNodeProps(option as GoViewIframeOption); nodes.push({ id: c.id ?? `import_iframe_${Math.random().toString(16).slice(2)}`, @@ -374,7 +378,7 @@ export function convertGoViewProjectToScreen(input: GoViewProjectLike | GoViewSt continue; } - if (isVideo(c) || looksLikeVideoOption(option)) { + if (isVideo(c)) { const props = convertGoViewVideoOptionToNodeProps(option as GoViewVideoOption); nodes.push({ id: c.id ?? `import_video_${Math.random().toString(16).slice(2)}`, @@ -387,6 +391,36 @@ export function convertGoViewProjectToScreen(input: GoViewProjectLike | GoViewSt }); continue; } + + // Heuristic fallback: distinguish common URL patterns. + // Important: run video checks before iframe checks; iframe URL detection is broader. + if (looksLikeVideoOption(option)) { + const props = convertGoViewVideoOptionToNodeProps(option as GoViewVideoOption); + nodes.push({ + id: c.id ?? `import_video_${Math.random().toString(16).slice(2)}`, + type: 'video', + rect, + zIndex: c.attr?.zIndex === undefined ? undefined : toNumber((c.attr as unknown as Record).zIndex, 0), + locked: c.status?.lock ?? false, + hidden: c.status?.hide ?? false, + props, + }); + continue; + } + + if (looksLikeIframeOption(option)) { + const props = convertGoViewIframeOptionToNodeProps(option as GoViewIframeOption); + nodes.push({ + id: c.id ?? `import_iframe_${Math.random().toString(16).slice(2)}`, + type: 'iframe', + rect, + zIndex: c.attr?.zIndex === undefined ? undefined : toNumber((c.attr as unknown as Record).zIndex, 0), + locked: c.status?.lock ?? false, + hidden: c.status?.hide ?? false, + props, + }); + continue; + } } return {