sdk: normalize imported iframe/video urls

This commit is contained in:
clawdbot 2026-01-28 22:50:18 +08:00
parent 5ff0c22724
commit 3c3c2b74aa
3 changed files with 34 additions and 10 deletions

View File

@ -1,5 +1,5 @@
import type { IframeWidgetNode } from '../schema';
import { pickUrlLike } from './urlLike';
import { normalizeUrlLike, pickUrlLike } from './urlLike';
/**
* goView iframe option shape varies across versions.
@ -209,16 +209,16 @@ function pickSrc(option: GoViewIframeOption): string {
if (url) {
if (looksLikeHtml(url)) {
const extracted = extractSrcFromEmbedHtml(url);
return extracted || toDataHtmlUrl(url);
return extracted ? normalizeUrlLike(extracted) : toDataHtmlUrl(url);
}
return url;
return normalizeUrlLike(url);
}
// 2) Some exports store raw HTML instead of a URL.
const html = pickHtmlString(option);
if (html) {
const extracted = extractSrcFromEmbedHtml(html);
return extracted || toDataHtmlUrl(html);
return extracted ? normalizeUrlLike(extracted) : toDataHtmlUrl(html);
}
// 3) List-ish shapes.
@ -237,9 +237,9 @@ function pickSrc(option: GoViewIframeOption): string {
if (!listUrl) return '';
if (looksLikeHtml(listUrl)) {
const extracted = extractSrcFromEmbedHtml(listUrl);
return extracted || toDataHtmlUrl(listUrl);
return extracted ? normalizeUrlLike(extracted) : toDataHtmlUrl(listUrl);
}
return listUrl;
return normalizeUrlLike(listUrl);
}
function pickFit(option: GoViewIframeOption): IframeWidgetNode['props']['fit'] | undefined {

View File

@ -10,7 +10,31 @@
* - nested objects under `data` / `config` / `options`
*/
export function pickUrlLike(input: unknown, maxDepth = 3): string {
return pickUrlLikeInner(input, maxDepth);
const raw = pickUrlLikeInner(input, maxDepth);
return normalizeUrlLike(raw);
}
/**
* Normalize URL-ish strings from low-code exports.
*
* Common cases:
* - protocol-relative URLs (//example.com) → https://example.com
* - "www.example.com" https://www.example.com
*/
export function normalizeUrlLike(url: string): string {
const s = url.trim();
if (!s) return '';
// Don't touch data URLs, streaming protocols, or explicit protocols.
if (/^(data:|rtsp:\/\/|rtmp:\/\/|https?:\/\/)/i.test(s)) return s;
// protocol-relative URLs
if (s.startsWith('//')) return `https:${s}`;
// bare hostnames
if (/^www\./i.test(s)) return `https://${s}`;
return s;
}
function looksLikeJsonString(input: string): boolean {

View File

@ -1,5 +1,5 @@
import type { VideoWidgetNode } from '../schema';
import { pickUrlLike } from './urlLike';
import { normalizeUrlLike, pickUrlLike } from './urlLike';
/**
* goView video option shape varies across versions.
@ -221,9 +221,9 @@ function pickFirstUrlFromList(input: unknown): string {
function normalizeSrcMaybeFromHtml(raw: string): string {
if (!raw) return '';
if (!looksLikeHtml(raw)) return raw;
if (!looksLikeHtml(raw)) return normalizeUrlLike(raw);
const extracted = extractSrcFromVideoHtml(raw);
return extracted || raw;
return extracted ? normalizeUrlLike(extracted) : raw;
}
function pickSrc(option: GoViewVideoOption): string {