@uptrademedia/site-kit 1.0.9 → 1.0.11

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.
Files changed (55) hide show
  1. package/dist/api-CWtoFJCO.d.mts +137 -0
  2. package/dist/api-CWtoFJCO.d.ts +137 -0
  3. package/dist/{api-QUIPJJCX.js → api-UBHLAPUG.js} +20 -20
  4. package/dist/api-UBHLAPUG.js.map +1 -0
  5. package/dist/{api-V3BA5PMX.mjs → api-XNF6Q5HO.mjs} +3 -3
  6. package/dist/api-XNF6Q5HO.mjs.map +1 -0
  7. package/dist/{chunk-QQB4FO4Q.js → chunk-AWAJEIZS.js} +11 -8
  8. package/dist/chunk-AWAJEIZS.js.map +1 -0
  9. package/dist/{chunk-MB3WR5KJ.mjs → chunk-CDJL2YGL.mjs} +61 -443
  10. package/dist/chunk-CDJL2YGL.mjs.map +1 -0
  11. package/dist/{chunk-TDK7DLCH.js → chunk-FLAA4ZJO.js} +59 -448
  12. package/dist/chunk-FLAA4ZJO.js.map +1 -0
  13. package/dist/{chunk-JGQPAXTL.mjs → chunk-H5AGHERY.mjs} +8 -5
  14. package/dist/chunk-H5AGHERY.mjs.map +1 -0
  15. package/dist/{chunk-VDI7KYME.js → chunk-IYVJGUYX.js} +8 -4
  16. package/dist/chunk-IYVJGUYX.js.map +1 -0
  17. package/dist/{chunk-FQVGK746.mjs → chunk-SKHOW2CI.mjs} +8 -4
  18. package/dist/chunk-SKHOW2CI.mjs.map +1 -0
  19. package/dist/cli/index.js +32 -25
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/index.mjs +32 -25
  22. package/dist/cli/index.mjs.map +1 -1
  23. package/dist/images/index.d.mts +49 -126
  24. package/dist/images/index.d.ts +49 -126
  25. package/dist/images/index.js +12 -12
  26. package/dist/images/index.mjs +1 -5
  27. package/dist/index.d.mts +2 -2
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +510 -106
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +440 -13
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/{routing-CIOFpFCB.d.mts → routing-BT0RrBLk.d.mts} +14 -1
  34. package/dist/{routing-CF91y6NO.d.ts → routing-wmNSxSvP.d.ts} +14 -1
  35. package/dist/seo/index.d.mts +37 -4
  36. package/dist/seo/index.d.ts +37 -4
  37. package/dist/seo/index.js +49 -19
  38. package/dist/seo/index.js.map +1 -1
  39. package/dist/seo/index.mjs +35 -6
  40. package/dist/seo/index.mjs.map +1 -1
  41. package/dist/seo/server.d.mts +15 -4
  42. package/dist/seo/server.d.ts +15 -4
  43. package/dist/seo/server.js +16 -16
  44. package/dist/seo/server.mjs +2 -2
  45. package/dist/{types-j8X4vUhB.d.mts → types-wf4dwNMO.d.mts} +5 -0
  46. package/dist/{types-j8X4vUhB.d.ts → types-wf4dwNMO.d.ts} +5 -0
  47. package/package.json +1 -1
  48. package/dist/api-QUIPJJCX.js.map +0 -1
  49. package/dist/api-V3BA5PMX.mjs.map +0 -1
  50. package/dist/chunk-FQVGK746.mjs.map +0 -1
  51. package/dist/chunk-JGQPAXTL.mjs.map +0 -1
  52. package/dist/chunk-MB3WR5KJ.mjs.map +0 -1
  53. package/dist/chunk-QQB4FO4Q.js.map +0 -1
  54. package/dist/chunk-TDK7DLCH.js.map +0 -1
  55. package/dist/chunk-VDI7KYME.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uptrademedia/site-kit",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Complete client-side integration kit for Uptrade Portal - SEO, Analytics, Engage, Forms, Blog",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"api-QUIPJJCX.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"api-V3BA5PMX.mjs"}
