69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
export function safeHttpUrl(input: string) {
|
|
try {
|
|
const url = new URL(input);
|
|
if (!["http:", "https:"].includes(url.protocol)) return null;
|
|
return url;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function extractXhsPublishUrl(input: string) {
|
|
const candidates =
|
|
input.match(/https?:\/\/[^\s<>"',。!?;:、【】()]+/gi) ?? [];
|
|
for (const candidate of candidates) {
|
|
const cleaned = candidate.replace(/[.,!?;:~)\]}]+$/g, "");
|
|
const url = safeHttpUrl(cleaned);
|
|
if (!url) continue;
|
|
const hostname = url.hostname.toLowerCase();
|
|
const isXhs =
|
|
hostname === "xiaohongshu.com" ||
|
|
hostname.endsWith(".xiaohongshu.com") ||
|
|
hostname === "xhslink.cn" ||
|
|
hostname.endsWith(".xhslink.cn");
|
|
if (isXhs) return url.toString();
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export type SupportedPlatform = "小红书" | "抖音";
|
|
|
|
function platformMatches(url: URL, platform: SupportedPlatform) {
|
|
const hostname = url.hostname.toLowerCase();
|
|
if (platform === "抖音") {
|
|
return hostname === "douyin.com" || hostname.endsWith(".douyin.com");
|
|
}
|
|
return (
|
|
hostname === "xiaohongshu.com" ||
|
|
hostname.endsWith(".xiaohongshu.com") ||
|
|
hostname === "xhslink.cn" ||
|
|
hostname.endsWith(".xhslink.cn")
|
|
);
|
|
}
|
|
|
|
export function extractPublishUrl(
|
|
input: string,
|
|
platform: SupportedPlatform = "小红书",
|
|
) {
|
|
const candidates =
|
|
input.match(/https?:\/\/[^\s<>"',。!?;:、【】()]+/gi) ?? [];
|
|
for (const candidate of candidates) {
|
|
const cleaned = candidate.replace(/[.,!?;:~)\]}]+$/g, "");
|
|
const url = safeHttpUrl(cleaned);
|
|
if (url && platformMatches(url, platform)) return url.toString();
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export function extractAnyPublishUrl(input: string) {
|
|
return extractPublishUrl(input, "小红书") || extractPublishUrl(input, "抖音");
|
|
}
|
|
|
|
export function platformFromPublishUrl(input: string): SupportedPlatform | "" {
|
|
const url = safeHttpUrl(input);
|
|
if (!url) return "";
|
|
if (platformMatches(url, "小红书")) return "小红书";
|
|
if (platformMatches(url, "抖音")) return "抖音";
|
|
return "";
|
|
}
|