55 lines
1.4 KiB
TypeScript
55 lines
1.4 KiB
TypeScript
const THREE_ASSET_PROXY_PATH = "/api/canvas/3d/model-proxy";
|
|
|
|
const PROXY_HOST_KEYWORDS = [
|
|
"tripo3d.ai",
|
|
"tripo3d.com",
|
|
"worldlabs",
|
|
"marble",
|
|
"s3.1080p.hk",
|
|
"img.yydd.ai",
|
|
"blob.vercel-storage.com",
|
|
"aliyuncs.com",
|
|
"amazonaws.com",
|
|
"googleapis.com",
|
|
"googleusercontent.com",
|
|
"cloudfront.net",
|
|
];
|
|
|
|
function isSameOriginBrowserAssetUrl(raw: string) {
|
|
if (typeof window === "undefined") return false;
|
|
|
|
try {
|
|
const parsed = new URL(raw, window.location.origin);
|
|
return parsed.origin === window.location.origin;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function shouldProxyThreeAssetUrl(value?: string | null) {
|
|
const raw = String(value || "").trim();
|
|
if (!raw || raw.startsWith("/") || raw.startsWith("blob:") || raw.startsWith("data:")) {
|
|
return false;
|
|
}
|
|
|
|
if (isSameOriginBrowserAssetUrl(raw)) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
const parsed = new URL(raw);
|
|
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return false;
|
|
const hostname = parsed.hostname.toLowerCase();
|
|
return PROXY_HOST_KEYWORDS.some((keyword) => hostname.includes(keyword));
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function buildThreeAssetUrl(value?: string | null) {
|
|
const raw = String(value || "").trim();
|
|
if (!raw) return "";
|
|
if (!shouldProxyThreeAssetUrl(raw)) return raw;
|
|
return `${THREE_ASSET_PROXY_PATH}?url=${encodeURIComponent(raw)}`;
|
|
}
|