@@ -1 +0,0 @@
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 +0,0 @@
1
- {"version":3,"sources":["../src/seo/routing.ts"],"names":[],"mappings":"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","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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/signal/SignalBridge.tsx","../src/SiteKitProvider.tsx","../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["createContext","useContext","useEffect","useMemo","jsx","useState","useCallback","Fragment","jsxs"],"mappings":"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","file":"chunk-MB3WR5KJ.mjs","sourcesContent":["/**\n * @uptrade/site-kit/signal - SignalBridge\n * \n * Central coordination layer for Signal AI integration.\n * Handles config fetching, SSE streaming, experiment assignment, and outcome tracking.\n */\n\n'use client'\n\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef, useMemo } from 'react'\nimport type { \n SignalConfig, \n SignalContextValue, \n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment \n} from './types'\n\n// ============================================\n// Context\n// ============================================\n\nconst SignalContext = createContext<SignalContextValue | null>(null)\n\nexport function useSignal(): SignalContextValue {\n const context = useContext(SignalContext)\n if (!context) {\n throw new Error('useSignal must be used within a SignalBridge')\n }\n return context\n}\n\n// ============================================\n// Utility Functions\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 getVisitorId(): string {\n if (typeof window === 'undefined') return ''\n \n const key = '_uptrade_vid'\n let visitorId = localStorage.getItem(key)\n \n if (!visitorId) {\n visitorId = crypto.randomUUID()\n localStorage.setItem(key, visitorId)\n }\n \n return visitorId\n}\n\nfunction getSessionId(): string {\n if (typeof window === 'undefined') return ''\n \n const key = '_uptrade_sid'\n let sessionId = sessionStorage.getItem(key)\n \n if (!sessionId) {\n sessionId = crypto.randomUUID()\n sessionStorage.setItem(key, sessionId)\n }\n \n return sessionId\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\nfunction getBrowser(): string {\n if (typeof window === 'undefined') return 'unknown'\n const ua = navigator.userAgent\n if (ua.includes('Firefox')) return 'Firefox'\n if (ua.includes('Edg')) return 'Edge'\n if (ua.includes('Chrome')) return 'Chrome'\n if (ua.includes('Safari')) return 'Safari'\n return 'Other'\n}\n\nfunction getOS(): string {\n if (typeof window === 'undefined') return 'unknown'\n const ua = navigator.userAgent\n if (ua.includes('Windows')) return 'Windows'\n if (ua.includes('Mac')) return 'macOS'\n if (ua.includes('iPhone') || ua.includes('iPad')) return 'iOS'\n if (ua.includes('Android')) return 'Android'\n if (ua.includes('Linux')) return 'Linux'\n return 'Other'\n}\n\n// ============================================\n// SignalBridge Component\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n \n // Refs for SSE and tracking\n const eventSourceRef = useRef<EventSource | null>(null)\n const eventQueueRef = useRef<Partial<SignalEvent>[]>([])\n const flushTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const assignmentsRef = useRef<Map<string, ExperimentAssignment>>(new Map())\n \n // Behavioral tracking state\n const pageLoadTimeRef = useRef<number>(Date.now())\n const scrollDepthRef = useRef<number>(0)\n const clickCountRef = useRef<number>(0)\n \n const { apiUrl, apiKey } = getApiConfig()\n\n // ============================================\n // Config Fetching\n // ============================================\n \n const fetchConfig = useCallback(async () => {\n if (!apiKey || !enabled) {\n setLoading(false)\n return\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/signal/config`, {\n headers: {\n 'x-api-key': apiKey,\n 'x-visitor-id': getVisitorId(),\n },\n })\n \n if (!response.ok) {\n throw new Error(`Failed to fetch Signal config: ${response.statusText}`)\n }\n \n const data = await response.json()\n setConfig(data.config)\n setError(null)\n \n // Load experiment assignments\n if (experiments && data.config?.experiments) {\n for (const exp of data.config.experiments) {\n if (exp.status === 'running') {\n await loadExperimentAssignment(exp.id)\n }\n }\n }\n } catch (err) {\n console.error('[Signal] Config fetch error:', err)\n setError(err as Error)\n } finally {\n setLoading(false)\n }\n }, [apiUrl, apiKey, enabled, experiments])\n\n // ============================================\n // SSE Real-time Updates\n // ============================================\n \n const connectSSE = useCallback(() => {\n if (!apiKey || !enabled || !realtime) return\n \n // Close existing connection\n if (eventSourceRef.current) {\n eventSourceRef.current.close()\n }\n \n const url = `${apiUrl}/api/public/signal/stream?key=${apiKey}`\n const eventSource = new EventSource(url)\n \n eventSource.addEventListener('config_update', (e) => {\n try {\n const { config: newConfig, version } = JSON.parse(e.data)\n setConfig(prev => {\n if (prev?.version !== version) {\n console.log('[Signal] Config updated to version:', version)\n return newConfig\n }\n return prev\n })\n } catch (err) {\n console.error('[Signal] SSE parse error:', err)\n }\n })\n \n eventSource.addEventListener('experiment_update', (e) => {\n try {\n const { experiment_id, action } = JSON.parse(e.data)\n if (action === 'started' || action === 'updated') {\n loadExperimentAssignment(experiment_id)\n } else if (action === 'stopped') {\n assignmentsRef.current.delete(experiment_id)\n }\n } catch (err) {\n console.error('[Signal] Experiment update error:', err)\n }\n })\n \n eventSource.onerror = () => {\n console.warn('[Signal] SSE connection error, reconnecting...')\n eventSource.close()\n // Reconnect after 5 seconds\n setTimeout(connectSSE, 5000)\n }\n \n eventSourceRef.current = eventSource\n }, [apiUrl, apiKey, enabled, realtime])\n\n // ============================================\n // Experiment Assignment\n // ============================================\n \n const loadExperimentAssignment = useCallback(async (experimentId: string): Promise<ExperimentAssignment | null> => {\n // Check localStorage first\n const storageKey = `_signal_exp_${experimentId}`\n const stored = localStorage.getItem(storageKey)\n \n if (stored) {\n try {\n const assignment = JSON.parse(stored) as ExperimentAssignment\n if (assignment.expires > Date.now()) {\n assignmentsRef.current.set(experimentId, assignment)\n return assignment\n }\n } catch {\n // Invalid stored data, continue to fetch\n }\n }\n \n // Fetch from API\n try {\n const response = await fetch(`${apiUrl}/api/public/signal/experiment/${experimentId}`, {\n headers: {\n 'x-api-key': apiKey!,\n 'x-visitor-id': getVisitorId(),\n },\n })\n \n if (!response.ok) return null\n \n const assignment = await response.json() as ExperimentAssignment\n \n // Store assignment\n localStorage.setItem(storageKey, JSON.stringify(assignment))\n assignmentsRef.current.set(experimentId, assignment)\n \n return assignment\n } catch (err) {\n console.error('[Signal] Experiment assignment error:', err)\n return null\n }\n }, [apiUrl, apiKey])\n \n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n return assignmentsRef.current.get(experimentId) || null\n }, [])\n\n // ============================================\n // Event Tracking\n // ============================================\n \n const flushEvents = useCallback(async () => {\n if (eventQueueRef.current.length === 0) return\n \n const events = [...eventQueueRef.current]\n eventQueueRef.current = []\n \n try {\n await fetch(`${apiUrl}/api/public/signal/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey!,\n },\n body: JSON.stringify({\n visitor_id: getVisitorId(),\n session_id: getSessionId(),\n events,\n }),\n })\n } catch (err) {\n // Re-queue failed events\n eventQueueRef.current = [...events, ...eventQueueRef.current]\n console.error('[Signal] Event flush error:', err)\n }\n }, [apiUrl, apiKey])\n \n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (!enabled || !apiKey) return\n \n // Enrich event with context\n const enrichedEvent: Partial<SignalEvent> = {\n ...event,\n page_url: window.location.href,\n page_path: window.location.pathname,\n referrer: document.referrer,\n device_type: getDeviceType(),\n browser: getBrowser(),\n os: getOS(),\n viewport_width: window.innerWidth,\n viewport_height: window.innerHeight,\n time_on_page: Date.now() - pageLoadTimeRef.current,\n scroll_depth: scrollDepthRef.current,\n click_count: clickCountRef.current,\n experiments: Array.from(assignmentsRef.current.values()).map(a => ({\n experiment_id: a.experiment_id,\n variant_key: a.variant_key,\n })),\n timestamp: new Date().toISOString(),\n }\n \n eventQueueRef.current.push(enrichedEvent)\n \n // Debounce flush\n if (flushTimeoutRef.current) {\n clearTimeout(flushTimeoutRef.current)\n }\n flushTimeoutRef.current = setTimeout(flushEvents, 1000)\n }, [enabled, apiKey, flushEvents])\n\n // ============================================\n // Outcome Tracking\n // ============================================\n \n const trackOutcome = useCallback(async (outcome: SignalOutcome) => {\n if (!enabled || !apiKey) return\n \n try {\n await fetch(`${apiUrl}/api/public/signal/outcome`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n ...outcome,\n visitor_id: getVisitorId(),\n session_id: getSessionId(),\n experiments: Array.from(assignmentsRef.current.keys()),\n page_url: window.location.href,\n timestamp: new Date().toISOString(),\n }),\n })\n } catch (err) {\n console.error('[Signal] Outcome tracking error:', err)\n }\n }, [apiUrl, apiKey, enabled])\n\n // ============================================\n // Behavioral Tracking\n // ============================================\n \n useEffect(() => {\n if (!behaviorTracking || typeof window === 'undefined') return\n \n // Track scroll depth\n const handleScroll = () => {\n const scrollTop = window.scrollY\n const docHeight = document.documentElement.scrollHeight - window.innerHeight\n const depth = docHeight > 0 ? Math.round((scrollTop / docHeight) * 100) : 0\n scrollDepthRef.current = Math.max(scrollDepthRef.current, depth)\n }\n \n // Track clicks\n const handleClick = () => {\n clickCountRef.current++\n }\n \n // Reset on page change\n const handlePageChange = () => {\n pageLoadTimeRef.current = Date.now()\n scrollDepthRef.current = 0\n clickCountRef.current = 0\n }\n \n window.addEventListener('scroll', handleScroll, { passive: true })\n window.addEventListener('click', handleClick)\n \n // Flush on visibility change or unload\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'hidden') {\n flushEvents()\n }\n }\n \n document.addEventListener('visibilitychange', handleVisibilityChange)\n window.addEventListener('beforeunload', flushEvents)\n \n return () => {\n window.removeEventListener('scroll', handleScroll)\n window.removeEventListener('click', handleClick)\n document.removeEventListener('visibilitychange', handleVisibilityChange)\n window.removeEventListener('beforeunload', flushEvents)\n }\n }, [behaviorTracking, flushEvents])\n\n // ============================================\n // Initialization\n // ============================================\n \n useEffect(() => {\n fetchConfig()\n }, [fetchConfig])\n \n useEffect(() => {\n if (config && realtime) {\n connectSSE()\n }\n \n return () => {\n if (eventSourceRef.current) {\n eventSourceRef.current.close()\n }\n }\n }, [config, realtime, connectSSE])\n\n // ============================================\n // Context Value\n // ============================================\n \n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig: fetchConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, fetchConfig])\n\n return (\n <SignalContext.Provider value={contextValue}>\n {children}\n </SignalContext.Provider>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n \n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n \n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n","/**\n * @uptrade/site-kit - SiteKitProvider\n * \n * Unified provider component that initializes all enabled modules.\n * \n * IMPORTANT: Client sites ONLY need to provide an API key.\n * - apiKey: Required - identifies project and provides access\n * - apiUrl: Optional - defaults to https://api.uptrademedia.com\n * \n * All API calls go through Portal API with API key auth - never Supabase directly.\n * The API key identifies the project, so no project_id is needed.\n * \n * Example minimal setup:\n * ```tsx\n * <SiteKitProvider\n * apiKey={process.env.NEXT_PUBLIC_UPTRADE_API_KEY}\n * analytics={{ enabled: true }}\n * engage={{ enabled: true }}\n * forms={{ enabled: true }}\n * >\n * ```\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo, useEffect, ReactNode, Suspense } from 'react'\nimport type { SiteKitConfig } from './types'\n\n// Module providers\nimport { AnalyticsProvider } from './analytics/AnalyticsProvider'\nimport { EngageWidget } from './engage/EngageWidget'\nimport { configureFormsApi } from './forms/formsApi'\nimport { SitemapSync } from './seo/SitemapSync'\nimport { SignalBridge } from './signal/SignalBridge'\n\ninterface SignalConfig {\n enabled: boolean\n realtime?: boolean\n experiments?: boolean\n behaviorTracking?: boolean\n}\n\ninterface SiteKitContextValue extends SiteKitConfig {\n isReady: boolean\n signal?: SignalConfig\n signalUrl?: string\n}\n\nconst SiteKitContext = createContext<SiteKitContextValue | null>(null)\n\nexport function useSiteKit(): SiteKitContextValue {\n const context = useContext(SiteKitContext)\n if (!context) {\n throw new Error('useSiteKit must be used within a SiteKitProvider')\n }\n return context\n}\n\ninterface SiteKitProviderProps extends SiteKitConfig {\n children: ReactNode\n signalUrl?: string\n}\n\nexport function SiteKitProvider({\n children,\n apiKey,\n apiUrl,\n signalUrl,\n analytics,\n engage,\n forms,\n signal,\n debug = false,\n}: SiteKitProviderProps & { signal?: SignalConfig }) {\n // Default to production URLs if not specified\n const finalApiUrl = apiUrl || 'https://api.uptrademedia.com'\n const finalSignalUrl = signalUrl || 'https://signal.uptrademedia.com'\n \n // Validate API key\n if (!apiKey) {\n console.error('@uptrade/site-kit: No API key provided. Set NEXT_PUBLIC_UPTRADE_API_KEY environment variable.')\n }\n \n // Set window globals for Portal API access\n useEffect(() => {\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = finalApiUrl\n ;(window as any).__SITE_KIT_SIGNAL_URL__ = finalSignalUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n \n // Configure forms API\n if (apiKey) {\n configureFormsApi({\n baseUrl: finalApiUrl,\n apiKey,\n })\n }\n }, [finalApiUrl, finalSignalUrl, apiKey, debug])\n\n const contextValue = useMemo<SiteKitContextValue>(\n () => ({\n apiUrl: finalApiUrl,\n signalUrl: finalSignalUrl,\n apiKey,\n analytics,\n engage,\n forms,\n signal,\n debug,\n isReady: true,\n }),\n [finalApiUrl, finalSignalUrl, apiKey, analytics, engage, forms, signal, debug]\n )\n\n // Build the provider tree based on enabled modules\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled (must be outermost for context access)\n if (signal?.enabled) {\n content = (\n <SignalBridge\n enabled={signal.enabled}\n realtime={signal.realtime !== false}\n experiments={signal.experiments !== false}\n behaviorTracking={signal.behaviorTracking !== false}\n >\n {content}\n </SignalBridge>\n )\n }\n\n // Wrap with Analytics if enabled\n if (analytics?.enabled) {\n content = (\n <Suspense fallback={null}>\n <AnalyticsProvider\n apiUrl={finalApiUrl}\n apiKey={apiKey}\n trackPageViews={analytics.trackPageViews !== false}\n trackWebVitals={analytics.trackWebVitals !== false}\n trackScrollDepth={analytics.trackScrollDepth !== false}\n trackClicks={analytics.trackClicks !== false}\n debug={debug}\n >\n {content}\n </AnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (doesn't wrap, just renders alongside)\n if (engage?.enabled) {\n content = (\n <>\n {content}\n <EngageWidget \n apiUrl={finalApiUrl} \n apiKey={apiKey}\n position={engage.position || 'bottom-right'}\n chatEnabled={engage.chatEnabled !== false}\n />\n </>\n )\n }\n\n // Always include SitemapSync to keep seo_pages in sync with sitemap.xml\n // This is the canonical source of truth for what pages exist\n content = (\n <>\n {content}\n <SitemapSync debug={debug} />\n </>\n )\n\n return (\n <SiteKitContext.Provider value={contextValue}>\n {content}\n </SiteKitContext.Provider>\n )\n}\n\n/**\n * Hook to check if a specific module is enabled\n */\nexport function useModuleEnabled(module: 'analytics' | 'engage' | 'forms' | 'seo'): boolean {\n const context = useSiteKit()\n \n switch (module) {\n case 'analytics':\n return context.analytics?.enabled ?? false\n case 'engage':\n return context.engage?.enabled ?? false\n case 'forms':\n return context.forms?.enabled ?? false\n case 'seo':\n return true // SEO is always enabled via RSC components\n default:\n return false\n }\n}\n","/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { useSiteKit } from '../SiteKitProvider'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const context = useSiteKit()\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!context?.apiKey || !context?.apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await fetch(\n `${context.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': context.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n console.error('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [context?.apiKey, context?.apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={context}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={context}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/files?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.error('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n }\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.error('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n const res = await fetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n headers: {\n 'x-api-key': config.apiKey,\n },\n body: formData,\n })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.error('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n method: 'DELETE',\n headers: {\n 'x-api-key': config.apiKey,\n },\n }\n )\n onSelect()\n } catch (err) {\n console.error('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await fetch(\n `${config.apiUrl}/public/images?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/files?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n const res = await fetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n headers: {\n 'x-api-key': config.apiKey,\n },\n body: formData,\n })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n method: 'DELETE',\n headers: {\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/seo/routing.ts"],"names":["getRedirectData","getRobotsData","getSitemapEntries"],"mappings":"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","file":"chunk-QQB4FO4Q.js","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 +0,0 @@
1
- {"version":3,"sources":["../src/signal/SignalBridge.tsx","../src/SiteKitProvider.tsx","../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["createContext","useContext","useState","useRef","useCallback","useEffect","useMemo","configureFormsApi","jsx","Fragment","Suspense","AnalyticsProvider","jsxs","EngageWidget","SitemapSync"],"mappings":"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","file":"chunk-TDK7DLCH.js","sourcesContent":["/**\n * @uptrade/site-kit/signal - SignalBridge\n * \n * Central coordination layer for Signal AI integration.\n * Handles config fetching, SSE streaming, experiment assignment, and outcome tracking.\n */\n\n'use client'\n\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef, useMemo } from 'react'\nimport type { \n SignalConfig, \n SignalContextValue, \n SignalBridgeProps,\n SignalEvent,\n SignalOutcome,\n ExperimentAssignment \n} from './types'\n\n// ============================================\n// Context\n// ============================================\n\nconst SignalContext = createContext<SignalContextValue | null>(null)\n\nexport function useSignal(): SignalContextValue {\n const context = useContext(SignalContext)\n if (!context) {\n throw new Error('useSignal must be used within a SignalBridge')\n }\n return context\n}\n\n// ============================================\n// Utility Functions\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 getVisitorId(): string {\n if (typeof window === 'undefined') return ''\n \n const key = '_uptrade_vid'\n let visitorId = localStorage.getItem(key)\n \n if (!visitorId) {\n visitorId = crypto.randomUUID()\n localStorage.setItem(key, visitorId)\n }\n \n return visitorId\n}\n\nfunction getSessionId(): string {\n if (typeof window === 'undefined') return ''\n \n const key = '_uptrade_sid'\n let sessionId = sessionStorage.getItem(key)\n \n if (!sessionId) {\n sessionId = crypto.randomUUID()\n sessionStorage.setItem(key, sessionId)\n }\n \n return sessionId\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\nfunction getBrowser(): string {\n if (typeof window === 'undefined') return 'unknown'\n const ua = navigator.userAgent\n if (ua.includes('Firefox')) return 'Firefox'\n if (ua.includes('Edg')) return 'Edge'\n if (ua.includes('Chrome')) return 'Chrome'\n if (ua.includes('Safari')) return 'Safari'\n return 'Other'\n}\n\nfunction getOS(): string {\n if (typeof window === 'undefined') return 'unknown'\n const ua = navigator.userAgent\n if (ua.includes('Windows')) return 'Windows'\n if (ua.includes('Mac')) return 'macOS'\n if (ua.includes('iPhone') || ua.includes('iPad')) return 'iOS'\n if (ua.includes('Android')) return 'Android'\n if (ua.includes('Linux')) return 'Linux'\n return 'Other'\n}\n\n// ============================================\n// SignalBridge Component\n// ============================================\n\nexport function SignalBridge({\n enabled = true,\n realtime = true,\n experiments = true,\n behaviorTracking = true,\n children,\n}: SignalBridgeProps) {\n const [config, setConfig] = useState<SignalConfig | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n \n // Refs for SSE and tracking\n const eventSourceRef = useRef<EventSource | null>(null)\n const eventQueueRef = useRef<Partial<SignalEvent>[]>([])\n const flushTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n const assignmentsRef = useRef<Map<string, ExperimentAssignment>>(new Map())\n \n // Behavioral tracking state\n const pageLoadTimeRef = useRef<number>(Date.now())\n const scrollDepthRef = useRef<number>(0)\n const clickCountRef = useRef<number>(0)\n \n const { apiUrl, apiKey } = getApiConfig()\n\n // ============================================\n // Config Fetching\n // ============================================\n \n const fetchConfig = useCallback(async () => {\n if (!apiKey || !enabled) {\n setLoading(false)\n return\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/signal/config`, {\n headers: {\n 'x-api-key': apiKey,\n 'x-visitor-id': getVisitorId(),\n },\n })\n \n if (!response.ok) {\n throw new Error(`Failed to fetch Signal config: ${response.statusText}`)\n }\n \n const data = await response.json()\n setConfig(data.config)\n setError(null)\n \n // Load experiment assignments\n if (experiments && data.config?.experiments) {\n for (const exp of data.config.experiments) {\n if (exp.status === 'running') {\n await loadExperimentAssignment(exp.id)\n }\n }\n }\n } catch (err) {\n console.error('[Signal] Config fetch error:', err)\n setError(err as Error)\n } finally {\n setLoading(false)\n }\n }, [apiUrl, apiKey, enabled, experiments])\n\n // ============================================\n // SSE Real-time Updates\n // ============================================\n \n const connectSSE = useCallback(() => {\n if (!apiKey || !enabled || !realtime) return\n \n // Close existing connection\n if (eventSourceRef.current) {\n eventSourceRef.current.close()\n }\n \n const url = `${apiUrl}/api/public/signal/stream?key=${apiKey}`\n const eventSource = new EventSource(url)\n \n eventSource.addEventListener('config_update', (e) => {\n try {\n const { config: newConfig, version } = JSON.parse(e.data)\n setConfig(prev => {\n if (prev?.version !== version) {\n console.log('[Signal] Config updated to version:', version)\n return newConfig\n }\n return prev\n })\n } catch (err) {\n console.error('[Signal] SSE parse error:', err)\n }\n })\n \n eventSource.addEventListener('experiment_update', (e) => {\n try {\n const { experiment_id, action } = JSON.parse(e.data)\n if (action === 'started' || action === 'updated') {\n loadExperimentAssignment(experiment_id)\n } else if (action === 'stopped') {\n assignmentsRef.current.delete(experiment_id)\n }\n } catch (err) {\n console.error('[Signal] Experiment update error:', err)\n }\n })\n \n eventSource.onerror = () => {\n console.warn('[Signal] SSE connection error, reconnecting...')\n eventSource.close()\n // Reconnect after 5 seconds\n setTimeout(connectSSE, 5000)\n }\n \n eventSourceRef.current = eventSource\n }, [apiUrl, apiKey, enabled, realtime])\n\n // ============================================\n // Experiment Assignment\n // ============================================\n \n const loadExperimentAssignment = useCallback(async (experimentId: string): Promise<ExperimentAssignment | null> => {\n // Check localStorage first\n const storageKey = `_signal_exp_${experimentId}`\n const stored = localStorage.getItem(storageKey)\n \n if (stored) {\n try {\n const assignment = JSON.parse(stored) as ExperimentAssignment\n if (assignment.expires > Date.now()) {\n assignmentsRef.current.set(experimentId, assignment)\n return assignment\n }\n } catch {\n // Invalid stored data, continue to fetch\n }\n }\n \n // Fetch from API\n try {\n const response = await fetch(`${apiUrl}/api/public/signal/experiment/${experimentId}`, {\n headers: {\n 'x-api-key': apiKey!,\n 'x-visitor-id': getVisitorId(),\n },\n })\n \n if (!response.ok) return null\n \n const assignment = await response.json() as ExperimentAssignment\n \n // Store assignment\n localStorage.setItem(storageKey, JSON.stringify(assignment))\n assignmentsRef.current.set(experimentId, assignment)\n \n return assignment\n } catch (err) {\n console.error('[Signal] Experiment assignment error:', err)\n return null\n }\n }, [apiUrl, apiKey])\n \n const getExperiment = useCallback((experimentId: string): ExperimentAssignment | null => {\n return assignmentsRef.current.get(experimentId) || null\n }, [])\n\n // ============================================\n // Event Tracking\n // ============================================\n \n const flushEvents = useCallback(async () => {\n if (eventQueueRef.current.length === 0) return\n \n const events = [...eventQueueRef.current]\n eventQueueRef.current = []\n \n try {\n await fetch(`${apiUrl}/api/public/signal/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey!,\n },\n body: JSON.stringify({\n visitor_id: getVisitorId(),\n session_id: getSessionId(),\n events,\n }),\n })\n } catch (err) {\n // Re-queue failed events\n eventQueueRef.current = [...events, ...eventQueueRef.current]\n console.error('[Signal] Event flush error:', err)\n }\n }, [apiUrl, apiKey])\n \n const trackEvent = useCallback((event: Partial<SignalEvent>) => {\n if (!enabled || !apiKey) return\n \n // Enrich event with context\n const enrichedEvent: Partial<SignalEvent> = {\n ...event,\n page_url: window.location.href,\n page_path: window.location.pathname,\n referrer: document.referrer,\n device_type: getDeviceType(),\n browser: getBrowser(),\n os: getOS(),\n viewport_width: window.innerWidth,\n viewport_height: window.innerHeight,\n time_on_page: Date.now() - pageLoadTimeRef.current,\n scroll_depth: scrollDepthRef.current,\n click_count: clickCountRef.current,\n experiments: Array.from(assignmentsRef.current.values()).map(a => ({\n experiment_id: a.experiment_id,\n variant_key: a.variant_key,\n })),\n timestamp: new Date().toISOString(),\n }\n \n eventQueueRef.current.push(enrichedEvent)\n \n // Debounce flush\n if (flushTimeoutRef.current) {\n clearTimeout(flushTimeoutRef.current)\n }\n flushTimeoutRef.current = setTimeout(flushEvents, 1000)\n }, [enabled, apiKey, flushEvents])\n\n // ============================================\n // Outcome Tracking\n // ============================================\n \n const trackOutcome = useCallback(async (outcome: SignalOutcome) => {\n if (!enabled || !apiKey) return\n \n try {\n await fetch(`${apiUrl}/api/public/signal/outcome`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n ...outcome,\n visitor_id: getVisitorId(),\n session_id: getSessionId(),\n experiments: Array.from(assignmentsRef.current.keys()),\n page_url: window.location.href,\n timestamp: new Date().toISOString(),\n }),\n })\n } catch (err) {\n console.error('[Signal] Outcome tracking error:', err)\n }\n }, [apiUrl, apiKey, enabled])\n\n // ============================================\n // Behavioral Tracking\n // ============================================\n \n useEffect(() => {\n if (!behaviorTracking || typeof window === 'undefined') return\n \n // Track scroll depth\n const handleScroll = () => {\n const scrollTop = window.scrollY\n const docHeight = document.documentElement.scrollHeight - window.innerHeight\n const depth = docHeight > 0 ? Math.round((scrollTop / docHeight) * 100) : 0\n scrollDepthRef.current = Math.max(scrollDepthRef.current, depth)\n }\n \n // Track clicks\n const handleClick = () => {\n clickCountRef.current++\n }\n \n // Reset on page change\n const handlePageChange = () => {\n pageLoadTimeRef.current = Date.now()\n scrollDepthRef.current = 0\n clickCountRef.current = 0\n }\n \n window.addEventListener('scroll', handleScroll, { passive: true })\n window.addEventListener('click', handleClick)\n \n // Flush on visibility change or unload\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'hidden') {\n flushEvents()\n }\n }\n \n document.addEventListener('visibilitychange', handleVisibilityChange)\n window.addEventListener('beforeunload', flushEvents)\n \n return () => {\n window.removeEventListener('scroll', handleScroll)\n window.removeEventListener('click', handleClick)\n document.removeEventListener('visibilitychange', handleVisibilityChange)\n window.removeEventListener('beforeunload', flushEvents)\n }\n }, [behaviorTracking, flushEvents])\n\n // ============================================\n // Initialization\n // ============================================\n \n useEffect(() => {\n fetchConfig()\n }, [fetchConfig])\n \n useEffect(() => {\n if (config && realtime) {\n connectSSE()\n }\n \n return () => {\n if (eventSourceRef.current) {\n eventSourceRef.current.close()\n }\n }\n }, [config, realtime, connectSSE])\n\n // ============================================\n // Context Value\n // ============================================\n \n const contextValue = useMemo<SignalContextValue>(() => ({\n config,\n loading,\n error,\n trackEvent,\n trackOutcome,\n getExperiment,\n refreshConfig: fetchConfig,\n }), [config, loading, error, trackEvent, trackOutcome, getExperiment, fetchConfig])\n\n return (\n <SignalContext.Provider value={contextValue}>\n {children}\n </SignalContext.Provider>\n )\n}\n\n// ============================================\n// Convenience Hooks\n// ============================================\n\n/**\n * Hook to access Signal config\n */\nexport function useSignalConfig(): SignalConfig | null {\n const { config } = useSignal()\n return config\n}\n\n/**\n * Hook for tracking events\n */\nexport function useSignalEvent() {\n const { trackEvent } = useSignal()\n return trackEvent\n}\n\n/**\n * Hook for tracking outcomes/conversions\n */\nexport function useSignalOutcome() {\n const { trackOutcome } = useSignal()\n return { trackOutcome }\n}\n\n/**\n * Hook for experiment assignment\n */\nexport function useSignalExperiment(experimentId: string): {\n assignment: ExperimentAssignment | null\n variant: string | null\n isControl: boolean\n} {\n const { getExperiment, config } = useSignal()\n const assignment = getExperiment(experimentId)\n \n // Check if experiment is running\n const experiment = config?.experiments?.find(e => e.id === experimentId)\n const isRunning = experiment?.status === 'running'\n \n return {\n assignment: isRunning ? assignment : null,\n variant: isRunning && assignment ? assignment.variant_key : null,\n isControl: !assignment || assignment.variant_key === 'control',\n }\n}\n","/**\n * @uptrade/site-kit - SiteKitProvider\n * \n * Unified provider component that initializes all enabled modules.\n * \n * IMPORTANT: Client sites ONLY need to provide an API key.\n * - apiKey: Required - identifies project and provides access\n * - apiUrl: Optional - defaults to https://api.uptrademedia.com\n * \n * All API calls go through Portal API with API key auth - never Supabase directly.\n * The API key identifies the project, so no project_id is needed.\n * \n * Example minimal setup:\n * ```tsx\n * <SiteKitProvider\n * apiKey={process.env.NEXT_PUBLIC_UPTRADE_API_KEY}\n * analytics={{ enabled: true }}\n * engage={{ enabled: true }}\n * forms={{ enabled: true }}\n * >\n * ```\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo, useEffect, ReactNode, Suspense } from 'react'\nimport type { SiteKitConfig } from './types'\n\n// Module providers\nimport { AnalyticsProvider } from './analytics/AnalyticsProvider'\nimport { EngageWidget } from './engage/EngageWidget'\nimport { configureFormsApi } from './forms/formsApi'\nimport { SitemapSync } from './seo/SitemapSync'\nimport { SignalBridge } from './signal/SignalBridge'\n\ninterface SignalConfig {\n enabled: boolean\n realtime?: boolean\n experiments?: boolean\n behaviorTracking?: boolean\n}\n\ninterface SiteKitContextValue extends SiteKitConfig {\n isReady: boolean\n signal?: SignalConfig\n signalUrl?: string\n}\n\nconst SiteKitContext = createContext<SiteKitContextValue | null>(null)\n\nexport function useSiteKit(): SiteKitContextValue {\n const context = useContext(SiteKitContext)\n if (!context) {\n throw new Error('useSiteKit must be used within a SiteKitProvider')\n }\n return context\n}\n\ninterface SiteKitProviderProps extends SiteKitConfig {\n children: ReactNode\n signalUrl?: string\n}\n\nexport function SiteKitProvider({\n children,\n apiKey,\n apiUrl,\n signalUrl,\n analytics,\n engage,\n forms,\n signal,\n debug = false,\n}: SiteKitProviderProps & { signal?: SignalConfig }) {\n // Default to production URLs if not specified\n const finalApiUrl = apiUrl || 'https://api.uptrademedia.com'\n const finalSignalUrl = signalUrl || 'https://signal.uptrademedia.com'\n \n // Validate API key\n if (!apiKey) {\n console.error('@uptrade/site-kit: No API key provided. Set NEXT_PUBLIC_UPTRADE_API_KEY environment variable.')\n }\n \n // Set window globals for Portal API access\n useEffect(() => {\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = finalApiUrl\n ;(window as any).__SITE_KIT_SIGNAL_URL__ = finalSignalUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n \n // Configure forms API\n if (apiKey) {\n configureFormsApi({\n baseUrl: finalApiUrl,\n apiKey,\n })\n }\n }, [finalApiUrl, finalSignalUrl, apiKey, debug])\n\n const contextValue = useMemo<SiteKitContextValue>(\n () => ({\n apiUrl: finalApiUrl,\n signalUrl: finalSignalUrl,\n apiKey,\n analytics,\n engage,\n forms,\n signal,\n debug,\n isReady: true,\n }),\n [finalApiUrl, finalSignalUrl, apiKey, analytics, engage, forms, signal, debug]\n )\n\n // Build the provider tree based on enabled modules\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled (must be outermost for context access)\n if (signal?.enabled) {\n content = (\n <SignalBridge\n enabled={signal.enabled}\n realtime={signal.realtime !== false}\n experiments={signal.experiments !== false}\n behaviorTracking={signal.behaviorTracking !== false}\n >\n {content}\n </SignalBridge>\n )\n }\n\n // Wrap with Analytics if enabled\n if (analytics?.enabled) {\n content = (\n <Suspense fallback={null}>\n <AnalyticsProvider\n apiUrl={finalApiUrl}\n apiKey={apiKey}\n trackPageViews={analytics.trackPageViews !== false}\n trackWebVitals={analytics.trackWebVitals !== false}\n trackScrollDepth={analytics.trackScrollDepth !== false}\n trackClicks={analytics.trackClicks !== false}\n debug={debug}\n >\n {content}\n </AnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (doesn't wrap, just renders alongside)\n if (engage?.enabled) {\n content = (\n <>\n {content}\n <EngageWidget \n apiUrl={finalApiUrl} \n apiKey={apiKey}\n position={engage.position || 'bottom-right'}\n chatEnabled={engage.chatEnabled !== false}\n />\n </>\n )\n }\n\n // Always include SitemapSync to keep seo_pages in sync with sitemap.xml\n // This is the canonical source of truth for what pages exist\n content = (\n <>\n {content}\n <SitemapSync debug={debug} />\n </>\n )\n\n return (\n <SiteKitContext.Provider value={contextValue}>\n {content}\n </SiteKitContext.Provider>\n )\n}\n\n/**\n * Hook to check if a specific module is enabled\n */\nexport function useModuleEnabled(module: 'analytics' | 'engage' | 'forms' | 'seo'): boolean {\n const context = useSiteKit()\n \n switch (module) {\n case 'analytics':\n return context.analytics?.enabled ?? false\n case 'engage':\n return context.engage?.enabled ?? false\n case 'forms':\n return context.forms?.enabled ?? false\n case 'seo':\n return true // SEO is always enabled via RSC components\n default:\n return false\n }\n}\n","/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { useSiteKit } from '../SiteKitProvider'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const context = useSiteKit()\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!context?.apiKey || !context?.apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await fetch(\n `${context.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': context.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n console.error('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [context?.apiKey, context?.apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={context}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={context}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/files?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.error('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n }\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.error('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n const res = await fetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n headers: {\n 'x-api-key': config.apiKey,\n },\n body: formData,\n })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.error('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n method: 'DELETE',\n headers: {\n 'x-api-key': config.apiKey,\n },\n }\n )\n onSelect()\n } catch (err) {\n console.error('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await fetch(\n `${config.apiUrl}/public/images?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/files?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n const res = await fetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n headers: {\n 'x-api-key': config.apiKey,\n },\n body: formData,\n })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n method: 'DELETE',\n headers: {\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/seo/api.ts"],"names":["cache"],"mappings":"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","file":"chunk-VDI7KYME.js","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"]}