UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

78 lines (77 loc) • 3.16 kB
import { o as normalizeLowercaseStringOrEmpty } from "./string-coerce-1VuiLaaR.mjs"; import "./avatar-limits-2506OuP3.mjs"; import path from "node:path"; //#region src/shared/avatar-policy.ts /** * Shared avatar source policy for config validation, agent identity loading, * gateway uploads, and Control UI rendering hints. */ const LOCAL_AVATAR_EXTENSIONS = /* @__PURE__ */ new Set([ ".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg" ]); /** MIME hints for known image extensions, including formats not accepted for local serving. */ const AVATAR_MIME_BY_EXT = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".webp": "image/webp", ".gif": "image/gif", ".svg": "image/svg+xml", ".bmp": "image/bmp", ".tif": "image/tiff", ".tiff": "image/tiff" }; /** Detects data URLs before image-specific avatar validation. */ const AVATAR_DATA_RE = /^data:/i; /** Detects remote avatar URLs served over HTTP(S). */ const AVATAR_HTTP_RE = /^https?:\/\//i; /** Detects URI schemes so non-path avatar values can be rejected or routed. */ const AVATAR_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i; /** Detects Windows absolute paths before URI-scheme classification. */ const WINDOWS_ABS_RE = /^[a-zA-Z]:[\\/]/; const AVATAR_PATH_EXT_RE = /\.(png|jpe?g|gif|webp|svg|ico)$/i; /** Resolves a local avatar file MIME type from its extension. */ function resolveAvatarMime(filePath) { const ext = normalizeLowercaseStringOrEmpty(path.extname(filePath)); return AVATAR_MIME_BY_EXT[ext] ?? "application/octet-stream"; } /** Detects any data URL value before image-specific validation. */ function isAvatarDataUrl(value) { return AVATAR_DATA_RE.test(value); } /** Detects remote HTTP(S) avatar URLs. */ function isAvatarHttpUrl(value) { return AVATAR_HTTP_RE.test(value); } /** Detects URI-scheme-like avatar values, including non-HTTP schemes. */ function hasAvatarUriScheme(value) { return AVATAR_SCHEME_RE.test(value); } /** Detects Windows absolute paths so they are not mistaken for URI schemes. */ function isWindowsAbsolutePath(value) { return WINDOWS_ABS_RE.test(value); } /** * Trimmed avatar values that config validation confines to the agent workspace. * Data and HTTP(S) URLs are allowed anywhere; "~" and other URI-like values are rejected. */ function isAvatarWorkspacePath(value) { return value !== "" && !isAvatarDataUrl(value) && !isAvatarHttpUrl(value) && !value.startsWith("~") && (!hasAvatarUriScheme(value) || isWindowsAbsolutePath(value)); } /** Heuristically detects strings that look like local avatar file paths. */ function looksLikeAvatarPath(value) { if (/[\\/]/.test(value)) return true; return AVATAR_PATH_EXT_RE.test(value); } /** Restricts local avatar files to image extensions that can be safely served inline. */ function isSupportedLocalAvatarExtension(filePath) { const ext = normalizeLowercaseStringOrEmpty(path.extname(filePath)); return LOCAL_AVATAR_EXTENSIONS.has(ext); } //#endregion export { isSupportedLocalAvatarExtension as a, resolveAvatarMime as c, isAvatarWorkspacePath as i, isAvatarDataUrl as n, isWindowsAbsolutePath as o, isAvatarHttpUrl as r, looksLikeAvatarPath as s, hasAvatarUriScheme as t };