"use client"; import { createContext, useContext } from "react"; import { Badge, Code, Image, Text, Title } from "@mantine/core"; export const SubFetchDataContext = createContext(undefined); const BLOCKED_KEYS = new Set(["constructor", "prototype", "__proto__"]); export function normalizeParams(value: unknown) { if (value === undefined) return {}; if (!value || typeof value !== "object" || Array.isArray(value)) return null; const result: Record = {}; for (const [key, param] of Object.entries(value)) { if (BLOCKED_KEYS.has(key)) return null; if (typeof param !== "string" && typeof param !== "number" && typeof param !== "boolean") return null; result[key] = param; } return result; } export function getByPath(value: unknown, path?: string): unknown { if (!path?.trim()) return value; return path.split(".").reduce((current, key) => { if (current == null || typeof current !== "object" || BLOCKED_KEYS.has(key)) return undefined; return Object.hasOwn(current, key) ? (current as Record)[key] : undefined; }, value); } export function formatDisplayValue(value: unknown): string { if (value == null) return "—"; if (typeof value === "object") return JSON.stringify(value); return String(value); } export interface SubDataProps { path?: string; as?: string; order?: number; size?: string; color?: string; variant?: string; fw?: number; c?: string; alt?: string; fit?: string; w?: string | number; h?: string | number; radius?: string | number; } export function SubData({ path, as = "Text", ...props }: SubDataProps) { const value = getByPath(useContext(SubFetchDataContext), path); if (value === undefined && path) return —; const displayValue = as === "Code" ? JSON.stringify(value, null, 2) : formatDisplayValue(value); if (as === "Title") { return {displayValue}; } if (as === "Badge") { return ( {displayValue} ); } if (as === "Code") return {displayValue}; if (as === "Image") { const src = safeDisplayImageUrl(value); if (!src) return null; return ( {props.alt ); } return ( {displayValue} ); } function safeDisplayImageUrl(value: unknown): string | undefined { if (typeof value !== "string") return undefined; if (value.startsWith("/") && !value.startsWith("//")) return value; try { const url = new URL(value); return url.protocol === "http:" || url.protocol === "https:" ? url.toString() : undefined; } catch { return undefined; } }