@sonordev/site-kit 3.3.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-manifest.json +1 -1
- package/dist/AnalyticsProvider-3MZ3O5OB.mjs +8 -0
- package/dist/{AnalyticsProvider-AMHG4DIE.mjs.map → AnalyticsProvider-3MZ3O5OB.mjs.map} +1 -1
- package/dist/AnalyticsProvider-PLGTU56K.js +29 -0
- package/dist/{AnalyticsProvider-26VS3CQR.js.map → AnalyticsProvider-PLGTU56K.js.map} +1 -1
- package/dist/ChatWidget-7JHVRNVE.mjs +8 -0
- package/dist/{ChatWidget-UKPEQEHB.mjs.map → ChatWidget-7JHVRNVE.mjs.map} +1 -1
- package/dist/ChatWidget-FQARJMGU.js +17 -0
- package/dist/{ChatWidget-NIYNSMLU.js.map → ChatWidget-FQARJMGU.js.map} +1 -1
- package/dist/EngageWidget-DQ62NQPU.js +16 -0
- package/dist/{EngageWidget-33QCFWQW.js.map → EngageWidget-DQ62NQPU.js.map} +1 -1
- package/dist/EngageWidget-VXQOZOYA.mjs +7 -0
- package/dist/{EngageWidget-S76ZMDEF.mjs.map → EngageWidget-VXQOZOYA.mjs.map} +1 -1
- package/dist/{SignalCore-2UXXM4FF.js → SignalCore-3SG3LFQL.js} +8 -8
- package/dist/{SignalCore-2UXXM4FF.js.map → SignalCore-3SG3LFQL.js.map} +1 -1
- package/dist/{SignalCore-2AUGAOQT.mjs → SignalCore-BKG66B4C.mjs} +4 -4
- package/dist/{SignalCore-2AUGAOQT.mjs.map → SignalCore-BKG66B4C.mjs.map} +1 -1
- package/dist/SitemapSync-DWX7I6MX.js +16 -0
- package/dist/{SitemapSync-WQJMHJNY.js.map → SitemapSync-DWX7I6MX.js.map} +1 -1
- package/dist/SitemapSync-IO2VOR23.mjs +7 -0
- package/dist/{SitemapSync-RBHXPQAQ.mjs.map → SitemapSync-IO2VOR23.mjs.map} +1 -1
- package/dist/analytics/index.js +11 -11
- package/dist/analytics/index.mjs +4 -4
- package/dist/{chunk-WEHJRE3H.mjs → chunk-25YPXQBA.mjs} +3 -3
- package/dist/{chunk-WEHJRE3H.mjs.map → chunk-25YPXQBA.mjs.map} +1 -1
- package/dist/{chunk-NNPF4KRZ.mjs → chunk-3AG6O3IA.mjs} +3 -3
- package/dist/{chunk-NNPF4KRZ.mjs.map → chunk-3AG6O3IA.mjs.map} +1 -1
- package/dist/{chunk-EL6ZMYD2.js → chunk-3WRE7ZDC.js} +6 -6
- package/dist/{chunk-EL6ZMYD2.js.map → chunk-3WRE7ZDC.js.map} +1 -1
- package/dist/chunk-3X2YPJU5.js +8 -0
- package/dist/{chunk-EOENN46G.js.map → chunk-3X2YPJU5.js.map} +1 -1
- package/dist/{chunk-BOTWTNHW.js → chunk-4JMXBIUC.js} +12 -12
- package/dist/{chunk-BOTWTNHW.js.map → chunk-4JMXBIUC.js.map} +1 -1
- package/dist/{chunk-XOCQANYF.js → chunk-4ROFY6PM.js} +13 -13
- package/dist/{chunk-XOCQANYF.js.map → chunk-4ROFY6PM.js.map} +1 -1
- package/dist/{chunk-PLQ4CUNI.mjs → chunk-7OROUYZH.mjs} +4 -4
- package/dist/{chunk-PLQ4CUNI.mjs.map → chunk-7OROUYZH.mjs.map} +1 -1
- package/dist/{chunk-WAYG3LS2.js → chunk-BOWR5QEV.js} +14 -14
- package/dist/{chunk-WAYG3LS2.js.map → chunk-BOWR5QEV.js.map} +1 -1
- package/dist/{chunk-P3QZRG2Z.js → chunk-C4JAMON3.js} +15 -15
- package/dist/{chunk-P3QZRG2Z.js.map → chunk-C4JAMON3.js.map} +1 -1
- package/dist/{chunk-PUGRSMAV.mjs → chunk-DIXWP4BO.mjs} +3 -3
- package/dist/{chunk-PUGRSMAV.mjs.map → chunk-DIXWP4BO.mjs.map} +1 -1
- package/dist/{chunk-BPKDRTEA.js → chunk-DNW7FTJD.js} +9 -9
- package/dist/{chunk-BPKDRTEA.js.map → chunk-DNW7FTJD.js.map} +1 -1
- package/dist/{chunk-6UK5JIKE.js → chunk-FMQHK6MM.js} +3 -3
- package/dist/{chunk-6UK5JIKE.js.map → chunk-FMQHK6MM.js.map} +1 -1
- package/dist/{chunk-G4FJJK6J.js → chunk-FSYXHIAI.js} +14 -14
- package/dist/{chunk-G4FJJK6J.js.map → chunk-FSYXHIAI.js.map} +1 -1
- package/dist/{chunk-FO6Y27AH.mjs → chunk-GUU3AEFM.mjs} +3 -3
- package/dist/{chunk-FO6Y27AH.mjs.map → chunk-GUU3AEFM.mjs.map} +1 -1
- package/dist/{chunk-5KVT66R6.mjs → chunk-JD6LV6JZ.mjs} +3 -3
- package/dist/{chunk-5KVT66R6.mjs.map → chunk-JD6LV6JZ.mjs.map} +1 -1
- package/dist/chunk-JEOKDUPQ.js +45 -0
- package/dist/chunk-JEOKDUPQ.js.map +1 -0
- package/dist/chunk-K6YGF2KJ.mjs +6 -0
- package/dist/{chunk-S4FJIG6Y.mjs.map → chunk-K6YGF2KJ.mjs.map} +1 -1
- package/dist/{chunk-M2EGCGIT.js → chunk-KPKZBIAQ.js} +7 -7
- package/dist/{chunk-M2EGCGIT.js.map → chunk-KPKZBIAQ.js.map} +1 -1
- package/dist/chunk-LOS5D6B3.js +72 -0
- package/dist/chunk-LOS5D6B3.js.map +1 -0
- package/dist/{chunk-6BDXN4X3.mjs → chunk-MLD3EGM2.mjs} +3 -3
- package/dist/{chunk-6BDXN4X3.mjs.map → chunk-MLD3EGM2.mjs.map} +1 -1
- package/dist/{chunk-AXFM4MFK.mjs → chunk-NQ3K4NWX.mjs} +8 -8
- package/dist/{chunk-AXFM4MFK.mjs.map → chunk-NQ3K4NWX.mjs.map} +1 -1
- package/dist/{chunk-ILLOVVVP.mjs → chunk-OC64AHKN.mjs} +3 -3
- package/dist/{chunk-ILLOVVVP.mjs.map → chunk-OC64AHKN.mjs.map} +1 -1
- package/dist/{chunk-I2M533CW.js → chunk-PCDAVHVX.js} +8 -8
- package/dist/{chunk-I2M533CW.js.map → chunk-PCDAVHVX.js.map} +1 -1
- package/dist/{chunk-QOFC3BYG.js → chunk-PIV54R2O.js} +9 -28
- package/dist/chunk-PIV54R2O.js.map +1 -0
- package/dist/{chunk-ZCZEKWFW.mjs → chunk-QFWBAGBT.mjs} +3 -3
- package/dist/{chunk-ZCZEKWFW.mjs.map → chunk-QFWBAGBT.mjs.map} +1 -1
- package/dist/{chunk-DLJZYWP3.mjs → chunk-QGV7FEUI.mjs} +7 -43
- package/dist/chunk-QGV7FEUI.mjs.map +1 -0
- package/dist/chunk-QJU6HBSK.mjs +39 -0
- package/dist/chunk-QJU6HBSK.mjs.map +1 -0
- package/dist/{chunk-FX3VR4BF.js → chunk-QRIGY6EM.js} +7 -7
- package/dist/{chunk-FX3VR4BF.js.map → chunk-QRIGY6EM.js.map} +1 -1
- package/dist/{chunk-M4HLDK62.mjs → chunk-QW3T6WH2.mjs} +6 -25
- package/dist/chunk-QW3T6WH2.mjs.map +1 -0
- package/dist/{chunk-2RLG4KBJ.mjs → chunk-S2N3NSC7.mjs} +4 -4
- package/dist/{chunk-2RLG4KBJ.mjs.map → chunk-S2N3NSC7.mjs.map} +1 -1
- package/dist/{chunk-EM4DFSC5.js → chunk-TXEOLHMC.js} +4 -4
- package/dist/{chunk-EM4DFSC5.js.map → chunk-TXEOLHMC.js.map} +1 -1
- package/dist/{chunk-Z26CMPBX.js → chunk-VMVEL4WU.js} +7 -43
- package/dist/chunk-VMVEL4WU.js.map +1 -0
- package/dist/chunk-XIJ4F6IE.mjs +63 -0
- package/dist/chunk-XIJ4F6IE.mjs.map +1 -0
- package/dist/{chunk-K2P7KPEQ.js → chunk-YFYMOQAX.js} +10 -10
- package/dist/{chunk-K2P7KPEQ.js.map → chunk-YFYMOQAX.js.map} +1 -1
- package/dist/{chunk-X72PFC4X.mjs → chunk-ZFF3BKNE.mjs} +4 -4
- package/dist/{chunk-X72PFC4X.mjs.map → chunk-ZFF3BKNE.mjs.map} +1 -1
- package/dist/{chunk-SLOZWRWU.mjs → chunk-ZYIONE7A.mjs} +4 -4
- package/dist/{chunk-SLOZWRWU.mjs.map → chunk-ZYIONE7A.mjs.map} +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.mjs +1 -1
- package/dist/commerce/index.js +50 -50
- package/dist/commerce/index.mjs +5 -5
- package/dist/discover-Q5RWC27Y.js +21 -0
- package/dist/discover-Q5RWC27Y.js.map +1 -0
- package/dist/discover-ROPVYJJP.mjs +4 -0
- package/dist/discover-ROPVYJJP.mjs.map +1 -0
- package/dist/engage/index.js +8 -8
- package/dist/engage/index.mjs +5 -5
- package/dist/fleet/index.js +7 -7
- package/dist/fleet/index.mjs +3 -3
- package/dist/forms/index.js +12 -12
- package/dist/forms/index.mjs +4 -4
- package/dist/images/index.js +10 -10
- package/dist/images/index.mjs +3 -3
- package/dist/index.js +63 -63
- package/dist/index.mjs +9 -9
- package/dist/layout/client.js +6 -6
- package/dist/layout/client.mjs +5 -5
- package/dist/layout/index.js +7 -7
- package/dist/layout/index.mjs +5 -5
- package/dist/maps/index.js +4 -4
- package/dist/maps/index.mjs +2 -2
- package/dist/seo/client.js +5 -4
- package/dist/seo/client.mjs +4 -3
- package/dist/seo/index.js +14 -13
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +6 -5
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/register-sitemap-cli.js +64 -96
- package/dist/seo/register-sitemap-cli.js.map +1 -1
- package/dist/seo/register-sitemap-cli.mjs +62 -94
- package/dist/seo/register-sitemap-cli.mjs.map +1 -1
- package/dist/seo/server.js +5 -5
- package/dist/seo/server.mjs +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/index.d.mts +15 -17
- package/dist/sitemap/index.d.ts +15 -17
- package/dist/sitemap/index.js +14 -37
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +11 -34
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/sync/index.js +15 -15
- package/dist/sync/index.mjs +3 -3
- package/package.json +1 -1
- package/dist/AnalyticsProvider-26VS3CQR.js +0 -29
- package/dist/AnalyticsProvider-AMHG4DIE.mjs +0 -8
- package/dist/ChatWidget-NIYNSMLU.js +0 -17
- package/dist/ChatWidget-UKPEQEHB.mjs +0 -8
- package/dist/EngageWidget-33QCFWQW.js +0 -16
- package/dist/EngageWidget-S76ZMDEF.mjs +0 -7
- package/dist/SitemapSync-RBHXPQAQ.mjs +0 -6
- package/dist/SitemapSync-WQJMHJNY.js +0 -15
- package/dist/chunk-DLJZYWP3.mjs.map +0 -1
- package/dist/chunk-EOENN46G.js +0 -8
- package/dist/chunk-M4HLDK62.mjs.map +0 -1
- package/dist/chunk-QOFC3BYG.js.map +0 -1
- package/dist/chunk-S4FJIG6Y.mjs +0 -6
- package/dist/chunk-Z26CMPBX.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/seo/register-sitemap-cli.ts","../../src/brand/extract-brand-profile.ts","../../src/seo/register-sitemap-cli-impl.ts"],"names":["__toESM","require_main","fs","cwd","path","dotenvConfig"],"mappings":"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","file":"register-sitemap-cli.js","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to register sitemap entries at build time\n * \n * Usage:\n * npx sonor-register-sitemap\n * npx sonor-register-sitemap --auto-discover\n * npx sonor-register-sitemap --no-optimize # Skip Signal AI meta optimization\n *\n * Or in package.json:\n * {\n * \"scripts\": {\n * \"postbuild\": \"sonor-register-sitemap --auto-discover\"\n * }\n * }\n */\n\nimport path from 'path'\nimport { config as dotenvConfig } from 'dotenv'\nimport { registerLocalSitemap } from './register-sitemap-cli-impl'\n\n// npm postbuild runs outside Next.js — env from .env* is not loaded automatically\nconst cwd = process.cwd()\ndotenvConfig({ path: path.join(cwd, '.env') })\ndotenvConfig({ path: path.join(cwd, '.env.local'), override: true })\nif (process.env.NODE_ENV === 'production') {\n dotenvConfig({ path: path.join(cwd, '.env.production') })\n dotenvConfig({ path: path.join(cwd, '.env.production.local'), override: true })\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n const autoDiscover = args.includes('--auto-discover') || args.includes('-a')\n const skipOptimize = args.includes('--no-optimize') || args.includes('--skip-optimize')\n \n console.log('[Sonor] Registering sitemap entries...')\n \n try {\n const result = await registerLocalSitemap({\n autoDiscover,\n optimize_meta: !skipOptimize,\n })\n \n if (result.success) {\n console.log(`[Sonor] ✓ Sitemap registered successfully`)\n console.log(`[Sonor] Created: ${result.created}`)\n console.log(`[Sonor] Updated: ${result.updated}`)\n if (result.removed !== undefined && result.removed > 0) {\n console.log(`[Sonor] Removed: ${result.removed}`)\n }\n if (result.meta_optimization?.triggered) {\n console.log(`[Sonor] ✓ Signal AI meta optimization triggered for ${result.meta_optimization.pages_queued} pages`)\n console.log(`[Sonor] (Running in background - check Portal SEO module for results)`)\n }\n process.exit(0)\n } else {\n console.error('[Sonor] ✗ Failed to register sitemap')\n process.exit(1)\n }\n } catch (error) {\n console.error('[Sonor] ✗ Error:', error)\n process.exit(1)\n }\n}\n\nmain()\n","/**\n * Brand Profile Extraction\n *\n * Extracts the visual design DNA from a Next.js project's source files:\n * - globals.css: CSS custom properties (colors, fonts, theme)\n * - tailwind.config.js/ts: extended colors, fontFamily\n * - design-system.ts: explicit color palettes (if present)\n *\n * The extracted profile is pushed to Sonor alongside sitemap registration,\n * giving Signal AI full brand awareness for image generation, blog context,\n * and portfolio design decisions.\n *\n * This is static file analysis (regex, not AST) — runs at build time in Node.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n\nexport interface BrandProfile {\n colors: {\n primary?: string\n secondary?: string\n accent?: string\n background?: string\n surface?: string\n text?: string\n gradient?: string\n }\n typography: {\n heading?: string\n body?: string\n mono?: string\n }\n theme: 'dark' | 'light'\n style_keywords: string[]\n border_radius?: string\n captured_at: string\n}\n\n/**\n * Detect whether a hex color is \"dark\" (luminance < 0.5)\n */\nfunction isDarkColor(hex: string): boolean {\n const c = hex.replace('#', '')\n if (c.length < 6) return false\n const r = parseInt(c.substring(0, 2), 16) / 255\n const g = parseInt(c.substring(2, 4), 16) / 255\n const b = parseInt(c.substring(4, 6), 16) / 255\n // Relative luminance (ITU-R BT.709)\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b\n return luminance < 0.35\n}\n\n/**\n * Extract CSS custom properties from a CSS file's :root block\n */\nfunction extractCssVariables(css: string): Record<string, string> {\n const vars: Record<string, string> = {}\n // Match :root { ... } blocks (may be multiple)\n const rootBlocks = css.match(/:root\\s*\\{[^}]+\\}/g)\n if (!rootBlocks) return vars\n\n for (const block of rootBlocks) {\n const matches = block.matchAll(/--([a-zA-Z0-9_-]+)\\s*:\\s*([^;]+)/g)\n for (const m of matches) {\n const name = m[1].trim()\n const value = m[2].trim()\n // Skip var() references and rgb() values — we want hex/named colors\n if (!value.startsWith('var(')) {\n vars[name] = value\n }\n }\n }\n return vars\n}\n\n/**\n * Try to find the \"primary\" brand color from CSS variables\n */\nfunction findColor(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val && val.startsWith('#')) return val\n }\n return undefined\n}\n\n/**\n * Extract font family from CSS variable or Tailwind config\n */\nfunction extractFontFromCss(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val) {\n // Extract first font name: \"'Inter', system-ui\" -> \"Inter\"\n const match = val.match(/['\"]?([A-Za-z][A-Za-z0-9 _-]+)['\"]?/)\n return match?.[1]?.trim()\n }\n }\n return undefined\n}\n\n/**\n * Extract from Tailwind config — reads as text, uses regex (no require/import)\n */\nfunction extractFromTailwindConfig(configPath: string): {\n colors: Record<string, string>\n fonts: Record<string, string>\n} {\n const colors: Record<string, string> = {}\n const fonts: Record<string, string> = {}\n\n if (!fs.existsSync(configPath)) return { colors, fonts }\n\n const content = fs.readFileSync(configPath, 'utf-8')\n\n // Extract fontFamily entries: fontFamily: { sans: ['var(--font-satoshi)', ...] }\n const fontMatches = content.matchAll(/(?:fontFamily|font-family)\\s*:\\s*\\{([^}]+)\\}/g)\n for (const m of fontMatches) {\n const block = m[1]\n // Match: sans: ['Satoshi', ...] or sans: ['var(--font-satoshi)', ...]\n const entries = block.matchAll(/(\\w+)\\s*:\\s*\\[([^\\]]+)\\]/g)\n for (const e of entries) {\n const key = e[1] // sans, serif, mono\n const values = e[2]\n // Extract first real font name (not var())\n const varMatch = values.match(/var\\(--font-([a-z0-9-]+)\\)/)\n if (varMatch) {\n fonts[key] = varMatch[1].charAt(0).toUpperCase() + varMatch[1].slice(1) // capitalize\n } else {\n const nameMatch = values.match(/['\"]([A-Za-z][A-Za-z0-9 -]+)['\"]/)\n if (nameMatch) fonts[key] = nameMatch[1]\n }\n }\n }\n\n return { colors, fonts }\n}\n\n/**\n * Extract from design-system.ts if it exists\n */\nfunction extractFromDesignSystem(filePath: string): {\n primary?: string\n secondary?: string\n accent?: string\n gradient?: string\n} {\n if (!fs.existsSync(filePath)) return {}\n\n const content = fs.readFileSync(filePath, 'utf-8')\n\n // Look for default/fallback color definitions\n const result: Record<string, string> = {}\n\n // Match: primary: '#54b948'\n const colorMatches = content.matchAll(/(primary|secondary|accent)\\s*:\\s*['\"]([#a-fA-F0-9]+)['\"]/g)\n for (const m of colorMatches) {\n // Take the LAST match (usually the default/fallback)\n result[m[1]] = m[2]\n }\n\n // Match gradient: 'linear-gradient(...)'\n const gradientMatch = content.match(/gradient(?:Css)?\\s*:\\s*['\"]([^'\"]+)['\"]/)\n if (gradientMatch) {\n result.gradient = gradientMatch[1]\n }\n\n return result\n}\n\n/**\n * Infer style keywords from the extracted data\n */\nfunction inferStyleKeywords(\n theme: 'dark' | 'light',\n vars: Record<string, string>,\n tailwindContent?: string,\n): string[] {\n const keywords: string[] = []\n\n keywords.push(theme === 'dark' ? 'dark' : 'light')\n keywords.push('modern')\n\n // Check for specific patterns\n if (tailwindContent) {\n if (tailwindContent.includes('backdrop-blur') || tailwindContent.includes('glass')) keywords.push('glass')\n if (tailwindContent.includes('gradient')) keywords.push('gradient')\n if (tailwindContent.includes('rounded-full') || tailwindContent.includes('rounded-3xl')) keywords.push('rounded')\n if (tailwindContent.includes('animate-') || tailwindContent.includes('framer-motion')) keywords.push('animated')\n }\n\n // Check font styles\n const allVars = Object.values(vars).join(' ').toLowerCase()\n if (allVars.includes('mono') || allVars.includes('code') || allVars.includes('jetbrains')) keywords.push('tech')\n if (allVars.includes('serif') || allVars.includes('georgia') || allVars.includes('playfair')) keywords.push('editorial')\n\n return [...new Set(keywords)]\n}\n\n/**\n * Main extraction function — scans the project directory\n */\nexport function extractBrandProfile(projectDir?: string): BrandProfile | null {\n const cwd = projectDir || process.cwd()\n\n // Find globals.css\n const globalsLocations = [\n path.join(cwd, 'app', 'globals.css'),\n path.join(cwd, 'src', 'app', 'globals.css'),\n path.join(cwd, 'styles', 'globals.css'),\n ]\n\n let cssVars: Record<string, string> = {}\n let globalsCss = ''\n for (const loc of globalsLocations) {\n if (fs.existsSync(loc)) {\n globalsCss = fs.readFileSync(loc, 'utf-8')\n cssVars = extractCssVariables(globalsCss)\n break\n }\n }\n\n // Find tailwind config\n const tailwindLocations = [\n path.join(cwd, 'tailwind.config.js'),\n path.join(cwd, 'tailwind.config.ts'),\n path.join(cwd, 'tailwind.config.mjs'),\n ]\n\n let tailwindResult = { colors: {} as Record<string, string>, fonts: {} as Record<string, string> }\n let tailwindContent = ''\n for (const loc of tailwindLocations) {\n if (fs.existsSync(loc)) {\n tailwindContent = fs.readFileSync(loc, 'utf-8')\n tailwindResult = extractFromTailwindConfig(loc)\n break\n }\n }\n\n // Find design-system.ts\n const designSystemLocations = [\n path.join(cwd, 'design-system.ts'),\n path.join(cwd, 'src', 'design-system.ts'),\n path.join(cwd, 'lib', 'design-system.ts'),\n ]\n\n let designSystem: ReturnType<typeof extractFromDesignSystem> = {}\n for (const loc of designSystemLocations) {\n if (fs.existsSync(loc)) {\n designSystem = extractFromDesignSystem(loc)\n break\n }\n }\n\n // If we found nothing at all, skip\n if (Object.keys(cssVars).length === 0 && !tailwindContent && Object.keys(designSystem).length === 0) {\n return null\n }\n\n // === Build the profile ===\n\n // Colors — priority: CSS vars > design-system > tailwind\n const primary = findColor(cssVars,\n 'color-accent', 'sk-primary', 'color-primary', 'color-brand', 'brand-primary',\n ) || designSystem.primary\n\n const secondary = findColor(cssVars,\n 'color-accent-dark', 'sk-secondary', 'color-secondary',\n ) || designSystem.secondary\n\n const accent = findColor(cssVars,\n 'color-accent-light', 'sk-accent', 'color-accent-light',\n ) || designSystem.accent\n\n const background = findColor(cssVars,\n 'color-charcoal', 'sk-bg', 'color-bg', 'color-background',\n 'background', 'bg',\n )\n\n const surface = findColor(cssVars,\n 'color-charcoal-light', 'sk-surface', 'color-surface', 'sk-bg-elevated',\n )\n\n const textColor = findColor(cssVars,\n 'sk-text-primary', 'color-text', 'color-text-primary',\n )\n\n const gradient = designSystem.gradient || undefined\n\n // Typography — priority: tailwind fontFamily > CSS vars\n const headingFont = tailwindResult.fonts.sans || tailwindResult.fonts.heading ||\n extractFontFromCss(cssVars, 'font-heading', 'font-display', 'font-sans')\n const bodyFont = tailwindResult.fonts.sans || tailwindResult.fonts.body ||\n extractFontFromCss(cssVars, 'font-body', 'font-sans')\n const monoFont = tailwindResult.fonts.mono ||\n extractFontFromCss(cssVars, 'font-mono', 'font-code')\n\n // Theme detection — check if background is dark\n const theme: 'dark' | 'light' = (background && isDarkColor(background)) ? 'dark' :\n globalsCss.includes('.dark') || globalsCss.includes('dark:') ? 'dark' : 'light'\n\n // Style keywords\n const styleKeywords = inferStyleKeywords(theme, cssVars, tailwindContent + globalsCss)\n\n // Border radius — look for common patterns\n const radiusMatch = globalsCss.match(/border-radius\\s*:\\s*([^;]+)/) ||\n tailwindContent.match(/borderRadius\\s*:\\s*\\{[^}]*DEFAULT\\s*:\\s*['\"]([^'\"]+)['\"]/)\n const borderRadius = radiusMatch?.[1]?.trim()\n\n const profile: BrandProfile = {\n colors: {\n ...(primary && { primary }),\n ...(secondary && { secondary }),\n ...(accent && { accent }),\n ...(background && { background }),\n ...(surface && { surface }),\n ...(textColor && { text: textColor }),\n ...(gradient && { gradient }),\n },\n typography: {\n ...(headingFont && { heading: headingFont }),\n ...(bodyFont && { body: bodyFont }),\n ...(monoFont && { mono: monoFont }),\n },\n theme,\n style_keywords: styleKeywords,\n ...(borderRadius && { border_radius: borderRadius }),\n captured_at: new Date().toISOString(),\n }\n\n // Only return if we got meaningful data\n const hasColors = Object.keys(profile.colors).length > 0\n const hasTypography = Object.keys(profile.typography).length > 0\n\n if (!hasColors && !hasTypography) return null\n\n return profile\n}\n\n/**\n * Push brand profile to Sonor API\n */\nexport async function pushBrandProfile(profile: BrandProfile): Promise<boolean> {\n const apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = process.env.SONOR_API_KEY || ''\n\n if (!apiKey) {\n console.warn('[Sonor] No API key — skipping brand profile push')\n return false\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/seo/brand-profile`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(profile),\n })\n\n if (!response.ok) {\n console.warn(`[Sonor] Brand profile push failed: ${response.status}`)\n return false\n }\n\n const result = await response.json()\n console.log(`[Sonor] Brand profile pushed: theme=${profile.theme}, ${Object.keys(profile.colors).length} colors`)\n return result.success\n } catch (err) {\n console.warn(`[Sonor] Brand profile push error: ${err}`)\n return false\n }\n}\n","/**\n * Standalone implementation for uptrade-register-sitemap CLI.\n * Does NOT import from server-api or routing, so it can run in Node without\n * pulling in server-only (which throws when required outside Next.js server context).\n */\n\nimport fs from 'fs'\nimport path from 'path'\nimport { extractBrandProfile, pushBrandProfile } from '../brand/extract-brand-profile'\n\n/**\n * Infer page type from URL path pattern for Signal context.\n */\nfunction inferPageTypeFromPath(urlPath: string): string {\n if (urlPath === '/' || urlPath === '') return 'homepage'\n if (/^\\/services(\\/|$)/i.test(urlPath)) return 'service'\n if (/^\\/compare(\\/|$)/i.test(urlPath)) return 'comparison'\n if (/^\\/(insights|blog)(\\/|$)/i.test(urlPath)) return 'blog'\n if (/^\\/industries(\\/|$)/i.test(urlPath)) return 'industry'\n if (/^\\/work(\\/|$)/i.test(urlPath)) return 'portfolio'\n if (/^\\/faq(\\/|$)/i.test(urlPath)) return 'faq'\n if (/^\\/pricing(\\/|$)/i.test(urlPath)) return 'pricing'\n return 'page'\n}\n\nfunction getApiConfig(): { apiUrl: string; apiKey: string } {\n const apiUrl =\n process.env.SONOR_API_URL ||\n 'https://api.sonor.io'\n const apiKey =\n process.env.SONOR_API_KEY ||\n ''\n return { apiUrl, apiKey }\n}\n\nfunction discoverNextJsRoutes(\n appDir: string,\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 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 const hasPage =\n 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 const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\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 if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(\n itemPath,\n isRouteGroup ? basePath : routePath\n )\n entries.push(...subEntries)\n }\n }\n }\n\n if (basePath === '') {\n const hasRootPage =\n 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\nasync function registerSitemapViaApi(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: string\n description?: string\n pageType?: string\n }>,\n optimizeMeta: boolean\n): Promise<{\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: { triggered: boolean; pages_queued: number } | null\n}> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n console.warn(\n '[Sonor] No API key (SONOR_API_KEY)',\n )\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, optimize_meta: optimizeMeta, mode: 'full-replace' }),\n })\n\n if (!response.ok) {\n console.error(`[Sonor] Sitemap registration failed: ${response.status} ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n\n return await response.json()\n } catch (error) {\n console.error('[Sonor] Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\nexport type RegisterLocalSitemapOptions = {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n description?: string\n pageType?: string\n }>\n autoDiscover?: boolean\n optimize_meta?: boolean\n}\n\nexport type RegisterLocalSitemapResult = {\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: {\n triggered: boolean\n pages_queued: number\n } | null\n}\n\nexport async function registerLocalSitemap(\n options: RegisterLocalSitemapOptions\n): Promise<RegisterLocalSitemapResult> {\n let entries = options.entries || []\n\n if (options.autoDiscover && entries.length === 0) {\n const cwd = process.cwd()\n const appDirs = [\n path.join(cwd, 'app'),\n path.join(cwd, 'src', 'app'),\n ]\n for (const appDir of appDirs) {\n if (fs.existsSync(appDir)) {\n entries = discoverNextJsRoutes(appDir)\n console.log(`[Sonor] Auto-discovered ${entries.length} routes from ${path.relative(cwd, appDir)}`)\n break\n }\n }\n }\n\n if (entries.length === 0) {\n console.warn('[Sonor] No sitemap entries to register')\n return { success: true, created: 0, updated: 0 }\n }\n\n console.log(`[Sonor] Registering ${entries.length} sitemap entries...`)\n const payload = entries.map((e) => ({\n path: e.path,\n title: e.title,\n priority: e.priority,\n changefreq: e.changefreq,\n ...(e.description ? { description: e.description } : {}),\n pageType: e.pageType ?? inferPageTypeFromPath(e.path),\n }))\n const result = await registerSitemapViaApi(\n payload,\n options.optimize_meta !== false\n )\n\n if (result.success) {\n console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n\n // Push brand profile alongside sitemap (fire-and-forget, non-blocking)\n try {\n const brandProfile = extractBrandProfile()\n if (brandProfile) {\n await pushBrandProfile(brandProfile)\n }\n } catch (brandErr) {\n // Non-fatal — brand profile is supplementary\n console.debug(`[Sonor] Brand profile extraction skipped: ${brandErr}`)\n }\n }\n\n return result\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/seo/register-sitemap-cli.ts","../../src/brand/extract-brand-profile.ts","../../src/seo/register-sitemap-cli-impl.ts"],"names":["__toESM","require_main","fs","cwd","path","findSitemapRoute","findAppDirForDiscovery","discoverNextJsRoutes","inferPageType","dotenvConfig"],"mappings":";;;;;;;;;;;;;;;;AA0BA,IAAA,aAAA,GAAuCA,wBAAA,CAAAC,6BAAA,EAAA,CAAA;ACgBvC,SAAS,YAAY,GAAA,EAAsB;AACzC,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC7B,EAAA,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,EAAG,OAAO,KAAA;AACzB,EAAA,MAAM,CAAA,GAAI,SAAS,CAAA,CAAE,SAAA,CAAU,GAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA;AAC5C,EAAA,MAAM,CAAA,GAAI,SAAS,CAAA,CAAE,SAAA,CAAU,GAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA;AAC5C,EAAA,MAAM,CAAA,GAAI,SAAS,CAAA,CAAE,SAAA,CAAU,GAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA;AAE5C,EAAA,MAAM,SAAA,GAAY,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,IAAI,MAAA,GAAS,CAAA;AACrD,EAAA,OAAO,SAAA,GAAY,IAAA;AACrB;AAKA,SAAS,oBAAoB,GAAA,EAAqC;AAChE,EAAA,MAAM,OAA+B,EAAC;AAEtC,EAAA,MAAM,UAAA,GAAa,GAAA,CAAI,KAAA,CAAM,oBAAoB,CAAA;AACjD,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,KAAA,MAAW,SAAS,UAAA,EAAY;AAC9B,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,QAAA,CAAS,mCAAmC,CAAA;AAClE,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,CAAE,IAAA,EAAK;AACvB,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,IAAA,EAAK;AAExB,MAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AAC7B,QAAA,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAKA,SAAS,SAAA,CAAU,SAAiC,IAAA,EAAoC;AACtF,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,GAAA,GAAM,KAAK,GAAG,CAAA;AACpB,IAAA,IAAI,GAAA,IAAO,GAAA,CAAI,UAAA,CAAW,GAAG,GAAG,OAAO,GAAA;AAAA,EACzC;AACA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,kBAAA,CAAmB,SAAiC,IAAA,EAAoC;AAC/F,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,GAAA,GAAM,KAAK,GAAG,CAAA;AACpB,IAAA,IAAI,GAAA,EAAK;AAEP,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,qCAAqC,CAAA;AAC7D,MAAA,OAAO,KAAA,GAAQ,CAAC,CAAA,EAAG,IAAA,EAAK;AAAA,IAC1B;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,0BAA0B,UAAA,EAGjC;AACA,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,MAAM,QAAgC,EAAC;AAEvC,EAAA,IAAI,CAACC,oBAAG,UAAA,CAAW,UAAU,GAAG,OAAO,EAAE,QAAQ,KAAA,EAAM;AAEvD,EAAA,MAAM,OAAA,GAAUA,mBAAA,CAAG,YAAA,CAAa,UAAA,EAAY,OAAO,CAAA;AAGnD,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,QAAA,CAAS,+CAA+C,CAAA;AACpF,EAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,IAAA,MAAM,KAAA,GAAQ,EAAE,CAAC,CAAA;AAEjB,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,QAAA,CAAS,2BAA2B,CAAA;AAC1D,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,MAAM,GAAA,GAAM,EAAE,CAAC,CAAA;AACf,MAAA,MAAM,MAAA,GAAS,EAAE,CAAC,CAAA;AAElB,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,KAAA,CAAM,4BAA4B,CAAA;AAC1D,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,KAAA,CAAM,GAAG,CAAA,GAAI,QAAA,CAAS,CAAC,EAAE,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,QAAA,CAAS,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,MACxE,CAAA,MAAO;AACL,QAAA,MAAM,SAAA,GAAY,MAAA,CAAO,KAAA,CAAM,kCAAkC,CAAA;AACjE,QAAA,IAAI,SAAA,EAAW,KAAA,CAAM,GAAG,CAAA,GAAI,UAAU,CAAC,CAAA;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,QAAQ,KAAA,EAAM;AACzB;AAKA,SAAS,wBAAwB,QAAA,EAK/B;AACA,EAAA,IAAI,CAACA,mBAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,SAAU,EAAC;AAEtC,EAAA,MAAM,OAAA,GAAUA,mBAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAGjD,EAAA,MAAM,SAAiC,EAAC;AAGxC,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,QAAA,CAAS,2DAA2D,CAAA;AACjG,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAE5B,IAAA,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,EAAE,CAAC,CAAA;AAAA,EACpB;AAGA,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,KAAA,CAAM,yCAAyC,CAAA;AAC7E,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAA,CAAO,QAAA,GAAW,cAAc,CAAC,CAAA;AAAA,EACnC;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,kBAAA,CACP,KAAA,EACA,IAAA,EACA,eAAA,EACU;AACV,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,QAAA,CAAS,IAAA,CAAK,KAAA,KAAU,MAAA,GAAS,MAAA,GAAS,OAAO,CAAA;AACjD,EAAA,QAAA,CAAS,KAAK,QAAQ,CAAA;AAGtB,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,IAAI,eAAA,CAAgB,QAAA,CAAS,eAAe,CAAA,IAAK,eAAA,CAAgB,SAAS,OAAO,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,OAAO,CAAA;AACzG,IAAA,IAAI,gBAAgB,QAAA,CAAS,UAAU,CAAA,EAAG,QAAA,CAAS,KAAK,UAAU,CAAA;AAClE,IAAA,IAAI,eAAA,CAAgB,QAAA,CAAS,cAAc,CAAA,IAAK,eAAA,CAAgB,SAAS,aAAa,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,SAAS,CAAA;AAChH,IAAA,IAAI,eAAA,CAAgB,QAAA,CAAS,UAAU,CAAA,IAAK,eAAA,CAAgB,SAAS,eAAe,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,UAAU,CAAA;AAAA,EACjH;AAGA,EAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,IAAI,EAAE,IAAA,CAAK,GAAG,EAAE,WAAA,EAAY;AAC1D,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,IAAK,QAAQ,QAAA,CAAS,MAAM,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,EAAG,QAAA,CAAS,KAAK,MAAM,CAAA;AAC/G,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAA,IAAK,QAAQ,QAAA,CAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,UAAU,CAAA,EAAG,QAAA,CAAS,KAAK,WAAW,CAAA;AAEvH,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,QAAQ,CAAC,CAAA;AAC9B;AAKO,SAAS,oBAAoB,UAAA,EAA0C;AAC5E,EAAA,MAAMC,IAAAA,GAAoB,OAAA,CAAQ,GAAA,EAAI;AAGtC,EAAA,MAAM,gBAAA,GAAmB;AAAA,IACvBC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,KAAA,EAAO,aAAa,CAAA;AAAA,IACnCC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,KAAA,EAAO,OAAO,aAAa,CAAA;AAAA,IAC1CC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,QAAA,EAAU,aAAa;AAAA,GACxC;AAEA,EAAA,IAAI,UAAkC,EAAC;AACvC,EAAA,IAAI,UAAA,GAAa,EAAA;AACjB,EAAA,KAAA,MAAW,OAAO,gBAAA,EAAkB;AAClC,IAAA,IAAID,mBAAA,CAAG,UAAA,CAAW,GAAG,CAAA,EAAG;AACtB,MAAA,UAAA,GAAaA,mBAAA,CAAG,YAAA,CAAa,GAAA,EAAK,OAAO,CAAA;AACzC,MAAA,OAAA,GAAU,oBAAoB,UAAU,CAAA;AACxC,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,iBAAA,GAAoB;AAAA,IACxBE,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,oBAAoB,CAAA;AAAA,IACnCC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,oBAAoB,CAAA;AAAA,IACnCC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,qBAAqB;AAAA,GACtC;AAEA,EAAA,IAAI,iBAAiB,EAAwC,KAAA,EAAO,EAAC,EAA4B;AACjG,EAAA,IAAI,eAAA,GAAkB,EAAA;AACtB,EAAA,KAAA,MAAW,OAAO,iBAAA,EAAmB;AACnC,IAAA,IAAID,mBAAA,CAAG,UAAA,CAAW,GAAG,CAAA,EAAG;AACtB,MAAA,eAAA,GAAkBA,mBAAA,CAAG,YAAA,CAAa,GAAA,EAAK,OAAO,CAAA;AAC9C,MAAA,cAAA,GAAiB,0BAA0B,GAAG,CAAA;AAC9C,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,qBAAA,GAAwB;AAAA,IAC5BE,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,kBAAkB,CAAA;AAAA,IACjCC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,KAAA,EAAO,kBAAkB,CAAA;AAAA,IACxCC,qBAAA,CAAK,IAAA,CAAKD,IAAAA,EAAK,KAAA,EAAO,kBAAkB;AAAA,GAC1C;AAEA,EAAA,IAAI,eAA2D,EAAC;AAChE,EAAA,KAAA,MAAW,OAAO,qBAAA,EAAuB;AACvC,IAAA,IAAID,mBAAA,CAAG,UAAA,CAAW,GAAG,CAAA,EAAG;AACtB,MAAA,YAAA,GAAe,wBAAwB,GAAG,CAAA;AAC1C,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,CAAE,MAAA,KAAW,CAAA,IAAK,CAAC,eAAA,IAAmB,MAAA,CAAO,IAAA,CAAK,YAAY,CAAA,CAAE,WAAW,CAAA,EAAG;AACnG,IAAA,OAAO,IAAA;AAAA,EACT;AAKA,EAAA,MAAM,OAAA,GAAU,SAAA;AAAA,IAAU,OAAA;AAAA,IACxB,cAAA;AAAA,IAAgB,YAAA;AAAA,IAAc,eAAA;AAAA,IAAiB,aAAA;AAAA,IAAe;AAAA,OAC3D,YAAA,CAAa,OAAA;AAElB,EAAA,MAAM,SAAA,GAAY,SAAA;AAAA,IAAU,OAAA;AAAA,IAC1B,mBAAA;AAAA,IAAqB,cAAA;AAAA,IAAgB;AAAA,OAClC,YAAA,CAAa,SAAA;AAElB,EAAA,MAAM,MAAA,GAAS,SAAA;AAAA,IAAU,OAAA;AAAA,IACvB,oBAAA;AAAA,IAAsB,WAAA;AAAA,IAAa;AAAA,OAChC,YAAA,CAAa,MAAA;AAElB,EAAA,MAAM,UAAA,GAAa,SAAA;AAAA,IAAU,OAAA;AAAA,IAC3B,gBAAA;AAAA,IAAkB,OAAA;AAAA,IAAS,UAAA;AAAA,IAAY,kBAAA;AAAA,IACvC,YAAA;AAAA,IAAc;AAAA,GAChB;AAEA,EAAA,MAAM,OAAA,GAAU,SAAA;AAAA,IAAU,OAAA;AAAA,IACxB,sBAAA;AAAA,IAAwB,YAAA;AAAA,IAAc,eAAA;AAAA,IAAiB;AAAA,GACzD;AAEA,EAAA,MAAM,SAAA,GAAY,SAAA;AAAA,IAAU,OAAA;AAAA,IAC1B,iBAAA;AAAA,IAAmB,YAAA;AAAA,IAAc;AAAA,GACnC;AAEA,EAAA,MAAM,QAAA,GAAW,aAAa,QAAA,IAAY,MAAA;AAG1C,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,KAAA,CAAM,IAAA,IAAQ,cAAA,CAAe,KAAA,CAAM,OAAA,IACpE,kBAAA,CAAmB,OAAA,EAAS,cAAA,EAAgB,cAAA,EAAgB,WAAW,CAAA;AACzE,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,KAAA,CAAM,IAAA,IAAQ,cAAA,CAAe,MAAM,IAAA,IACjE,kBAAA,CAAmB,OAAA,EAAS,WAAA,EAAa,WAAW,CAAA;AACtD,EAAA,MAAM,WAAW,cAAA,CAAe,KAAA,CAAM,QACpC,kBAAA,CAAmB,OAAA,EAAS,aAAa,WAAW,CAAA;AAGtD,EAAA,MAAM,KAAA,GAA2B,UAAA,IAAc,WAAA,CAAY,UAAU,IAAK,MAAA,GACxE,UAAA,CAAW,QAAA,CAAS,OAAO,CAAA,IAAK,UAAA,CAAW,QAAA,CAAS,OAAO,IAAI,MAAA,GAAS,OAAA;AAG1E,EAAA,MAAM,aAAA,GAAgB,kBAAA,CAAmB,KAAA,EAAO,OAAA,EAAS,kBAAkB,UAAU,CAAA;AAGrF,EAAA,MAAM,cAAc,UAAA,CAAW,KAAA,CAAM,6BAA6B,CAAA,IAChE,eAAA,CAAgB,MAAM,0DAA0D,CAAA;AAClF,EAAA,MAAM,YAAA,GAAe,WAAA,GAAc,CAAC,CAAA,EAAG,IAAA,EAAK;AAE5C,EAAA,MAAM,OAAA,GAAwB;AAAA,IAC5B,MAAA,EAAQ;AAAA,MACN,GAAI,OAAA,IAAW,EAAE,OAAA,EAAQ;AAAA,MACzB,GAAI,SAAA,IAAa,EAAE,SAAA,EAAU;AAAA,MAC7B,GAAI,MAAA,IAAU,EAAE,MAAA,EAAO;AAAA,MACvB,GAAI,UAAA,IAAc,EAAE,UAAA,EAAW;AAAA,MAC/B,GAAI,OAAA,IAAW,EAAE,OAAA,EAAQ;AAAA,MACzB,GAAI,SAAA,IAAa,EAAE,IAAA,EAAM,SAAA,EAAU;AAAA,MACnC,GAAI,QAAA,IAAY,EAAE,QAAA;AAAS,KAC7B;AAAA,IACA,UAAA,EAAY;AAAA,MACV,GAAI,WAAA,IAAe,EAAE,OAAA,EAAS,WAAA,EAAY;AAAA,MAC1C,GAAI,QAAA,IAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,MACjC,GAAI,QAAA,IAAY,EAAE,IAAA,EAAM,QAAA;AAAS,KACnC;AAAA,IACA,KAAA;AAAA,IACA,cAAA,EAAgB,aAAA;AAAA,IAChB,GAAI,YAAA,IAAgB,EAAE,aAAA,EAAe,YAAA,EAAa;AAAA,IAClD,WAAA,EAAA,iBAAa,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GACtC;AAGA,EAAA,MAAM,YAAY,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,MAAM,EAAE,MAAA,GAAS,CAAA;AACvD,EAAA,MAAM,gBAAgB,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,UAAU,EAAE,MAAA,GAAS,CAAA;AAE/D,EAAA,IAAI,CAAC,SAAA,IAAa,CAAC,aAAA,EAAe,OAAO,IAAA;AAEzC,EAAA,OAAO,OAAA;AACT;AAKA,eAAsB,iBAAiB,OAAA,EAAyC;AAC9E,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,aAAA,IAAiB,sBAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,aAAA,IAAiB,EAAA;AAE5C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAA,CAAQ,KAAK,uDAAkD,CAAA;AAC/D,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,6BAAA,CAAA,EAAiC;AAAA,MACrE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,OAAO;AAAA,KAC7B,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,mCAAA,EAAsC,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AACpE,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,oCAAA,EAAuC,OAAA,CAAQ,KAAK,CAAA,EAAA,EAAK,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAM,CAAA,OAAA,CAAS,CAAA;AAChH,IAAA,OAAO,MAAA,CAAO,OAAA;AAAA,EAChB,SAAS,GAAA,EAAK;AACZ,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kCAAA,EAAqC,GAAG,CAAA,CAAE,CAAA;AACvD,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;ACnWA,SAAS,YAAA,GAAmD;AAC1D,EAAA,MAAM,MAAA,GACJ,OAAA,CAAQ,GAAA,CAAI,aAAA,IACZ,sBAAA;AACF,EAAA,MAAM,MAAA,GACJ,OAAA,CAAQ,GAAA,CAAI,aAAA,IACZ,EAAA;AACF,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEA,eAAe,qBAAA,CACb,OAAA,EAQA,YAAA,EACA,IAAA,EAOC;AACD,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,YAAA,EAAa;AACxC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,EAClD;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,gCAAA,CAAA,EAAoC;AAAA,MACxE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU,EAAE,SAAS,aAAA,EAAe,YAAA,EAAc,MAAM;AAAA,KACpE,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,MAAM,CAAA,qCAAA,EAAwC,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAC9F,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,IAClD;AAEA,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,KAAK,CAAA;AAC1D,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,EAClD;AACF;AAqCA,eAAsB,qBACpB,OAAA,EACqC;AACrC,EAAA,IAAI,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,EAAC;AAClC,EAAA,MAAM,oBAAoB,CAAC,CAAC,OAAA,CAAQ,YAAA,IAAgB,QAAQ,MAAA,KAAW,CAAA;AAEvE,EAAA,IAAI,MAAA;AASJ,EAAA,MAAM,YAAA,GAAe,iBAAA,GAAoBG,iCAAA,EAAiB,GAAI,IAAA;AAE9D,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,qCAAqC,YAAY,CAAA,6RAAA;AAAA,KAKnD;AACA,IAAA,MAAA,GAAS,EAAE,SAAS,IAAA,EAAM,OAAA,EAAS,GAAG,OAAA,EAAS,CAAA,EAAG,SAAS,IAAA,EAAK;AAAA,EAClE,CAAA,MAAO;AACL,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,MAAM,SAASC,uCAAA,EAAuB;AACtC,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAA,GAAUC,sCAAqB,MAAM,CAAA;AACrC,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,wBAAA,EAA2B,OAAA,CAAQ,MAAM,CAAA,aAAA,EAAgBH,qBAAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,GAAA,EAAI,EAAG,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,MAC7G;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,OAAA,CAAQ,KAAK,wCAAwC,CAAA;AACrD,MAAA,MAAA,GAAS,EAAE,OAAA,EAAS,IAAA,EAAM,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,IACnD,CAAA,MAAO;AAIL,MAAA,MAAM,IAAA,GACJ,OAAA,CAAQ,IAAA,KAAS,iBAAA,GAAoB,UAAA,GAAa,cAAA,CAAA;AAEpD,MAAA,OAAA,CAAQ,IAAI,CAAA,oBAAA,EAAuB,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,IAAI,CAAA,IAAA,CAAM,CAAA;AACtF,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QAClC,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,YAAY,CAAA,CAAE,UAAA;AAAA,QACd,GAAI,EAAE,WAAA,GAAc,EAAE,aAAa,CAAA,CAAE,WAAA,KAAgB,EAAC;AAAA,QACtD,QAAA,EAAU,CAAA,CAAE,QAAA,IAAYI,8BAAA,CAAc,EAAE,IAAI;AAAA,OAC9C,CAAE,CAAA;AACF,MAAA,MAAA,GAAS,MAAM,qBAAA;AAAA,QACb,OAAA;AAAA,QACA,QAAQ,aAAA,KAAkB,KAAA;AAAA,QAC1B;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAA,CAAQ,IAAI,CAAA,4BAAA,EAA+B,MAAA,CAAO,OAAO,CAAA,MAAA,EAAS,MAAA,CAAO,OAAO,CAAA,QAAA,CAAU,CAAA;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AAQA,EAAA,MAAM,iBAAA,GAAoB,MAAA,CAAO,OAAA,KAAY,IAAA,IAAQ,QAAQ,MAAA,GAAS,CAAA;AACtE,EAAA,IAAI,MAAA,CAAO,WAAW,iBAAA,EAAmB;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,eAAe,mBAAA,EAAoB;AACzC,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAM,iBAAiB,YAAY,CAAA;AAAA,MACrC;AAAA,IACF,SAAS,QAAA,EAAU;AAEjB,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,0CAAA,EAA6C,QAAQ,CAAA,CAAE,CAAA;AAAA,IACvE;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;;;AFxKA,IAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AAAA,IACxB,aAAA,CAAAC,QAAa,EAAE,IAAA,EAAML,sBAAK,IAAA,CAAK,GAAA,EAAK,MAAM,CAAA,EAAG,CAAA;AAAA,IAC7C,aAAA,CAAAK,MAAAA,EAAa,EAAE,IAAA,EAAML,qBAAAA,CAAK,IAAA,CAAK,GAAA,EAAK,YAAY,CAAA,EAAG,QAAA,EAAU,IAAA,EAAM,CAAA;AACnE,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA,EAAc;AACzC,EAAA,IAAA,aAAA,CAAAK,MAAAA,EAAa,EAAE,IAAA,EAAML,qBAAAA,CAAK,KAAK,GAAA,EAAK,iBAAiB,GAAG,CAAA;AACxD,EAAA,IAAA,aAAA,CAAAK,MAAAA,EAAa,EAAE,IAAA,EAAML,qBAAAA,CAAK,IAAA,CAAK,KAAK,uBAAuB,CAAA,EAAG,QAAA,EAAU,IAAA,EAAM,CAAA;AAChF;AAEA,eAAe,IAAA,GAAO;AACpB,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACjC,EAAA,MAAM,eAAe,IAAA,CAAK,QAAA,CAAS,iBAAiB,CAAA,IAAK,IAAA,CAAK,SAAS,IAAI,CAAA;AAC3E,EAAA,MAAM,eAAe,IAAA,CAAK,QAAA,CAAS,eAAe,CAAA,IAAK,IAAA,CAAK,SAAS,iBAAiB,CAAA;AAItF,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA;AAElD,EAAA,OAAA,CAAQ,IAAI,wCAAwC,CAAA;AAEpD,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,oBAAA,CAAqB;AAAA,MACxC,YAAA;AAAA,MACA,eAAe,CAAC,YAAA;AAAA,MAChB,GAAI,WAAA,GAAc,EAAE,IAAA,EAAM,cAAA,KAA4B;AAAC,KACxD,CAAA;AAED,IAAA,IAAI,OAAO,OAAA,EAAS;AAElB,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,OAAA,CAAQ,IAAI,CAAA,8CAAA,CAA2C,CAAA;AACvD,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,mBAAA,EAAsB,MAAA,CAAO,OAAO,CAAA,CAAE,CAAA;AAClD,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,mBAAA,EAAsB,MAAA,CAAO,OAAO,CAAA,CAAE,CAAA;AAClD,MAAA,IAAI,MAAA,CAAO,OAAA,KAAY,KAAA,CAAA,IAAa,MAAA,CAAO,UAAU,CAAA,EAAG;AACtD,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,mBAAA,EAAsB,MAAA,CAAO,OAAO,CAAA,CAAE,CAAA;AAAA,MACpD;AACA,MAAA,IAAI,MAAA,CAAO,mBAAmB,SAAA,EAAW;AACvC,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,yDAAA,EAAuD,MAAA,CAAO,iBAAA,CAAkB,YAAY,CAAA,MAAA,CAAQ,CAAA;AAChH,QAAA,OAAA,CAAQ,IAAI,CAAA,uEAAA,CAAyE,CAAA;AAAA,MACvF;AACA,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,MAAM,2CAAsC,CAAA;AACpD,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,yBAAoB,KAAK,CAAA;AACvC,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAEA,IAAA,EAAK","file":"register-sitemap-cli.js","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to register sitemap entries at build time\n *\n * Usage:\n * npx sonor-register-sitemap\n * npx sonor-register-sitemap --auto-discover\n * npx sonor-register-sitemap --no-optimize # Skip Signal AI meta optimization\n * npx sonor-register-sitemap --auto-discover --full-replace # Prune removed pages (pure-static sites only)\n *\n * Or in package.json:\n * {\n * \"scripts\": {\n * \"postbuild\": \"sonor-register-sitemap --auto-discover\"\n * }\n * }\n *\n * SAFETY: --auto-discover self-skips when the app has an app/sitemap.{ts,js}\n * route (createSitemap owns authoritative build-time sync, and site-kit's\n * runtime SitemapSync mirrors it) — so this line is safe to leave in any\n * postbuild. When it does run (no sitemap route), it syncs ADDITIVELY: a\n * filesystem scan can't see dynamic routes, so it must never delete. Pass\n * --full-replace to prune removed pages on a pure-static site that wants it.\n */\n\nimport path from 'path'\nimport { config as dotenvConfig } from 'dotenv'\nimport { registerLocalSitemap } from './register-sitemap-cli-impl'\n\n// npm postbuild runs outside Next.js — env from .env* is not loaded automatically\nconst cwd = process.cwd()\ndotenvConfig({ path: path.join(cwd, '.env') })\ndotenvConfig({ path: path.join(cwd, '.env.local'), override: true })\nif (process.env.NODE_ENV === 'production') {\n dotenvConfig({ path: path.join(cwd, '.env.production') })\n dotenvConfig({ path: path.join(cwd, '.env.production.local'), override: true })\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n const autoDiscover = args.includes('--auto-discover') || args.includes('-a')\n const skipOptimize = args.includes('--no-optimize') || args.includes('--skip-optimize')\n // Opt-in: prune pages missing from the discovered set. Only honored on\n // pure-static sites with no sitemap route (a filesystem scan is otherwise\n // incomplete — see register-sitemap-cli-impl for why full-replace is unsafe).\n const fullReplace = args.includes('--full-replace')\n\n console.log('[Sonor] Registering sitemap entries...')\n\n try {\n const result = await registerLocalSitemap({\n autoDiscover,\n optimize_meta: !skipOptimize,\n ...(fullReplace ? { mode: 'full-replace' as const } : {}),\n })\n\n if (result.skipped) {\n // A sitemap route already owns build-time sync — nothing to report.\n process.exit(0)\n }\n\n if (result.success) {\n console.log(`[Sonor] ✓ Sitemap registered successfully`)\n console.log(`[Sonor] Created: ${result.created}`)\n console.log(`[Sonor] Updated: ${result.updated}`)\n if (result.removed !== undefined && result.removed > 0) {\n console.log(`[Sonor] Removed: ${result.removed}`)\n }\n if (result.meta_optimization?.triggered) {\n console.log(`[Sonor] ✓ Signal AI meta optimization triggered for ${result.meta_optimization.pages_queued} pages`)\n console.log(`[Sonor] (Running in background - check Portal SEO module for results)`)\n }\n process.exit(0)\n } else {\n console.error('[Sonor] ✗ Failed to register sitemap')\n process.exit(1)\n }\n } catch (error) {\n console.error('[Sonor] ✗ Error:', error)\n process.exit(1)\n }\n}\n\nmain()\n","/**\n * Brand Profile Extraction\n *\n * Extracts the visual design DNA from a Next.js project's source files:\n * - globals.css: CSS custom properties (colors, fonts, theme)\n * - tailwind.config.js/ts: extended colors, fontFamily\n * - design-system.ts: explicit color palettes (if present)\n *\n * The extracted profile is pushed to Sonor alongside sitemap registration,\n * giving Signal AI full brand awareness for image generation, blog context,\n * and portfolio design decisions.\n *\n * This is static file analysis (regex, not AST) — runs at build time in Node.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n\nexport interface BrandProfile {\n colors: {\n primary?: string\n secondary?: string\n accent?: string\n background?: string\n surface?: string\n text?: string\n gradient?: string\n }\n typography: {\n heading?: string\n body?: string\n mono?: string\n }\n theme: 'dark' | 'light'\n style_keywords: string[]\n border_radius?: string\n captured_at: string\n}\n\n/**\n * Detect whether a hex color is \"dark\" (luminance < 0.5)\n */\nfunction isDarkColor(hex: string): boolean {\n const c = hex.replace('#', '')\n if (c.length < 6) return false\n const r = parseInt(c.substring(0, 2), 16) / 255\n const g = parseInt(c.substring(2, 4), 16) / 255\n const b = parseInt(c.substring(4, 6), 16) / 255\n // Relative luminance (ITU-R BT.709)\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b\n return luminance < 0.35\n}\n\n/**\n * Extract CSS custom properties from a CSS file's :root block\n */\nfunction extractCssVariables(css: string): Record<string, string> {\n const vars: Record<string, string> = {}\n // Match :root { ... } blocks (may be multiple)\n const rootBlocks = css.match(/:root\\s*\\{[^}]+\\}/g)\n if (!rootBlocks) return vars\n\n for (const block of rootBlocks) {\n const matches = block.matchAll(/--([a-zA-Z0-9_-]+)\\s*:\\s*([^;]+)/g)\n for (const m of matches) {\n const name = m[1].trim()\n const value = m[2].trim()\n // Skip var() references and rgb() values — we want hex/named colors\n if (!value.startsWith('var(')) {\n vars[name] = value\n }\n }\n }\n return vars\n}\n\n/**\n * Try to find the \"primary\" brand color from CSS variables\n */\nfunction findColor(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val && val.startsWith('#')) return val\n }\n return undefined\n}\n\n/**\n * Extract font family from CSS variable or Tailwind config\n */\nfunction extractFontFromCss(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val) {\n // Extract first font name: \"'Inter', system-ui\" -> \"Inter\"\n const match = val.match(/['\"]?([A-Za-z][A-Za-z0-9 _-]+)['\"]?/)\n return match?.[1]?.trim()\n }\n }\n return undefined\n}\n\n/**\n * Extract from Tailwind config — reads as text, uses regex (no require/import)\n */\nfunction extractFromTailwindConfig(configPath: string): {\n colors: Record<string, string>\n fonts: Record<string, string>\n} {\n const colors: Record<string, string> = {}\n const fonts: Record<string, string> = {}\n\n if (!fs.existsSync(configPath)) return { colors, fonts }\n\n const content = fs.readFileSync(configPath, 'utf-8')\n\n // Extract fontFamily entries: fontFamily: { sans: ['var(--font-satoshi)', ...] }\n const fontMatches = content.matchAll(/(?:fontFamily|font-family)\\s*:\\s*\\{([^}]+)\\}/g)\n for (const m of fontMatches) {\n const block = m[1]\n // Match: sans: ['Satoshi', ...] or sans: ['var(--font-satoshi)', ...]\n const entries = block.matchAll(/(\\w+)\\s*:\\s*\\[([^\\]]+)\\]/g)\n for (const e of entries) {\n const key = e[1] // sans, serif, mono\n const values = e[2]\n // Extract first real font name (not var())\n const varMatch = values.match(/var\\(--font-([a-z0-9-]+)\\)/)\n if (varMatch) {\n fonts[key] = varMatch[1].charAt(0).toUpperCase() + varMatch[1].slice(1) // capitalize\n } else {\n const nameMatch = values.match(/['\"]([A-Za-z][A-Za-z0-9 -]+)['\"]/)\n if (nameMatch) fonts[key] = nameMatch[1]\n }\n }\n }\n\n return { colors, fonts }\n}\n\n/**\n * Extract from design-system.ts if it exists\n */\nfunction extractFromDesignSystem(filePath: string): {\n primary?: string\n secondary?: string\n accent?: string\n gradient?: string\n} {\n if (!fs.existsSync(filePath)) return {}\n\n const content = fs.readFileSync(filePath, 'utf-8')\n\n // Look for default/fallback color definitions\n const result: Record<string, string> = {}\n\n // Match: primary: '#54b948'\n const colorMatches = content.matchAll(/(primary|secondary|accent)\\s*:\\s*['\"]([#a-fA-F0-9]+)['\"]/g)\n for (const m of colorMatches) {\n // Take the LAST match (usually the default/fallback)\n result[m[1]] = m[2]\n }\n\n // Match gradient: 'linear-gradient(...)'\n const gradientMatch = content.match(/gradient(?:Css)?\\s*:\\s*['\"]([^'\"]+)['\"]/)\n if (gradientMatch) {\n result.gradient = gradientMatch[1]\n }\n\n return result\n}\n\n/**\n * Infer style keywords from the extracted data\n */\nfunction inferStyleKeywords(\n theme: 'dark' | 'light',\n vars: Record<string, string>,\n tailwindContent?: string,\n): string[] {\n const keywords: string[] = []\n\n keywords.push(theme === 'dark' ? 'dark' : 'light')\n keywords.push('modern')\n\n // Check for specific patterns\n if (tailwindContent) {\n if (tailwindContent.includes('backdrop-blur') || tailwindContent.includes('glass')) keywords.push('glass')\n if (tailwindContent.includes('gradient')) keywords.push('gradient')\n if (tailwindContent.includes('rounded-full') || tailwindContent.includes('rounded-3xl')) keywords.push('rounded')\n if (tailwindContent.includes('animate-') || tailwindContent.includes('framer-motion')) keywords.push('animated')\n }\n\n // Check font styles\n const allVars = Object.values(vars).join(' ').toLowerCase()\n if (allVars.includes('mono') || allVars.includes('code') || allVars.includes('jetbrains')) keywords.push('tech')\n if (allVars.includes('serif') || allVars.includes('georgia') || allVars.includes('playfair')) keywords.push('editorial')\n\n return [...new Set(keywords)]\n}\n\n/**\n * Main extraction function — scans the project directory\n */\nexport function extractBrandProfile(projectDir?: string): BrandProfile | null {\n const cwd = projectDir || process.cwd()\n\n // Find globals.css\n const globalsLocations = [\n path.join(cwd, 'app', 'globals.css'),\n path.join(cwd, 'src', 'app', 'globals.css'),\n path.join(cwd, 'styles', 'globals.css'),\n ]\n\n let cssVars: Record<string, string> = {}\n let globalsCss = ''\n for (const loc of globalsLocations) {\n if (fs.existsSync(loc)) {\n globalsCss = fs.readFileSync(loc, 'utf-8')\n cssVars = extractCssVariables(globalsCss)\n break\n }\n }\n\n // Find tailwind config\n const tailwindLocations = [\n path.join(cwd, 'tailwind.config.js'),\n path.join(cwd, 'tailwind.config.ts'),\n path.join(cwd, 'tailwind.config.mjs'),\n ]\n\n let tailwindResult = { colors: {} as Record<string, string>, fonts: {} as Record<string, string> }\n let tailwindContent = ''\n for (const loc of tailwindLocations) {\n if (fs.existsSync(loc)) {\n tailwindContent = fs.readFileSync(loc, 'utf-8')\n tailwindResult = extractFromTailwindConfig(loc)\n break\n }\n }\n\n // Find design-system.ts\n const designSystemLocations = [\n path.join(cwd, 'design-system.ts'),\n path.join(cwd, 'src', 'design-system.ts'),\n path.join(cwd, 'lib', 'design-system.ts'),\n ]\n\n let designSystem: ReturnType<typeof extractFromDesignSystem> = {}\n for (const loc of designSystemLocations) {\n if (fs.existsSync(loc)) {\n designSystem = extractFromDesignSystem(loc)\n break\n }\n }\n\n // If we found nothing at all, skip\n if (Object.keys(cssVars).length === 0 && !tailwindContent && Object.keys(designSystem).length === 0) {\n return null\n }\n\n // === Build the profile ===\n\n // Colors — priority: CSS vars > design-system > tailwind\n const primary = findColor(cssVars,\n 'color-accent', 'sk-primary', 'color-primary', 'color-brand', 'brand-primary',\n ) || designSystem.primary\n\n const secondary = findColor(cssVars,\n 'color-accent-dark', 'sk-secondary', 'color-secondary',\n ) || designSystem.secondary\n\n const accent = findColor(cssVars,\n 'color-accent-light', 'sk-accent', 'color-accent-light',\n ) || designSystem.accent\n\n const background = findColor(cssVars,\n 'color-charcoal', 'sk-bg', 'color-bg', 'color-background',\n 'background', 'bg',\n )\n\n const surface = findColor(cssVars,\n 'color-charcoal-light', 'sk-surface', 'color-surface', 'sk-bg-elevated',\n )\n\n const textColor = findColor(cssVars,\n 'sk-text-primary', 'color-text', 'color-text-primary',\n )\n\n const gradient = designSystem.gradient || undefined\n\n // Typography — priority: tailwind fontFamily > CSS vars\n const headingFont = tailwindResult.fonts.sans || tailwindResult.fonts.heading ||\n extractFontFromCss(cssVars, 'font-heading', 'font-display', 'font-sans')\n const bodyFont = tailwindResult.fonts.sans || tailwindResult.fonts.body ||\n extractFontFromCss(cssVars, 'font-body', 'font-sans')\n const monoFont = tailwindResult.fonts.mono ||\n extractFontFromCss(cssVars, 'font-mono', 'font-code')\n\n // Theme detection — check if background is dark\n const theme: 'dark' | 'light' = (background && isDarkColor(background)) ? 'dark' :\n globalsCss.includes('.dark') || globalsCss.includes('dark:') ? 'dark' : 'light'\n\n // Style keywords\n const styleKeywords = inferStyleKeywords(theme, cssVars, tailwindContent + globalsCss)\n\n // Border radius — look for common patterns\n const radiusMatch = globalsCss.match(/border-radius\\s*:\\s*([^;]+)/) ||\n tailwindContent.match(/borderRadius\\s*:\\s*\\{[^}]*DEFAULT\\s*:\\s*['\"]([^'\"]+)['\"]/)\n const borderRadius = radiusMatch?.[1]?.trim()\n\n const profile: BrandProfile = {\n colors: {\n ...(primary && { primary }),\n ...(secondary && { secondary }),\n ...(accent && { accent }),\n ...(background && { background }),\n ...(surface && { surface }),\n ...(textColor && { text: textColor }),\n ...(gradient && { gradient }),\n },\n typography: {\n ...(headingFont && { heading: headingFont }),\n ...(bodyFont && { body: bodyFont }),\n ...(monoFont && { mono: monoFont }),\n },\n theme,\n style_keywords: styleKeywords,\n ...(borderRadius && { border_radius: borderRadius }),\n captured_at: new Date().toISOString(),\n }\n\n // Only return if we got meaningful data\n const hasColors = Object.keys(profile.colors).length > 0\n const hasTypography = Object.keys(profile.typography).length > 0\n\n if (!hasColors && !hasTypography) return null\n\n return profile\n}\n\n/**\n * Push brand profile to Sonor API\n */\nexport async function pushBrandProfile(profile: BrandProfile): Promise<boolean> {\n const apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = process.env.SONOR_API_KEY || ''\n\n if (!apiKey) {\n console.warn('[Sonor] No API key — skipping brand profile push')\n return false\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/seo/brand-profile`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(profile),\n })\n\n if (!response.ok) {\n console.warn(`[Sonor] Brand profile push failed: ${response.status}`)\n return false\n }\n\n const result = await response.json()\n console.log(`[Sonor] Brand profile pushed: theme=${profile.theme}, ${Object.keys(profile.colors).length} colors`)\n return result.success\n } catch (err) {\n console.warn(`[Sonor] Brand profile push error: ${err}`)\n return false\n }\n}\n","/**\n * Standalone implementation for the sonor-register-sitemap CLI.\n * Does NOT import from server-api or routing, so it can run in Node without\n * pulling in server-only (which throws when required outside Next.js server context).\n *\n * Route discovery + page classification live in `../sitemap/discover` and\n * `../sitemap/shared` (shared with createSitemap, SitemapSync, and the routing\n * helper) — see those files for the sitemap-oscillation background.\n */\n\nimport path from 'path'\nimport { extractBrandProfile, pushBrandProfile } from '../brand/extract-brand-profile'\nimport { inferPageType } from '../sitemap/shared'\nimport {\n discoverNextJsRoutes,\n findAppDirForDiscovery,\n findSitemapRoute,\n} from '../sitemap/discover'\n\nfunction getApiConfig(): { apiUrl: string; apiKey: string } {\n const apiUrl =\n process.env.SONOR_API_URL ||\n 'https://api.sonor.io'\n const apiKey =\n process.env.SONOR_API_KEY ||\n ''\n return { apiUrl, apiKey }\n}\n\nasync function registerSitemapViaApi(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: string\n description?: string\n pageType?: string\n }>,\n optimizeMeta: boolean,\n mode: 'additive' | 'full-replace',\n): Promise<{\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: { triggered: boolean; pages_queued: number } | null\n}> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n console.warn(\n '[Sonor] No API key (SONOR_API_KEY)',\n )\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, optimize_meta: optimizeMeta, mode }),\n })\n\n if (!response.ok) {\n console.error(`[Sonor] Sitemap registration failed: ${response.status} ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n\n return await response.json()\n } catch (error) {\n console.error('[Sonor] Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\nexport type RegisterLocalSitemapOptions = {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n description?: string\n pageType?: string\n }>\n autoDiscover?: boolean\n optimize_meta?: boolean\n /**\n * Sync mode. Defaults to `'additive'` for auto-discovered route sets — a\n * filesystem scan is structurally incomplete (it can't enumerate dynamic\n * route params and ignores the app's sitemap exclude config), so it must\n * never drive a `'full-replace'` that would delete the pages it can't see.\n * Pure-static sites that want removed pages pruned can opt back in with\n * `'full-replace'`.\n */\n mode?: 'additive' | 'full-replace'\n}\n\nexport type RegisterLocalSitemapResult = {\n success: boolean\n created: number\n updated: number\n removed?: number\n /** True when the sync was intentionally skipped (a sitemap route owns it). */\n skipped?: boolean\n meta_optimization?: {\n triggered: boolean\n pages_queued: number\n } | null\n}\n\nexport async function registerLocalSitemap(\n options: RegisterLocalSitemapOptions\n): Promise<RegisterLocalSitemapResult> {\n let entries = options.entries || []\n const usingAutoDiscover = !!options.autoDiscover && entries.length === 0\n\n let result: RegisterLocalSitemapResult\n\n // SAFETY GUARD: never let a filesystem scan fight an authoritative sitemap.\n // If the app has a Next.js sitemap route (app/sitemap.{ts,js}, which\n // createSitemap syncs as a full-replace, and which site-kit's runtime\n // SitemapSync mirrors additively), an --auto-discover full-replace from an\n // incomplete fs scan would delete every dynamic-route page on every build and\n // the two syncs would oscillate — destroying managed metadata, Signal\n // optimizations, LLM schemas, and GSC history. Skip and let the route own it.\n const sitemapRoute = usingAutoDiscover ? findSitemapRoute() : null\n\n if (sitemapRoute) {\n console.warn(\n `[Sonor] Skipping --auto-discover: ${sitemapRoute} already handles build-time ` +\n `sitemap sync, and its /sitemap.xml is mirrored to Sonor at runtime. A ` +\n `filesystem scan can't see dynamic routes, so syncing it here would delete ` +\n `real pages and fight the route on every build. Nothing to do — this line ` +\n `is safe to leave in your postbuild.`,\n )\n result = { success: true, created: 0, updated: 0, skipped: true }\n } else {\n if (usingAutoDiscover) {\n const appDir = findAppDirForDiscovery()\n if (appDir) {\n entries = discoverNextJsRoutes(appDir)\n console.log(`[Sonor] Auto-discovered ${entries.length} routes from ${path.relative(process.cwd(), appDir)}`)\n }\n }\n\n if (entries.length === 0) {\n console.warn('[Sonor] No sitemap entries to register')\n result = { success: true, created: 0, updated: 0 }\n } else {\n // Auto-discovered sets are additive by default (incomplete → never delete).\n // Explicit entry lists keep the caller-provided mode, defaulting to\n // full-replace only when the caller asserts a complete set via `mode`.\n const mode: 'additive' | 'full-replace' =\n options.mode ?? (usingAutoDiscover ? 'additive' : 'full-replace')\n\n console.log(`[Sonor] Registering ${entries.length} sitemap entries (mode: ${mode})...`)\n const payload = entries.map((e) => ({\n path: e.path,\n title: e.title,\n priority: e.priority,\n changefreq: e.changefreq,\n ...(e.description ? { description: e.description } : {}),\n pageType: e.pageType ?? inferPageType(e.path),\n }))\n result = await registerSitemapViaApi(\n payload,\n options.optimize_meta !== false,\n mode,\n )\n\n if (result.success) {\n console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n }\n }\n\n // Push brand profile whenever the CLI did real work — a sync ran, or we\n // skipped because a sitemap route owns the sync — but not on the degenerate\n // \"nothing to register\" path (preserving prior behavior). It's an independent\n // side effect (a separate endpoint), so it must survive the skip path: keeping\n // the postbuild line shouldn't silently stop refreshing brand awareness.\n // Fire-and-forget, non-blocking.\n const didMeaningfulWork = result.skipped === true || entries.length > 0\n if (result.success && didMeaningfulWork) {\n try {\n const brandProfile = extractBrandProfile()\n if (brandProfile) {\n await pushBrandProfile(brandProfile)\n }\n } catch (brandErr) {\n // Non-fatal — brand profile is supplementary\n console.debug(`[Sonor] Brand profile extraction skipped: ${brandErr}`)\n }\n }\n\n return result\n}\n"]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { findSitemapRoute, findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-XIJ4F6IE.mjs';
|
|
2
3
|
import { require_main } from '../chunk-5OKOV3NJ.mjs';
|
|
4
|
+
import { inferPageType } from '../chunk-QJU6HBSK.mjs';
|
|
3
5
|
import { __toESM } from '../chunk-4XPGGLVP.mjs';
|
|
4
|
-
import
|
|
6
|
+
import path from 'path';
|
|
5
7
|
import fs from 'fs';
|
|
6
8
|
|
|
7
9
|
// src/seo/register-sitemap-cli.ts
|
|
@@ -103,9 +105,9 @@ function inferStyleKeywords(theme, vars, tailwindContent) {
|
|
|
103
105
|
function extractBrandProfile(projectDir) {
|
|
104
106
|
const cwd2 = process.cwd();
|
|
105
107
|
const globalsLocations = [
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
path.join(cwd2, "app", "globals.css"),
|
|
109
|
+
path.join(cwd2, "src", "app", "globals.css"),
|
|
110
|
+
path.join(cwd2, "styles", "globals.css")
|
|
109
111
|
];
|
|
110
112
|
let cssVars = {};
|
|
111
113
|
let globalsCss = "";
|
|
@@ -117,9 +119,9 @@ function extractBrandProfile(projectDir) {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
const tailwindLocations = [
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
path.join(cwd2, "tailwind.config.js"),
|
|
123
|
+
path.join(cwd2, "tailwind.config.ts"),
|
|
124
|
+
path.join(cwd2, "tailwind.config.mjs")
|
|
123
125
|
];
|
|
124
126
|
let tailwindResult = { fonts: {} };
|
|
125
127
|
let tailwindContent = "";
|
|
@@ -131,9 +133,9 @@ function extractBrandProfile(projectDir) {
|
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
const designSystemLocations = [
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
path.join(cwd2, "design-system.ts"),
|
|
137
|
+
path.join(cwd2, "src", "design-system.ts"),
|
|
138
|
+
path.join(cwd2, "lib", "design-system.ts")
|
|
137
139
|
];
|
|
138
140
|
let designSystem = {};
|
|
139
141
|
for (const loc of designSystemLocations) {
|
|
@@ -250,60 +252,12 @@ async function pushBrandProfile(profile) {
|
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
// src/seo/register-sitemap-cli-impl.ts
|
|
253
|
-
function inferPageTypeFromPath(urlPath) {
|
|
254
|
-
if (urlPath === "/" || urlPath === "") return "homepage";
|
|
255
|
-
if (/^\/services(\/|$)/i.test(urlPath)) return "service";
|
|
256
|
-
if (/^\/compare(\/|$)/i.test(urlPath)) return "comparison";
|
|
257
|
-
if (/^\/(insights|blog)(\/|$)/i.test(urlPath)) return "blog";
|
|
258
|
-
if (/^\/industries(\/|$)/i.test(urlPath)) return "industry";
|
|
259
|
-
if (/^\/work(\/|$)/i.test(urlPath)) return "portfolio";
|
|
260
|
-
if (/^\/faq(\/|$)/i.test(urlPath)) return "faq";
|
|
261
|
-
if (/^\/pricing(\/|$)/i.test(urlPath)) return "pricing";
|
|
262
|
-
return "page";
|
|
263
|
-
}
|
|
264
255
|
function getApiConfig() {
|
|
265
256
|
const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
266
257
|
const apiKey = process.env.SONOR_API_KEY || "";
|
|
267
258
|
return { apiUrl, apiKey };
|
|
268
259
|
}
|
|
269
|
-
function
|
|
270
|
-
const entries = [];
|
|
271
|
-
const items = fs.readdirSync(appDir, { withFileTypes: true });
|
|
272
|
-
for (const item of items) {
|
|
273
|
-
if (item.name.startsWith("_") || item.name.startsWith(".")) continue;
|
|
274
|
-
if (item.name === "api") continue;
|
|
275
|
-
if (item.name === "node_modules") continue;
|
|
276
|
-
const itemPath = path2.join(appDir, item.name);
|
|
277
|
-
if (item.isDirectory()) {
|
|
278
|
-
const hasPage = fs.existsSync(path2.join(itemPath, "page.tsx")) || fs.existsSync(path2.join(itemPath, "page.js")) || fs.existsSync(path2.join(itemPath, "page.jsx"));
|
|
279
|
-
const isRouteGroup = item.name.startsWith("(") && item.name.endsWith(")");
|
|
280
|
-
const isDynamic = item.name.startsWith("[") && item.name.endsWith("]");
|
|
281
|
-
let routePath = basePath;
|
|
282
|
-
if (!isRouteGroup && !isDynamic) {
|
|
283
|
-
routePath = `${basePath}/${item.name}`;
|
|
284
|
-
}
|
|
285
|
-
if (hasPage && !isDynamic) {
|
|
286
|
-
const priority = routePath === "" ? 1 : 0.8;
|
|
287
|
-
entries.push({ path: routePath || "/", priority });
|
|
288
|
-
}
|
|
289
|
-
if (!isDynamic) {
|
|
290
|
-
const subEntries = discoverNextJsRoutes(
|
|
291
|
-
itemPath,
|
|
292
|
-
isRouteGroup ? basePath : routePath
|
|
293
|
-
);
|
|
294
|
-
entries.push(...subEntries);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (basePath === "") {
|
|
299
|
-
const hasRootPage = fs.existsSync(path2.join(appDir, "page.tsx")) || fs.existsSync(path2.join(appDir, "page.js")) || fs.existsSync(path2.join(appDir, "page.jsx"));
|
|
300
|
-
if (hasRootPage) {
|
|
301
|
-
entries.unshift({ path: "/", priority: 1 });
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return entries;
|
|
305
|
-
}
|
|
306
|
-
async function registerSitemapViaApi(entries, optimizeMeta) {
|
|
260
|
+
async function registerSitemapViaApi(entries, optimizeMeta, mode) {
|
|
307
261
|
const { apiUrl, apiKey } = getApiConfig();
|
|
308
262
|
if (!apiKey) {
|
|
309
263
|
console.warn(
|
|
@@ -318,7 +272,7 @@ async function registerSitemapViaApi(entries, optimizeMeta) {
|
|
|
318
272
|
"Content-Type": "application/json",
|
|
319
273
|
"x-api-key": apiKey
|
|
320
274
|
},
|
|
321
|
-
body: JSON.stringify({ entries, optimize_meta: optimizeMeta, mode
|
|
275
|
+
body: JSON.stringify({ entries, optimize_meta: optimizeMeta, mode })
|
|
322
276
|
});
|
|
323
277
|
if (!response.ok) {
|
|
324
278
|
console.error(`[Sonor] Sitemap registration failed: ${response.status} ${response.statusText}`);
|
|
@@ -332,39 +286,48 @@ async function registerSitemapViaApi(entries, optimizeMeta) {
|
|
|
332
286
|
}
|
|
333
287
|
async function registerLocalSitemap(options) {
|
|
334
288
|
let entries = options.entries || [];
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
289
|
+
const usingAutoDiscover = !!options.autoDiscover && entries.length === 0;
|
|
290
|
+
let result;
|
|
291
|
+
const sitemapRoute = usingAutoDiscover ? findSitemapRoute() : null;
|
|
292
|
+
if (sitemapRoute) {
|
|
293
|
+
console.warn(
|
|
294
|
+
`[Sonor] Skipping --auto-discover: ${sitemapRoute} already handles build-time sitemap sync, and its /sitemap.xml is mirrored to Sonor at runtime. A filesystem scan can't see dynamic routes, so syncing it here would delete real pages and fight the route on every build. Nothing to do \u2014 this line is safe to leave in your postbuild.`
|
|
295
|
+
);
|
|
296
|
+
result = { success: true, created: 0, updated: 0, skipped: true };
|
|
297
|
+
} else {
|
|
298
|
+
if (usingAutoDiscover) {
|
|
299
|
+
const appDir = findAppDirForDiscovery();
|
|
300
|
+
if (appDir) {
|
|
343
301
|
entries = discoverNextJsRoutes(appDir);
|
|
344
|
-
console.log(`[Sonor] Auto-discovered ${entries.length} routes from ${
|
|
345
|
-
|
|
302
|
+
console.log(`[Sonor] Auto-discovered ${entries.length} routes from ${path.relative(process.cwd(), appDir)}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (entries.length === 0) {
|
|
306
|
+
console.warn("[Sonor] No sitemap entries to register");
|
|
307
|
+
result = { success: true, created: 0, updated: 0 };
|
|
308
|
+
} else {
|
|
309
|
+
const mode = options.mode ?? (usingAutoDiscover ? "additive" : "full-replace");
|
|
310
|
+
console.log(`[Sonor] Registering ${entries.length} sitemap entries (mode: ${mode})...`);
|
|
311
|
+
const payload = entries.map((e) => ({
|
|
312
|
+
path: e.path,
|
|
313
|
+
title: e.title,
|
|
314
|
+
priority: e.priority,
|
|
315
|
+
changefreq: e.changefreq,
|
|
316
|
+
...e.description ? { description: e.description } : {},
|
|
317
|
+
pageType: e.pageType ?? inferPageType(e.path)
|
|
318
|
+
}));
|
|
319
|
+
result = await registerSitemapViaApi(
|
|
320
|
+
payload,
|
|
321
|
+
options.optimize_meta !== false,
|
|
322
|
+
mode
|
|
323
|
+
);
|
|
324
|
+
if (result.success) {
|
|
325
|
+
console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`);
|
|
346
326
|
}
|
|
347
327
|
}
|
|
348
328
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
return { success: true, created: 0, updated: 0 };
|
|
352
|
-
}
|
|
353
|
-
console.log(`[Sonor] Registering ${entries.length} sitemap entries...`);
|
|
354
|
-
const payload = entries.map((e) => ({
|
|
355
|
-
path: e.path,
|
|
356
|
-
title: e.title,
|
|
357
|
-
priority: e.priority,
|
|
358
|
-
changefreq: e.changefreq,
|
|
359
|
-
...e.description ? { description: e.description } : {},
|
|
360
|
-
pageType: e.pageType ?? inferPageTypeFromPath(e.path)
|
|
361
|
-
}));
|
|
362
|
-
const result = await registerSitemapViaApi(
|
|
363
|
-
payload,
|
|
364
|
-
options.optimize_meta !== false
|
|
365
|
-
);
|
|
366
|
-
if (result.success) {
|
|
367
|
-
console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`);
|
|
329
|
+
const didMeaningfulWork = result.skipped === true || entries.length > 0;
|
|
330
|
+
if (result.success && didMeaningfulWork) {
|
|
368
331
|
try {
|
|
369
332
|
const brandProfile = extractBrandProfile();
|
|
370
333
|
if (brandProfile) {
|
|
@@ -379,22 +342,27 @@ async function registerLocalSitemap(options) {
|
|
|
379
342
|
|
|
380
343
|
// src/seo/register-sitemap-cli.ts
|
|
381
344
|
var cwd = process.cwd();
|
|
382
|
-
(0, import_dotenv.config)({ path:
|
|
383
|
-
(0, import_dotenv.config)({ path:
|
|
345
|
+
(0, import_dotenv.config)({ path: path.join(cwd, ".env") });
|
|
346
|
+
(0, import_dotenv.config)({ path: path.join(cwd, ".env.local"), override: true });
|
|
384
347
|
if (process.env.NODE_ENV === "production") {
|
|
385
|
-
(0, import_dotenv.config)({ path:
|
|
386
|
-
(0, import_dotenv.config)({ path:
|
|
348
|
+
(0, import_dotenv.config)({ path: path.join(cwd, ".env.production") });
|
|
349
|
+
(0, import_dotenv.config)({ path: path.join(cwd, ".env.production.local"), override: true });
|
|
387
350
|
}
|
|
388
351
|
async function main() {
|
|
389
352
|
const args = process.argv.slice(2);
|
|
390
353
|
const autoDiscover = args.includes("--auto-discover") || args.includes("-a");
|
|
391
354
|
const skipOptimize = args.includes("--no-optimize") || args.includes("--skip-optimize");
|
|
355
|
+
const fullReplace = args.includes("--full-replace");
|
|
392
356
|
console.log("[Sonor] Registering sitemap entries...");
|
|
393
357
|
try {
|
|
394
358
|
const result = await registerLocalSitemap({
|
|
395
359
|
autoDiscover,
|
|
396
|
-
optimize_meta: !skipOptimize
|
|
360
|
+
optimize_meta: !skipOptimize,
|
|
361
|
+
...fullReplace ? { mode: "full-replace" } : {}
|
|
397
362
|
});
|
|
363
|
+
if (result.skipped) {
|
|
364
|
+
process.exit(0);
|
|
365
|
+
}
|
|
398
366
|
if (result.success) {
|
|
399
367
|
console.log(`[Sonor] \u2713 Sitemap registered successfully`);
|
|
400
368
|
console.log(`[Sonor] Created: ${result.created}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/seo/register-sitemap-cli.ts","../../src/brand/extract-brand-profile.ts","../../src/seo/register-sitemap-cli-impl.ts"],"names":["cwd","path","fs","dotenvConfig"],"mappings":"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","file":"register-sitemap-cli.mjs","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to register sitemap entries at build time\n * \n * Usage:\n * npx sonor-register-sitemap\n * npx sonor-register-sitemap --auto-discover\n * npx sonor-register-sitemap --no-optimize # Skip Signal AI meta optimization\n *\n * Or in package.json:\n * {\n * \"scripts\": {\n * \"postbuild\": \"sonor-register-sitemap --auto-discover\"\n * }\n * }\n */\n\nimport path from 'path'\nimport { config as dotenvConfig } from 'dotenv'\nimport { registerLocalSitemap } from './register-sitemap-cli-impl'\n\n// npm postbuild runs outside Next.js — env from .env* is not loaded automatically\nconst cwd = process.cwd()\ndotenvConfig({ path: path.join(cwd, '.env') })\ndotenvConfig({ path: path.join(cwd, '.env.local'), override: true })\nif (process.env.NODE_ENV === 'production') {\n dotenvConfig({ path: path.join(cwd, '.env.production') })\n dotenvConfig({ path: path.join(cwd, '.env.production.local'), override: true })\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n const autoDiscover = args.includes('--auto-discover') || args.includes('-a')\n const skipOptimize = args.includes('--no-optimize') || args.includes('--skip-optimize')\n \n console.log('[Sonor] Registering sitemap entries...')\n \n try {\n const result = await registerLocalSitemap({\n autoDiscover,\n optimize_meta: !skipOptimize,\n })\n \n if (result.success) {\n console.log(`[Sonor] ✓ Sitemap registered successfully`)\n console.log(`[Sonor] Created: ${result.created}`)\n console.log(`[Sonor] Updated: ${result.updated}`)\n if (result.removed !== undefined && result.removed > 0) {\n console.log(`[Sonor] Removed: ${result.removed}`)\n }\n if (result.meta_optimization?.triggered) {\n console.log(`[Sonor] ✓ Signal AI meta optimization triggered for ${result.meta_optimization.pages_queued} pages`)\n console.log(`[Sonor] (Running in background - check Portal SEO module for results)`)\n }\n process.exit(0)\n } else {\n console.error('[Sonor] ✗ Failed to register sitemap')\n process.exit(1)\n }\n } catch (error) {\n console.error('[Sonor] ✗ Error:', error)\n process.exit(1)\n }\n}\n\nmain()\n","/**\n * Brand Profile Extraction\n *\n * Extracts the visual design DNA from a Next.js project's source files:\n * - globals.css: CSS custom properties (colors, fonts, theme)\n * - tailwind.config.js/ts: extended colors, fontFamily\n * - design-system.ts: explicit color palettes (if present)\n *\n * The extracted profile is pushed to Sonor alongside sitemap registration,\n * giving Signal AI full brand awareness for image generation, blog context,\n * and portfolio design decisions.\n *\n * This is static file analysis (regex, not AST) — runs at build time in Node.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n\nexport interface BrandProfile {\n colors: {\n primary?: string\n secondary?: string\n accent?: string\n background?: string\n surface?: string\n text?: string\n gradient?: string\n }\n typography: {\n heading?: string\n body?: string\n mono?: string\n }\n theme: 'dark' | 'light'\n style_keywords: string[]\n border_radius?: string\n captured_at: string\n}\n\n/**\n * Detect whether a hex color is \"dark\" (luminance < 0.5)\n */\nfunction isDarkColor(hex: string): boolean {\n const c = hex.replace('#', '')\n if (c.length < 6) return false\n const r = parseInt(c.substring(0, 2), 16) / 255\n const g = parseInt(c.substring(2, 4), 16) / 255\n const b = parseInt(c.substring(4, 6), 16) / 255\n // Relative luminance (ITU-R BT.709)\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b\n return luminance < 0.35\n}\n\n/**\n * Extract CSS custom properties from a CSS file's :root block\n */\nfunction extractCssVariables(css: string): Record<string, string> {\n const vars: Record<string, string> = {}\n // Match :root { ... } blocks (may be multiple)\n const rootBlocks = css.match(/:root\\s*\\{[^}]+\\}/g)\n if (!rootBlocks) return vars\n\n for (const block of rootBlocks) {\n const matches = block.matchAll(/--([a-zA-Z0-9_-]+)\\s*:\\s*([^;]+)/g)\n for (const m of matches) {\n const name = m[1].trim()\n const value = m[2].trim()\n // Skip var() references and rgb() values — we want hex/named colors\n if (!value.startsWith('var(')) {\n vars[name] = value\n }\n }\n }\n return vars\n}\n\n/**\n * Try to find the \"primary\" brand color from CSS variables\n */\nfunction findColor(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val && val.startsWith('#')) return val\n }\n return undefined\n}\n\n/**\n * Extract font family from CSS variable or Tailwind config\n */\nfunction extractFontFromCss(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val) {\n // Extract first font name: \"'Inter', system-ui\" -> \"Inter\"\n const match = val.match(/['\"]?([A-Za-z][A-Za-z0-9 _-]+)['\"]?/)\n return match?.[1]?.trim()\n }\n }\n return undefined\n}\n\n/**\n * Extract from Tailwind config — reads as text, uses regex (no require/import)\n */\nfunction extractFromTailwindConfig(configPath: string): {\n colors: Record<string, string>\n fonts: Record<string, string>\n} {\n const colors: Record<string, string> = {}\n const fonts: Record<string, string> = {}\n\n if (!fs.existsSync(configPath)) return { colors, fonts }\n\n const content = fs.readFileSync(configPath, 'utf-8')\n\n // Extract fontFamily entries: fontFamily: { sans: ['var(--font-satoshi)', ...] }\n const fontMatches = content.matchAll(/(?:fontFamily|font-family)\\s*:\\s*\\{([^}]+)\\}/g)\n for (const m of fontMatches) {\n const block = m[1]\n // Match: sans: ['Satoshi', ...] or sans: ['var(--font-satoshi)', ...]\n const entries = block.matchAll(/(\\w+)\\s*:\\s*\\[([^\\]]+)\\]/g)\n for (const e of entries) {\n const key = e[1] // sans, serif, mono\n const values = e[2]\n // Extract first real font name (not var())\n const varMatch = values.match(/var\\(--font-([a-z0-9-]+)\\)/)\n if (varMatch) {\n fonts[key] = varMatch[1].charAt(0).toUpperCase() + varMatch[1].slice(1) // capitalize\n } else {\n const nameMatch = values.match(/['\"]([A-Za-z][A-Za-z0-9 -]+)['\"]/)\n if (nameMatch) fonts[key] = nameMatch[1]\n }\n }\n }\n\n return { colors, fonts }\n}\n\n/**\n * Extract from design-system.ts if it exists\n */\nfunction extractFromDesignSystem(filePath: string): {\n primary?: string\n secondary?: string\n accent?: string\n gradient?: string\n} {\n if (!fs.existsSync(filePath)) return {}\n\n const content = fs.readFileSync(filePath, 'utf-8')\n\n // Look for default/fallback color definitions\n const result: Record<string, string> = {}\n\n // Match: primary: '#54b948'\n const colorMatches = content.matchAll(/(primary|secondary|accent)\\s*:\\s*['\"]([#a-fA-F0-9]+)['\"]/g)\n for (const m of colorMatches) {\n // Take the LAST match (usually the default/fallback)\n result[m[1]] = m[2]\n }\n\n // Match gradient: 'linear-gradient(...)'\n const gradientMatch = content.match(/gradient(?:Css)?\\s*:\\s*['\"]([^'\"]+)['\"]/)\n if (gradientMatch) {\n result.gradient = gradientMatch[1]\n }\n\n return result\n}\n\n/**\n * Infer style keywords from the extracted data\n */\nfunction inferStyleKeywords(\n theme: 'dark' | 'light',\n vars: Record<string, string>,\n tailwindContent?: string,\n): string[] {\n const keywords: string[] = []\n\n keywords.push(theme === 'dark' ? 'dark' : 'light')\n keywords.push('modern')\n\n // Check for specific patterns\n if (tailwindContent) {\n if (tailwindContent.includes('backdrop-blur') || tailwindContent.includes('glass')) keywords.push('glass')\n if (tailwindContent.includes('gradient')) keywords.push('gradient')\n if (tailwindContent.includes('rounded-full') || tailwindContent.includes('rounded-3xl')) keywords.push('rounded')\n if (tailwindContent.includes('animate-') || tailwindContent.includes('framer-motion')) keywords.push('animated')\n }\n\n // Check font styles\n const allVars = Object.values(vars).join(' ').toLowerCase()\n if (allVars.includes('mono') || allVars.includes('code') || allVars.includes('jetbrains')) keywords.push('tech')\n if (allVars.includes('serif') || allVars.includes('georgia') || allVars.includes('playfair')) keywords.push('editorial')\n\n return [...new Set(keywords)]\n}\n\n/**\n * Main extraction function — scans the project directory\n */\nexport function extractBrandProfile(projectDir?: string): BrandProfile | null {\n const cwd = projectDir || process.cwd()\n\n // Find globals.css\n const globalsLocations = [\n path.join(cwd, 'app', 'globals.css'),\n path.join(cwd, 'src', 'app', 'globals.css'),\n path.join(cwd, 'styles', 'globals.css'),\n ]\n\n let cssVars: Record<string, string> = {}\n let globalsCss = ''\n for (const loc of globalsLocations) {\n if (fs.existsSync(loc)) {\n globalsCss = fs.readFileSync(loc, 'utf-8')\n cssVars = extractCssVariables(globalsCss)\n break\n }\n }\n\n // Find tailwind config\n const tailwindLocations = [\n path.join(cwd, 'tailwind.config.js'),\n path.join(cwd, 'tailwind.config.ts'),\n path.join(cwd, 'tailwind.config.mjs'),\n ]\n\n let tailwindResult = { colors: {} as Record<string, string>, fonts: {} as Record<string, string> }\n let tailwindContent = ''\n for (const loc of tailwindLocations) {\n if (fs.existsSync(loc)) {\n tailwindContent = fs.readFileSync(loc, 'utf-8')\n tailwindResult = extractFromTailwindConfig(loc)\n break\n }\n }\n\n // Find design-system.ts\n const designSystemLocations = [\n path.join(cwd, 'design-system.ts'),\n path.join(cwd, 'src', 'design-system.ts'),\n path.join(cwd, 'lib', 'design-system.ts'),\n ]\n\n let designSystem: ReturnType<typeof extractFromDesignSystem> = {}\n for (const loc of designSystemLocations) {\n if (fs.existsSync(loc)) {\n designSystem = extractFromDesignSystem(loc)\n break\n }\n }\n\n // If we found nothing at all, skip\n if (Object.keys(cssVars).length === 0 && !tailwindContent && Object.keys(designSystem).length === 0) {\n return null\n }\n\n // === Build the profile ===\n\n // Colors — priority: CSS vars > design-system > tailwind\n const primary = findColor(cssVars,\n 'color-accent', 'sk-primary', 'color-primary', 'color-brand', 'brand-primary',\n ) || designSystem.primary\n\n const secondary = findColor(cssVars,\n 'color-accent-dark', 'sk-secondary', 'color-secondary',\n ) || designSystem.secondary\n\n const accent = findColor(cssVars,\n 'color-accent-light', 'sk-accent', 'color-accent-light',\n ) || designSystem.accent\n\n const background = findColor(cssVars,\n 'color-charcoal', 'sk-bg', 'color-bg', 'color-background',\n 'background', 'bg',\n )\n\n const surface = findColor(cssVars,\n 'color-charcoal-light', 'sk-surface', 'color-surface', 'sk-bg-elevated',\n )\n\n const textColor = findColor(cssVars,\n 'sk-text-primary', 'color-text', 'color-text-primary',\n )\n\n const gradient = designSystem.gradient || undefined\n\n // Typography — priority: tailwind fontFamily > CSS vars\n const headingFont = tailwindResult.fonts.sans || tailwindResult.fonts.heading ||\n extractFontFromCss(cssVars, 'font-heading', 'font-display', 'font-sans')\n const bodyFont = tailwindResult.fonts.sans || tailwindResult.fonts.body ||\n extractFontFromCss(cssVars, 'font-body', 'font-sans')\n const monoFont = tailwindResult.fonts.mono ||\n extractFontFromCss(cssVars, 'font-mono', 'font-code')\n\n // Theme detection — check if background is dark\n const theme: 'dark' | 'light' = (background && isDarkColor(background)) ? 'dark' :\n globalsCss.includes('.dark') || globalsCss.includes('dark:') ? 'dark' : 'light'\n\n // Style keywords\n const styleKeywords = inferStyleKeywords(theme, cssVars, tailwindContent + globalsCss)\n\n // Border radius — look for common patterns\n const radiusMatch = globalsCss.match(/border-radius\\s*:\\s*([^;]+)/) ||\n tailwindContent.match(/borderRadius\\s*:\\s*\\{[^}]*DEFAULT\\s*:\\s*['\"]([^'\"]+)['\"]/)\n const borderRadius = radiusMatch?.[1]?.trim()\n\n const profile: BrandProfile = {\n colors: {\n ...(primary && { primary }),\n ...(secondary && { secondary }),\n ...(accent && { accent }),\n ...(background && { background }),\n ...(surface && { surface }),\n ...(textColor && { text: textColor }),\n ...(gradient && { gradient }),\n },\n typography: {\n ...(headingFont && { heading: headingFont }),\n ...(bodyFont && { body: bodyFont }),\n ...(monoFont && { mono: monoFont }),\n },\n theme,\n style_keywords: styleKeywords,\n ...(borderRadius && { border_radius: borderRadius }),\n captured_at: new Date().toISOString(),\n }\n\n // Only return if we got meaningful data\n const hasColors = Object.keys(profile.colors).length > 0\n const hasTypography = Object.keys(profile.typography).length > 0\n\n if (!hasColors && !hasTypography) return null\n\n return profile\n}\n\n/**\n * Push brand profile to Sonor API\n */\nexport async function pushBrandProfile(profile: BrandProfile): Promise<boolean> {\n const apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = process.env.SONOR_API_KEY || ''\n\n if (!apiKey) {\n console.warn('[Sonor] No API key — skipping brand profile push')\n return false\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/seo/brand-profile`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(profile),\n })\n\n if (!response.ok) {\n console.warn(`[Sonor] Brand profile push failed: ${response.status}`)\n return false\n }\n\n const result = await response.json()\n console.log(`[Sonor] Brand profile pushed: theme=${profile.theme}, ${Object.keys(profile.colors).length} colors`)\n return result.success\n } catch (err) {\n console.warn(`[Sonor] Brand profile push error: ${err}`)\n return false\n }\n}\n","/**\n * Standalone implementation for uptrade-register-sitemap CLI.\n * Does NOT import from server-api or routing, so it can run in Node without\n * pulling in server-only (which throws when required outside Next.js server context).\n */\n\nimport fs from 'fs'\nimport path from 'path'\nimport { extractBrandProfile, pushBrandProfile } from '../brand/extract-brand-profile'\n\n/**\n * Infer page type from URL path pattern for Signal context.\n */\nfunction inferPageTypeFromPath(urlPath: string): string {\n if (urlPath === '/' || urlPath === '') return 'homepage'\n if (/^\\/services(\\/|$)/i.test(urlPath)) return 'service'\n if (/^\\/compare(\\/|$)/i.test(urlPath)) return 'comparison'\n if (/^\\/(insights|blog)(\\/|$)/i.test(urlPath)) return 'blog'\n if (/^\\/industries(\\/|$)/i.test(urlPath)) return 'industry'\n if (/^\\/work(\\/|$)/i.test(urlPath)) return 'portfolio'\n if (/^\\/faq(\\/|$)/i.test(urlPath)) return 'faq'\n if (/^\\/pricing(\\/|$)/i.test(urlPath)) return 'pricing'\n return 'page'\n}\n\nfunction getApiConfig(): { apiUrl: string; apiKey: string } {\n const apiUrl =\n process.env.SONOR_API_URL ||\n 'https://api.sonor.io'\n const apiKey =\n process.env.SONOR_API_KEY ||\n ''\n return { apiUrl, apiKey }\n}\n\nfunction discoverNextJsRoutes(\n appDir: string,\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 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 const hasPage =\n 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 const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\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 if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(\n itemPath,\n isRouteGroup ? basePath : routePath\n )\n entries.push(...subEntries)\n }\n }\n }\n\n if (basePath === '') {\n const hasRootPage =\n 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\nasync function registerSitemapViaApi(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: string\n description?: string\n pageType?: string\n }>,\n optimizeMeta: boolean\n): Promise<{\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: { triggered: boolean; pages_queued: number } | null\n}> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n console.warn(\n '[Sonor] No API key (SONOR_API_KEY)',\n )\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, optimize_meta: optimizeMeta, mode: 'full-replace' }),\n })\n\n if (!response.ok) {\n console.error(`[Sonor] Sitemap registration failed: ${response.status} ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n\n return await response.json()\n } catch (error) {\n console.error('[Sonor] Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\nexport type RegisterLocalSitemapOptions = {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n description?: string\n pageType?: string\n }>\n autoDiscover?: boolean\n optimize_meta?: boolean\n}\n\nexport type RegisterLocalSitemapResult = {\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: {\n triggered: boolean\n pages_queued: number\n } | null\n}\n\nexport async function registerLocalSitemap(\n options: RegisterLocalSitemapOptions\n): Promise<RegisterLocalSitemapResult> {\n let entries = options.entries || []\n\n if (options.autoDiscover && entries.length === 0) {\n const cwd = process.cwd()\n const appDirs = [\n path.join(cwd, 'app'),\n path.join(cwd, 'src', 'app'),\n ]\n for (const appDir of appDirs) {\n if (fs.existsSync(appDir)) {\n entries = discoverNextJsRoutes(appDir)\n console.log(`[Sonor] Auto-discovered ${entries.length} routes from ${path.relative(cwd, appDir)}`)\n break\n }\n }\n }\n\n if (entries.length === 0) {\n console.warn('[Sonor] No sitemap entries to register')\n return { success: true, created: 0, updated: 0 }\n }\n\n console.log(`[Sonor] Registering ${entries.length} sitemap entries...`)\n const payload = entries.map((e) => ({\n path: e.path,\n title: e.title,\n priority: e.priority,\n changefreq: e.changefreq,\n ...(e.description ? { description: e.description } : {}),\n pageType: e.pageType ?? inferPageTypeFromPath(e.path),\n }))\n const result = await registerSitemapViaApi(\n payload,\n options.optimize_meta !== false\n )\n\n if (result.success) {\n console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n\n // Push brand profile alongside sitemap (fire-and-forget, non-blocking)\n try {\n const brandProfile = extractBrandProfile()\n if (brandProfile) {\n await pushBrandProfile(brandProfile)\n }\n } catch (brandErr) {\n // Non-fatal — brand profile is supplementary\n console.debug(`[Sonor] Brand profile extraction skipped: ${brandErr}`)\n }\n }\n\n return result\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/seo/register-sitemap-cli.ts","../../src/brand/extract-brand-profile.ts","../../src/seo/register-sitemap-cli-impl.ts"],"names":["cwd","path","dotenvConfig"],"mappings":"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","file":"register-sitemap-cli.mjs","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to register sitemap entries at build time\n *\n * Usage:\n * npx sonor-register-sitemap\n * npx sonor-register-sitemap --auto-discover\n * npx sonor-register-sitemap --no-optimize # Skip Signal AI meta optimization\n * npx sonor-register-sitemap --auto-discover --full-replace # Prune removed pages (pure-static sites only)\n *\n * Or in package.json:\n * {\n * \"scripts\": {\n * \"postbuild\": \"sonor-register-sitemap --auto-discover\"\n * }\n * }\n *\n * SAFETY: --auto-discover self-skips when the app has an app/sitemap.{ts,js}\n * route (createSitemap owns authoritative build-time sync, and site-kit's\n * runtime SitemapSync mirrors it) — so this line is safe to leave in any\n * postbuild. When it does run (no sitemap route), it syncs ADDITIVELY: a\n * filesystem scan can't see dynamic routes, so it must never delete. Pass\n * --full-replace to prune removed pages on a pure-static site that wants it.\n */\n\nimport path from 'path'\nimport { config as dotenvConfig } from 'dotenv'\nimport { registerLocalSitemap } from './register-sitemap-cli-impl'\n\n// npm postbuild runs outside Next.js — env from .env* is not loaded automatically\nconst cwd = process.cwd()\ndotenvConfig({ path: path.join(cwd, '.env') })\ndotenvConfig({ path: path.join(cwd, '.env.local'), override: true })\nif (process.env.NODE_ENV === 'production') {\n dotenvConfig({ path: path.join(cwd, '.env.production') })\n dotenvConfig({ path: path.join(cwd, '.env.production.local'), override: true })\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n const autoDiscover = args.includes('--auto-discover') || args.includes('-a')\n const skipOptimize = args.includes('--no-optimize') || args.includes('--skip-optimize')\n // Opt-in: prune pages missing from the discovered set. Only honored on\n // pure-static sites with no sitemap route (a filesystem scan is otherwise\n // incomplete — see register-sitemap-cli-impl for why full-replace is unsafe).\n const fullReplace = args.includes('--full-replace')\n\n console.log('[Sonor] Registering sitemap entries...')\n\n try {\n const result = await registerLocalSitemap({\n autoDiscover,\n optimize_meta: !skipOptimize,\n ...(fullReplace ? { mode: 'full-replace' as const } : {}),\n })\n\n if (result.skipped) {\n // A sitemap route already owns build-time sync — nothing to report.\n process.exit(0)\n }\n\n if (result.success) {\n console.log(`[Sonor] ✓ Sitemap registered successfully`)\n console.log(`[Sonor] Created: ${result.created}`)\n console.log(`[Sonor] Updated: ${result.updated}`)\n if (result.removed !== undefined && result.removed > 0) {\n console.log(`[Sonor] Removed: ${result.removed}`)\n }\n if (result.meta_optimization?.triggered) {\n console.log(`[Sonor] ✓ Signal AI meta optimization triggered for ${result.meta_optimization.pages_queued} pages`)\n console.log(`[Sonor] (Running in background - check Portal SEO module for results)`)\n }\n process.exit(0)\n } else {\n console.error('[Sonor] ✗ Failed to register sitemap')\n process.exit(1)\n }\n } catch (error) {\n console.error('[Sonor] ✗ Error:', error)\n process.exit(1)\n }\n}\n\nmain()\n","/**\n * Brand Profile Extraction\n *\n * Extracts the visual design DNA from a Next.js project's source files:\n * - globals.css: CSS custom properties (colors, fonts, theme)\n * - tailwind.config.js/ts: extended colors, fontFamily\n * - design-system.ts: explicit color palettes (if present)\n *\n * The extracted profile is pushed to Sonor alongside sitemap registration,\n * giving Signal AI full brand awareness for image generation, blog context,\n * and portfolio design decisions.\n *\n * This is static file analysis (regex, not AST) — runs at build time in Node.\n */\n\nimport fs from 'fs'\nimport path from 'path'\n\nexport interface BrandProfile {\n colors: {\n primary?: string\n secondary?: string\n accent?: string\n background?: string\n surface?: string\n text?: string\n gradient?: string\n }\n typography: {\n heading?: string\n body?: string\n mono?: string\n }\n theme: 'dark' | 'light'\n style_keywords: string[]\n border_radius?: string\n captured_at: string\n}\n\n/**\n * Detect whether a hex color is \"dark\" (luminance < 0.5)\n */\nfunction isDarkColor(hex: string): boolean {\n const c = hex.replace('#', '')\n if (c.length < 6) return false\n const r = parseInt(c.substring(0, 2), 16) / 255\n const g = parseInt(c.substring(2, 4), 16) / 255\n const b = parseInt(c.substring(4, 6), 16) / 255\n // Relative luminance (ITU-R BT.709)\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b\n return luminance < 0.35\n}\n\n/**\n * Extract CSS custom properties from a CSS file's :root block\n */\nfunction extractCssVariables(css: string): Record<string, string> {\n const vars: Record<string, string> = {}\n // Match :root { ... } blocks (may be multiple)\n const rootBlocks = css.match(/:root\\s*\\{[^}]+\\}/g)\n if (!rootBlocks) return vars\n\n for (const block of rootBlocks) {\n const matches = block.matchAll(/--([a-zA-Z0-9_-]+)\\s*:\\s*([^;]+)/g)\n for (const m of matches) {\n const name = m[1].trim()\n const value = m[2].trim()\n // Skip var() references and rgb() values — we want hex/named colors\n if (!value.startsWith('var(')) {\n vars[name] = value\n }\n }\n }\n return vars\n}\n\n/**\n * Try to find the \"primary\" brand color from CSS variables\n */\nfunction findColor(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val && val.startsWith('#')) return val\n }\n return undefined\n}\n\n/**\n * Extract font family from CSS variable or Tailwind config\n */\nfunction extractFontFromCss(vars: Record<string, string>, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const val = vars[key]\n if (val) {\n // Extract first font name: \"'Inter', system-ui\" -> \"Inter\"\n const match = val.match(/['\"]?([A-Za-z][A-Za-z0-9 _-]+)['\"]?/)\n return match?.[1]?.trim()\n }\n }\n return undefined\n}\n\n/**\n * Extract from Tailwind config — reads as text, uses regex (no require/import)\n */\nfunction extractFromTailwindConfig(configPath: string): {\n colors: Record<string, string>\n fonts: Record<string, string>\n} {\n const colors: Record<string, string> = {}\n const fonts: Record<string, string> = {}\n\n if (!fs.existsSync(configPath)) return { colors, fonts }\n\n const content = fs.readFileSync(configPath, 'utf-8')\n\n // Extract fontFamily entries: fontFamily: { sans: ['var(--font-satoshi)', ...] }\n const fontMatches = content.matchAll(/(?:fontFamily|font-family)\\s*:\\s*\\{([^}]+)\\}/g)\n for (const m of fontMatches) {\n const block = m[1]\n // Match: sans: ['Satoshi', ...] or sans: ['var(--font-satoshi)', ...]\n const entries = block.matchAll(/(\\w+)\\s*:\\s*\\[([^\\]]+)\\]/g)\n for (const e of entries) {\n const key = e[1] // sans, serif, mono\n const values = e[2]\n // Extract first real font name (not var())\n const varMatch = values.match(/var\\(--font-([a-z0-9-]+)\\)/)\n if (varMatch) {\n fonts[key] = varMatch[1].charAt(0).toUpperCase() + varMatch[1].slice(1) // capitalize\n } else {\n const nameMatch = values.match(/['\"]([A-Za-z][A-Za-z0-9 -]+)['\"]/)\n if (nameMatch) fonts[key] = nameMatch[1]\n }\n }\n }\n\n return { colors, fonts }\n}\n\n/**\n * Extract from design-system.ts if it exists\n */\nfunction extractFromDesignSystem(filePath: string): {\n primary?: string\n secondary?: string\n accent?: string\n gradient?: string\n} {\n if (!fs.existsSync(filePath)) return {}\n\n const content = fs.readFileSync(filePath, 'utf-8')\n\n // Look for default/fallback color definitions\n const result: Record<string, string> = {}\n\n // Match: primary: '#54b948'\n const colorMatches = content.matchAll(/(primary|secondary|accent)\\s*:\\s*['\"]([#a-fA-F0-9]+)['\"]/g)\n for (const m of colorMatches) {\n // Take the LAST match (usually the default/fallback)\n result[m[1]] = m[2]\n }\n\n // Match gradient: 'linear-gradient(...)'\n const gradientMatch = content.match(/gradient(?:Css)?\\s*:\\s*['\"]([^'\"]+)['\"]/)\n if (gradientMatch) {\n result.gradient = gradientMatch[1]\n }\n\n return result\n}\n\n/**\n * Infer style keywords from the extracted data\n */\nfunction inferStyleKeywords(\n theme: 'dark' | 'light',\n vars: Record<string, string>,\n tailwindContent?: string,\n): string[] {\n const keywords: string[] = []\n\n keywords.push(theme === 'dark' ? 'dark' : 'light')\n keywords.push('modern')\n\n // Check for specific patterns\n if (tailwindContent) {\n if (tailwindContent.includes('backdrop-blur') || tailwindContent.includes('glass')) keywords.push('glass')\n if (tailwindContent.includes('gradient')) keywords.push('gradient')\n if (tailwindContent.includes('rounded-full') || tailwindContent.includes('rounded-3xl')) keywords.push('rounded')\n if (tailwindContent.includes('animate-') || tailwindContent.includes('framer-motion')) keywords.push('animated')\n }\n\n // Check font styles\n const allVars = Object.values(vars).join(' ').toLowerCase()\n if (allVars.includes('mono') || allVars.includes('code') || allVars.includes('jetbrains')) keywords.push('tech')\n if (allVars.includes('serif') || allVars.includes('georgia') || allVars.includes('playfair')) keywords.push('editorial')\n\n return [...new Set(keywords)]\n}\n\n/**\n * Main extraction function — scans the project directory\n */\nexport function extractBrandProfile(projectDir?: string): BrandProfile | null {\n const cwd = projectDir || process.cwd()\n\n // Find globals.css\n const globalsLocations = [\n path.join(cwd, 'app', 'globals.css'),\n path.join(cwd, 'src', 'app', 'globals.css'),\n path.join(cwd, 'styles', 'globals.css'),\n ]\n\n let cssVars: Record<string, string> = {}\n let globalsCss = ''\n for (const loc of globalsLocations) {\n if (fs.existsSync(loc)) {\n globalsCss = fs.readFileSync(loc, 'utf-8')\n cssVars = extractCssVariables(globalsCss)\n break\n }\n }\n\n // Find tailwind config\n const tailwindLocations = [\n path.join(cwd, 'tailwind.config.js'),\n path.join(cwd, 'tailwind.config.ts'),\n path.join(cwd, 'tailwind.config.mjs'),\n ]\n\n let tailwindResult = { colors: {} as Record<string, string>, fonts: {} as Record<string, string> }\n let tailwindContent = ''\n for (const loc of tailwindLocations) {\n if (fs.existsSync(loc)) {\n tailwindContent = fs.readFileSync(loc, 'utf-8')\n tailwindResult = extractFromTailwindConfig(loc)\n break\n }\n }\n\n // Find design-system.ts\n const designSystemLocations = [\n path.join(cwd, 'design-system.ts'),\n path.join(cwd, 'src', 'design-system.ts'),\n path.join(cwd, 'lib', 'design-system.ts'),\n ]\n\n let designSystem: ReturnType<typeof extractFromDesignSystem> = {}\n for (const loc of designSystemLocations) {\n if (fs.existsSync(loc)) {\n designSystem = extractFromDesignSystem(loc)\n break\n }\n }\n\n // If we found nothing at all, skip\n if (Object.keys(cssVars).length === 0 && !tailwindContent && Object.keys(designSystem).length === 0) {\n return null\n }\n\n // === Build the profile ===\n\n // Colors — priority: CSS vars > design-system > tailwind\n const primary = findColor(cssVars,\n 'color-accent', 'sk-primary', 'color-primary', 'color-brand', 'brand-primary',\n ) || designSystem.primary\n\n const secondary = findColor(cssVars,\n 'color-accent-dark', 'sk-secondary', 'color-secondary',\n ) || designSystem.secondary\n\n const accent = findColor(cssVars,\n 'color-accent-light', 'sk-accent', 'color-accent-light',\n ) || designSystem.accent\n\n const background = findColor(cssVars,\n 'color-charcoal', 'sk-bg', 'color-bg', 'color-background',\n 'background', 'bg',\n )\n\n const surface = findColor(cssVars,\n 'color-charcoal-light', 'sk-surface', 'color-surface', 'sk-bg-elevated',\n )\n\n const textColor = findColor(cssVars,\n 'sk-text-primary', 'color-text', 'color-text-primary',\n )\n\n const gradient = designSystem.gradient || undefined\n\n // Typography — priority: tailwind fontFamily > CSS vars\n const headingFont = tailwindResult.fonts.sans || tailwindResult.fonts.heading ||\n extractFontFromCss(cssVars, 'font-heading', 'font-display', 'font-sans')\n const bodyFont = tailwindResult.fonts.sans || tailwindResult.fonts.body ||\n extractFontFromCss(cssVars, 'font-body', 'font-sans')\n const monoFont = tailwindResult.fonts.mono ||\n extractFontFromCss(cssVars, 'font-mono', 'font-code')\n\n // Theme detection — check if background is dark\n const theme: 'dark' | 'light' = (background && isDarkColor(background)) ? 'dark' :\n globalsCss.includes('.dark') || globalsCss.includes('dark:') ? 'dark' : 'light'\n\n // Style keywords\n const styleKeywords = inferStyleKeywords(theme, cssVars, tailwindContent + globalsCss)\n\n // Border radius — look for common patterns\n const radiusMatch = globalsCss.match(/border-radius\\s*:\\s*([^;]+)/) ||\n tailwindContent.match(/borderRadius\\s*:\\s*\\{[^}]*DEFAULT\\s*:\\s*['\"]([^'\"]+)['\"]/)\n const borderRadius = radiusMatch?.[1]?.trim()\n\n const profile: BrandProfile = {\n colors: {\n ...(primary && { primary }),\n ...(secondary && { secondary }),\n ...(accent && { accent }),\n ...(background && { background }),\n ...(surface && { surface }),\n ...(textColor && { text: textColor }),\n ...(gradient && { gradient }),\n },\n typography: {\n ...(headingFont && { heading: headingFont }),\n ...(bodyFont && { body: bodyFont }),\n ...(monoFont && { mono: monoFont }),\n },\n theme,\n style_keywords: styleKeywords,\n ...(borderRadius && { border_radius: borderRadius }),\n captured_at: new Date().toISOString(),\n }\n\n // Only return if we got meaningful data\n const hasColors = Object.keys(profile.colors).length > 0\n const hasTypography = Object.keys(profile.typography).length > 0\n\n if (!hasColors && !hasTypography) return null\n\n return profile\n}\n\n/**\n * Push brand profile to Sonor API\n */\nexport async function pushBrandProfile(profile: BrandProfile): Promise<boolean> {\n const apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = process.env.SONOR_API_KEY || ''\n\n if (!apiKey) {\n console.warn('[Sonor] No API key — skipping brand profile push')\n return false\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/seo/brand-profile`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(profile),\n })\n\n if (!response.ok) {\n console.warn(`[Sonor] Brand profile push failed: ${response.status}`)\n return false\n }\n\n const result = await response.json()\n console.log(`[Sonor] Brand profile pushed: theme=${profile.theme}, ${Object.keys(profile.colors).length} colors`)\n return result.success\n } catch (err) {\n console.warn(`[Sonor] Brand profile push error: ${err}`)\n return false\n }\n}\n","/**\n * Standalone implementation for the sonor-register-sitemap CLI.\n * Does NOT import from server-api or routing, so it can run in Node without\n * pulling in server-only (which throws when required outside Next.js server context).\n *\n * Route discovery + page classification live in `../sitemap/discover` and\n * `../sitemap/shared` (shared with createSitemap, SitemapSync, and the routing\n * helper) — see those files for the sitemap-oscillation background.\n */\n\nimport path from 'path'\nimport { extractBrandProfile, pushBrandProfile } from '../brand/extract-brand-profile'\nimport { inferPageType } from '../sitemap/shared'\nimport {\n discoverNextJsRoutes,\n findAppDirForDiscovery,\n findSitemapRoute,\n} from '../sitemap/discover'\n\nfunction getApiConfig(): { apiUrl: string; apiKey: string } {\n const apiUrl =\n process.env.SONOR_API_URL ||\n 'https://api.sonor.io'\n const apiKey =\n process.env.SONOR_API_KEY ||\n ''\n return { apiUrl, apiKey }\n}\n\nasync function registerSitemapViaApi(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: string\n description?: string\n pageType?: string\n }>,\n optimizeMeta: boolean,\n mode: 'additive' | 'full-replace',\n): Promise<{\n success: boolean\n created: number\n updated: number\n removed?: number\n meta_optimization?: { triggered: boolean; pages_queued: number } | null\n}> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n console.warn(\n '[Sonor] No API key (SONOR_API_KEY)',\n )\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, optimize_meta: optimizeMeta, mode }),\n })\n\n if (!response.ok) {\n console.error(`[Sonor] Sitemap registration failed: ${response.status} ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n\n return await response.json()\n } catch (error) {\n console.error('[Sonor] Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\nexport type RegisterLocalSitemapOptions = {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n description?: string\n pageType?: string\n }>\n autoDiscover?: boolean\n optimize_meta?: boolean\n /**\n * Sync mode. Defaults to `'additive'` for auto-discovered route sets — a\n * filesystem scan is structurally incomplete (it can't enumerate dynamic\n * route params and ignores the app's sitemap exclude config), so it must\n * never drive a `'full-replace'` that would delete the pages it can't see.\n * Pure-static sites that want removed pages pruned can opt back in with\n * `'full-replace'`.\n */\n mode?: 'additive' | 'full-replace'\n}\n\nexport type RegisterLocalSitemapResult = {\n success: boolean\n created: number\n updated: number\n removed?: number\n /** True when the sync was intentionally skipped (a sitemap route owns it). */\n skipped?: boolean\n meta_optimization?: {\n triggered: boolean\n pages_queued: number\n } | null\n}\n\nexport async function registerLocalSitemap(\n options: RegisterLocalSitemapOptions\n): Promise<RegisterLocalSitemapResult> {\n let entries = options.entries || []\n const usingAutoDiscover = !!options.autoDiscover && entries.length === 0\n\n let result: RegisterLocalSitemapResult\n\n // SAFETY GUARD: never let a filesystem scan fight an authoritative sitemap.\n // If the app has a Next.js sitemap route (app/sitemap.{ts,js}, which\n // createSitemap syncs as a full-replace, and which site-kit's runtime\n // SitemapSync mirrors additively), an --auto-discover full-replace from an\n // incomplete fs scan would delete every dynamic-route page on every build and\n // the two syncs would oscillate — destroying managed metadata, Signal\n // optimizations, LLM schemas, and GSC history. Skip and let the route own it.\n const sitemapRoute = usingAutoDiscover ? findSitemapRoute() : null\n\n if (sitemapRoute) {\n console.warn(\n `[Sonor] Skipping --auto-discover: ${sitemapRoute} already handles build-time ` +\n `sitemap sync, and its /sitemap.xml is mirrored to Sonor at runtime. A ` +\n `filesystem scan can't see dynamic routes, so syncing it here would delete ` +\n `real pages and fight the route on every build. Nothing to do — this line ` +\n `is safe to leave in your postbuild.`,\n )\n result = { success: true, created: 0, updated: 0, skipped: true }\n } else {\n if (usingAutoDiscover) {\n const appDir = findAppDirForDiscovery()\n if (appDir) {\n entries = discoverNextJsRoutes(appDir)\n console.log(`[Sonor] Auto-discovered ${entries.length} routes from ${path.relative(process.cwd(), appDir)}`)\n }\n }\n\n if (entries.length === 0) {\n console.warn('[Sonor] No sitemap entries to register')\n result = { success: true, created: 0, updated: 0 }\n } else {\n // Auto-discovered sets are additive by default (incomplete → never delete).\n // Explicit entry lists keep the caller-provided mode, defaulting to\n // full-replace only when the caller asserts a complete set via `mode`.\n const mode: 'additive' | 'full-replace' =\n options.mode ?? (usingAutoDiscover ? 'additive' : 'full-replace')\n\n console.log(`[Sonor] Registering ${entries.length} sitemap entries (mode: ${mode})...`)\n const payload = entries.map((e) => ({\n path: e.path,\n title: e.title,\n priority: e.priority,\n changefreq: e.changefreq,\n ...(e.description ? { description: e.description } : {}),\n pageType: e.pageType ?? inferPageType(e.path),\n }))\n result = await registerSitemapViaApi(\n payload,\n options.optimize_meta !== false,\n mode,\n )\n\n if (result.success) {\n console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n }\n }\n\n // Push brand profile whenever the CLI did real work — a sync ran, or we\n // skipped because a sitemap route owns the sync — but not on the degenerate\n // \"nothing to register\" path (preserving prior behavior). It's an independent\n // side effect (a separate endpoint), so it must survive the skip path: keeping\n // the postbuild line shouldn't silently stop refreshing brand awareness.\n // Fire-and-forget, non-blocking.\n const didMeaningfulWork = result.skipped === true || entries.length > 0\n if (result.success && didMeaningfulWork) {\n try {\n const brandProfile = extractBrandProfile()\n if (brandProfile) {\n await pushBrandProfile(brandProfile)\n }\n } catch (brandErr) {\n // Non-fatal — brand profile is supplementary\n console.debug(`[Sonor] Brand profile extraction skipped: ${brandErr}`)\n }\n }\n\n return result\n}\n"]}
|