@uptrademedia/site-kit 1.0.5 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics/index.js +7 -7
- package/dist/analytics/index.mjs +3 -3
- package/dist/api-QUIPJJCX.js +77 -0
- package/dist/api-QUIPJJCX.js.map +1 -0
- package/dist/api-V3BA5PMX.mjs +4 -0
- package/dist/api-V3BA5PMX.mjs.map +1 -0
- package/dist/blog/index.d.mts +2 -2
- package/dist/blog/index.d.ts +2 -2
- package/dist/blog/index.js +40 -6
- package/dist/blog/index.js.map +1 -1
- package/dist/blog/index.mjs +40 -6
- package/dist/blog/index.mjs.map +1 -1
- package/dist/blog/server.d.mts +3 -2
- package/dist/blog/server.d.ts +3 -2
- package/dist/blog/server.js +13 -6
- package/dist/blog/server.js.map +1 -1
- package/dist/blog/server.mjs +13 -6
- package/dist/blog/server.mjs.map +1 -1
- package/dist/{chunk-FKVJOT2F.mjs → chunk-42EXHJTC.mjs} +196 -7
- package/dist/chunk-42EXHJTC.mjs.map +1 -0
- package/dist/{scanner-AZV5I6US.mjs → chunk-44OMJFCG.mjs} +354 -14
- package/dist/chunk-44OMJFCG.mjs.map +1 -0
- package/dist/chunk-4TGJYNHV.js +981 -0
- package/dist/chunk-4TGJYNHV.js.map +1 -0
- package/dist/chunk-4XPGGLVP.mjs +53 -0
- package/dist/{chunk-NYKRE2FL.mjs.map → chunk-4XPGGLVP.mjs.map} +1 -1
- package/dist/{generators-TO2FKJR6.mjs → chunk-6ONUXZDO.mjs} +26 -9
- package/dist/chunk-6ONUXZDO.mjs.map +1 -0
- package/dist/chunk-CG53ASWX.mjs +729 -0
- package/dist/chunk-CG53ASWX.mjs.map +1 -0
- package/dist/{scanner-ETJAMIT7.js → chunk-DERI27QC.js} +448 -102
- package/dist/chunk-DERI27QC.js.map +1 -0
- package/dist/chunk-DYM5ML2V.mjs +1518 -0
- package/dist/chunk-DYM5ML2V.mjs.map +1 -0
- package/dist/chunk-FLZZOX44.js +1526 -0
- package/dist/chunk-FLZZOX44.js.map +1 -0
- package/dist/{chunk-7H6I3ECV.mjs → chunk-FQVGK746.mjs} +63 -3
- package/dist/chunk-FQVGK746.mjs.map +1 -0
- package/dist/{chunk-GQ6ZOU2N.mjs → chunk-JGQPAXTL.mjs} +4 -4
- package/dist/{chunk-GQ6ZOU2N.mjs.map → chunk-JGQPAXTL.mjs.map} +1 -1
- package/dist/{chunk-V3F5J6CV.js → chunk-JUEVN4Q4.js} +196 -7
- package/dist/chunk-JUEVN4Q4.js.map +1 -0
- package/dist/chunk-KKMGTT7F.mjs +968 -0
- package/dist/chunk-KKMGTT7F.mjs.map +1 -0
- package/dist/{chunk-XQJX252G.mjs → chunk-MB3WR5KJ.mjs} +28 -18
- package/dist/chunk-MB3WR5KJ.mjs.map +1 -0
- package/dist/{chunk-2IHTEKHU.mjs → chunk-QD5CN2OI.mjs} +16 -7
- package/dist/chunk-QD5CN2OI.mjs.map +1 -0
- package/dist/{chunk-SBVEYCSV.js → chunk-QQB4FO4Q.js} +7 -7
- package/dist/{chunk-SBVEYCSV.js.map → chunk-QQB4FO4Q.js.map} +1 -1
- package/dist/{generators-YZWIGHCO.js → chunk-S2GXR5HY.js} +26 -9
- package/dist/chunk-S2GXR5HY.js.map +1 -0
- package/dist/{chunk-O2OHHBUD.js → chunk-TDK7DLCH.js} +30 -20
- package/dist/chunk-TDK7DLCH.js.map +1 -0
- package/dist/{chunk-QP5NCO2E.js → chunk-VDI7KYME.js} +67 -2
- package/dist/chunk-VDI7KYME.js.map +1 -0
- package/dist/chunk-VOR53RUR.js +753 -0
- package/dist/chunk-VOR53RUR.js.map +1 -0
- package/dist/{chunk-GAJLEDRD.js → chunk-ZKJ7JKFV.js} +16 -7
- package/dist/chunk-ZKJ7JKFV.js.map +1 -0
- package/dist/chunk-ZSMWDLMK.js +63 -0
- package/dist/{chunk-EQCVQC35.js.map → chunk-ZSMWDLMK.js.map} +1 -1
- package/dist/cli/index.js +37269 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +37233 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/commerce/index.js +1 -1
- package/dist/commerce/index.mjs +1 -1
- package/dist/commerce/server.d.mts +12 -3
- package/dist/commerce/server.d.ts +12 -3
- package/dist/commerce/server.js +71 -70
- package/dist/commerce/server.js.map +1 -1
- package/dist/commerce/server.mjs +71 -70
- package/dist/commerce/server.mjs.map +1 -1
- package/dist/engage/index.d.mts +6 -4
- package/dist/engage/index.d.ts +6 -4
- package/dist/engage/index.js +8 -4
- package/dist/engage/index.mjs +2 -2
- package/dist/forms/index.js +1 -1
- package/dist/forms/index.mjs +1 -1
- package/dist/generators-5EU4PTVF.js +33 -0
- package/dist/generators-5EU4PTVF.js.map +1 -0
- package/dist/generators-TYPILCWD.mjs +4 -0
- package/dist/generators-TYPILCWD.mjs.map +1 -0
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.d.mts +154 -5
- package/dist/index.d.ts +154 -5
- package/dist/index.js +940 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +819 -7
- package/dist/index.mjs.map +1 -1
- package/dist/llms/index.d.mts +657 -0
- package/dist/llms/index.d.ts +657 -0
- package/dist/llms/index.js +101 -0
- package/dist/llms/index.js.map +1 -0
- package/dist/llms/index.mjs +4 -0
- package/dist/llms/index.mjs.map +1 -0
- package/dist/migrator-ARLHUNB3.mjs +4 -0
- package/dist/migrator-ARLHUNB3.mjs.map +1 -0
- package/dist/migrator-VZLBH3VY.js +37 -0
- package/dist/migrator-VZLBH3VY.js.map +1 -0
- package/dist/redirects/index.js +1 -1
- package/dist/redirects/index.mjs +1 -1
- package/dist/reputation/index.js +1 -1
- package/dist/reputation/index.mjs +1 -1
- package/dist/{routing-BWjUF7lp.d.ts → routing-CF91y6NO.d.ts} +1 -1
- package/dist/{routing-CgmRi9tD.d.mts → routing-CIOFpFCB.d.mts} +1 -1
- package/dist/scanner-7ZMUM2P5.mjs +4 -0
- package/dist/scanner-7ZMUM2P5.mjs.map +1 -0
- package/dist/scanner-OY7UF3WA.js +53 -0
- package/dist/scanner-OY7UF3WA.js.map +1 -0
- package/dist/seo/index.d.mts +267 -7
- package/dist/seo/index.d.ts +267 -7
- package/dist/seo/index.js +433 -24
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +401 -11
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/server.d.mts +11 -4
- package/dist/seo/server.d.ts +11 -4
- package/dist/seo/server.js +17 -17
- package/dist/seo/server.mjs +3 -3
- package/dist/setup/client.js +1 -1
- package/dist/setup/client.mjs +1 -1
- package/dist/setup/index.js +3 -3
- package/dist/setup/index.mjs +2 -2
- package/dist/setup/server.js +3 -3
- package/dist/setup/server.mjs +2 -2
- package/dist/sitemap/index.js +2 -2
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +2 -2
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/{types-C0pJGfbH.d.mts → types-D6FHAVWX.d.mts} +99 -3
- package/dist/{types-C0pJGfbH.d.ts → types-D6FHAVWX.d.ts} +99 -3
- package/dist/{types-BN4OwtCO.d.mts → types-DI0jnhjJ.d.mts} +2 -0
- package/dist/{types-BN4OwtCO.d.ts → types-DI0jnhjJ.d.ts} +2 -0
- package/dist/{types-BmzutFwy.d.ts → types-j8X4vUhB.d.mts} +19 -2
- package/dist/{types-BmzutFwy.d.mts → types-j8X4vUhB.d.ts} +19 -2
- package/dist/{web-vitals-BH55V7EJ.js → web-vitals-444RLW3B.js} +11 -11
- package/dist/{web-vitals-BH55V7EJ.js.map → web-vitals-444RLW3B.js.map} +1 -1
- package/dist/{web-vitals-RJYPWAR3.mjs → web-vitals-KPICZIEF.mjs} +3 -3
- package/dist/{web-vitals-RJYPWAR3.mjs.map → web-vitals-KPICZIEF.mjs.map} +1 -1
- package/package.json +17 -10
- package/dist/api-N35S3EES.js +0 -57
- package/dist/api-N35S3EES.js.map +0 -1
- package/dist/api-SYBTK7Z7.mjs +0 -4
- package/dist/api-SYBTK7Z7.mjs.map +0 -1
- package/dist/chunk-2IHTEKHU.mjs.map +0 -1
- package/dist/chunk-7H6I3ECV.mjs.map +0 -1
- package/dist/chunk-BGJLOJ7T.mjs +0 -605
- package/dist/chunk-BGJLOJ7T.mjs.map +0 -1
- package/dist/chunk-EQCVQC35.js +0 -35
- package/dist/chunk-FKVJOT2F.mjs.map +0 -1
- package/dist/chunk-GAJLEDRD.js.map +0 -1
- package/dist/chunk-NYKRE2FL.mjs +0 -31
- package/dist/chunk-O2OHHBUD.js.map +0 -1
- package/dist/chunk-QAYJV4KK.js +0 -608
- package/dist/chunk-QAYJV4KK.js.map +0 -1
- package/dist/chunk-QP5NCO2E.js.map +0 -1
- package/dist/chunk-V3F5J6CV.js.map +0 -1
- package/dist/chunk-XQJX252G.mjs.map +0 -1
- package/dist/generators-TO2FKJR6.mjs.map +0 -1
- package/dist/generators-YZWIGHCO.js.map +0 -1
- package/dist/migrator-V6KS75EA.mjs +0 -265
- package/dist/migrator-V6KS75EA.mjs.map +0 -1
- package/dist/migrator-XKM7YQCY.js +0 -272
- package/dist/migrator-XKM7YQCY.js.map +0 -1
- package/dist/scanner-AZV5I6US.mjs.map +0 -1
- package/dist/scanner-ETJAMIT7.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engage/ChatWidget.tsx","../src/engage/DesignRenderer.tsx","../src/engage/EngageWidget.tsx"],"names":["useState","useRef","useCallback","io","useEffect","jsx","jsxs","Fragment","createElement","React","getApiConfig","usePathname"],"mappings":"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","file":"chunk-FLZZOX44.js","sourcesContent":["/**\n * @uptrade/site-kit/engage - Chat Widget (Enhanced)\n *\n * Single widget that encompasses:\n * - Echo (AI) chat when mode is ai or hybrid (session starts in AI; gateway returns Echo responses)\n * - Automated handoff to live agent when user requests or AI suggests (re-check availability; if agents online, POST handoff)\n * - Managed offline form when nobody is online (configurable prompt from project config)\n * - Socket.io for real-time live chat (replaces raw WebSocket)\n */\n\n'use client'\n\nimport React, { useState, useRef, useEffect, useCallback } from 'react'\nimport { io, type Socket } from 'socket.io-client'\nimport type { ChatConfig } from './types'\n\ninterface ChatWidgetProps {\n projectId: string\n config?: Partial<ChatConfig>\n apiUrl?: string\n}\n\ninterface MessageAttachment {\n name: string\n url: string\n size?: number\n mimeType?: string\n}\n\ninterface Message {\n id: string\n role: 'user' | 'assistant' | 'agent' | 'system'\n content: string\n timestamp: Date\n agentName?: string\n attachments?: MessageAttachment[]\n /** Echo quick-reply suggestions (render as chips) */\n suggestions?: string[]\n /** Shown when send failed (connection lost) */\n sendFailed?: boolean\n}\n\ninterface AvailabilityStatus {\n available: boolean\n mode: 'live' | 'ai' | 'offline'\n agentsOnline: number\n operatingHoursActive: boolean\n}\n\ninterface OfflineFormData {\n name: string\n email: string\n phone: string\n message: string\n}\n\n/** Widget config from API (engage_chat_config) for managed prompts */\ninterface WidgetConfigFromApi {\n initial_message?: string\n welcome_message?: string\n form_heading?: string\n form_description?: string\n offline_message?: string\n offlineFormSlug?: string\n chat_mode?: string\n offline_mode?: string\n}\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.uptrademedia.com'\n : 'https://api.uptrademedia.com'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__\n : undefined\n return { apiUrl, apiKey }\n}\n\nfunction generateVisitorId(): string {\n const stored = typeof localStorage !== 'undefined' \n ? localStorage.getItem('engage_visitor_id') \n : null\n if (stored) return stored\n \n const id = `visitor_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('engage_visitor_id', id)\n }\n return id\n}\n\nexport function ChatWidget({ projectId, config, apiUrl: propApiUrl }: ChatWidgetProps) {\n const [isOpen, setIsOpen] = useState(false)\n const [messages, setMessages] = useState<Message[]>([])\n const [inputValue, setInputValue] = useState('')\n const [isLoading, setIsLoading] = useState(false)\n const [availability, setAvailability] = useState<AvailabilityStatus | null>(null)\n const [sessionId, setSessionId] = useState<string | null>(null)\n const [visitorId] = useState(generateVisitorId)\n const [agentTyping, setAgentTyping] = useState(false)\n const [showOfflineForm, setShowOfflineForm] = useState(false)\n const [offlineForm, setOfflineForm] = useState<OfflineFormData>({ name: '', email: '', phone: '', message: '' })\n const [offlineSubmitted, setOfflineSubmitted] = useState(false)\n const [connectionStatus, setConnectionStatus] = useState<'connecting' | 'connected' | 'disconnected'>('disconnected')\n const [widgetConfig, setWidgetConfig] = useState<WidgetConfigFromApi | null>(null)\n /** When handoff requested but no agents online, show form with this prompt */\n const [handoffOfflinePrompt, setHandoffOfflinePrompt] = useState<string | null>(null)\n const [pendingFiles, setPendingFiles] = useState<File[]>([])\n const [lastFailedSend, setLastFailedSend] = useState<{ content: string; attachments: MessageAttachment[] } | null>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const messagesEndRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const socketRef = useRef<Socket | null>(null)\n const pollingIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n const position = config?.position || 'bottom-right'\n const buttonColor = config?.buttonColor || '#00afab'\n const welcomeMessage =\n widgetConfig?.initial_message ?? widgetConfig?.welcome_message ?? config?.welcomeMessage ?? \"Hi! How can I help you today?\"\n const offlineFormPrompt =\n handoffOfflinePrompt ??\n widgetConfig?.form_description ??\n widgetConfig?.offline_message ??\n config?.offlineMessage ??\n \"We're currently offline. Leave us a message and we'll get back to you!\"\n\n const baseUrl = propApiUrl || getApiConfig().apiUrl\n\n // Fetch widget config (managed prompts: welcome, offline form message)\n const fetchWidgetConfig = useCallback(async () => {\n try {\n const { apiKey } = getApiConfig()\n const response = await fetch(`${baseUrl}/api/engage/widget/config?projectId=${projectId}`, {\n headers: apiKey ? { 'x-api-key': apiKey } : {},\n })\n if (response.ok) {\n const { data } = await response.json()\n setWidgetConfig(data ?? null)\n }\n } catch (error) {\n console.error('[ChatWidget] Config fetch failed:', error)\n }\n }, [projectId, baseUrl])\n\n // Check agent availability on mount and periodically\n const checkAvailability = useCallback(async () => {\n try {\n const { apiKey } = getApiConfig()\n const response = await fetch(`${baseUrl}/api/engage/widget/availability?projectId=${projectId}`, {\n headers: apiKey ? { 'x-api-key': apiKey } : {},\n })\n if (response.ok) {\n const { data } = await response.json()\n setAvailability(data)\n if (data.mode === 'offline' && !sessionId) {\n setShowOfflineForm(true)\n }\n }\n } catch (error) {\n console.error('[ChatWidget] Availability check failed:', error)\n }\n }, [projectId, baseUrl, sessionId])\n\n // Create or restore session (backend sets status to 'ai' for ai/hybrid so Echo runs over socket)\n const initSession = useCallback(async () => {\n try {\n const { apiKey } = getApiConfig()\n const response = await fetch(`${baseUrl}/api/engage/widget/session`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey && { 'x-api-key': apiKey }),\n },\n body: JSON.stringify({\n projectId,\n visitorId,\n sourceUrl: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n }),\n })\n if (response.ok) {\n const { data } = await response.json()\n const sid = data.id || data.session_id\n setSessionId(sid)\n if (data.messages?.length > 0) {\n setMessages(data.messages.map((m: any) => ({\n id: m.id,\n role: m.role === 'visitor' ? 'user' : m.role,\n content: m.content,\n timestamp: new Date(m.created_at),\n agentName: m.sender_name,\n })))\n }\n return sid\n }\n } catch (error) {\n console.error('[ChatWidget] Session init failed:', error)\n }\n return null\n }, [projectId, visitorId, baseUrl])\n\n // Handle incoming socket messages (Echo = role 'ai', live = role 'agent')\n const handleSocketMessage = useCallback((data: any) => {\n switch (data.type || data.event) {\n case 'message': {\n const role =\n data.role === 'visitor' ? 'user' : data.role === 'ai' ? 'assistant' : (data.role as Message['role'])\n const newMessage: Message = {\n id: data.id || `msg-${Date.now()}`,\n role,\n content: data.content ?? '',\n timestamp: new Date(),\n agentName: data.agentName,\n }\n const withAttachments = data.attachments?.length ? { ...newMessage, attachments: data.attachments } : newMessage\n const withSuggestions = (data.suggestions?.length ? { ...withAttachments, suggestions: data.suggestions as string[] } : withAttachments) as Message & { suggestions?: string[] }\n setMessages(prev => [...prev, withSuggestions])\n if (role === 'assistant' || role === 'agent') {\n setAgentTyping(false)\n setIsLoading(false)\n }\n break\n }\n \n case 'agent:joined':\n setMessages(prev => [...prev, {\n id: `system-${Date.now()}`,\n role: 'system',\n content: data.agentName ? `${data.agentName} has joined the chat.` : 'An agent has joined the chat.',\n timestamp: new Date(),\n }])\n break\n \n case 'typing':\n setAgentTyping(data.isTyping)\n break\n \n case 'handoff:initiated':\n setMessages(prev => [...prev, {\n id: `system-${Date.now()}`,\n role: 'system',\n content: data.message || \"Connecting you with a team member...\",\n timestamp: new Date(),\n }])\n break\n \n case 'chat:closed':\n setMessages(prev => [...prev, {\n id: `system-${Date.now()}`,\n role: 'system',\n content: data.message || \"This chat has been closed.\",\n timestamp: new Date(),\n }])\n break\n }\n }, [])\n\n // Connect via Socket.io (Echo + live chat; gateway handles AI when session status is 'ai')\n const connectSocket = useCallback(\n (currentSessionId: string) => {\n if (socketRef.current?.connected) return\n\n const namespaceUrl = `${baseUrl.replace(/\\/$/, '')}/engage/chat`\n const socket = io(namespaceUrl, {\n query: { projectId, visitorId, sessionId: currentSessionId },\n transports: ['websocket', 'polling'],\n })\n\n socket.on('connect', () => {\n setConnectionStatus('connected')\n console.log('[ChatWidget] Socket.io connected')\n // Refetch messages after reconnect so nothing is missed during disconnect\n if (currentSessionId) {\n const { apiKey } = getApiConfig()\n fetch(`${baseUrl}/api/engage/widget/messages?sessionId=${currentSessionId}`, {\n headers: apiKey ? { 'x-api-key': apiKey } : {},\n })\n .then((res) => res.ok ? res.json() : null)\n .then((json) => {\n const data = json?.data ?? json\n if (Array.isArray(data) && data.length) {\n setMessages(prev => {\n const byId = new Map(prev.map(m => [m.id, m]))\n data.forEach((m: any) => byId.set(m.id, { id: m.id, role: m.role === 'visitor' ? 'user' : m.role, content: m.content, timestamp: new Date(m.created_at), agentName: m.sender_name, attachments: m.attachments }))\n return Array.from(byId.values()).sort((a, b) => (a.timestamp as Date).getTime() - (b.timestamp as Date).getTime())\n })\n }\n })\n .catch((err) => console.warn('[ChatWidget] Refetch messages on reconnect failed', err))\n }\n })\n\n socket.on('message', (data: { role?: string; content?: string; agentName?: string; suggestions?: string[]; attachments?: MessageAttachment[] }) => {\n handleSocketMessage({ type: 'message', ...data })\n })\n\n socket.on('agent:joined', (data: { agentName?: string }) => {\n handleSocketMessage({ type: 'agent:joined', ...data })\n })\n\n socket.on('typing', (data: { isTyping?: boolean }) => {\n handleSocketMessage({ type: 'typing', ...data })\n })\n\n socket.on('handoff:initiated', (data: { message?: string }) => {\n handleSocketMessage({ type: 'handoff:initiated', ...data })\n })\n\n socket.on('chat:closed', (data: { message?: string }) => {\n handleSocketMessage({ type: 'chat:closed', ...data })\n })\n\n socket.on('disconnect', (reason) => {\n setConnectionStatus('disconnected')\n console.log('[ChatWidget] Socket disconnected:', reason)\n })\n\n socket.on('connect_error', (err) => {\n console.error('[ChatWidget] Socket connect error:', err)\n setConnectionStatus('disconnected')\n if (isOpen && currentSessionId) startPolling(currentSessionId)\n })\n\n socketRef.current = socket\n },\n [projectId, visitorId, baseUrl, isOpen, handleSocketMessage, getApiConfig],\n )\n\n // Polling fallback when Socket.io fails to connect\n const startPolling = useCallback((currentSessionId: string) => {\n if (pollingIntervalRef.current) return\n pollingIntervalRef.current = setInterval(async () => {\n try {\n const { apiKey } = getApiConfig()\n const response = await fetch(\n `${baseUrl}/api/engage/widget/messages?sessionId=${currentSessionId}`,\n { headers: apiKey ? { 'x-api-key': apiKey } : {} }\n )\n if (response.ok) {\n const { data } = await response.json()\n // Update messages if there are new ones\n setMessages(prev => {\n const existingIds = new Set(prev.map(m => m.id))\n const newMessages = data.filter((m: any) => !existingIds.has(m.id))\n if (newMessages.length > 0) {\n return [...prev, ...newMessages.map((m: any) => ({\n id: m.id,\n role: m.role === 'visitor' ? 'user' : m.role,\n content: m.content,\n timestamp: new Date(m.created_at),\n agentName: m.sender_name,\n }))]\n }\n return prev\n })\n }\n } catch (error) {\n console.error('[ChatWidget] Polling failed:', error)\n }\n }, 3000)\n }, [baseUrl])\n\n // Scroll to bottom when messages change\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })\n }, [messages, agentTyping])\n\n // Focus input when chat opens\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus()\n }\n }, [isOpen])\n\n // Check availability on mount; disconnect socket on unmount\n useEffect(() => {\n checkAvailability()\n const interval = setInterval(checkAvailability, 60000)\n return () => {\n clearInterval(interval)\n if (socketRef.current) {\n socketRef.current.disconnect()\n socketRef.current = null\n }\n }\n }, [checkAvailability])\n\n // Fetch widget config when opening (for managed welcome/offline prompts)\n useEffect(() => {\n if (isOpen) fetchWidgetConfig()\n }, [isOpen, fetchWidgetConfig])\n\n // Initialize session and connect Socket.io when chat opens (Echo + live both use socket)\n useEffect(() => {\n if (isOpen && !sessionId && availability?.mode !== 'offline') {\n initSession().then(id => {\n if (id && (availability?.mode === 'live' || availability?.mode === 'ai')) {\n setConnectionStatus('connecting')\n connectSocket(id)\n }\n })\n }\n return () => {\n if (pollingIntervalRef.current) clearInterval(pollingIntervalRef.current)\n }\n }, [isOpen, sessionId, availability?.mode, initSession, connectSocket])\n\n // Handle chat toggle\n const handleToggle = useCallback(() => {\n setIsOpen(prev => !prev)\n if (!isOpen && messages.length === 0 && availability?.mode !== 'offline') {\n // Show welcome message on first open\n setMessages([{\n id: 'welcome',\n role: 'assistant',\n content: welcomeMessage,\n timestamp: new Date()\n }])\n }\n }, [isOpen, messages.length, welcomeMessage, availability?.mode])\n\n // Upload a file for chat (widget endpoint: sessionId + visitorId)\n const uploadWidgetFile = useCallback(\n async (file: File): Promise<MessageAttachment | null> => {\n if (!sessionId || !visitorId) return null\n const { apiKey } = getApiConfig()\n const form = new FormData()\n form.append('file', file)\n form.append('sessionId', sessionId)\n form.append('visitorId', visitorId)\n const res = await fetch(`${baseUrl}/api/engage/widget/upload`, {\n method: 'POST',\n headers: apiKey ? { 'x-api-key': apiKey } : {},\n body: form,\n })\n if (!res.ok) throw new Error('Upload failed')\n const json = await res.json()\n const d = json?.data ?? json\n return d?.url ? { name: d.name ?? file.name, url: d.url, size: d.size, mimeType: d.mimeType } : null\n },\n [sessionId, visitorId, baseUrl],\n )\n\n // Send message via Socket.io (gateway returns Echo when session status is 'ai', else live)\n const handleSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault()\n const hasText = !!inputValue.trim()\n const hasFiles = pendingFiles.length > 0\n if ((!hasText && !hasFiles) || isLoading) return\n\n const content = inputValue.trim() || ''\n let attachments: MessageAttachment[] = []\n if (pendingFiles.length) {\n try {\n for (const file of pendingFiles) {\n const att = await uploadWidgetFile(file)\n if (att) attachments.push(att)\n }\n setPendingFiles([])\n } catch (err) {\n console.error('[ChatWidget] File upload failed', err)\n setMessages(prev => [...prev, { id: `err-${Date.now()}`, role: 'assistant', content: 'Failed to upload file. Please try again.', timestamp: new Date() }])\n return\n }\n }\n\n const userMessage: Message = {\n id: `user-${Date.now()}`,\n role: 'user',\n content,\n timestamp: new Date(),\n ...(attachments.length ? { attachments } : {}),\n }\n setMessages(prev => [...prev, userMessage])\n setInputValue('')\n setIsLoading(true)\n\n const socket = socketRef.current\n if (socket?.connected) {\n socket.emit('visitor:message', { content: userMessage.content, attachments: attachments.length ? attachments : undefined })\n setLastFailedSend(null)\n return\n }\n\n setLastFailedSend({ content: userMessage.content, attachments })\n setMessages(prev => [\n ...prev,\n { id: `error-${Date.now()}`, role: 'assistant', content: \"Connection lost.\", timestamp: new Date(), sendFailed: true },\n ])\n setIsLoading(false)\n },\n [inputValue, isLoading, pendingFiles, uploadWidgetFile, sessionId],\n )\n\n const retryFailedSend = useCallback(() => {\n if (!lastFailedSend || !sessionId) return\n const socket = socketRef.current\n if (socket?.connected) {\n socket.emit('visitor:message', { content: lastFailedSend.content, attachments: lastFailedSend.attachments?.length ? lastFailedSend.attachments : undefined })\n setLastFailedSend(null)\n setMessages(prev => prev.filter(m => !(m as Message & { sendFailed?: boolean }).sendFailed))\n setIsLoading(true)\n } else {\n connectSocket(sessionId)\n setLastFailedSend(lastFailedSend)\n }\n }, [lastFailedSend, sessionId, connectSocket])\n\n // Request handoff: re-check availability; if nobody online show managed offline form\n const requestHandoff = useCallback(async () => {\n if (!sessionId) return\n\n try {\n const { apiKey } = getApiConfig()\n const availRes = await fetch(`${baseUrl}/api/engage/widget/availability?projectId=${projectId}`, {\n headers: apiKey ? { 'x-api-key': apiKey } : {},\n })\n const avail = availRes.ok ? (await availRes.json()).data : null\n\n if (avail?.agentsOnline === 0) {\n setHandoffOfflinePrompt(\n widgetConfig?.form_description ??\n widgetConfig?.offline_message ??\n \"Nobody is online right now. Leave your details and we'll get back to you.\",\n )\n setShowOfflineForm(true)\n setMessages(prev => [\n ...prev,\n {\n id: `handoff-offline-${Date.now()}`,\n role: 'system',\n content: \"We're not available at the moment. Please leave your info below and we'll follow up soon.\",\n timestamp: new Date(),\n },\n ])\n return\n }\n\n await fetch(`${baseUrl}/api/engage/widget/handoff`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey && { 'x-api-key': apiKey }),\n },\n body: JSON.stringify({ sessionId }),\n })\n setMessages(prev => [\n ...prev,\n {\n id: `handoff-${Date.now()}`,\n role: 'system',\n content: \"Connecting you with a team member. Please hold on!\",\n timestamp: new Date(),\n },\n ])\n } catch (error) {\n console.error('[ChatWidget] Handoff request failed:', error)\n }\n }, [sessionId, baseUrl, projectId, widgetConfig])\n\n // Handle offline form submission\n const handleOfflineSubmit = useCallback(async (e: React.FormEvent) => {\n e.preventDefault()\n if (!offlineForm.name || !offlineForm.email || !offlineForm.message) return\n \n setIsLoading(true)\n \n try {\n const { apiKey } = getApiConfig()\n const response = await fetch(`${baseUrl}/api/engage/widget/offline-form`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey && { 'x-api-key': apiKey }),\n },\n body: JSON.stringify({\n projectId,\n visitorId,\n ...offlineForm,\n pageUrl: typeof window !== 'undefined' ? window.location.href : '',\n ...(widgetConfig?.offlineFormSlug && { formSlug: widgetConfig.offlineFormSlug }),\n }),\n })\n \n if (response.ok) {\n setOfflineSubmitted(true)\n }\n } catch (error) {\n console.error('[ChatWidget] Offline form submission failed:', error)\n } finally {\n setIsLoading(false)\n }\n }, [offlineForm, projectId, visitorId, baseUrl])\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n handleSubmit(e as any)\n }\n }, [handleSubmit])\n\n // Send typing indicator via Socket.io\n const handleTyping = useCallback(() => {\n const socket = socketRef.current\n if (socket?.connected) {\n socket.emit('visitor:typing', { isTyping: true })\n setTimeout(() => {\n if (socketRef.current?.connected) {\n socketRef.current.emit('visitor:typing', { isTyping: false })\n }\n }, 2000)\n }\n }, [])\n\n // Chat bubble button\n const ChatButton = (\n <button\n onClick={handleToggle}\n aria-label={isOpen ? 'Close chat' : 'Open chat'}\n style={{\n position: 'fixed',\n [position === 'bottom-left' ? 'left' : 'right']: 20,\n bottom: 20,\n width: 60,\n height: 60,\n borderRadius: '50%',\n backgroundColor: buttonColor,\n border: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.25)',\n transition: 'transform 0.2s, box-shadow 0.2s',\n zIndex: 9999,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.transform = 'scale(1.05)'\n e.currentTarget.style.boxShadow = '0 6px 16px rgba(0, 0, 0, 0.3)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.transform = 'scale(1)'\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.25)'\n }}\n >\n {isOpen ? (\n // Close icon (X)\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n ) : (\n // Chat icon\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n )}\n </button>\n )\n\n // Chat popup window\n const ChatPopup = isOpen && (\n <div\n style={{\n position: 'fixed',\n [position === 'bottom-left' ? 'left' : 'right']: 20,\n bottom: 90,\n width: 380,\n maxWidth: 'calc(100vw - 40px)',\n height: 500,\n maxHeight: 'calc(100vh - 120px)',\n backgroundColor: '#ffffff',\n borderRadius: 16,\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.2)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n zIndex: 9998,\n animation: 'chatSlideUp 0.3s ease-out',\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: '16px 20px',\n background: `linear-gradient(135deg, ${buttonColor}, ${adjustColor(buttonColor, -20)})`,\n color: 'white',\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n }}\n >\n <div\n style={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n backgroundColor: 'rgba(255,255,255,0.2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n </div>\n <div style={{ flex: 1 }}>\n <div style={{ fontWeight: 600, fontSize: 16 }}>\n {showOfflineForm ? 'Leave a Message' : 'Chat with us'}\n </div>\n <div style={{ fontSize: 13, opacity: 0.9, display: 'flex', alignItems: 'center', gap: 6 }}>\n {availability?.mode === 'live' && availability.agentsOnline > 0 ? (\n <>\n <span style={{ width: 8, height: 8, borderRadius: '50%', backgroundColor: '#22c55e' }} />\n {availability.agentsOnline} online\n </>\n ) : availability?.mode === 'ai' ? (\n 'AI-powered support'\n ) : (\n \"We'll respond soon\"\n )}\n </div>\n </div>\n \n {/* Switch between form and chat */}\n {availability?.mode === 'offline' && !offlineSubmitted && (\n <button\n onClick={() => setShowOfflineForm(prev => !prev)}\n style={{\n background: 'rgba(255,255,255,0.2)',\n border: 'none',\n borderRadius: 6,\n padding: '4px 8px',\n color: 'white',\n fontSize: 12,\n cursor: 'pointer',\n }}\n >\n {showOfflineForm ? 'Try Chat' : 'Leave Message'}\n </button>\n )}\n </div>\n\n {/* Offline Form Content */}\n {showOfflineForm ? (\n <div style={{ padding: 20, flex: 1, overflowY: 'auto' }}>\n {offlineSubmitted ? (\n <div style={{ textAlign: 'center', padding: 20 }}>\n <div style={{ fontSize: 48, marginBottom: 16 }}>✓</div>\n <h3 style={{ margin: '0 0 8px', fontSize: 18, fontWeight: 600 }}>Message Sent!</h3>\n <p style={{ margin: 0, color: '#666', fontSize: 14 }}>\n We'll get back to you as soon as possible.\n </p>\n </div>\n ) : (\n <form onSubmit={handleOfflineSubmit}>\n <p style={{ margin: '0 0 16px', color: '#666', fontSize: 14 }}>\n {offlineFormPrompt}\n </p>\n \n <div style={{ marginBottom: 12 }}>\n <input\n type=\"text\"\n placeholder=\"Your name *\"\n value={offlineForm.name}\n onChange={(e) => setOfflineForm(prev => ({ ...prev, name: e.target.value }))}\n required\n style={{\n width: '100%',\n padding: '10px 12px',\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n fontSize: 14,\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n \n <div style={{ marginBottom: 12 }}>\n <input\n type=\"email\"\n placeholder=\"Your email *\"\n value={offlineForm.email}\n onChange={(e) => setOfflineForm(prev => ({ ...prev, email: e.target.value }))}\n required\n style={{\n width: '100%',\n padding: '10px 12px',\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n fontSize: 14,\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n \n <div style={{ marginBottom: 12 }}>\n <input\n type=\"tel\"\n placeholder=\"Phone (optional)\"\n value={offlineForm.phone}\n onChange={(e) => setOfflineForm(prev => ({ ...prev, phone: e.target.value }))}\n style={{\n width: '100%',\n padding: '10px 12px',\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n fontSize: 14,\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n \n <div style={{ marginBottom: 16 }}>\n <textarea\n placeholder=\"How can we help? *\"\n value={offlineForm.message}\n onChange={(e) => setOfflineForm(prev => ({ ...prev, message: e.target.value }))}\n required\n rows={4}\n style={{\n width: '100%',\n padding: '10px 12px',\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n fontSize: 14,\n outline: 'none',\n resize: 'vertical',\n boxSizing: 'border-box',\n }}\n />\n </div>\n \n <button\n type=\"submit\"\n disabled={isLoading}\n style={{\n width: '100%',\n padding: '12px',\n borderRadius: 8,\n border: 'none',\n backgroundColor: buttonColor,\n color: 'white',\n fontSize: 14,\n fontWeight: 600,\n cursor: isLoading ? 'wait' : 'pointer',\n opacity: isLoading ? 0.7 : 1,\n }}\n >\n {isLoading ? 'Sending...' : 'Send Message'}\n </button>\n </form>\n )}\n </div>\n ) : (\n <>\n {/* Messages */}\n <div\n style={{\n flex: 1,\n overflowY: 'auto',\n padding: 16,\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n backgroundColor: '#f8f9fa',\n }}\n >\n {messages.map((message) => (\n <div\n key={message.id}\n style={{\n display: 'flex',\n justifyContent: message.role === 'user' ? 'flex-end' : 'flex-start',\n }}\n >\n <div\n style={{\n maxWidth: '80%',\n padding: message.role === 'system' ? '8px 12px' : '10px 14px',\n borderRadius: message.role === 'user' \n ? '16px 16px 4px 16px' \n : message.role === 'system'\n ? '8px'\n : '16px 16px 16px 4px',\n backgroundColor: message.role === 'user' \n ? buttonColor \n : message.role === 'system'\n ? '#e5e7eb'\n : '#ffffff',\n color: message.role === 'user' \n ? 'white' \n : message.role === 'system'\n ? '#666'\n : '#1a1a1a',\n boxShadow: message.role === 'system' ? 'none' : '0 1px 2px rgba(0,0,0,0.1)',\n fontSize: message.role === 'system' ? 13 : 14,\n fontStyle: message.role === 'system' ? 'italic' : 'normal',\n lineHeight: 1.5,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n }}\n >\n {message.agentName && message.role === 'agent' && (\n <div style={{ fontSize: 12, opacity: 0.7, marginBottom: 4 }}>\n {message.agentName}\n </div>\n )}\n {message.content}\n {message.attachments?.length ? (\n <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 6 }}>\n {message.attachments.map((att, i) => (\n att.mimeType?.startsWith('image/') ? (\n <a key={i} href={att.url} target=\"_blank\" rel=\"noopener noreferrer\" style={{ display: 'block' }}>\n <img src={att.url} alt={att.name} style={{ maxWidth: '100%', maxHeight: 200, borderRadius: 8, objectFit: 'contain' }} />\n </a>\n ) : (\n <a key={i} href={att.url} target=\"_blank\" rel=\"noopener noreferrer\" style={{ fontSize: 13, wordBreak: 'break-all' }}>\n 📎 {att.name}\n </a>\n )\n ))}\n </div>\n ) : null}\n {/* Echo suggestion chips */}\n {message.suggestions?.length ? (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 8 }}>\n {message.suggestions.map((s, i) => (\n <button\n key={i}\n type=\"button\"\n onClick={() => { setInputValue(s); inputRef.current?.focus() }}\n style={{\n padding: '6px 12px',\n borderRadius: 16,\n border: `1px solid ${buttonColor}`,\n backgroundColor: 'rgba(255,255,255,0.9)',\n color: buttonColor,\n fontSize: 13,\n cursor: 'pointer',\n }}\n >\n {s}\n </button>\n ))}\n </div>\n ) : null}\n {/* Failed send: show Retry */}\n {message.sendFailed && lastFailedSend && (\n <div style={{ marginTop: 8 }}>\n <button\n type=\"button\"\n onClick={retryFailedSend}\n style={{\n padding: '6px 12px',\n borderRadius: 6,\n border: '1px solid #ef4444',\n backgroundColor: '#fef2f2',\n color: '#dc2626',\n fontSize: 13,\n cursor: 'pointer',\n }}\n >\n Retry send\n </button>\n </div>\n )}\n {/* Handoff button for system prompts */}\n {message.content.includes('speak with') && (\n <button\n onClick={requestHandoff}\n style={{\n display: 'block',\n marginTop: 8,\n padding: '6px 12px',\n borderRadius: 6,\n border: `1px solid ${buttonColor}`,\n backgroundColor: 'transparent',\n color: buttonColor,\n fontSize: 13,\n cursor: 'pointer',\n }}\n >\n Talk to a person\n </button>\n )}\n </div>\n </div>\n ))}\n \n {/* Typing indicator */}\n {(isLoading || agentTyping) && (\n <div style={{ display: 'flex', justifyContent: 'flex-start' }}>\n <div\n style={{\n padding: '10px 14px',\n borderRadius: '16px 16px 16px 4px',\n backgroundColor: '#ffffff',\n boxShadow: '0 1px 2px rgba(0,0,0,0.1)',\n display: 'flex',\n gap: 4,\n }}\n >\n <span style={{ animation: 'chatDot 1.4s infinite ease-in-out', animationDelay: '0s' }}>●</span>\n <span style={{ animation: 'chatDot 1.4s infinite ease-in-out', animationDelay: '0.2s' }}>●</span>\n <span style={{ animation: 'chatDot 1.4s infinite ease-in-out', animationDelay: '0.4s' }}>●</span>\n </div>\n </div>\n )}\n \n <div ref={messagesEndRef} />\n </div>\n\n {/* Failed send bar */}\n {lastFailedSend && (\n <div style={{ padding: '8px 12px', backgroundColor: '#fef2f2', borderTop: '1px solid #fecaca', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>\n <span style={{ fontSize: 13, color: '#dc2626' }}>Failed to send</span>\n <button type=\"button\" onClick={retryFailedSend} style={{ padding: '4px 10px', borderRadius: 6, border: '1px solid #dc2626', background: '#fff', color: '#dc2626', fontSize: 12, cursor: 'pointer' }}>Retry</button>\n </div>\n )}\n {/* Input */}\n <form onSubmit={handleSubmit} style={{ padding: 12, borderTop: '1px solid #e5e7eb', backgroundColor: '#ffffff' }}>\n <div style={{ display: 'flex', gap: 8 }}>\n <input\n ref={inputRef}\n type=\"text\"\n value={inputValue}\n onChange={(e) => {\n setInputValue(e.target.value)\n handleTyping()\n }}\n onKeyDown={handleKeyDown}\n placeholder=\"Type a message...\"\n disabled={isLoading}\n style={{\n flex: 1,\n padding: '10px 14px',\n borderRadius: 24,\n border: '1px solid #e5e7eb',\n fontSize: 14,\n outline: 'none',\n transition: 'border-color 0.2s',\n }}\n onFocus={(e) => e.currentTarget.style.borderColor = buttonColor}\n onBlur={(e) => e.currentTarget.style.borderColor = '#e5e7eb'}\n />\n <button\n type=\"submit\"\n disabled={!inputValue.trim() || isLoading}\n style={{\n width: 40,\n height: 40,\n borderRadius: '50%',\n border: 'none',\n backgroundColor: (inputValue.trim() || pendingFiles.length) && !isLoading ? buttonColor : '#e5e7eb',\n color: 'white',\n cursor: inputValue.trim() && !isLoading ? 'pointer' : 'not-allowed',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'background-color 0.2s',\n }}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n </button>\n </div>\n </form>\n </>\n )}\n\n {/* CSS animations */}\n <style>{`\n @keyframes chatSlideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n @keyframes chatDot {\n 0%, 80%, 100% {\n opacity: 0.3;\n }\n 40% {\n opacity: 1;\n }\n }\n `}</style>\n </div>\n )\n\n return (\n <>\n {ChatPopup}\n {ChatButton}\n </>\n )\n}\n\n// Helper to darken/lighten a hex color\nfunction adjustColor(hex: string, amount: number): string {\n const num = parseInt(hex.replace('#', ''), 16)\n const r = Math.min(255, Math.max(0, (num >> 16) + amount))\n const g = Math.min(255, Math.max(0, ((num >> 8) & 0x00ff) + amount))\n const b = Math.min(255, Math.max(0, (num & 0x0000ff) + amount))\n return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`\n}\n","/**\n * @uptrade/site-kit/engage - Design Renderer\n * \n * Renders design_json from Engage Studio as React components.\n * This is the runtime renderer that converts the visual builder's\n * JSON structure into actual React elements.\n */\n\n'use client'\n\nimport React, { createElement, CSSProperties, MouseEvent, useState } from 'react'\n\n// ============================================\n// Types\n// ============================================\n\nexport interface DesignNode {\n id: string\n type: string\n name: string\n children?: DesignNode[]\n props?: Record<string, any>\n style?: CSSProperties\n}\n\nexport interface DesignDocument {\n id: string\n type: string\n name: string\n children: DesignNode[]\n style?: CSSProperties\n props?: Record<string, any>\n}\n\nexport interface DesignRendererProps {\n design: DesignDocument\n onClose?: () => void\n onAction?: (action: ActionConfig, node: DesignNode) => void\n context?: EngageContext\n}\n\nexport interface ActionConfig {\n action: string\n url?: string\n newTab?: boolean\n target?: string\n text?: string\n productId?: string\n formId?: string\n}\n\nexport interface EngageContext {\n // Site-Kit context data that can be bound to elements\n user?: {\n name?: string\n email?: string\n isLoggedIn?: boolean\n }\n cart?: {\n itemCount?: number\n total?: number\n }\n page?: {\n url?: string\n title?: string\n }\n // Custom data from the page\n [key: string]: any\n}\n\n// ============================================\n// Action Handlers\n// ============================================\n\nfunction handleAction(\n action: ActionConfig,\n node: DesignNode,\n onClose?: () => void,\n onAction?: (action: ActionConfig, node: DesignNode) => void,\n): void {\n if (!action?.action || action.action === 'none') return\n\n // Let parent handle custom actions\n if (onAction) {\n onAction(action, node)\n }\n\n switch (action.action) {\n case 'link':\n if (action.url) {\n if (action.newTab) {\n window.open(action.url, '_blank', 'noopener,noreferrer')\n } else {\n window.location.href = action.url\n }\n }\n break\n\n case 'scroll':\n if (action.target) {\n const element = document.querySelector(action.target)\n element?.scrollIntoView({ behavior: 'smooth' })\n }\n break\n\n case 'close':\n onClose?.()\n break\n\n case 'copy':\n if (action.text) {\n navigator.clipboard.writeText(action.text).catch(console.error)\n }\n break\n\n case 'share':\n if (navigator.share) {\n navigator.share({\n title: document.title,\n url: window.location.href,\n }).catch(console.error)\n }\n break\n\n case 'download':\n if (action.url) {\n const a = document.createElement('a')\n a.href = action.url\n a.download = ''\n a.click()\n }\n break\n\n // Commerce actions - these should be handled by onAction callback\n case 'add_to_cart':\n case 'checkout':\n case 'book':\n case 'submit_form':\n case 'open_form':\n // Handled by parent via onAction\n break\n }\n}\n\n// ============================================\n// Animation Styles\n// ============================================\n\nconst animationKeyframes = `\n@keyframes engageFadeIn { from { opacity: 0; } to { opacity: 1; } }\n@keyframes engageFadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes engageFadeInDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } }\n@keyframes engageSlideInLeft { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } }\n@keyframes engageSlideInRight { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } }\n@keyframes engageSlideInUp { from { opacity: 0; transform: translateY(100%); } to { opacity: 1; transform: translateY(0); } }\n@keyframes engageScaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }\n@keyframes engageBounceIn { 0% { opacity: 0; transform: scale(0.3); } 50% { transform: scale(1.05); } 70% { transform: scale(0.9); } 100% { opacity: 1; transform: scale(1); } }\n`\n\nfunction getAnimationStyle(animation?: string, delay?: number, duration?: number): CSSProperties {\n if (!animation || animation === 'none') return {}\n \n const animationMap: Record<string, string> = {\n fadeIn: 'engageFadeIn',\n fadeInUp: 'engageFadeInUp',\n fadeInDown: 'engageFadeInDown',\n slideInLeft: 'engageSlideInLeft',\n slideInRight: 'engageSlideInRight',\n slideInUp: 'engageSlideInUp',\n scaleIn: 'engageScaleIn',\n bounceIn: 'engageBounceIn',\n }\n \n const animationName = animationMap[animation]\n if (!animationName) return {}\n \n return {\n animation: `${animationName} ${duration || 300}ms ease-out ${delay || 0}ms forwards`,\n opacity: 0, // Start invisible, animation will show it\n }\n}\n\n// ============================================\n// Node Renderer\n// ============================================\n\ninterface NodeRendererProps {\n node: DesignNode\n onClose?: () => void\n onAction?: (action: ActionConfig, node: DesignNode) => void\n context?: EngageContext\n}\n\nfunction NodeRenderer({ node, onClose, onAction, context }: NodeRendererProps): React.ReactElement | null {\n const [isHovered, setIsHovered] = useState(false)\n const { type, props = {}, style = {}, children } = node\n\n // Build styles with hover effects\n const computedStyle: CSSProperties = { ...style }\n \n // Apply animation\n if (props.animation) {\n Object.assign(computedStyle, getAnimationStyle(\n props.animation,\n props.animationDelay,\n props.animationDuration\n ))\n }\n \n // Apply hover effects\n if (isHovered) {\n if (props.hoverScale && props.hoverScale !== 'none') {\n computedStyle.transform = `scale(${props.hoverScale})`\n computedStyle.transition = 'transform 0.2s ease'\n }\n if (props.hoverShadow && props.hoverShadow !== 'none') {\n const shadowMap: Record<string, string> = {\n sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',\n md: '0 4px 6px -1px rgb(0 0 0 / 0.1)',\n lg: '0 10px 15px -3px rgb(0 0 0 / 0.1)',\n }\n computedStyle.boxShadow = shadowMap[props.hoverShadow]\n }\n }\n\n // Event handlers\n const eventHandlers: Record<string, (e: MouseEvent) => void> = {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n }\n \n // Click handler\n if (props.onClick) {\n eventHandlers.onClick = (e: MouseEvent) => {\n e.preventDefault()\n handleAction(props.onClick, node, onClose, onAction)\n }\n computedStyle.cursor = 'pointer'\n }\n\n // Render children recursively\n const renderedChildren = children?.map((child) => (\n <NodeRenderer\n key={child.id}\n node={child}\n onClose={onClose}\n onAction={onAction}\n context={context}\n />\n ))\n\n // Render based on type\n switch (type) {\n case 'Container':\n case 'Box':\n case 'Section':\n return (\n <div style={computedStyle} {...eventHandlers}>\n {renderedChildren}\n </div>\n )\n\n case 'Text':\n return (\n <p style={computedStyle} {...eventHandlers}>\n {resolveText(props.text, context)}\n </p>\n )\n\n case 'Heading':\n const HeadingTag = `h${props.level || 2}` as keyof JSX.IntrinsicElements\n return createElement(\n HeadingTag,\n { style: computedStyle, ...eventHandlers },\n resolveText(props.text, context)\n )\n\n case 'Button':\n case 'BookingButton':\n case 'BuyNow':\n case 'AddToCart':\n case 'EventRSVP':\n return (\n <button\n style={computedStyle}\n {...eventHandlers}\n type=\"button\"\n >\n {resolveText(props.text || props.label, context) || 'Button'}\n </button>\n )\n\n case 'Image':\n return (\n <img\n src={props.src}\n alt={props.alt || ''}\n style={computedStyle}\n {...eventHandlers}\n />\n )\n\n case 'Link':\n return (\n <a\n href={props.href || '#'}\n target={props.newTab ? '_blank' : undefined}\n rel={props.newTab ? 'noopener noreferrer' : undefined}\n style={computedStyle}\n {...eventHandlers}\n >\n {resolveText(props.text, context) || renderedChildren}\n </a>\n )\n\n case 'Input':\n return (\n <input\n type={props.inputType || 'text'}\n placeholder={props.placeholder}\n style={computedStyle}\n {...eventHandlers}\n />\n )\n\n case 'Divider':\n return <hr style={{ border: 'none', borderTop: '1px solid #e5e7eb', ...computedStyle }} />\n\n case 'Spacer':\n return <div style={{ ...computedStyle, width: props.width, height: props.height }} />\n\n case 'Icon':\n // Simple emoji/text icon rendering\n return (\n <span style={computedStyle} {...eventHandlers}>\n {props.icon || '★'}\n </span>\n )\n\n case 'FormEmbed':\n // For form embeds, we need to render the form from Forms module\n // This would integrate with the ManagedForm component\n return (\n <div \n style={computedStyle} \n data-engage-form={props.form_id}\n {...eventHandlers}\n >\n {/* ManagedForm would be rendered here by the parent */}\n <div style={{ padding: '16px', background: '#f5f5f5', borderRadius: '8px', textAlign: 'center' }}>\n Form: {props.form_id || 'Not configured'}\n </div>\n </div>\n )\n\n case 'ProductCard':\n case 'EventCard':\n // Product/event cards need data binding from Commerce\n return (\n <div \n style={computedStyle} \n data-engage-offering={props.offering_id}\n {...eventHandlers}\n >\n {renderedChildren}\n </div>\n )\n\n default:\n // Unknown type - render as div with children\n console.warn(`[DesignRenderer] Unknown node type: ${type}`)\n return (\n <div style={computedStyle} {...eventHandlers}>\n {renderedChildren}\n </div>\n )\n }\n}\n\n// ============================================\n// Text Resolution (Data Bindings)\n// ============================================\n\nfunction resolveText(text: string | undefined, context?: EngageContext): string {\n if (!text) return ''\n if (!context) return text\n \n // Replace {{variable}} patterns with context values\n return text.replace(/\\{\\{(\\w+(?:\\.\\w+)*)\\}\\}/g, (match, path) => {\n const value = getNestedValue(context, path)\n return value !== undefined ? String(value) : match\n })\n}\n\nfunction getNestedValue(obj: Record<string, any>, path: string): any {\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\n}\n\n// ============================================\n// Main Component\n// ============================================\n\nexport function DesignRenderer({\n design,\n onClose,\n onAction,\n context,\n}: DesignRendererProps): React.ReactElement {\n // Inject animation keyframes\n React.useEffect(() => {\n if (typeof document === 'undefined') return\n \n const styleId = 'engage-design-renderer-animations'\n if (!document.getElementById(styleId)) {\n const styleSheet = document.createElement('style')\n styleSheet.id = styleId\n styleSheet.textContent = animationKeyframes\n document.head.appendChild(styleSheet)\n }\n }, [])\n\n // Render the root container\n const rootStyle: CSSProperties = {\n ...design.style,\n }\n\n return (\n <div style={rootStyle} data-engage-design={design.id}>\n {design.children?.map((node) => (\n <NodeRenderer\n key={node.id}\n node={node}\n onClose={onClose}\n onAction={onAction}\n context={context}\n />\n ))}\n </div>\n )\n}\n\nexport default DesignRenderer\n","/**\n * @uptrade/site-kit/engage - Engage Widget\n * \n * Loads and renders engagement widgets (popups, nudges, bars, chat) via Portal API\n * Supports both legacy config-based rendering and new design_json from Engage Studio\n */\n\n'use client'\n\nimport React, { useEffect, useState, useCallback } from 'react'\nimport { usePathname } from 'next/navigation'\nimport type { EngageElement } from './types'\nimport { ChatWidget } from './ChatWidget'\nimport { DesignRenderer, type ActionConfig, type DesignDocument } from './DesignRenderer'\n\ninterface EngageWidgetProps {\n apiUrl?: string\n apiKey?: string\n position?: 'bottom-right' | 'bottom-left'\n zIndex?: number\n chatEnabled?: boolean\n debug?: boolean\n}\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.uptrademedia.com'\n : 'https://api.uptrademedia.com'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__\n : undefined\n return { apiUrl, apiKey }\n}\n\nexport function EngageWidget({\n apiUrl: propApiUrl,\n apiKey: propApiKey,\n position = 'bottom-right',\n zIndex = 9999,\n chatEnabled = true,\n debug = false,\n}: EngageWidgetProps) {\n const pathname = usePathname()\n const [elements, setElements] = useState<EngageElement[]>([])\n const [activeElements, setActiveElements] = useState<string[]>([])\n const [dismissedElements, setDismissedElements] = useState<Set<string>>(new Set())\n \n // Load elements from API\n useEffect(() => {\n async function loadElements() {\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) {\n if (debug) console.warn('[Engage] No API key configured')\n return\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/engage/elements`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({}),\n })\n \n if (!response.ok) {\n if (debug) console.error('[Engage] Error loading elements:', response.statusText)\n return\n }\n \n const data = await response.json()\n if (debug) console.log('[Engage] Loaded elements:', data.elements)\n setElements(data.elements || [])\n } catch (error) {\n if (debug) console.error('[Engage] Error loading elements:', error)\n }\n }\n \n loadElements()\n }, [propApiUrl, propApiKey, debug])\n \n // Check targeting and trigger for each element\n useEffect(() => {\n if (!elements.length) return\n \n const checkElement = (element: EngageElement): boolean => {\n // Check if dismissed\n if (dismissedElements.has(element.id)) return false\n \n // Check page targeting\n if (element.targeting?.pages) {\n const { include, exclude } = element.targeting.pages\n \n if (exclude?.some(p => matchPath(pathname, p))) return false\n if (include && !include.some(p => matchPath(pathname, p))) return false\n }\n \n // Check device targeting\n if (element.targeting?.devices) {\n const device = getDeviceType()\n if (!element.targeting.devices.includes(device)) return false\n }\n \n // Check frequency capping\n if (element.trigger?.frequency) {\n const { type, days } = element.trigger.frequency\n const key = `_engage_${element.id}`\n \n if (type === 'once') {\n if (localStorage.getItem(key)) return false\n } else if (type === 'once-per-session') {\n if (sessionStorage.getItem(key)) return false\n } else if (type === 'every-n-days' && days) {\n const lastShown = localStorage.getItem(key)\n if (lastShown) {\n const elapsed = Date.now() - parseInt(lastShown, 10)\n if (elapsed < days * 24 * 60 * 60 * 1000) return false\n }\n }\n }\n \n return true\n }\n \n // Filter elements that pass targeting\n const eligible = elements.filter(checkElement)\n \n if (debug) console.log('[Engage] Eligible elements:', eligible)\n \n // Set up triggers for eligible elements\n eligible.forEach(element => {\n const trigger = element.trigger\n \n if (trigger?.type === 'immediate' || !trigger?.type) {\n setActiveElements(prev => [...prev, element.id])\n } else if (trigger?.type === 'delay' && trigger.delay) {\n setTimeout(() => {\n setActiveElements(prev => [...prev, element.id])\n }, trigger.delay * 1000)\n } else if (trigger?.type === 'exit-intent') {\n const handleMouseLeave = (e: MouseEvent) => {\n if (e.clientY < 10) {\n setActiveElements(prev => [...prev, element.id])\n document.removeEventListener('mouseleave', handleMouseLeave)\n }\n }\n document.addEventListener('mouseleave', handleMouseLeave)\n } else if (trigger?.type === 'scroll' && trigger.scrollPercentage) {\n const handleScroll = () => {\n const scrollPercent = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100\n if (scrollPercent >= (trigger.scrollPercentage || 50)) {\n setActiveElements(prev => [...prev, element.id])\n window.removeEventListener('scroll', handleScroll)\n }\n }\n window.addEventListener('scroll', handleScroll)\n }\n })\n }, [elements, pathname, dismissedElements, debug])\n \n const handleDismiss = useCallback((elementId: string) => {\n setDismissedElements(prev => new Set([...prev, elementId]))\n setActiveElements(prev => prev.filter(id => id !== elementId))\n \n // Record dismissal in storage\n const element = elements.find(e => e.id === elementId)\n if (element?.trigger?.frequency) {\n const key = `_engage_${elementId}`\n if (element.trigger.frequency.type === 'once-per-session') {\n sessionStorage.setItem(key, 'true')\n } else {\n localStorage.setItem(key, Date.now().toString())\n }\n }\n }, [elements])\n \n // Render active elements + chat widget\n return (\n <>\n {activeElements.map(elementId => {\n const element = elements.find(e => e.id === elementId)\n if (!element) return null\n \n return (\n <EngageElementRenderer\n key={element.id}\n element={element}\n onDismiss={() => handleDismiss(element.id)}\n zIndex={zIndex}\n />\n )\n })}\n \n {/* Chat Widget - always rendered when chatEnabled */}\n {chatEnabled && (\n <ChatWidget\n projectId={propApiKey || ''}\n config={{\n position,\n buttonColor: '#00afab', // Default teal, can be customized later\n }}\n />\n )}\n </>\n )\n}\n\n// Helper components\nfunction EngageElementRenderer({ \n element, \n onDismiss,\n zIndex,\n}: { \n element: EngageElement\n onDismiss: () => void\n zIndex: number\n}) {\n // If element has design_json from Engage Studio, use DesignRenderer\n if (element.design_json) {\n // Wrap in appropriate container based on element type\n if (element.type === 'popup') {\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0,0,0,0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex,\n }}\n onClick={onDismiss}\n >\n <div onClick={e => e.stopPropagation()}>\n <DesignRenderer\n design={element.design_json}\n onClose={onDismiss}\n onAction={(action, node) => {\n // Handle commerce/form actions here\n console.log('[Engage] Action:', action, node)\n }}\n />\n </div>\n </div>\n )\n }\n \n if (element.type === 'bar') {\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n zIndex,\n }}\n >\n <DesignRenderer\n design={element.design_json}\n onClose={onDismiss}\n onAction={(action, node) => {\n console.log('[Engage] Action:', action, node)\n }}\n />\n </div>\n )\n }\n \n if (element.type === 'nudge' || element.type === 'slide-in') {\n const position = element.config?.position || 'bottom-right'\n const positionStyles: Record<string, React.CSSProperties> = {\n 'bottom-right': { bottom: 20, right: 20 },\n 'bottom-left': { bottom: 20, left: 20 },\n 'top-right': { top: 20, right: 20 },\n 'top-left': { top: 20, left: 20 },\n }\n \n return (\n <div\n style={{\n position: 'fixed',\n zIndex,\n ...positionStyles[position],\n }}\n >\n <DesignRenderer\n design={element.design_json}\n onClose={onDismiss}\n onAction={(action, node) => {\n console.log('[Engage] Action:', action, node)\n }}\n />\n </div>\n )\n }\n \n // Default: render design_json directly\n return (\n <DesignRenderer\n design={element.design_json}\n onClose={onDismiss}\n onAction={(action, node) => {\n console.log('[Engage] Action:', action, node)\n }}\n />\n )\n }\n\n // Legacy: Simple popup rendering for elements without design_json\n if (element.type === 'popup') {\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0,0,0,0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex,\n }}\n onClick={onDismiss}\n >\n <div\n style={{\n backgroundColor: 'white',\n padding: 24,\n borderRadius: 8,\n maxWidth: 500,\n width: '90%',\n }}\n onClick={e => e.stopPropagation()}\n >\n <button\n onClick={onDismiss}\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n background: 'none',\n border: 'none',\n fontSize: 24,\n cursor: 'pointer',\n }}\n >\n ×\n </button>\n {element.config?.title && <h2>{element.config.title}</h2>}\n {element.config?.message && <p>{element.config.message}</p>}\n </div>\n </div>\n )\n }\n \n // Bar/banner rendering\n if (element.type === 'bar') {\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n backgroundColor: element.config?.backgroundColor || '#3b82f6',\n color: element.config?.textColor || 'white',\n padding: '12px 24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 16,\n zIndex,\n }}\n >\n <span>{element.config?.message}</span>\n <button\n onClick={onDismiss}\n style={{\n background: 'none',\n border: 'none',\n color: 'inherit',\n fontSize: 20,\n cursor: 'pointer',\n }}\n >\n ×\n </button>\n </div>\n )\n }\n \n return null\n}\n\n// Utilities\nfunction matchPath(pathname: string, pattern: string): boolean {\n if (pattern.endsWith('*')) {\n return pathname.startsWith(pattern.slice(0, -1))\n }\n return pathname === pattern\n}\n\nfunction getDeviceType(): 'desktop' | 'mobile' | 'tablet' {\n if (typeof window === 'undefined') return 'desktop'\n const ua = navigator.userAgent\n if (/tablet|ipad|playbook|silk/i.test(ua)) return 'tablet'\n if (/mobile|iphone|ipod|android|blackberry|opera mini|iemobile/i.test(ua)) return 'mobile'\n return 'desktop'\n}\n"]}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { cache } from 'react';
|
|
2
2
|
|
|
3
3
|
// src/seo/api.ts
|
|
4
|
+
if (process.env.NODE_ENV === "development") {
|
|
5
|
+
console.warn(
|
|
6
|
+
"@uptrade/seo: WARNING - You are using the deprecated api.ts which exposes API keys. Please migrate to server-api.ts for better security. See: packages/site-kit/src/seo/README.md#migration"
|
|
7
|
+
);
|
|
8
|
+
}
|
|
4
9
|
function getApiConfig() {
|
|
5
10
|
const apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com";
|
|
6
11
|
const apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "";
|
|
@@ -114,7 +119,62 @@ async function registerSitemap(entries) {
|
|
|
114
119
|
return { success: false, created: 0, updated: 0 };
|
|
115
120
|
}
|
|
116
121
|
}
|
|
122
|
+
function getSignalApiConfig() {
|
|
123
|
+
const apiUrl = process.env.NEXT_PUBLIC_SIGNAL_API_URL || "https://signal.uptrademedia.com";
|
|
124
|
+
const apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "";
|
|
125
|
+
return { apiUrl, apiKey };
|
|
126
|
+
}
|
|
127
|
+
async function signalApiGet(endpoint) {
|
|
128
|
+
const { apiUrl, apiKey } = getSignalApiConfig();
|
|
129
|
+
if (!apiKey) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
134
|
+
method: "GET",
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "application/json",
|
|
137
|
+
"x-api-key": apiKey
|
|
138
|
+
},
|
|
139
|
+
next: { revalidate: 300 }
|
|
140
|
+
// Cache for 5 minutes
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const result = await response.json();
|
|
146
|
+
return result?.data || result;
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error("@uptrade/seo: Signal API error:", error);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
var getEntities = cache(async (projectId, options) => {
|
|
153
|
+
let endpoint = `/skills/seo/entities/${projectId}`;
|
|
154
|
+
if (options?.type) {
|
|
155
|
+
endpoint += `?type=${options.type}`;
|
|
156
|
+
}
|
|
157
|
+
const result = await signalApiGet(endpoint);
|
|
158
|
+
return result || [];
|
|
159
|
+
});
|
|
160
|
+
var getPrimaryEntity = cache(async (projectId) => {
|
|
161
|
+
return signalApiGet(`/skills/seo/entities/${projectId}/primary`);
|
|
162
|
+
});
|
|
163
|
+
var getEntityEnhancedSchema = cache(async (projectId, pagePath) => {
|
|
164
|
+
const result = await signalApiGet(
|
|
165
|
+
`/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`
|
|
166
|
+
);
|
|
167
|
+
return result?.schemas || [];
|
|
168
|
+
});
|
|
169
|
+
var getVisibilityScore = cache(async (projectId, pagePath) => {
|
|
170
|
+
const result = await signalApiGet(`/skills/seo/visibility/${projectId}`);
|
|
171
|
+
if (!result) return null;
|
|
172
|
+
return result.find((s) => s.page_path === pagePath) || null;
|
|
173
|
+
});
|
|
174
|
+
var getVisibilitySummary = cache(async (projectId) => {
|
|
175
|
+
return signalApiGet(`/skills/seo/visibility/${projectId}/summary`);
|
|
176
|
+
});
|
|
117
177
|
|
|
118
|
-
export { getABTest, getContentBlock, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap };
|
|
119
|
-
//# sourceMappingURL=chunk-
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
178
|
+
export { getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap };
|
|
179
|
+
//# sourceMappingURL=chunk-FQVGK746.mjs.map
|
|
180
|
+
//# sourceMappingURL=chunk-FQVGK746.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/seo/api.ts"],"names":[],"mappings":"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","file":"chunk-FQVGK746.mjs","sourcesContent":["/**\n * @uptrade/site-kit/seo - API Functions\n * \n * ⚠️ DEPRECATED: This file exposes API keys in client bundles.\n * Use `server-api.ts` instead for server-side operations.\n * \n * This file is kept for backward compatibility but will be removed in a future version.\n * \n * Migration guide:\n * - Replace: import { getSEOPageData } from '@uptrade/seo/api'\n * - With: import { getSEOPageData } from '@uptrade/seo/server'\n * - Use private env vars: UPTRADE_API_KEY instead of NEXT_PUBLIC_UPTRADE_API_KEY\n */\n\nimport { cache } from 'react'\n\n// Show deprecation warning in development\nif (process.env.NODE_ENV === 'development') {\n console.warn(\n '@uptrade/seo: WARNING - You are using the deprecated api.ts which exposes API keys. ' +\n 'Please migrate to server-api.ts for better security. ' +\n 'See: packages/site-kit/src/seo/README.md#migration'\n )\n}\n\n// ============================================\n// API Config (DEPRECATED)\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n const apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function apiPost<T>(endpoint: string, body: Record<string, any> = {}): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@uptrade/seo: No API key configured. Set NEXT_PUBLIC_UPTRADE_API_KEY.')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n next: { revalidate: 60 }, // Cache for 60 seconds\n })\n \n if (!response.ok) {\n console.error(`@uptrade/seo: API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('@uptrade/seo: Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Cached Data Fetchers\n// ============================================\n\n/**\n * Fetch SEO page data - cached per request\n */\nexport const getSEOPageData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ page: any }>('/api/public/seo/page', { path })\n return result?.page || null\n})\n\n/**\n * Fetch schema markups for a page - cached per request\n */\nexport const getSchemaMarkups = cache(async (\n projectId: string,\n path: string,\n options?: { includeTypes?: string[]; excludeTypes?: string[] }\n) => {\n const result = await apiPost<{ schemas: any[] }>('/api/public/seo/schemas', {\n path,\n includeTypes: options?.includeTypes,\n excludeTypes: options?.excludeTypes,\n })\n return result?.schemas || []\n})\n\n/**\n * Fetch FAQ data for a page - cached per request\n */\nexport const getFAQData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ faq: any }>('/api/public/seo/faq', { path })\n return result?.faq || null\n})\n\n/**\n * Fetch internal links for a page - cached per request\n */\nexport const getInternalLinks = cache(async (\n projectId: string,\n sourcePath: string,\n options?: { position?: string; limit?: number }\n) => {\n const result = await apiPost<{ links: any[] }>('/api/public/seo/internal-links', {\n sourcePath,\n position: options?.position,\n limit: options?.limit,\n })\n return result?.links || []\n})\n\n/**\n * Fetch content block - cached per request\n */\nexport const getContentBlock = cache(async (\n projectId: string,\n path: string,\n section: string\n) => {\n const result = await apiPost<{ content: any }>('/api/public/seo/content', { path, section })\n return result?.content || null\n})\n\n/**\n * Fetch A/B test and determine variant - cached per request\n */\nexport const getABTest = cache(async (\n projectId: string,\n path: string,\n field: string\n) => {\n const result = await apiPost<{ test: any }>('/api/public/seo/ab-test', { path, field })\n return result?.test || null\n})\n\n/**\n * Record A/B test impression\n */\nexport async function recordABImpression(\n testId: string,\n variant: 'a' | 'b',\n sessionId?: string\n): Promise<void> {\n await apiPost('/api/public/seo/ab-impression', { testId, variant, sessionId })\n}\n\n/**\n * Fetch redirect for a path - cached per request\n */\nexport const getRedirectData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ redirect: any }>('/api/public/seo/redirect', { path })\n return result?.redirect || null\n})\n\n/**\n * Fetch managed scripts - cached per request\n */\nexport const getManagedScripts = cache(async (\n projectId: string,\n position: string,\n currentPath?: string\n) => {\n const result = await apiPost<{ scripts: any[] }>('/api/public/seo/scripts', {\n position,\n currentPath,\n })\n return result?.scripts || []\n})\n\n/**\n * Fetch robots directive for a page - cached per request\n */\nexport const getRobotsData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ page: any }>('/api/public/seo/page', { path })\n return result?.page?.managed_robots || null\n})\n\n/**\n * Fetch sitemap entries - cached per request\n */\nexport const getSitemapEntries = cache(async (\n projectId: string,\n options?: { publishedOnly?: boolean }\n) => {\n const result = await apiPost<{ entries: any[] }>('/api/public/seo/sitemap', {\n publishedOnly: options?.publishedOnly,\n })\n return result?.entries || []\n})\n\n/**\n * Register/sync sitemap entries from the client site\n * Call this at build time to populate seo_pages from your sitemap.xml\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts (run at build time)\n * import { registerSitemap } from '@uptrade/seo/server'\n * \n * await registerSitemap([\n * { path: '/', priority: 1.0, changefreq: 'daily' },\n * { path: '/about', priority: 0.8, changefreq: 'weekly' },\n * ])\n * ```\n */\nexport async function registerSitemap(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>\n): Promise<{ success: boolean; created: number; updated: number }> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@uptrade/seo: No API key configured. Set NEXT_PUBLIC_UPTRADE_API_KEY.')\n return { success: false, created: 0, updated: 0 }\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({ entries }),\n })\n \n if (!response.ok) {\n console.error(`@uptrade/seo: Sitemap registration failed: ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n \n return await response.json()\n } catch (error) {\n console.error('@uptrade/seo: Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n// ============================================\n// AI Visibility & Entity Graph API\n// ============================================\n\n/**\n * Get Signal API config for AI visibility features\n */\nfunction getSignalApiConfig() {\n const apiUrl = process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.uptrademedia.com'\n const apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function signalApiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getSignalApiConfig()\n \n if (!apiKey) {\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 300 }, // Cache for 5 minutes\n })\n \n if (!response.ok) {\n return null\n }\n \n const result = await response.json()\n return result?.data || result\n } catch (error) {\n console.error('@uptrade/seo: Signal API error:', error)\n return null\n }\n}\n\n/**\n * Entity types for the knowledge graph\n */\nexport type EntityType = \n | 'organization'\n | 'person'\n | 'service'\n | 'product'\n | 'location'\n | 'concept'\n | 'credential'\n\n/**\n * Entity from the knowledge graph\n */\nexport interface SEOEntity {\n id: string\n project_id: string\n entity_type: EntityType\n name: string\n slug: string\n properties: Record<string, unknown>\n knows_about: string[]\n same_as: string[]\n schema_type?: string\n is_primary: boolean\n}\n\n/**\n * Fetch entities for a project - cached per request\n * Returns the entity graph for enhanced schema markup\n */\nexport const getEntities = cache(async (\n projectId: string,\n options?: { type?: EntityType }\n): Promise<SEOEntity[]> => {\n let endpoint = `/skills/seo/entities/${projectId}`\n if (options?.type) {\n endpoint += `?type=${options.type}`\n }\n const result = await signalApiGet<SEOEntity[]>(endpoint)\n return result || []\n})\n\n/**\n * Fetch primary entity (the business) - cached per request\n */\nexport const getPrimaryEntity = cache(async (\n projectId: string\n): Promise<SEOEntity | null> => {\n return signalApiGet<SEOEntity>(`/skills/seo/entities/${projectId}/primary`)\n})\n\n/**\n * Fetch entity-enhanced schema for a page\n * Returns Organization schema with knowsAbout, areaServed, employee, etc.\n */\nexport const getEntityEnhancedSchema = cache(async (\n projectId: string,\n pagePath: string\n): Promise<object[]> => {\n const result = await signalApiGet<{ schemas: object[] }>(\n `/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`\n )\n return result?.schemas || []\n})\n\n/**\n * Get AI visibility score for a page\n */\nexport const getVisibilityScore = cache(async (\n projectId: string,\n pagePath: string\n): Promise<{\n overall_score: number\n entity_coverage: number\n answer_density: number\n chunk_readability: number\n authority_signals: number\n schema_completeness: number\n} | null> => {\n const result = await signalApiGet<any[]>(`/skills/seo/visibility/${projectId}`)\n if (!result) return null\n return result.find(s => s.page_path === pagePath) || null\n})\n\n/**\n * Get AI visibility summary for project\n */\nexport const getVisibilitySummary = cache(async (\n projectId: string\n): Promise<{\n overall_score: number\n total_entities: number\n pages_analyzed: number\n top_recommendations: Array<{ priority: string; type: string; message: string }>\n} | null> => {\n return signalApiGet(`/skills/seo/visibility/${projectId}/summary`)\n})\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getRedirectData, getRobotsData, getSitemapEntries } from './chunk-
|
|
1
|
+
import { getRedirectData, getRobotsData, getSitemapEntries } from './chunk-FQVGK746.mjs';
|
|
2
2
|
|
|
3
3
|
// src/seo/routing.ts
|
|
4
4
|
async function getRedirect(options) {
|
|
@@ -64,7 +64,7 @@ async function generateSitemap(options) {
|
|
|
64
64
|
}));
|
|
65
65
|
}
|
|
66
66
|
async function registerLocalSitemap(options) {
|
|
67
|
-
const { registerSitemap } = await import('./api-
|
|
67
|
+
const { registerSitemap } = await import('./api-V3BA5PMX.mjs');
|
|
68
68
|
let entries = options.entries || [];
|
|
69
69
|
if (options.autoDiscover && entries.length === 0) {
|
|
70
70
|
try {
|
|
@@ -130,5 +130,5 @@ async function isIndexable(projectId, path) {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
export { generateSitemap, getRedirect, getRobotsDirective, isIndexable, registerLocalSitemap };
|
|
133
|
-
//# sourceMappingURL=chunk-
|
|
134
|
-
//# sourceMappingURL=chunk-
|
|
133
|
+
//# sourceMappingURL=chunk-JGQPAXTL.mjs.map
|
|
134
|
+
//# sourceMappingURL=chunk-JGQPAXTL.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/seo/routing.ts"],"names":[],"mappings":"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","file":"chunk-GQ6ZOU2N.mjs","sourcesContent":["import { getRedirectData, getRobotsData, getSitemapEntries } from './api'\nimport type { \n GetRedirectOptions, \n RedirectResult, \n GetRobotsOptions, \n RobotsDirective,\n GetSitemapEntriesOptions,\n SitemapEntry \n} from './types'\n\n/**\n * Get redirect for a path if one exists\n * \n * Use in Next.js middleware to handle managed redirects\n * \n * @example\n * ```tsx\n * // middleware.ts\n * import { getRedirect } from '@uptrade/seo'\n * \n * export async function middleware(request) {\n * const redirect = await getRedirect({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: request.nextUrl.pathname\n * })\n * \n * if (redirect) {\n * return NextResponse.redirect(redirect.destination, redirect.statusCode)\n * }\n * }\n * ```\n */\nexport async function getRedirect(\n options: GetRedirectOptions\n): Promise<RedirectResult | null> {\n const { projectId, path } = options\n\n const redirect = await getRedirectData(projectId, path)\n\n if (!redirect) {\n return null\n }\n\n // Check if expired\n if (redirect.expires_at && new Date(redirect.expires_at) < new Date()) {\n return null\n }\n\n // Determine destination\n const destination = redirect.destination_url || redirect.destination_path\n const isExternal = destination.startsWith('http://') || destination.startsWith('https://')\n\n return {\n destination,\n statusCode: redirect.status_code,\n isExternal,\n }\n}\n\n/**\n * Parse robots directive string into structured object\n */\nfunction parseRobotsString(robots: string): RobotsDirective {\n const directive: RobotsDirective = {\n index: true,\n follow: true,\n }\n\n const parts = robots.toLowerCase().split(',').map(p => p.trim())\n\n for (const part of parts) {\n if (part === 'noindex') directive.index = false\n if (part === 'nofollow') directive.follow = false\n if (part === 'noarchive') directive.noarchive = true\n if (part === 'nosnippet') directive.nosnippet = true\n if (part === 'noimageindex') directive.noimageindex = true\n if (part.startsWith('max-snippet:')) {\n directive.max_snippet = parseInt(part.split(':')[1], 10)\n }\n if (part.startsWith('max-image-preview:')) {\n const value = part.split(':')[1] as 'none' | 'standard' | 'large'\n directive.max_image_preview = value\n }\n if (part.startsWith('max-video-preview:')) {\n directive.max_video_preview = parseInt(part.split(':')[1], 10)\n }\n }\n\n return directive\n}\n\n/**\n * Get robots directive for a page\n * \n * @example\n * ```tsx\n * const robots = await getRobotsDirective({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: '/private-page'\n * })\n * \n * if (!robots.index) {\n * // Page should not be indexed\n * }\n * ```\n */\nexport async function getRobotsDirective(\n options: GetRobotsOptions\n): Promise<RobotsDirective> {\n const { projectId, path } = options\n\n const robotsString = await getRobotsData(projectId, path)\n\n if (!robotsString) {\n // Default: index and follow\n return { index: true, follow: true }\n }\n\n return parseRobotsString(robotsString)\n}\n\n/**\n * Get sitemap entries for a project\n * \n * Use in sitemap.ts to generate dynamic sitemap\n * \n * @example\n * ```tsx\n * // app/sitemap.ts\n * import { generateSitemap } from '@uptrade/seo'\n * \n * export default async function sitemap() {\n * return generateSitemap({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * baseUrl: 'https://example.com',\n * publishedOnly: true\n * })\n * }\n * ```\n */\nexport async function generateSitemap(\n options: GetSitemapEntriesOptions\n): Promise<SitemapEntry[]> {\n const { projectId, baseUrl, publishedOnly = true } = options\n\n const pages = await getSitemapEntries(projectId, { publishedOnly })\n\n const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n\n return pages.map(page => ({\n path: page.path,\n url: `${normalizedBase}${page.path}`,\n lastmod: page.updated_at,\n changefreq: page.sitemap_changefreq || 'weekly',\n priority: page.sitemap_priority || 0.5,\n }))\n}\n\n/**\n * Register local sitemap entries with Uptrade Portal\n * \n * Call this at build time to sync your local routes to seo_pages.\n * This ensures analytics only tracks real pages.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts\n * import { registerLocalSitemap } from '@uptrade/seo'\n * \n * // Option 1: Provide entries directly\n * await registerLocalSitemap({\n * entries: [\n * { path: '/', title: 'Home', priority: 1.0 },\n * { path: '/about', title: 'About Us', priority: 0.8 },\n * ]\n * })\n * \n * // Option 2: Auto-discover from Next.js app directory\n * await registerLocalSitemap({ autoDiscover: true })\n * ```\n */\nexport async function registerLocalSitemap(options: {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>\n autoDiscover?: boolean\n}): Promise<{ success: boolean; created: number; updated: number }> {\n const { registerSitemap } = await import('./api')\n \n let entries = options.entries || []\n \n // Auto-discover from Next.js app directory if requested\n if (options.autoDiscover && entries.length === 0) {\n try {\n const fs = await import('fs')\n const path = await import('path')\n \n const appDir = path.join(process.cwd(), 'app')\n if (fs.existsSync(appDir)) {\n entries = discoverNextJsRoutes(appDir, fs, path)\n console.log(`[Uptrade] Auto-discovered ${entries.length} routes from app directory`)\n }\n } catch (error) {\n console.error('[Uptrade] Auto-discovery failed:', error)\n }\n }\n \n if (entries.length === 0) {\n console.warn('[Uptrade] No sitemap entries to register')\n return { success: true, created: 0, updated: 0 }\n }\n \n console.log(`[Uptrade] Registering ${entries.length} sitemap entries...`)\n const result = await registerSitemap(entries)\n \n if (result.success) {\n console.log(`[Uptrade] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n \n return result\n}\n\n/**\n * Discover routes from Next.js app directory\n */\nfunction discoverNextJsRoutes(\n appDir: string,\n fs: typeof import('fs'),\n path: typeof import('path'),\n basePath: string = ''\n): Array<{ path: string; priority: number }> {\n const entries: Array<{ path: string; priority: number }> = []\n \n const items = fs.readdirSync(appDir, { withFileTypes: true })\n \n for (const item of items) {\n // Skip private folders, api routes, and special files\n if (item.name.startsWith('_') || item.name.startsWith('.')) continue\n if (item.name === 'api') continue\n if (item.name === 'node_modules') continue\n \n const itemPath = path.join(appDir, item.name)\n \n if (item.isDirectory()) {\n // Check for page.tsx/page.js in this directory\n const hasPage = fs.existsSync(path.join(itemPath, 'page.tsx')) ||\n fs.existsSync(path.join(itemPath, 'page.js')) ||\n fs.existsSync(path.join(itemPath, 'page.jsx'))\n \n // Handle route groups (parentheses)\n const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\n \n // Handle dynamic segments [slug]\n const isDynamic = item.name.startsWith('[') && item.name.endsWith(']')\n \n let routePath = basePath\n if (!isRouteGroup && !isDynamic) {\n routePath = `${basePath}/${item.name}`\n }\n \n if (hasPage && !isDynamic) {\n const priority = routePath === '' ? 1.0 : 0.8\n entries.push({ path: routePath || '/', priority })\n }\n \n // Recurse into subdirectories (but not dynamic ones)\n if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(itemPath, fs, path, isRouteGroup ? basePath : routePath)\n entries.push(...subEntries)\n }\n }\n }\n \n // Add root if app/page.tsx exists and we're at root\n if (basePath === '') {\n const hasRootPage = fs.existsSync(path.join(appDir, 'page.tsx')) ||\n fs.existsSync(path.join(appDir, 'page.js')) ||\n fs.existsSync(path.join(appDir, 'page.jsx'))\n if (hasRootPage) {\n entries.unshift({ path: '/', priority: 1.0 })\n }\n }\n \n return entries\n}\n\n/**\n * Check if a path should be indexed\n * \n * Quick helper to check indexability without full directive parsing\n */\nexport async function isIndexable(\n projectId: string,\n path: string\n): Promise<boolean> {\n const directive = await getRobotsDirective({ projectId, path })\n return directive.index\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/seo/routing.ts"],"names":[],"mappings":";;;AAgCA,eAAsB,YACpB,OAAA,EACgC;AAChC,EAAA,MAAM,EAAE,SAAA,EAAW,IAAA,EAAK,GAAI,OAAA;AAE5B,EAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,SAAA,EAAW,IAAI,CAAA;AAEtD,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAA,CAAS,cAAc,IAAI,IAAA,CAAK,SAAS,UAAU,CAAA,mBAAI,IAAI,IAAA,EAAK,EAAG;AACrE,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,eAAA,IAAmB,QAAA,CAAS,gBAAA;AACzD,EAAA,MAAM,aAAa,WAAA,CAAY,UAAA,CAAW,SAAS,CAAA,IAAK,WAAA,CAAY,WAAW,UAAU,CAAA;AAEzF,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,YAAY,QAAA,CAAS,WAAA;AAAA,IACrB;AAAA,GACF;AACF;AAKA,SAAS,kBAAkB,MAAA,EAAiC;AAC1D,EAAA,MAAM,SAAA,GAA6B;AAAA,IACjC,KAAA,EAAO,IAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACV;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,WAAA,EAAY,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAM,CAAA;AAE/D,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,IAAA,KAAS,SAAA,EAAW,SAAA,CAAU,KAAA,GAAQ,KAAA;AAC1C,IAAA,IAAI,IAAA,KAAS,UAAA,EAAY,SAAA,CAAU,MAAA,GAAS,KAAA;AAC5C,IAAA,IAAI,IAAA,KAAS,WAAA,EAAa,SAAA,CAAU,SAAA,GAAY,IAAA;AAChD,IAAA,IAAI,IAAA,KAAS,WAAA,EAAa,SAAA,CAAU,SAAA,GAAY,IAAA;AAChD,IAAA,IAAI,IAAA,KAAS,cAAA,EAAgB,SAAA,CAAU,YAAA,GAAe,IAAA;AACtD,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,cAAc,CAAA,EAAG;AACnC,MAAA,SAAA,CAAU,WAAA,GAAc,SAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,GAAG,EAAE,CAAA;AAAA,IACzD;AACA,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,oBAAoB,CAAA,EAAG;AACzC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAC/B,MAAA,SAAA,CAAU,iBAAA,GAAoB,KAAA;AAAA,IAChC;AACA,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,oBAAoB,CAAA,EAAG;AACzC,MAAA,SAAA,CAAU,iBAAA,GAAoB,SAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,GAAG,EAAE,CAAA;AAAA,IAC/D;AAAA,EACF;AAEA,EAAA,OAAO,SAAA;AACT;AAiBA,eAAsB,mBACpB,OAAA,EAC0B;AAC1B,EAAA,MAAM,EAAE,SAAA,EAAW,IAAA,EAAK,GAAI,OAAA;AAE5B,EAAA,MAAM,YAAA,GAAe,MAAM,aAAA,CAAc,SAAA,EAAW,IAAI,CAAA;AAExD,EAAA,IAAI,CAAC,YAAA,EAAc;AAEjB,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAAA,EACrC;AAEA,EAAA,OAAO,kBAAkB,YAAY,CAAA;AACvC;AAqBA,eAAsB,gBACpB,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,aAAA,GAAgB,MAAK,GAAI,OAAA;AAErD,EAAA,MAAM,QAAQ,MAAM,iBAAA,CAAkB,SAAA,EAAW,EAAE,eAAe,CAAA;AAElE,EAAA,MAAM,cAAA,GAAiB,QAAQ,QAAA,CAAS,GAAG,IAAI,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,OAAA;AAEtE,EAAA,OAAO,KAAA,CAAM,IAAI,CAAA,IAAA,MAAS;AAAA,IACxB,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,GAAA,EAAK,CAAA,EAAG,cAAc,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA;AAAA,IAClC,SAAS,IAAA,CAAK,UAAA;AAAA,IACd,UAAA,EAAY,KAAK,kBAAA,IAAsB,QAAA;AAAA,IACvC,QAAA,EAAU,KAAK,gBAAA,IAAoB;AAAA,GACrC,CAAE,CAAA;AACJ;AAyBA,eAAsB,qBAAqB,OAAA,EAQyB;AAClE,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAI,MAAM,OAAO,oBAAO,CAAA;AAEhD,EAAA,IAAI,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,EAAC;AAGlC,EAAA,IAAI,OAAA,CAAQ,YAAA,IAAgB,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,MAAA,MAAM,IAAA,GAAO,MAAM,OAAO,MAAM,CAAA;AAEhC,MAAA,MAAM,SAAS,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,KAAK,CAAA;AAC7C,MAAA,IAAI,EAAA,CAAG,UAAA,CAAW,MAAM,CAAA,EAAG;AACzB,QAAA,OAAA,GAAU,oBAAA,CAAqB,MAAA,EAAQ,EAAA,EAAI,IAAI,CAAA;AAC/C,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,0BAAA,EAA6B,OAAA,CAAQ,MAAM,CAAA,0BAAA,CAA4B,CAAA;AAAA,MACrF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,oCAAoC,KAAK,CAAA;AAAA,IACzD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAA,CAAQ,KAAK,0CAA0C,CAAA;AACvD,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,EACjD;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,sBAAA,EAAyB,OAAA,CAAQ,MAAM,CAAA,mBAAA,CAAqB,CAAA;AACxE,EAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,OAAO,CAAA;AAE5C,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAA,CAAQ,IAAI,CAAA,8BAAA,EAAiC,MAAA,CAAO,OAAO,CAAA,MAAA,EAAS,MAAA,CAAO,OAAO,CAAA,QAAA,CAAU,CAAA;AAAA,EAC9F;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,oBAAA,CACP,MAAA,EACA,EAAA,EACA,IAAA,EACA,WAAmB,EAAA,EACwB;AAC3C,EAAA,MAAM,UAAqD,EAAC;AAE5D,EAAA,MAAM,QAAQ,EAAA,CAAG,WAAA,CAAY,QAAQ,EAAE,aAAA,EAAe,MAAM,CAAA;AAE5D,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AAExB,IAAA,IAAI,IAAA,CAAK,KAAK,UAAA,CAAW,GAAG,KAAK,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AAC5D,IAAA,IAAI,IAAA,CAAK,SAAS,KAAA,EAAO;AACzB,IAAA,IAAI,IAAA,CAAK,SAAS,cAAA,EAAgB;AAElC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAI,CAAA;AAE5C,IAAA,IAAI,IAAA,CAAK,aAAY,EAAG;AAEtB,MAAA,MAAM,OAAA,GAAU,GAAG,UAAA,CAAW,IAAA,CAAK,KAAK,QAAA,EAAU,UAAU,CAAC,CAAA,IAC7C,EAAA,CAAG,UAAA,CAAW,KAAK,IAAA,CAAK,QAAA,EAAU,SAAS,CAAC,CAAA,IAC5C,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,UAAU,CAAC,CAAA;AAG7D,MAAA,MAAM,YAAA,GAAe,KAAK,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA;AAGxE,MAAA,MAAM,SAAA,GAAY,KAAK,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA;AAErE,MAAA,IAAI,SAAA,GAAY,QAAA;AAChB,MAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,SAAA,EAAW;AAC/B,QAAA,SAAA,GAAY,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,MACtC;AAEA,MAAA,IAAI,OAAA,IAAW,CAAC,SAAA,EAAW;AACzB,QAAA,MAAM,QAAA,GAAW,SAAA,KAAc,EAAA,GAAK,CAAA,GAAM,GAAA;AAC1C,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,IAAa,GAAA,EAAK,UAAU,CAAA;AAAA,MACnD;AAGA,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,aAAa,oBAAA,CAAqB,QAAA,EAAU,IAAI,IAAA,EAAM,YAAA,GAAe,WAAW,SAAS,CAAA;AAC/F,QAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,UAAU,CAAA;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,aAAa,EAAA,EAAI;AACnB,IAAA,MAAM,WAAA,GAAc,GAAG,UAAA,CAAW,IAAA,CAAK,KAAK,MAAA,EAAQ,UAAU,CAAC,CAAA,IAC3C,EAAA,CAAG,UAAA,CAAW,KAAK,IAAA,CAAK,MAAA,EAAQ,SAAS,CAAC,CAAA,IAC1C,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,UAAU,CAAC,CAAA;AAC/D,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,OAAA,CAAQ,QAAQ,EAAE,IAAA,EAAM,GAAA,EAAK,QAAA,EAAU,GAAK,CAAA;AAAA,IAC9C;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAOA,eAAsB,WAAA,CACpB,WACA,IAAA,EACkB;AAClB,EAAA,MAAM,YAAY,MAAM,kBAAA,CAAmB,EAAE,SAAA,EAAW,MAAM,CAAA;AAC9D,EAAA,OAAO,SAAA,CAAU,KAAA;AACnB","file":"chunk-JGQPAXTL.mjs","sourcesContent":["import { getRedirectData, getRobotsData, getSitemapEntries } from './api'\nimport type { \n GetRedirectOptions, \n RedirectResult, \n GetRobotsOptions, \n RobotsDirective,\n GetSitemapEntriesOptions,\n SitemapEntry \n} from './types'\n\n/**\n * Get redirect for a path if one exists\n * \n * Use in Next.js middleware to handle managed redirects\n * \n * @example\n * ```tsx\n * // middleware.ts\n * import { getRedirect } from '@uptrade/seo'\n * \n * export async function middleware(request) {\n * const redirect = await getRedirect({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: request.nextUrl.pathname\n * })\n * \n * if (redirect) {\n * return NextResponse.redirect(redirect.destination, redirect.statusCode)\n * }\n * }\n * ```\n */\nexport async function getRedirect(\n options: GetRedirectOptions\n): Promise<RedirectResult | null> {\n const { projectId, path } = options\n\n const redirect = await getRedirectData(projectId, path)\n\n if (!redirect) {\n return null\n }\n\n // Check if expired\n if (redirect.expires_at && new Date(redirect.expires_at) < new Date()) {\n return null\n }\n\n // Determine destination\n const destination = redirect.destination_url || redirect.destination_path\n const isExternal = destination.startsWith('http://') || destination.startsWith('https://')\n\n return {\n destination,\n statusCode: redirect.status_code,\n isExternal,\n }\n}\n\n/**\n * Parse robots directive string into structured object\n */\nfunction parseRobotsString(robots: string): RobotsDirective {\n const directive: RobotsDirective = {\n index: true,\n follow: true,\n }\n\n const parts = robots.toLowerCase().split(',').map(p => p.trim())\n\n for (const part of parts) {\n if (part === 'noindex') directive.index = false\n if (part === 'nofollow') directive.follow = false\n if (part === 'noarchive') directive.noarchive = true\n if (part === 'nosnippet') directive.nosnippet = true\n if (part === 'noimageindex') directive.noimageindex = true\n if (part.startsWith('max-snippet:')) {\n directive.max_snippet = parseInt(part.split(':')[1], 10)\n }\n if (part.startsWith('max-image-preview:')) {\n const value = part.split(':')[1] as 'none' | 'standard' | 'large'\n directive.max_image_preview = value\n }\n if (part.startsWith('max-video-preview:')) {\n directive.max_video_preview = parseInt(part.split(':')[1], 10)\n }\n }\n\n return directive\n}\n\n/**\n * Get robots directive for a page\n * \n * @example\n * ```tsx\n * const robots = await getRobotsDirective({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: '/private-page'\n * })\n * \n * if (!robots.index) {\n * // Page should not be indexed\n * }\n * ```\n */\nexport async function getRobotsDirective(\n options: GetRobotsOptions\n): Promise<RobotsDirective> {\n const { projectId, path } = options\n\n const robotsString = await getRobotsData(projectId, path)\n\n if (!robotsString) {\n // Default: index and follow\n return { index: true, follow: true }\n }\n\n return parseRobotsString(robotsString)\n}\n\n/**\n * Get sitemap entries for a project\n * \n * Use in sitemap.ts to generate dynamic sitemap\n * \n * @example\n * ```tsx\n * // app/sitemap.ts\n * import { generateSitemap } from '@uptrade/seo'\n * \n * export default async function sitemap() {\n * return generateSitemap({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * baseUrl: 'https://example.com',\n * publishedOnly: true\n * })\n * }\n * ```\n */\nexport async function generateSitemap(\n options: GetSitemapEntriesOptions\n): Promise<SitemapEntry[]> {\n const { projectId, baseUrl, publishedOnly = true } = options\n\n const pages = await getSitemapEntries(projectId, { publishedOnly })\n\n const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n\n return pages.map(page => ({\n path: page.path,\n url: `${normalizedBase}${page.path}`,\n lastmod: page.updated_at,\n changefreq: page.sitemap_changefreq || 'weekly',\n priority: page.sitemap_priority || 0.5,\n }))\n}\n\n/**\n * Register local sitemap entries with Uptrade Portal\n * \n * Call this at build time to sync your local routes to seo_pages.\n * This ensures analytics only tracks real pages.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts\n * import { registerLocalSitemap } from '@uptrade/seo'\n * \n * // Option 1: Provide entries directly\n * await registerLocalSitemap({\n * entries: [\n * { path: '/', title: 'Home', priority: 1.0 },\n * { path: '/about', title: 'About Us', priority: 0.8 },\n * ]\n * })\n * \n * // Option 2: Auto-discover from Next.js app directory\n * await registerLocalSitemap({ autoDiscover: true })\n * ```\n */\nexport async function registerLocalSitemap(options: {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>\n autoDiscover?: boolean\n}): Promise<{ success: boolean; created: number; updated: number }> {\n const { registerSitemap } = await import('./api')\n \n let entries = options.entries || []\n \n // Auto-discover from Next.js app directory if requested\n if (options.autoDiscover && entries.length === 0) {\n try {\n const fs = await import('fs')\n const path = await import('path')\n \n const appDir = path.join(process.cwd(), 'app')\n if (fs.existsSync(appDir)) {\n entries = discoverNextJsRoutes(appDir, fs, path)\n console.log(`[Uptrade] Auto-discovered ${entries.length} routes from app directory`)\n }\n } catch (error) {\n console.error('[Uptrade] Auto-discovery failed:', error)\n }\n }\n \n if (entries.length === 0) {\n console.warn('[Uptrade] No sitemap entries to register')\n return { success: true, created: 0, updated: 0 }\n }\n \n console.log(`[Uptrade] Registering ${entries.length} sitemap entries...`)\n const result = await registerSitemap(entries)\n \n if (result.success) {\n console.log(`[Uptrade] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n \n return result\n}\n\n/**\n * Discover routes from Next.js app directory\n */\nfunction discoverNextJsRoutes(\n appDir: string,\n fs: typeof import('fs'),\n path: typeof import('path'),\n basePath: string = ''\n): Array<{ path: string; priority: number }> {\n const entries: Array<{ path: string; priority: number }> = []\n \n const items = fs.readdirSync(appDir, { withFileTypes: true })\n \n for (const item of items) {\n // Skip private folders, api routes, and special files\n if (item.name.startsWith('_') || item.name.startsWith('.')) continue\n if (item.name === 'api') continue\n if (item.name === 'node_modules') continue\n \n const itemPath = path.join(appDir, item.name)\n \n if (item.isDirectory()) {\n // Check for page.tsx/page.js in this directory\n const hasPage = fs.existsSync(path.join(itemPath, 'page.tsx')) ||\n fs.existsSync(path.join(itemPath, 'page.js')) ||\n fs.existsSync(path.join(itemPath, 'page.jsx'))\n \n // Handle route groups (parentheses)\n const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\n \n // Handle dynamic segments [slug]\n const isDynamic = item.name.startsWith('[') && item.name.endsWith(']')\n \n let routePath = basePath\n if (!isRouteGroup && !isDynamic) {\n routePath = `${basePath}/${item.name}`\n }\n \n if (hasPage && !isDynamic) {\n const priority = routePath === '' ? 1.0 : 0.8\n entries.push({ path: routePath || '/', priority })\n }\n \n // Recurse into subdirectories (but not dynamic ones)\n if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(itemPath, fs, path, isRouteGroup ? basePath : routePath)\n entries.push(...subEntries)\n }\n }\n }\n \n // Add root if app/page.tsx exists and we're at root\n if (basePath === '') {\n const hasRootPage = fs.existsSync(path.join(appDir, 'page.tsx')) ||\n fs.existsSync(path.join(appDir, 'page.js')) ||\n fs.existsSync(path.join(appDir, 'page.jsx'))\n if (hasRootPage) {\n entries.unshift({ path: '/', priority: 1.0 })\n }\n }\n \n return entries\n}\n\n/**\n * Check if a path should be indexed\n * \n * Quick helper to check indexability without full directive parsing\n */\nexport async function isIndexable(\n projectId: string,\n path: string\n): Promise<boolean> {\n const directive = await getRobotsDirective({ projectId, path })\n return directive.index\n}\n"]}
|