sdk: improve legacy import URL inference

This commit is contained in:
clawdbot 2026-01-27 21:52:27 +08:00
parent ee4fc74512
commit f1daf69d92
2 changed files with 37 additions and 3 deletions

View File

@ -118,6 +118,19 @@ function isVideo(c: GoViewComponentLike): boolean {
return k.includes('mp4') || k.includes('media') || k.includes('player') || k.includes('stream'); return k.includes('mp4') || k.includes('media') || k.includes('player') || k.includes('stream');
} }
function looksLikeImageOption(option: unknown): boolean {
const url = pickUrlLike(option);
if (!url) return false;
// Common direct image URLs.
if (/\.(png|jpe?g|gif|webp|bmp|svg)(\?|#|$)/i.test(url)) return true;
// data urls
if (/^data:image\//i.test(url)) return true;
return false;
}
function looksLikeIframeOption(option: unknown): boolean { function looksLikeIframeOption(option: unknown): boolean {
if (!option || typeof option !== 'object') return false; if (!option || typeof option !== 'object') return false;
const o = option as Record<string, unknown>; const o = option as Record<string, unknown>;
@ -130,7 +143,11 @@ function looksLikeIframeOption(option: unknown): boolean {
// If it isn't an obvious media URL, it's often an iframe/embed. // If it isn't an obvious media URL, it's often an iframe/embed.
// (We deliberately keep this conservative; image/video are handled earlier.) // (We deliberately keep this conservative; image/video are handled earlier.)
return /^https?:\/\//i.test(url) && !/\.(mp4|m3u8|flv)(\?|#|$)/i.test(url); return (
(/^https?:\/\//i.test(url) || /^data:text\/html/i.test(url)) &&
!/\.(png|jpe?g|gif|webp|bmp|svg)(\?|#|$)/i.test(url) &&
!/\.(mp4|m3u8|flv)(\?|#|$)/i.test(url)
);
} }
function looksLikeVideoOption(option: unknown): boolean { function looksLikeVideoOption(option: unknown): boolean {
@ -147,6 +164,9 @@ function looksLikeVideoOption(option: unknown): boolean {
if (/\.(mp4|m3u8|flv)(\?|#|$)/i.test(url)) return true; if (/\.(mp4|m3u8|flv)(\?|#|$)/i.test(url)) return true;
if (/\bm3u8\b/i.test(url)) return true; if (/\bm3u8\b/i.test(url)) return true;
// Streaming-ish protocols (seen in CCTV/camera widgets).
if (/^(rtsp|rtmp):\/\//i.test(url)) return true;
return false; return false;
} }
@ -300,7 +320,7 @@ export function convertGoViewProjectToScreen(input: GoViewProjectLike | GoViewSt
continue; continue;
} }
if (isImage(c)) { if (isImage(c) || looksLikeImageOption(option)) {
const props = convertGoViewImageOptionToNodeProps(option as GoViewImageOption); const props = convertGoViewImageOptionToNodeProps(option as GoViewImageOption);
nodes.push({ nodes.push({
id: c.id ?? `import_image_${Math.random().toString(16).slice(2)}`, id: c.id ?? `import_image_${Math.random().toString(16).slice(2)}`,

View File

@ -65,7 +65,21 @@ function pickUrlLikeInner(input: unknown, depth: number): string {
if (depth <= 0) return ''; if (depth <= 0) return '';
// Common nesting keys. // Common nesting keys.
for (const key of ['dataset', 'data', 'config', 'option', 'options', 'props', 'source', 'media']) { for (const key of [
'dataset',
'data',
'config',
'option',
'options',
'props',
'source',
'media',
// widget-ish wrappers seen in exports
'iframe',
'video',
'image',
'img',
]) {
const v = obj[key]; const v = obj[key];
const nested = pickUrlLikeInner(v, depth - 1); const nested = pickUrlLikeInner(v, depth - 1);
if (nested) return nested; if (nested) return nested;