Files
ozon-seller-kit/extension-v1/src/collector/url.ts
T

67 lines
1.8 KiB
TypeScript

/**
* URL 工具链 - 处理阿里系 CDN 图片 URL
* 从 docs/extension/plan.md §6.3 移植(来自生产代码)
*/
const IMG_EXT = /\.(jpg|jpeg|png|gif|bmp|heic|webp|avif)$/i;
/**
* 缩略图 URL → 原图 URL
* 阿里 CDN 尺寸后缀在扩展名后:xxx.jpg_400x400.jpg → xxx.jpg
*/
export function toOriginalUrl(url: string): string {
const m = url.match(/^(.+?\.(jpg|jpeg|png|gif|bmp|heic|webp|avif))_/i);
return m ? m[1] : url;
}
/** url("https://...") → https://... */
export function urlInBrackets(s: string): string {
if (!s?.trim()) return '';
return s.match(/\((.*?)\)/)?.[1]?.replace(/['"]/g, '') ?? '';
}
export function isDataUrl(u: string): boolean {
return /^data:image/.test(u);
}
/** 协议相对 // / 根相对 / / 相对路径 → 绝对 URL */
export function toAbsoluteUrl(u: string): string {
if (!u) return u;
if (isDataUrl(u) || u.startsWith('blob:')) return u;
const proto = u.startsWith('http:') ? 'http' : 'https';
if (/^\/\//.test(u)) return `${proto}:${u}`;
if (/^\//.test(u)) return `${location.origin}${u}`;
if (!/^(.*):/.test(u)) return `${location.origin}/${u}`;
return u;
}
/** 去重用的归一化 key:剥掉尺寸后缀和 query */
export function dedupeKey(url: string): string {
const base = toOriginalUrl(url);
try {
const u = new URL(base);
u.search = '';
u.hash = '';
return u.toString();
} catch {
return base;
}
}
export function looksLikeImageUrl(u: string): boolean {
if (isDataUrl(u)) return true;
try {
return IMG_EXT.test(new URL(u).pathname);
} catch {
return IMG_EXT.test(u);
}
}
/** 清洗文件名非法字符(Windows 兼容) */
export function cleanFilename(name: string): string {
return name
.replace(/[<>:"/\\|?*]/g, '_')
.replace(/\s+/g, '_')
.substring(0, 80);
}