AstralView/packages/sdk/src/core/widgets/urlLike.ts

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 '';
}