76 lines
1.7 KiB
TypeScript
76 lines
1.7 KiB
TypeScript
/**
|
|
* Small helper for permissive imports (goView / low-code exports).
|
|
*
|
|
* Many widgets store their URL-ish source in slightly different shapes:
|
|
* - string
|
|
* - { value: string }
|
|
* - { url: string }
|
|
* - { src: string }
|
|
* - { dataset: string | { value/url/src } }
|
|
* - nested objects under `data` / `config` / `options`
|
|
*/
|
|
export function pickUrlLike(input: unknown, maxDepth = 3): string {
|
|
return pickUrlLikeInner(input, maxDepth);
|
|
}
|
|
|
|
function pickUrlLikeInner(input: unknown, depth: number): string {
|
|
if (typeof input === 'string') return input;
|
|
if (!input) return '';
|
|
|
|
if (Array.isArray(input)) {
|
|
for (const item of input) {
|
|
const v = pickUrlLikeInner(item, depth - 1);
|
|
if (v) return v;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
if (typeof input !== 'object') return '';
|
|
|
|
const obj = input as Record<string, unknown>;
|
|
|
|
// Common direct keys.
|
|
// Keep this list generous; imports come from many low-code editors.
|
|
for (const key of [
|
|
'value',
|
|
'url',
|
|
'src',
|
|
'href',
|
|
'link',
|
|
'path',
|
|
'source',
|
|
'address',
|
|
// iframe-ish
|
|
'iframeUrl',
|
|
'iframeSrc',
|
|
'embedUrl',
|
|
// video-ish
|
|
'videoUrl',
|
|
'videoSrc',
|
|
'mp4',
|
|
'm3u8',
|
|
'flv',
|
|
// other streaming-ish keys
|
|
'hls',
|
|
'hlsUrl',
|
|
'stream',
|
|
'streamUrl',
|
|
'rtsp',
|
|
'rtspUrl',
|
|
]) {
|
|
const v = obj[key];
|
|
if (typeof v === 'string' && v) return v;
|
|
}
|
|
|
|
if (depth <= 0) return '';
|
|
|
|
// Common nesting keys.
|
|
for (const key of ['dataset', 'data', 'config', 'option', 'options', 'props', 'source', 'media']) {
|
|
const v = obj[key];
|
|
const nested = pickUrlLikeInner(v, depth - 1);
|
|
if (nested) return nested;
|
|
}
|
|
|
|
return '';
|
|
}
|