@sonordev/site-kit 1.5.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AnalyticsProvider-J7UMCBCJ.mjs +4 -0
- package/dist/{AnalyticsProvider-BBLU4U2T.mjs.map → AnalyticsProvider-J7UMCBCJ.mjs.map} +1 -1
- package/dist/AnalyticsProvider-PPDJIGWY.js +25 -0
- package/dist/{AnalyticsProvider-EMDIAAWR.js.map → AnalyticsProvider-PPDJIGWY.js.map} +1 -1
- package/dist/EngageWidget-IDBEBGQR.js +13 -0
- package/dist/{EngageWidget-UHWXXCAX.js.map → EngageWidget-IDBEBGQR.js.map} +1 -1
- package/dist/EngageWidget-SRRI4W7U.mjs +4 -0
- package/dist/{EngageWidget-CVZMTSB6.mjs.map → EngageWidget-SRRI4W7U.mjs.map} +1 -1
- package/dist/SignalBridge-D6W6OLVG.mjs +4 -0
- package/dist/{SignalBridge-WGHMEILW.mjs.map → SignalBridge-D6W6OLVG.mjs.map} +1 -1
- package/dist/SignalBridge-THATXU2R.js +33 -0
- package/dist/{SignalBridge-6UYUZ2CN.js.map → SignalBridge-THATXU2R.js.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +2 -2
- package/dist/blog/index.js +75 -75
- package/dist/blog/index.js.map +1 -1
- package/dist/blog/index.mjs +75 -75
- package/dist/blog/index.mjs.map +1 -1
- package/dist/blog/server.js +2 -2
- package/dist/blog/server.js.map +1 -1
- package/dist/blog/server.mjs +2 -2
- package/dist/blog/server.mjs.map +1 -1
- package/dist/brand.css +87 -0
- package/dist/{chunk-ZU6YPEAF.mjs → chunk-2OJCYWSQ.mjs} +85 -73
- package/dist/chunk-2OJCYWSQ.mjs.map +1 -0
- package/dist/{chunk-PM2KQ6YK.mjs → chunk-3CXAWGUP.mjs} +3 -3
- package/dist/{chunk-PM2KQ6YK.mjs.map → chunk-3CXAWGUP.mjs.map} +1 -1
- package/dist/{chunk-36Y7OWES.mjs → chunk-3YQCPLGP.mjs} +4 -4
- package/dist/chunk-3YQCPLGP.mjs.map +1 -0
- package/dist/{chunk-XWWBUC2I.js → chunk-6ZGM7S5O.js} +77 -61
- package/dist/chunk-6ZGM7S5O.js.map +1 -0
- package/dist/{chunk-XFOL6JDF.mjs → chunk-7LAOWIWE.mjs} +4 -4
- package/dist/chunk-7LAOWIWE.mjs.map +1 -0
- package/dist/{chunk-YBTYDBWY.js → chunk-7M3FNAS5.js} +6 -8
- package/dist/chunk-7M3FNAS5.js.map +1 -0
- package/dist/{chunk-4QHHFCAA.mjs → chunk-AOIG5PVY.mjs} +6 -8
- package/dist/chunk-AOIG5PVY.mjs.map +1 -0
- package/dist/{chunk-VZMDH3R4.mjs → chunk-B22WSN4L.mjs} +4 -4
- package/dist/chunk-B22WSN4L.mjs.map +1 -0
- package/dist/{chunk-ELDJDBQL.js → chunk-BVUOATPG.js} +7 -7
- package/dist/chunk-BVUOATPG.js.map +1 -0
- package/dist/{chunk-N24BPFF6.mjs → chunk-CU6OGBKK.mjs} +6 -6
- package/dist/chunk-CU6OGBKK.mjs.map +1 -0
- package/dist/{chunk-NRNK7LXK.mjs → chunk-DWI5ZKPM.mjs} +4 -4
- package/dist/chunk-DWI5ZKPM.mjs.map +1 -0
- package/dist/{chunk-KRPFLF62.mjs → chunk-F5NXD7VQ.mjs} +10 -12
- package/dist/{chunk-KRPFLF62.mjs.map → chunk-F5NXD7VQ.mjs.map} +1 -1
- package/dist/{chunk-PTTDKFL7.js → chunk-FCXQECM7.js} +6 -6
- package/dist/chunk-FCXQECM7.js.map +1 -0
- package/dist/{chunk-DY4K6X3A.js → chunk-GCPPXUAI.js} +6 -6
- package/dist/chunk-GCPPXUAI.js.map +1 -0
- package/dist/{chunk-KJN2C6YE.js → chunk-I34XL5VJ.js} +5 -5
- package/dist/chunk-I34XL5VJ.js.map +1 -0
- package/dist/{chunk-G6VGUAK2.js → chunk-IFVMZFNT.js} +4 -4
- package/dist/chunk-IFVMZFNT.js.map +1 -0
- package/dist/{chunk-FMB2RZDH.mjs → chunk-J4U3IEXL.mjs} +6 -6
- package/dist/chunk-J4U3IEXL.mjs.map +1 -0
- package/dist/{chunk-EUNL6GAL.js → chunk-JP5WGL75.js} +4 -4
- package/dist/chunk-JP5WGL75.js.map +1 -0
- package/dist/{chunk-MG23BS36.js → chunk-L3UB4B74.js} +5 -5
- package/dist/chunk-L3UB4B74.js.map +1 -0
- package/dist/{chunk-FVCQBTNK.mjs → chunk-MSRLAD7F.mjs} +77 -61
- package/dist/chunk-MSRLAD7F.mjs.map +1 -0
- package/dist/{chunk-M5FLRLHI.mjs → chunk-OM6R7CDP.mjs} +3 -3
- package/dist/chunk-OM6R7CDP.mjs.map +1 -0
- package/dist/{chunk-4X5TFGKD.mjs → chunk-P3POHQWW.mjs} +422 -426
- package/dist/chunk-P3POHQWW.mjs.map +1 -0
- package/dist/{chunk-GJD4CFHN.js → chunk-RLNG67S5.js} +7 -7
- package/dist/chunk-RLNG67S5.js.map +1 -0
- package/dist/{chunk-FTSXKDP3.js → chunk-RO6DHV6S.js} +10 -12
- package/dist/{chunk-FTSXKDP3.js.map → chunk-RO6DHV6S.js.map} +1 -1
- package/dist/{chunk-WW7UM7XY.js → chunk-TZAD7CZD.js} +424 -428
- package/dist/chunk-TZAD7CZD.js.map +1 -0
- package/dist/{chunk-TXZNP76P.js → chunk-UD5447TC.js} +13 -15
- package/dist/chunk-UD5447TC.js.map +1 -0
- package/dist/{chunk-TC6TOW2T.js → chunk-UJ757WGI.js} +4 -4
- package/dist/{chunk-TC6TOW2T.js.map → chunk-UJ757WGI.js.map} +1 -1
- package/dist/{chunk-C3A5HXHX.mjs → chunk-V6V6OXS2.mjs} +5 -5
- package/dist/chunk-V6V6OXS2.mjs.map +1 -0
- package/dist/{chunk-X4J33XQD.js → chunk-W6K7MQCC.js} +6 -6
- package/dist/chunk-W6K7MQCC.js.map +1 -0
- package/dist/{chunk-FI2ME55T.mjs → chunk-W7RZ3OTA.mjs} +7 -7
- package/dist/chunk-W7RZ3OTA.mjs.map +1 -0
- package/dist/{chunk-IJ2LWZID.js → chunk-WETCVFIK.js} +85 -73
- package/dist/chunk-WETCVFIK.js.map +1 -0
- package/dist/{chunk-VNAJQKYG.mjs → chunk-WN2PUL6B.mjs} +13 -15
- package/dist/chunk-WN2PUL6B.mjs.map +1 -0
- package/dist/cli/index.js +19339 -3461
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +19331 -3452
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cms/index.d.mts +1 -1
- package/dist/cms/index.d.ts +1 -1
- package/dist/cms/index.js +3 -3
- package/dist/cms/index.js.map +1 -1
- package/dist/cms/index.mjs +2 -2
- package/dist/cms/index.mjs.map +1 -1
- package/dist/cms/server.js +4 -4
- package/dist/cms/server.mjs +1 -1
- package/dist/commerce/index.js +47 -47
- package/dist/commerce/index.mjs +3 -3
- package/dist/engage/index.js +6 -6
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +3 -3
- package/dist/engage/index.mjs.map +1 -1
- package/dist/forms/index.js +379 -84
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +375 -65
- package/dist/forms/index.mjs.map +1 -1
- package/dist/forms/styles.css +312 -0
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +2 -2
- package/dist/images/server.js +4 -4
- package/dist/images/server.mjs +1 -1
- package/dist/index.d.mts +4 -131
- package/dist/index.d.ts +4 -131
- package/dist/index.js +85 -1373
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -1294
- package/dist/index.mjs.map +1 -1
- package/dist/layout/client.js +2 -2
- package/dist/layout/client.mjs +1 -1
- package/dist/layout/index.js +21 -11
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +17 -7
- package/dist/layout/index.mjs.map +1 -1
- package/dist/llms/index.d.mts +3 -3
- package/dist/llms/index.d.ts +3 -3
- package/dist/llms/index.js +12 -12
- package/dist/llms/index.js.map +1 -1
- package/dist/llms/index.mjs +2 -2
- package/dist/llms/index.mjs.map +1 -1
- package/dist/manifest/index.js +4 -4
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/index.mjs +3 -3
- package/dist/manifest/index.mjs.map +1 -1
- package/dist/middleware/index.js +3 -3
- package/dist/middleware/index.mjs +2 -2
- package/dist/redirects/index.js +6 -6
- package/dist/redirects/index.mjs +2 -2
- package/dist/robots/index.js +3 -3
- package/dist/robots/index.js.map +1 -1
- package/dist/robots/index.mjs +2 -2
- package/dist/robots/index.mjs.map +1 -1
- package/dist/{routing-DZYzyDHw.d.ts → routing-DQ_Et-OP.d.mts} +4 -4
- package/dist/{routing-B5XS-6_W.d.mts → routing-IYiJNIIX.d.ts} +4 -4
- package/dist/seo/index.d.mts +3 -5
- package/dist/seo/index.d.ts +3 -5
- package/dist/seo/index.js +77 -76
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +41 -40
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/register-sitemap-cli.js +3 -3
- package/dist/seo/register-sitemap-cli.js.map +1 -1
- package/dist/seo/register-sitemap-cli.mjs +3 -3
- package/dist/seo/register-sitemap-cli.mjs.map +1 -1
- package/dist/seo/server.d.mts +3 -3
- package/dist/seo/server.d.ts +3 -3
- package/dist/seo/server.js +7 -7
- package/dist/seo/server.js.map +1 -1
- package/dist/seo/server.mjs +5 -5
- package/dist/seo/server.mjs.map +1 -1
- package/dist/{server-api-XGKRGUMG.js → server-api-36R24YWN.js} +21 -21
- package/dist/{server-api-XGKRGUMG.js.map → server-api-36R24YWN.js.map} +1 -1
- package/dist/{server-api-COVFLFZ2.mjs → server-api-UIZU4JM3.mjs} +3 -3
- package/dist/{server-api-COVFLFZ2.mjs.map → server-api-UIZU4JM3.mjs.map} +1 -1
- package/dist/setup/index.d.mts +2 -5
- package/dist/setup/index.d.ts +2 -5
- package/dist/setup/index.js +0 -31
- package/dist/setup/index.mjs +1 -4
- package/dist/site-config/index.js +3 -3
- package/dist/site-config/index.mjs +1 -1
- package/dist/sitemap/index.js +10 -9
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +8 -7
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/sync/index.js +13 -13
- package/dist/sync/index.mjs +1 -1
- package/dist/{types-KZP_VWZp.d.mts → types-CGkyylOa.d.mts} +2 -2
- package/dist/{types-KZP_VWZp.d.ts → types-CGkyylOa.d.ts} +2 -2
- package/package.json +4 -12
- package/dist/AnalyticsProvider-BBLU4U2T.mjs +0 -4
- package/dist/AnalyticsProvider-EMDIAAWR.js +0 -25
- package/dist/EngageWidget-CVZMTSB6.mjs +0 -4
- package/dist/EngageWidget-UHWXXCAX.js +0 -13
- package/dist/SetupWizard-Cki06kB0.d.mts +0 -12
- package/dist/SetupWizard-Cki06kB0.d.ts +0 -12
- package/dist/SignalBridge-6UYUZ2CN.js +0 -33
- package/dist/SignalBridge-WGHMEILW.mjs +0 -4
- package/dist/chunk-36Y7OWES.mjs.map +0 -1
- package/dist/chunk-373TK6TZ.js +0 -321
- package/dist/chunk-373TK6TZ.js.map +0 -1
- package/dist/chunk-4MOJJSNA.js +0 -14867
- package/dist/chunk-4MOJJSNA.js.map +0 -1
- package/dist/chunk-4QHHFCAA.mjs.map +0 -1
- package/dist/chunk-4X5TFGKD.mjs.map +0 -1
- package/dist/chunk-5YDPPOUU.mjs +0 -810
- package/dist/chunk-5YDPPOUU.mjs.map +0 -1
- package/dist/chunk-7FKPJQVS.mjs +0 -289
- package/dist/chunk-7FKPJQVS.mjs.map +0 -1
- package/dist/chunk-C3A5HXHX.mjs.map +0 -1
- package/dist/chunk-DY4K6X3A.js.map +0 -1
- package/dist/chunk-ELDJDBQL.js.map +0 -1
- package/dist/chunk-EUNL6GAL.js.map +0 -1
- package/dist/chunk-FI2ME55T.mjs.map +0 -1
- package/dist/chunk-FMB2RZDH.mjs.map +0 -1
- package/dist/chunk-FVCQBTNK.mjs.map +0 -1
- package/dist/chunk-G6VGUAK2.js.map +0 -1
- package/dist/chunk-GJD4CFHN.js.map +0 -1
- package/dist/chunk-GVXZWXQ7.js +0 -814
- package/dist/chunk-GVXZWXQ7.js.map +0 -1
- package/dist/chunk-HF2FWDBJ.mjs +0 -968
- package/dist/chunk-HF2FWDBJ.mjs.map +0 -1
- package/dist/chunk-IFAW7JFO.js +0 -1429
- package/dist/chunk-IFAW7JFO.js.map +0 -1
- package/dist/chunk-IJ2LWZID.js.map +0 -1
- package/dist/chunk-IKIJEKU3.mjs +0 -1427
- package/dist/chunk-IKIJEKU3.mjs.map +0 -1
- package/dist/chunk-JFTGG6HK.mjs +0 -14848
- package/dist/chunk-JFTGG6HK.mjs.map +0 -1
- package/dist/chunk-JM3ZR6LB.js +0 -981
- package/dist/chunk-JM3ZR6LB.js.map +0 -1
- package/dist/chunk-KJN2C6YE.js.map +0 -1
- package/dist/chunk-M5FLRLHI.mjs.map +0 -1
- package/dist/chunk-MCGLYYAR.mjs +0 -341
- package/dist/chunk-MCGLYYAR.mjs.map +0 -1
- package/dist/chunk-MG23BS36.js.map +0 -1
- package/dist/chunk-N24BPFF6.mjs.map +0 -1
- package/dist/chunk-NRNK7LXK.mjs.map +0 -1
- package/dist/chunk-PTTDKFL7.js.map +0 -1
- package/dist/chunk-S7FRYNSU.mjs +0 -315
- package/dist/chunk-S7FRYNSU.mjs.map +0 -1
- package/dist/chunk-SLB5V4RT.js +0 -302
- package/dist/chunk-SLB5V4RT.js.map +0 -1
- package/dist/chunk-TXZNP76P.js.map +0 -1
- package/dist/chunk-VNAJQKYG.mjs.map +0 -1
- package/dist/chunk-VZMDH3R4.mjs.map +0 -1
- package/dist/chunk-WW7UM7XY.js.map +0 -1
- package/dist/chunk-X4J33XQD.js.map +0 -1
- package/dist/chunk-XFOL6JDF.mjs.map +0 -1
- package/dist/chunk-XWWBUC2I.js.map +0 -1
- package/dist/chunk-YBTYDBWY.js.map +0 -1
- package/dist/chunk-ZQO6FZZB.js +0 -343
- package/dist/chunk-ZQO6FZZB.js.map +0 -1
- package/dist/chunk-ZU6YPEAF.mjs.map +0 -1
- package/dist/generators-DOFWGRXS.js +0 -37
- package/dist/generators-DOFWGRXS.js.map +0 -1
- package/dist/generators-R62APO62.mjs +0 -4
- package/dist/generators-R62APO62.mjs.map +0 -1
- package/dist/migrator-3WQB3KQ2.mjs +0 -4
- package/dist/migrator-3WQB3KQ2.mjs.map +0 -1
- package/dist/migrator-HFVQYK5R.js +0 -37
- package/dist/migrator-HFVQYK5R.js.map +0 -1
- package/dist/scanner-AF7YUCFG.mjs +0 -4
- package/dist/scanner-AF7YUCFG.mjs.map +0 -1
- package/dist/scanner-DBD5K6F7.js +0 -53
- package/dist/scanner-DBD5K6F7.js.map +0 -1
- package/dist/setup/client.d.mts +0 -60
- package/dist/setup/client.d.ts +0 -60
- package/dist/setup/client.js +0 -31
- package/dist/setup/client.js.map +0 -1
- package/dist/setup/client.mjs +0 -6
- package/dist/setup/client.mjs.map +0 -1
- package/dist/setup/server.d.mts +0 -14
- package/dist/setup/server.d.ts +0 -14
- package/dist/setup/server.js +0 -13
- package/dist/setup/server.js.map +0 -1
- package/dist/setup/server.mjs +0 -4
- package/dist/setup/server.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/setup/integration-generator.ts","../src/setup/IntegrationCodeView.tsx"],"names":[],"mappings":"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","file":"chunk-5YDPPOUU.mjs","sourcesContent":["/**\n * Integration Code Generator\n * \n * Generates site-kit integration code snippets based on enabled modules.\n * Used by SetupWizard and can be called standalone.\n */\n\nexport interface IntegrationSnippet {\n module: string\n snippetType: 'install' | 'layout' | 'component' | 'page' | 'api-route' | 'env'\n title: string\n description?: string\n filePath?: string\n code: string\n language: 'typescript' | 'tsx' | 'bash' | 'env'\n order: number\n required: boolean\n}\n\nexport interface GeneratorContext {\n projectId: string\n projectName?: string\n apiUrl?: string\n enabledModules: string[]\n brand?: {\n primaryColor?: string\n secondaryColor?: string\n businessName?: string\n }\n}\n\n/**\n * Generate all integration code snippets for enabled modules\n */\nexport function generateIntegrationCode(context: GeneratorContext): IntegrationSnippet[] {\n const snippets: IntegrationSnippet[] = []\n const apiUrl = context.apiUrl || 'https://api.sonor.io'\n let order = 0\n\n // Always add provider setup first\n snippets.push(...generateProviderSnippets(context, apiUrl, order))\n order += 10\n\n // Add module-specific snippets\n for (const module of context.enabledModules) {\n switch (module) {\n case 'analytics':\n snippets.push(...generateAnalyticsSnippets(context, order))\n order += 10\n break\n case 'engage':\n snippets.push(...generateEngageSnippets(context, order))\n order += 10\n break\n case 'forms':\n snippets.push(...generateFormsSnippets(context, order))\n order += 10\n break\n case 'commerce':\n snippets.push(...generateCommerceSnippets(context, order))\n order += 10\n break\n case 'seo':\n snippets.push(...generateSEOSnippets(context, order))\n order += 10\n break\n case 'blog':\n snippets.push(...generateBlogSnippets(context, order))\n order += 10\n break\n }\n }\n\n return snippets\n}\n\n/**\n * Get snippets grouped by module\n */\nexport function getSnippetsByModule(snippets: IntegrationSnippet[]): Record<string, IntegrationSnippet[]> {\n return snippets.reduce((acc, snippet) => {\n if (!acc[snippet.module]) {\n acc[snippet.module] = []\n }\n acc[snippet.module].push(snippet)\n return acc\n }, {} as Record<string, IntegrationSnippet[]>)\n}\n\n// ============================================\n// Provider Snippets (always required)\n// ============================================\n\nfunction generateProviderSnippets(ctx: GeneratorContext, apiUrl: string, startOrder: number): IntegrationSnippet[] {\n const enabledModulesConfig = ctx.enabledModules\n .map(m => {\n if (m === 'analytics') return ' analytics={{ enabled: true }}'\n if (m === 'engage') return ' engage={{ enabled: true }}'\n return null\n })\n .filter(Boolean)\n .join('\\n')\n\n return [\n {\n module: 'provider',\n snippetType: 'install',\n title: 'Install @sonordev/site-kit',\n description: 'Install the Sonor Site Kit package',\n code: `pnpm add @sonordev/site-kit`,\n language: 'bash',\n order: startOrder,\n required: true,\n },\n {\n module: 'provider',\n snippetType: 'env',\n title: 'Environment Variables',\n description: 'Add these to your .env.local file',\n filePath: '.env.local',\n code: `# Sonor Integration\nSONOR_API_KEY=your-api-key-here\nSONOR_API_URL=${apiUrl}\nNEXT_PUBLIC_UPTRADE_PROJECT_ID=${ctx.projectId}`,\n language: 'env',\n order: startOrder + 1,\n required: true,\n },\n {\n module: 'provider',\n snippetType: 'layout',\n title: 'Root Layout Provider',\n description: 'Wrap your app with SiteKitProvider in app/layout.tsx',\n filePath: 'app/layout.tsx',\n code: `import { SiteKitProvider } from '@sonordev/site-kit'\nimport { ManagedFavicon } from '@sonordev/site-kit/images'\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <html lang=\"en\">\n <head>\n <ManagedFavicon />\n </head>\n <body>\n <SiteKitProvider\n apiUrl={process.env.NEXT_PUBLIC_UPTRADE_API_URL!}\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n${enabledModulesConfig}\n >\n {children}\n </SiteKitProvider>\n </body>\n </html>\n )\n}`,\n language: 'tsx',\n order: startOrder + 2,\n required: true,\n },\n ]\n}\n\n// ============================================\n// Analytics Snippets\n// ============================================\n\nfunction generateAnalyticsSnippets(ctx: GeneratorContext, startOrder: number): IntegrationSnippet[] {\n return [\n {\n module: 'analytics',\n snippetType: 'component',\n title: 'Custom Event Tracking',\n description: 'Track custom events throughout your app',\n filePath: 'components/TrackableButton.tsx',\n code: `'use client'\n\nimport { useSiteKit } from '@sonordev/site-kit'\n\ninterface TrackableButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n eventName: string\n eventData?: Record<string, unknown>\n children: React.ReactNode\n}\n\nexport function TrackableButton({ \n children, \n eventName,\n eventData,\n ...props \n}: TrackableButtonProps) {\n const { analytics } = useSiteKit()\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n analytics?.trackEvent(eventName, eventData)\n props.onClick?.(e)\n }\n\n return (\n <button {...props} onClick={handleClick}>\n {children}\n </button>\n )\n}`,\n language: 'tsx',\n order: startOrder,\n required: false,\n },\n ]\n}\n\n// ============================================\n// Engage Snippets (Chat Widget)\n// ============================================\n\nfunction generateEngageSnippets(ctx: GeneratorContext, startOrder: number): IntegrationSnippet[] {\n const primaryColor = ctx.brand?.primaryColor || '#0066cc'\n \n return [\n {\n module: 'engage',\n snippetType: 'component',\n title: 'Chat Widget',\n description: 'Add the AI chat widget to your site. This is unstyled - customize to match your brand.',\n filePath: 'components/ChatWidget.tsx',\n code: `'use client'\n\nimport { ChatWidget } from '@sonordev/site-kit/engage'\n\nexport function SiteChat() {\n return (\n <ChatWidget\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n config={{\n position: 'bottom-right',\n buttonColor: '${primaryColor}',\n greeting: 'Hi! How can I help you today?',\n placeholder: 'Type your message...',\n }}\n />\n )\n}`,\n language: 'tsx',\n order: startOrder,\n required: true,\n },\n {\n module: 'engage',\n snippetType: 'layout',\n title: 'Add Chat to Layout',\n description: 'Add the ChatWidget component to your root layout',\n filePath: 'app/layout.tsx',\n code: `// Add import at top:\nimport { SiteChat } from '@/components/ChatWidget'\n\n// Add inside your layout body, after SiteKitProvider children:\n<SiteChat />`,\n language: 'tsx',\n order: startOrder + 1,\n required: true,\n },\n ]\n}\n\n// ============================================\n// Forms Snippets\n// ============================================\n\nfunction generateFormsSnippets(ctx: GeneratorContext, startOrder: number): IntegrationSnippet[] {\n return [\n {\n module: 'forms',\n snippetType: 'component',\n title: 'Managed Form Component',\n description: 'Embed a managed form from the Portal. Form slug must match one created in Forms module.',\n filePath: 'components/ContactForm.tsx',\n code: `import { ManagedForm } from '@sonordev/site-kit/forms'\n\ninterface ContactFormProps {\n formSlug?: string\n className?: string\n}\n\nexport async function ContactForm({ \n formSlug = 'contact',\n className \n}: ContactFormProps) {\n return (\n <ManagedForm\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n formSlug={formSlug}\n className={className}\n />\n )\n}`,\n language: 'tsx',\n order: startOrder,\n required: false,\n },\n {\n module: 'forms',\n snippetType: 'api-route',\n title: 'Form Submission Handler',\n description: 'API route to proxy form submissions to Portal API',\n filePath: 'app/api/forms/[formId]/submit/route.ts',\n code: `import { NextRequest, NextResponse } from 'next/server'\n\nexport async function POST(\n request: NextRequest,\n { params }: { params: { formId: string } }\n) {\n const body = await request.json()\n\n const response = await fetch(\n \\`\\${process.env.SONOR_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL}/forms/\\${params.formId}/submit\\`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': process.env.SONOR_API_KEY!,\n },\n body: JSON.stringify(body),\n }\n )\n\n const data = await response.json()\n return NextResponse.json(data, { status: response.status })\n}`,\n language: 'typescript',\n order: startOrder + 1,\n required: true,\n },\n ]\n}\n\n// ============================================\n// Commerce Snippets\n// ============================================\n\nfunction generateCommerceSnippets(ctx: GeneratorContext, startOrder: number): IntegrationSnippet[] {\n return [\n {\n module: 'commerce',\n snippetType: 'component',\n title: 'Product Grid',\n description: 'Display products from your commerce catalog',\n filePath: 'components/Products.tsx',\n code: `import { ProductGrid } from '@sonordev/site-kit/commerce'\n\ninterface ProductsSectionProps {\n category?: string\n limit?: number\n}\n\nexport async function ProductsSection({ \n category = 'featured',\n limit = 8 \n}: ProductsSectionProps) {\n return (\n <section className=\"py-12\">\n <h2 className=\"text-2xl font-bold mb-6\">Our Products</h2>\n <ProductGrid\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n category={category}\n limit={limit}\n />\n </section>\n )\n}`,\n language: 'tsx',\n order: startOrder,\n required: false,\n },\n {\n module: 'commerce',\n snippetType: 'component',\n title: 'Upcoming Events',\n description: 'Display upcoming events and classes',\n filePath: 'components/Events.tsx',\n code: `import { UpcomingEvents, EventCalendar } from '@sonordev/site-kit/commerce'\n\nexport async function EventsSection({ limit = 6 }: { limit?: number }) {\n return (\n <section className=\"py-12\">\n <h2 className=\"text-2xl font-bold mb-6\">Upcoming Events</h2>\n <UpcomingEvents\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n limit={limit}\n />\n </section>\n )\n}\n\nexport async function FullCalendar() {\n return (\n <EventCalendar\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n />\n )\n}`,\n language: 'tsx',\n order: startOrder + 1,\n required: false,\n },\n ]\n}\n\n// ============================================\n// SEO Snippets (Managed FAQs, Schema)\n// ============================================\n\nfunction generateSEOSnippets(ctx: GeneratorContext, startOrder: number): IntegrationSnippet[] {\n return [\n {\n module: 'seo',\n snippetType: 'component',\n title: 'Managed FAQ Section',\n description: 'Render FAQs with automatic JSON-LD schema markup. FAQs are managed in Portal SEO module.',\n filePath: 'components/FAQSection.tsx',\n code: `import { ManagedFAQ } from '@sonordev/site-kit/seo'\n\ninterface FAQSectionProps {\n path: string // Page path to fetch FAQs for (e.g., '/services/plumbing')\n className?: string\n}\n\nexport async function FAQSection({ path, className }: FAQSectionProps) {\n return (\n <section className={className}>\n <ManagedFAQ\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n path={path}\n showTitle\n includeSchema\n />\n </section>\n )\n}`,\n language: 'tsx',\n order: startOrder,\n required: true,\n },\n {\n module: 'seo',\n snippetType: 'page',\n title: 'Page with Managed Metadata + FAQs',\n description: 'Example dynamic page using managed metadata and FAQ sections',\n filePath: 'app/services/[slug]/page.tsx',\n code: `import { getManagedMetadata, ManagedFAQ } from '@sonordev/site-kit/seo'\nimport type { Metadata } from 'next'\n\ninterface Props {\n params: { slug: string }\n}\n\nexport async function generateMetadata({ params }: Props): Promise<Metadata> {\n const path = \\`/services/\\${params.slug}\\`\n return getManagedMetadata({\n projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,\n path,\n })\n}\n\nexport default async function ServicePage({ params }: Props) {\n const path = \\`/services/\\${params.slug}\\`\n\n return (\n <main>\n <h1 className=\"text-3xl font-bold\">Service: {params.slug}</h1>\n \n {/* Your page content here */}\n \n {/* FAQs section with JSON-LD schema */}\n <section className=\"mt-12\">\n <ManagedFAQ\n projectId={process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!}\n path={path}\n showTitle\n includeSchema\n />\n </section>\n </main>\n )\n}`,\n language: 'tsx',\n order: startOrder + 1,\n required: false,\n },\n ]\n}\n\n// ============================================\n// Blog Snippets\n// ============================================\n\nfunction generateBlogSnippets(ctx: GeneratorContext, startOrder: number): IntegrationSnippet[] {\n return [\n {\n module: 'blog',\n snippetType: 'page',\n title: 'Blog List Page',\n description: 'Display all blog posts from Portal',\n filePath: 'app/blog/page.tsx',\n code: `import { getBlogPosts } from '@sonordev/site-kit/blog'\nimport Link from 'next/link'\n\nexport default async function BlogPage() {\n const posts = await getBlogPosts({\n projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,\n limit: 10,\n })\n\n return (\n <main className=\"py-12\">\n <h1 className=\"text-3xl font-bold mb-8\">Blog</h1>\n <div className=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {posts.map((post) => (\n <article key={post.id} className=\"border rounded-lg p-4\">\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n className=\"w-full h-48 object-cover rounded mb-4\"\n />\n )}\n <h2 className=\"text-xl font-semibold mb-2\">\n <Link href={\\`/blog/\\${post.slug}\\`}>{post.title}</Link>\n </h2>\n <p className=\"text-gray-600\">{post.excerpt}</p>\n </article>\n ))}\n </div>\n </main>\n )\n}`,\n language: 'tsx',\n order: startOrder,\n required: false,\n },\n {\n module: 'blog',\n snippetType: 'page',\n title: 'Blog Post Page',\n description: 'Individual blog post page with SEO metadata',\n filePath: 'app/blog/[slug]/page.tsx',\n code: `import { getBlogPost, getBlogPosts } from '@sonordev/site-kit/blog'\nimport type { Metadata } from 'next'\nimport { notFound } from 'next/navigation'\n\ninterface Props {\n params: { slug: string }\n}\n\nexport async function generateStaticParams() {\n const posts = await getBlogPosts({\n projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,\n })\n return posts.map((post) => ({ slug: post.slug }))\n}\n\nexport async function generateMetadata({ params }: Props): Promise<Metadata> {\n const post = await getBlogPost({\n projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,\n slug: params.slug,\n })\n \n if (!post) return {}\n \n return {\n title: post.title,\n description: post.excerpt,\n openGraph: {\n title: post.title,\n description: post.excerpt,\n images: post.featured_image ? [post.featured_image] : [],\n },\n }\n}\n\nexport default async function BlogPostPage({ params }: Props) {\n const post = await getBlogPost({\n projectId: process.env.NEXT_PUBLIC_UPTRADE_PROJECT_ID!,\n slug: params.slug,\n })\n\n if (!post) notFound()\n\n return (\n <article className=\"py-12 max-w-3xl mx-auto\">\n <h1 className=\"text-4xl font-bold mb-4\">{post.title}</h1>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n className=\"w-full rounded-lg mb-8\"\n />\n )}\n <div \n className=\"prose prose-lg\"\n dangerouslySetInnerHTML={{ __html: post.content }}\n />\n </article>\n )\n}`,\n language: 'tsx',\n order: startOrder + 1,\n required: false,\n },\n ]\n}\n","/**\n * IntegrationCodeView - Display generated site-kit integration code\n * \n * Shows code snippets grouped by module with copy functionality.\n * Can be used in setup wizards or admin dashboards.\n */\n\n'use client'\n\nimport * as React from 'react'\nimport { useState, useMemo } from 'react'\nimport { generateIntegrationCode, getSnippetsByModule, type IntegrationSnippet, type GeneratorContext } from './integration-generator'\n\n// ============================================\n// Icons (inline SVG to avoid dependencies)\n// ============================================\n\nfunction CopyIcon({ className }: { className?: string }) {\n return (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n )\n}\n\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )\n}\n\nfunction ChevronDownIcon({ className }: { className?: string }) {\n return (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n )\n}\n\n// ============================================\n// Module metadata\n// ============================================\n\nconst moduleLabels: Record<string, string> = {\n provider: 'Setup',\n analytics: 'Analytics',\n engage: 'Engage (Chat)',\n forms: 'Forms',\n commerce: 'Commerce',\n seo: 'SEO',\n blog: 'Blog',\n}\n\nconst moduleColors: Record<string, string> = {\n provider: '#6366f1', // indigo\n analytics: '#8b5cf6', // violet\n engage: '#ec4899', // pink\n forms: '#14b8a6', // teal\n commerce: '#f59e0b', // amber\n seo: '#10b981', // emerald\n blog: '#3b82f6', // blue\n}\n\n// ============================================\n// Component\n// ============================================\n\nexport interface IntegrationCodeViewProps {\n projectId: string\n enabledModules: string[]\n apiUrl?: string\n brand?: {\n primaryColor?: string\n businessName?: string\n }\n className?: string\n onCopy?: (code: string, title: string) => void\n}\n\nexport function IntegrationCodeView({\n projectId,\n enabledModules,\n apiUrl,\n brand,\n className,\n onCopy,\n}: IntegrationCodeViewProps) {\n const [expandedModules, setExpandedModules] = useState<Set<string>>(new Set(['provider']))\n const [copiedId, setCopiedId] = useState<string | null>(null)\n\n // Generate code snippets\n const snippets = useMemo(() => {\n return generateIntegrationCode({\n projectId,\n enabledModules,\n apiUrl,\n brand,\n })\n }, [projectId, enabledModules, apiUrl, brand])\n\n // Group by module\n const snippetsByModule = useMemo(() => {\n return getSnippetsByModule(snippets)\n }, [snippets])\n\n const toggleModule = (module: string) => {\n setExpandedModules(prev => {\n const next = new Set(prev)\n if (next.has(module)) {\n next.delete(module)\n } else {\n next.add(module)\n }\n return next\n })\n }\n\n const copyCode = async (code: string, id: string, title: string) => {\n try {\n await navigator.clipboard.writeText(code)\n setCopiedId(id)\n onCopy?.(code, title)\n setTimeout(() => setCopiedId(null), 2000)\n } catch (err) {\n console.error('Failed to copy:', err)\n }\n }\n\n const copyAll = async () => {\n const allCode = snippets\n .map(s => `// ${s.title}\\n${s.filePath ? `// File: ${s.filePath}\\n` : ''}${s.code}`)\n .join('\\n\\n// ---\\n\\n')\n try {\n await navigator.clipboard.writeText(allCode)\n onCopy?.(allCode, 'All snippets')\n } catch (err) {\n console.error('Failed to copy:', err)\n }\n }\n\n if (enabledModules.length === 0) {\n return (\n <div className={className} style={{ textAlign: 'center', padding: '2rem', color: '#666' }}>\n <p>No modules enabled for this project.</p>\n <p style={{ fontSize: '0.875rem', marginTop: '0.5rem' }}>\n Enable modules in Project Settings to generate integration code.\n </p>\n </div>\n )\n }\n\n return (\n <div className={className} style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Header */}\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n <div>\n <h3 style={{ margin: 0, fontWeight: 600 }}>Integration Code</h3>\n <p style={{ margin: '0.25rem 0 0', fontSize: '0.875rem', color: '#666' }}>\n {snippets.length} snippets for {enabledModules.length} modules\n </p>\n </div>\n <button\n onClick={copyAll}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.5rem 1rem',\n border: '1px solid #e5e7eb',\n borderRadius: '0.375rem',\n background: 'white',\n cursor: 'pointer',\n fontSize: '0.875rem',\n }}\n >\n <CopyIcon />\n Copy All\n </button>\n </div>\n\n {/* Module Groups */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>\n {Object.entries(snippetsByModule).map(([module, moduleSnippets]) => {\n const isExpanded = expandedModules.has(module)\n const color = moduleColors[module] || '#6366f1'\n \n return (\n <div \n key={module} \n style={{\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n overflow: 'hidden',\n }}\n >\n {/* Module Header */}\n <button\n onClick={() => toggleModule(module)}\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '0.75rem 1rem',\n background: '#f9fafb',\n border: 'none',\n cursor: 'pointer',\n textAlign: 'left',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>\n <div\n style={{\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n background: color,\n }}\n />\n <span style={{ fontWeight: 500 }}>\n {moduleLabels[module] || module}\n </span>\n <span\n style={{\n fontSize: '0.75rem',\n padding: '0.125rem 0.5rem',\n background: '#e5e7eb',\n borderRadius: '9999px',\n }}\n >\n {moduleSnippets.length}\n </span>\n </div>\n {isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}\n </button>\n\n {/* Snippets */}\n {isExpanded && (\n <div>\n {moduleSnippets.map((snippet, idx) => {\n const snippetId = `${module}-${idx}`\n const isCopied = copiedId === snippetId\n\n return (\n <div\n key={idx}\n style={{\n padding: '1rem',\n borderTop: '1px solid #e5e7eb',\n }}\n >\n {/* Snippet Header */}\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.75rem' }}>\n <div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <span style={{ fontWeight: 500, fontSize: '0.875rem' }}>\n {snippet.title}\n </span>\n {snippet.required && (\n <span\n style={{\n fontSize: '0.625rem',\n padding: '0.125rem 0.375rem',\n border: '1px solid #e5e7eb',\n borderRadius: '0.25rem',\n textTransform: 'uppercase',\n }}\n >\n Required\n </span>\n )}\n </div>\n {snippet.description && (\n <p style={{ margin: '0.25rem 0 0', fontSize: '0.75rem', color: '#666' }}>\n {snippet.description}\n </p>\n )}\n {snippet.filePath && (\n <p style={{ margin: '0.25rem 0 0', fontSize: '0.75rem', color: color, fontFamily: 'monospace' }}>\n {snippet.filePath}\n </p>\n )}\n </div>\n <button\n onClick={() => copyCode(snippet.code, snippetId, snippet.title)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '2rem',\n height: '2rem',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n borderRadius: '0.25rem',\n }}\n title=\"Copy code\"\n >\n {isCopied ? (\n <CheckIcon className=\"text-green-500\" />\n ) : (\n <CopyIcon />\n )}\n </button>\n </div>\n\n {/* Code Block */}\n <pre\n style={{\n margin: 0,\n padding: '0.75rem',\n background: '#1f2937',\n color: '#e5e7eb',\n borderRadius: '0.375rem',\n overflow: 'auto',\n fontSize: '0.75rem',\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n lineHeight: 1.5,\n }}\n >\n <code>{snippet.code}</code>\n </pre>\n </div>\n )\n })}\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n"]}
|
package/dist/chunk-7FKPJQVS.mjs
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
// src/cli/generators/index.ts
|
|
5
|
-
async function generateEnvFile(options) {
|
|
6
|
-
const envPath = path.join(process.cwd(), ".env.local");
|
|
7
|
-
let existingContent = "";
|
|
8
|
-
try {
|
|
9
|
-
existingContent = await fs.readFile(envPath, "utf-8");
|
|
10
|
-
} catch {
|
|
11
|
-
}
|
|
12
|
-
const lines = existingContent.split("\n");
|
|
13
|
-
const existingVars = {};
|
|
14
|
-
for (const line of lines) {
|
|
15
|
-
if (line.startsWith("#") || line.trim() === "") continue;
|
|
16
|
-
const [key, ...valueParts] = line.split("=");
|
|
17
|
-
if (key) {
|
|
18
|
-
existingVars[key.trim()] = valueParts.join("=").trim();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const sonorKeys = [
|
|
22
|
-
"SONOR_API_KEY",
|
|
23
|
-
"NEXT_PUBLIC_UPTRADE_PROJECT_ID",
|
|
24
|
-
"NEXT_PUBLIC_SUPABASE_URL",
|
|
25
|
-
"NEXT_PUBLIC_SUPABASE_ANON_KEY",
|
|
26
|
-
"UPTRADE_API_KEY",
|
|
27
|
-
"NEXT_PUBLIC_UPTRADE_API_KEY"
|
|
28
|
-
];
|
|
29
|
-
let newContent = `# Sonor Site-Kit Configuration
|
|
30
|
-
# Generated by @sonordev/site-kit setup wizard
|
|
31
|
-
#
|
|
32
|
-
# Only SONOR_API_KEY is required. SiteKitLayout reads it server-side
|
|
33
|
-
# and injects all necessary config to client components automatically.
|
|
34
|
-
|
|
35
|
-
SONOR_API_KEY=${options.apiKey}
|
|
36
|
-
|
|
37
|
-
`;
|
|
38
|
-
const otherVars = Object.entries(existingVars).filter(([key]) => !sonorKeys.includes(key));
|
|
39
|
-
if (otherVars.length > 0) {
|
|
40
|
-
newContent += "# Other Environment Variables\n";
|
|
41
|
-
for (const [key, value] of otherVars) {
|
|
42
|
-
newContent += `${key}=${value}
|
|
43
|
-
`;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
await fs.writeFile(envPath, newContent, "utf-8");
|
|
47
|
-
}
|
|
48
|
-
function addImportSafely(content, importStatement) {
|
|
49
|
-
const importModule = importStatement.match(/from\s+['"]([^'"]+)['"]/)?.[1];
|
|
50
|
-
if (importModule && content.includes(importModule)) {
|
|
51
|
-
return content;
|
|
52
|
-
}
|
|
53
|
-
const directiveMatch = content.match(/^(['"]use (client|server)['"][\s;]*\n?)/);
|
|
54
|
-
if (directiveMatch) {
|
|
55
|
-
const directive = directiveMatch[0];
|
|
56
|
-
const restOfFile = content.slice(directive.length);
|
|
57
|
-
return directive + importStatement + "\n" + restOfFile;
|
|
58
|
-
} else {
|
|
59
|
-
const firstImportMatch = content.match(/^(import\s+)/);
|
|
60
|
-
if (firstImportMatch) {
|
|
61
|
-
return importStatement + "\n" + content;
|
|
62
|
-
} else {
|
|
63
|
-
return importStatement + "\n\n" + content;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
var generateProvider = generateLayout;
|
|
68
|
-
async function generateLayout() {
|
|
69
|
-
const layoutPath = await findLayoutFile();
|
|
70
|
-
if (!layoutPath) {
|
|
71
|
-
throw new Error("Could not find layout.tsx file");
|
|
72
|
-
}
|
|
73
|
-
const content = await fs.readFile(layoutPath, "utf-8");
|
|
74
|
-
if (content.includes("SiteKitLayout") || content.includes("SiteKitProvider")) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const backupPath = layoutPath + ".backup";
|
|
78
|
-
await fs.writeFile(backupPath, content, "utf-8");
|
|
79
|
-
let newContent = addImportSafely(
|
|
80
|
-
content,
|
|
81
|
-
`import { SiteKitLayout } from '@sonordev/site-kit/layout'`
|
|
82
|
-
);
|
|
83
|
-
const childrenPattern = /(\s*)\{children\}/;
|
|
84
|
-
const childrenMatch = newContent.match(childrenPattern);
|
|
85
|
-
if (childrenMatch) {
|
|
86
|
-
const indent = childrenMatch[1] || " ";
|
|
87
|
-
const layoutWrap = `${indent}<SiteKitLayout>${indent} {children}${indent}</SiteKitLayout>`;
|
|
88
|
-
newContent = newContent.replace(childrenPattern, layoutWrap);
|
|
89
|
-
} else {
|
|
90
|
-
const bodyPattern = /(<body[^>]*>)([\s\S]*?)(<\/body>)/;
|
|
91
|
-
const bodyMatch = newContent.match(bodyPattern);
|
|
92
|
-
if (bodyMatch) {
|
|
93
|
-
const bodyContent = bodyMatch[2];
|
|
94
|
-
const wrappedContent = `
|
|
95
|
-
<SiteKitLayout>
|
|
96
|
-
${bodyContent.trim()}
|
|
97
|
-
</SiteKitLayout>
|
|
98
|
-
`;
|
|
99
|
-
newContent = newContent.replace(bodyPattern, `$1${wrappedContent}$3`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
await fs.writeFile(layoutPath, newContent, "utf-8");
|
|
103
|
-
}
|
|
104
|
-
async function findLayoutFile() {
|
|
105
|
-
const possiblePaths = [
|
|
106
|
-
"src/app/layout.tsx",
|
|
107
|
-
"app/layout.tsx",
|
|
108
|
-
"src/app/layout.jsx",
|
|
109
|
-
"app/layout.jsx"
|
|
110
|
-
];
|
|
111
|
-
for (const relativePath of possiblePaths) {
|
|
112
|
-
const fullPath = path.join(process.cwd(), relativePath);
|
|
113
|
-
try {
|
|
114
|
-
await fs.access(fullPath);
|
|
115
|
-
return fullPath;
|
|
116
|
-
} catch {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
async function generateSetupRoute() {
|
|
123
|
-
const routeDir = path.join(process.cwd(), "app", "_uptrade", "setup");
|
|
124
|
-
await fs.mkdir(routeDir, { recursive: true });
|
|
125
|
-
const pageContent = `/**
|
|
126
|
-
* Sonor Setup Wizard
|
|
127
|
-
*
|
|
128
|
-
* This route is automatically removed after setup is complete.
|
|
129
|
-
* Visit /_uptrade/setup to configure Site-Kit.
|
|
130
|
-
*/
|
|
131
|
-
|
|
132
|
-
import { SetupWizard } from '@sonordev/site-kit/setup'
|
|
133
|
-
|
|
134
|
-
export default function SetupPage() {
|
|
135
|
-
return <SetupWizard />
|
|
136
|
-
}
|
|
137
|
-
`;
|
|
138
|
-
await fs.writeFile(path.join(routeDir, "page.tsx"), pageContent, "utf-8");
|
|
139
|
-
}
|
|
140
|
-
async function selfDestruct() {
|
|
141
|
-
const setupDir = path.join(process.cwd(), "app", "_uptrade");
|
|
142
|
-
try {
|
|
143
|
-
await fs.rm(setupDir, { recursive: true, force: true });
|
|
144
|
-
} catch {
|
|
145
|
-
}
|
|
146
|
-
const layoutPath = await findLayoutFile();
|
|
147
|
-
if (layoutPath) {
|
|
148
|
-
let content = await fs.readFile(layoutPath, "utf-8");
|
|
149
|
-
content = content.replace(/import\s*{\s*UptradeSetup\s*}\s*from\s*['"]@sonordev\/site-kit\/setup['"][;\n]?/g, "");
|
|
150
|
-
content = content.replace(/\s*{process\.env\.NODE_ENV\s*===\s*['"]development['"]\s*&&\s*<UptradeSetup\s*\/>}\s*/g, "\n");
|
|
151
|
-
content = content.replace(/<UptradeSetup\s*\/>/g, "");
|
|
152
|
-
await fs.writeFile(layoutPath, content, "utf-8");
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
async function migrateSitemap(options) {
|
|
156
|
-
const deleted = [];
|
|
157
|
-
if (options.deleteExisting) {
|
|
158
|
-
for (const existing of options.existingSitemaps) {
|
|
159
|
-
if (existing.generator === "site-kit") continue;
|
|
160
|
-
const fullPath = path.join(process.cwd(), existing.filePath);
|
|
161
|
-
try {
|
|
162
|
-
await fs.unlink(fullPath);
|
|
163
|
-
deleted.push(existing.filePath);
|
|
164
|
-
} catch {
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
const configFiles = [
|
|
168
|
-
"next-sitemap.config.js",
|
|
169
|
-
"next-sitemap.config.mjs",
|
|
170
|
-
"next-sitemap.config.ts"
|
|
171
|
-
];
|
|
172
|
-
for (const config of configFiles) {
|
|
173
|
-
const fullPath = path.join(process.cwd(), config);
|
|
174
|
-
try {
|
|
175
|
-
await fs.access(fullPath);
|
|
176
|
-
await fs.unlink(fullPath);
|
|
177
|
-
deleted.push(config);
|
|
178
|
-
} catch {
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
const staticSitemap = path.join(process.cwd(), "public", "sitemap.xml");
|
|
182
|
-
try {
|
|
183
|
-
await fs.access(staticSitemap);
|
|
184
|
-
await fs.unlink(staticSitemap);
|
|
185
|
-
deleted.push("public/sitemap.xml");
|
|
186
|
-
} catch {
|
|
187
|
-
}
|
|
188
|
-
const staticSitemapIndex = path.join(process.cwd(), "public", "sitemap-0.xml");
|
|
189
|
-
try {
|
|
190
|
-
await fs.access(staticSitemapIndex);
|
|
191
|
-
const publicDir = path.join(process.cwd(), "public");
|
|
192
|
-
const files = await fs.readdir(publicDir);
|
|
193
|
-
for (const file of files) {
|
|
194
|
-
if (file.match(/^sitemap-\d+\.xml$/)) {
|
|
195
|
-
await fs.unlink(path.join(publicDir, file));
|
|
196
|
-
deleted.push(`public/${file}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
} catch {
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
const sitemapPath = await findSitemapLocation();
|
|
203
|
-
const sitemapContent = generateSitemapContent(options.baseUrl);
|
|
204
|
-
await fs.mkdir(path.dirname(sitemapPath), { recursive: true });
|
|
205
|
-
await fs.writeFile(sitemapPath, sitemapContent, "utf-8");
|
|
206
|
-
return {
|
|
207
|
-
deleted,
|
|
208
|
-
created: path.relative(process.cwd(), sitemapPath)
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
async function findSitemapLocation() {
|
|
212
|
-
const srcApp = path.join(process.cwd(), "src", "app", "sitemap.ts");
|
|
213
|
-
const app = path.join(process.cwd(), "app", "sitemap.ts");
|
|
214
|
-
try {
|
|
215
|
-
await fs.access(path.join(process.cwd(), "src", "app"));
|
|
216
|
-
return srcApp;
|
|
217
|
-
} catch {
|
|
218
|
-
return app;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function generateSitemapContent(baseUrl) {
|
|
222
|
-
return `/**
|
|
223
|
-
* Sitemap Generator - Powered by @sonordev/site-kit
|
|
224
|
-
*
|
|
225
|
-
* Automatically discovers pages from the app directory and syncs
|
|
226
|
-
* them to Portal API for SEO tracking and analytics validation.
|
|
227
|
-
*
|
|
228
|
-
* Generated by Sonor Site-Kit Setup Wizard
|
|
229
|
-
*/
|
|
230
|
-
|
|
231
|
-
import { createSitemap } from '@sonordev/site-kit/sitemap'
|
|
232
|
-
|
|
233
|
-
export default createSitemap({
|
|
234
|
-
baseUrl: '${baseUrl}',
|
|
235
|
-
|
|
236
|
-
// Optional: Exclude patterns (these are excluded by default)
|
|
237
|
-
// exclude: ['/admin/*', '/api/*'],
|
|
238
|
-
|
|
239
|
-
// Optional: Override priorities for specific paths
|
|
240
|
-
// priorities: {
|
|
241
|
-
// '/': 1.0,
|
|
242
|
-
// '/about': 0.8,
|
|
243
|
-
// '/contact': 0.7,
|
|
244
|
-
// },
|
|
245
|
-
|
|
246
|
-
// Optional: Add dynamic routes not discoverable from file system
|
|
247
|
-
// additionalPaths: async () => {
|
|
248
|
-
// // Example: Fetch blog posts from database
|
|
249
|
-
// // const posts = await getBlogPosts()
|
|
250
|
-
// // return posts.map(post => ({ path: \`/blog/\${post.slug}\`, priority: 0.7 }))
|
|
251
|
-
// return []
|
|
252
|
-
// },
|
|
253
|
-
})
|
|
254
|
-
`;
|
|
255
|
-
}
|
|
256
|
-
async function removeNextSitemapDependency() {
|
|
257
|
-
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
258
|
-
try {
|
|
259
|
-
const content = await fs.readFile(packageJsonPath, "utf-8");
|
|
260
|
-
const pkg = JSON.parse(content);
|
|
261
|
-
let modified = false;
|
|
262
|
-
if (pkg.dependencies?.["next-sitemap"]) {
|
|
263
|
-
delete pkg.dependencies["next-sitemap"];
|
|
264
|
-
modified = true;
|
|
265
|
-
}
|
|
266
|
-
if (pkg.devDependencies?.["next-sitemap"]) {
|
|
267
|
-
delete pkg.devDependencies["next-sitemap"];
|
|
268
|
-
modified = true;
|
|
269
|
-
}
|
|
270
|
-
if (pkg.scripts) {
|
|
271
|
-
for (const [key, value] of Object.entries(pkg.scripts)) {
|
|
272
|
-
if (typeof value === "string" && value.includes("next-sitemap")) {
|
|
273
|
-
delete pkg.scripts[key];
|
|
274
|
-
modified = true;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (modified) {
|
|
279
|
-
await fs.writeFile(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
280
|
-
}
|
|
281
|
-
return modified;
|
|
282
|
-
} catch {
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
export { generateEnvFile, generateLayout, generateProvider, generateSetupRoute, migrateSitemap, removeNextSitemapDependency, selfDestruct };
|
|
288
|
-
//# sourceMappingURL=chunk-7FKPJQVS.mjs.map
|
|
289
|
-
//# sourceMappingURL=chunk-7FKPJQVS.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/generators/index.ts"],"names":[],"mappings":"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","file":"chunk-7FKPJQVS.mjs","sourcesContent":["/**\n * Code Generators - Creates SiteKitLayout setup and env files\n */\n\nimport fs from 'fs/promises'\nimport path from 'path'\n\n// ============================================\n// Types\n// ============================================\n\ninterface EnvOptions {\n apiKey: string\n /** @deprecated Legacy — no longer needed. SiteKitLayout extracts projectId from the API key. */\n projectId?: string\n /** @deprecated Legacy — no longer needed. SiteKitLayout connects to Supabase internally. */\n supabaseUrl?: string\n /** @deprecated Legacy — no longer needed. SiteKitLayout connects to Supabase internally. */\n supabaseAnonKey?: string\n}\n\n// ============================================\n// Env File Generator\n// ============================================\n\nexport async function generateEnvFile(options: EnvOptions): Promise<void> {\n const envPath = path.join(process.cwd(), '.env.local')\n\n // Check if file exists and read existing content\n let existingContent = ''\n try {\n existingContent = await fs.readFile(envPath, 'utf-8')\n } catch {\n // File doesn't exist, that's fine\n }\n\n // Parse existing content\n const lines = existingContent.split('\\n')\n const existingVars: Record<string, string> = {}\n\n for (const line of lines) {\n if (line.startsWith('#') || line.trim() === '') continue\n const [key, ...valueParts] = line.split('=')\n if (key) {\n existingVars[key.trim()] = valueParts.join('=').trim()\n }\n }\n\n // Only SONOR_API_KEY is needed — SiteKitLayout reads it server-side,\n // extracts the project ID from the key prefix, and injects config to client.\n // Legacy vars (NEXT_PUBLIC_UPTRADE_PROJECT_ID, NEXT_PUBLIC_SUPABASE_*) are no longer required.\n const sonorKeys = [\n 'SONOR_API_KEY',\n 'NEXT_PUBLIC_UPTRADE_PROJECT_ID',\n 'NEXT_PUBLIC_SUPABASE_URL',\n 'NEXT_PUBLIC_SUPABASE_ANON_KEY',\n 'UPTRADE_API_KEY',\n 'NEXT_PUBLIC_UPTRADE_API_KEY',\n ]\n\n // Generate new content — single env var\n let newContent = `# Sonor Site-Kit Configuration\n# Generated by @sonordev/site-kit setup wizard\n#\n# Only SONOR_API_KEY is required. SiteKitLayout reads it server-side\n# and injects all necessary config to client components automatically.\n\nSONOR_API_KEY=${options.apiKey}\n\n`\n\n // Preserve any existing vars that aren't Sonor-related\n const otherVars = Object.entries(existingVars)\n .filter(([key]) => !sonorKeys.includes(key))\n\n if (otherVars.length > 0) {\n newContent += '# Other Environment Variables\\n'\n for (const [key, value] of otherVars) {\n newContent += `${key}=${value}\\n`\n }\n }\n\n await fs.writeFile(envPath, newContent, 'utf-8')\n}\n\n// ============================================\n// Provider Generator\n// ============================================\n\n/**\n * Safely adds an import statement to a file, respecting 'use client'/'use server' directives\n */\nfunction addImportSafely(content: string, importStatement: string): string {\n // Check if import already exists\n const importModule = importStatement.match(/from\\s+['\"]([^'\"]+)['\"]/)?.[1]\n if (importModule && content.includes(importModule)) {\n return content\n }\n \n // Check for 'use client' or 'use server' directive at the start\n const directiveMatch = content.match(/^(['\"]use (client|server)['\"][\\s;]*\\n?)/)\n \n if (directiveMatch) {\n // Insert import AFTER the directive\n const directive = directiveMatch[0]\n const restOfFile = content.slice(directive.length)\n return directive + importStatement + '\\n' + restOfFile\n } else {\n // No directive, add import at the top before other imports\n const firstImportMatch = content.match(/^(import\\s+)/)\n if (firstImportMatch) {\n return importStatement + '\\n' + content\n } else {\n return importStatement + '\\n\\n' + content\n }\n }\n}\n\n/**\n * @deprecated Use generateLayout() instead. SiteKitProvider forces all children\n * client-side, breaking Next.js Server Components. Kept for backwards compatibility.\n */\nexport const generateProvider = generateLayout\n\n/**\n * Injects SiteKitLayout into the root layout.tsx.\n *\n * SiteKitLayout is a Server Component that:\n * - Reads SONOR_API_KEY server-side (no NEXT_PUBLIC_ vars needed)\n * - Extracts the project ID from the API key prefix\n * - Renders server concerns (favicon, managed scripts) as RSC\n * - Delegates client concerns (analytics, engage, forms) to a client island\n * - Does NOT break Server Components (unlike the deprecated SiteKitProvider)\n */\nexport async function generateLayout(): Promise<void> {\n // Find the layout file\n const layoutPath = await findLayoutFile()\n if (!layoutPath) {\n throw new Error('Could not find layout.tsx file')\n }\n\n const content = await fs.readFile(layoutPath, 'utf-8')\n\n // Check if SiteKitLayout or SiteKitProvider is already added\n if (content.includes('SiteKitLayout') || content.includes('SiteKitProvider')) {\n return // Already configured\n }\n\n // Create backup first\n const backupPath = layoutPath + '.backup'\n await fs.writeFile(backupPath, content, 'utf-8')\n\n // Add import safely (respects 'use client' directive)\n let newContent = addImportSafely(\n content,\n `import { SiteKitLayout } from '@sonordev/site-kit/layout'`,\n )\n\n // Wrap {children} with SiteKitLayout\n const childrenPattern = /(\\s*)\\{children\\}/\n const childrenMatch = newContent.match(childrenPattern)\n\n if (childrenMatch) {\n const indent = childrenMatch[1] || ' '\n const layoutWrap = `${indent}<SiteKitLayout>${indent} {children}${indent}</SiteKitLayout>`\n newContent = newContent.replace(childrenPattern, layoutWrap)\n } else {\n // Try wrapping body content\n const bodyPattern = /(<body[^>]*>)([\\s\\S]*?)(<\\/body>)/\n const bodyMatch = newContent.match(bodyPattern)\n\n if (bodyMatch) {\n const bodyContent = bodyMatch[2]\n const wrappedContent = `\n <SiteKitLayout>\n ${bodyContent.trim()}\n </SiteKitLayout>\n `\n newContent = newContent.replace(bodyPattern, `$1${wrappedContent}$3`)\n }\n }\n\n await fs.writeFile(layoutPath, newContent, 'utf-8')\n}\n\n// ============================================\n// Helpers\n// ============================================\n\nasync function findLayoutFile(): Promise<string | null> {\n const possiblePaths = [\n 'src/app/layout.tsx',\n 'app/layout.tsx',\n 'src/app/layout.jsx',\n 'app/layout.jsx',\n ]\n\n for (const relativePath of possiblePaths) {\n const fullPath = path.join(process.cwd(), relativePath)\n try {\n await fs.access(fullPath)\n return fullPath\n } catch {\n continue\n }\n }\n\n return null\n}\n\n// ============================================\n// Setup Route Generator (for visual wizard)\n// ============================================\n\nexport async function generateSetupRoute(): Promise<void> {\n const routeDir = path.join(process.cwd(), 'app', '_uptrade', 'setup')\n \n // Create directory\n await fs.mkdir(routeDir, { recursive: true })\n\n // Create page.tsx\n const pageContent = `/**\n * Sonor Setup Wizard\n * \n * This route is automatically removed after setup is complete.\n * Visit /_uptrade/setup to configure Site-Kit.\n */\n\nimport { SetupWizard } from '@sonordev/site-kit/setup'\n\nexport default function SetupPage() {\n return <SetupWizard />\n}\n`\n\n await fs.writeFile(path.join(routeDir, 'page.tsx'), pageContent, 'utf-8')\n}\n\n// ============================================\n// Self-Destruct\n// ============================================\n\nexport async function selfDestruct(): Promise<void> {\n // Remove setup route\n const setupDir = path.join(process.cwd(), 'app', '_uptrade')\n try {\n await fs.rm(setupDir, { recursive: true, force: true })\n } catch {\n // Directory might not exist\n }\n\n // Remove UptradeSetup from layout if present\n const layoutPath = await findLayoutFile()\n if (layoutPath) {\n let content = await fs.readFile(layoutPath, 'utf-8')\n \n // Remove import\n content = content.replace(/import\\s*{\\s*UptradeSetup\\s*}\\s*from\\s*['\"]@sonordev\\/site-kit\\/setup['\"][;\\n]?/g, '')\n \n // Remove component usage\n content = content.replace(/\\s*{process\\.env\\.NODE_ENV\\s*===\\s*['\"]development['\"]\\s*&&\\s*<UptradeSetup\\s*\\/>}\\s*/g, '\\n')\n content = content.replace(/<UptradeSetup\\s*\\/>/g, '')\n \n await fs.writeFile(layoutPath, content, 'utf-8')\n }\n}\n\n// ============================================\n// Sitemap Generator\n// ============================================\n\ninterface SitemapMigrationOptions {\n baseUrl: string\n existingSitemaps: Array<{\n filePath: string\n type: string\n generator?: string\n }>\n deleteExisting: boolean\n}\n\n/**\n * Generate site-kit sitemap and optionally remove existing sitemap files\n */\nexport async function migrateSitemap(options: SitemapMigrationOptions): Promise<{\n deleted: string[]\n created: string\n}> {\n const deleted: string[] = []\n\n // Delete existing sitemap files if requested\n if (options.deleteExisting) {\n for (const existing of options.existingSitemaps) {\n // Skip if it's already site-kit\n if (existing.generator === 'site-kit') continue\n\n const fullPath = path.join(process.cwd(), existing.filePath)\n try {\n await fs.unlink(fullPath)\n deleted.push(existing.filePath)\n } catch {\n // File might not exist or be locked\n }\n }\n\n // Also delete next-sitemap config files\n const configFiles = [\n 'next-sitemap.config.js',\n 'next-sitemap.config.mjs', \n 'next-sitemap.config.ts',\n ]\n for (const config of configFiles) {\n const fullPath = path.join(process.cwd(), config)\n try {\n await fs.access(fullPath)\n await fs.unlink(fullPath)\n deleted.push(config)\n } catch {\n // File doesn't exist\n }\n }\n\n // Delete static sitemap.xml if it exists in public\n const staticSitemap = path.join(process.cwd(), 'public', 'sitemap.xml')\n try {\n await fs.access(staticSitemap)\n await fs.unlink(staticSitemap)\n deleted.push('public/sitemap.xml')\n } catch {\n // File doesn't exist\n }\n\n // Delete sitemap index if exists\n const staticSitemapIndex = path.join(process.cwd(), 'public', 'sitemap-0.xml')\n try {\n await fs.access(staticSitemapIndex)\n // Find all sitemap-N.xml files\n const publicDir = path.join(process.cwd(), 'public')\n const files = await fs.readdir(publicDir)\n for (const file of files) {\n if (file.match(/^sitemap-\\d+\\.xml$/)) {\n await fs.unlink(path.join(publicDir, file))\n deleted.push(`public/${file}`)\n }\n }\n } catch {\n // File doesn't exist\n }\n }\n\n // Generate new sitemap.ts using site-kit\n const sitemapPath = await findSitemapLocation()\n const sitemapContent = generateSitemapContent(options.baseUrl)\n\n await fs.mkdir(path.dirname(sitemapPath), { recursive: true })\n await fs.writeFile(sitemapPath, sitemapContent, 'utf-8')\n\n return {\n deleted,\n created: path.relative(process.cwd(), sitemapPath),\n }\n}\n\n/**\n * Find where to put the sitemap file\n */\nasync function findSitemapLocation(): Promise<string> {\n // Check if using src/app or app\n const srcApp = path.join(process.cwd(), 'src', 'app', 'sitemap.ts')\n const app = path.join(process.cwd(), 'app', 'sitemap.ts')\n\n try {\n await fs.access(path.join(process.cwd(), 'src', 'app'))\n return srcApp\n } catch {\n return app\n }\n}\n\n/**\n * Generate sitemap.ts content\n */\nfunction generateSitemapContent(baseUrl: string): string {\n return `/**\n * Sitemap Generator - Powered by @sonordev/site-kit\n * \n * Automatically discovers pages from the app directory and syncs\n * them to Portal API for SEO tracking and analytics validation.\n * \n * Generated by Sonor Site-Kit Setup Wizard\n */\n\nimport { createSitemap } from '@sonordev/site-kit/sitemap'\n\nexport default createSitemap({\n baseUrl: '${baseUrl}',\n \n // Optional: Exclude patterns (these are excluded by default)\n // exclude: ['/admin/*', '/api/*'],\n \n // Optional: Override priorities for specific paths\n // priorities: {\n // '/': 1.0,\n // '/about': 0.8,\n // '/contact': 0.7,\n // },\n \n // Optional: Add dynamic routes not discoverable from file system\n // additionalPaths: async () => {\n // // Example: Fetch blog posts from database\n // // const posts = await getBlogPosts()\n // // return posts.map(post => ({ path: \\`/blog/\\${post.slug}\\`, priority: 0.7 }))\n // return []\n // },\n})\n`\n}\n\n/**\n * Remove next-sitemap from package.json dependencies\n */\nexport async function removeNextSitemapDependency(): Promise<boolean> {\n const packageJsonPath = path.join(process.cwd(), 'package.json')\n \n try {\n const content = await fs.readFile(packageJsonPath, 'utf-8')\n const pkg = JSON.parse(content)\n \n let modified = false\n \n if (pkg.dependencies?.['next-sitemap']) {\n delete pkg.dependencies['next-sitemap']\n modified = true\n }\n \n if (pkg.devDependencies?.['next-sitemap']) {\n delete pkg.devDependencies['next-sitemap']\n modified = true\n }\n\n // Also remove from scripts if present\n if (pkg.scripts) {\n for (const [key, value] of Object.entries(pkg.scripts)) {\n if (typeof value === 'string' && value.includes('next-sitemap')) {\n delete pkg.scripts[key]\n modified = true\n }\n }\n }\n\n if (modified) {\n await fs.writeFile(packageJsonPath, JSON.stringify(pkg, null, 2) + '\\n', 'utf-8')\n }\n\n return modified\n } catch {\n return false\n }\n}\n\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cms/server-api.ts"],"names":[],"mappings":"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","file":"chunk-C3A5HXHX.mjs","sourcesContent":["/**\n * @sonordev/site-kit/cms - Server-Only API Functions\n *\n * Fetches CMS page/section data from Portal API.\n * Uses the same secure API pattern as seo/server-api.ts.\n */\n\n// React.cache is available in React 19+ / Next.js RSC\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { cache } = require('react') as { cache: <T extends (...args: any[]) => any>(fn: T) => T }\nimport 'server-only'\nimport type { CmsPageData, CmsSectionData, CmsPageSeo } from './types'\n\n// ============================================\n// Server-Only API Config\n// ============================================\n\nfunction getSecureApiConfig() {\n const apiUrl =\n process.env.SONOR_API_URL ||\n process.env.UPTRADE_API_URL ||\n process.env.NEXT_PUBLIC_UPTRADE_API_URL ||\n 'https://api.sonor.io'\n const apiKey =\n process.env.SONOR_API_KEY ||\n process.env.UPTRADE_API_KEY ||\n process.env.NEXT_PUBLIC_UPTRADE_API_KEY ||\n ''\n\n if (!apiKey) {\n throw new Error(\n '@sonordev/site-kit/cms: SONOR_API_KEY (or UPTRADE_API_KEY) environment variable is required',\n )\n }\n\n return { apiUrl, apiKey }\n}\n\nasync function secureApiPost<T>(\n endpoint: string,\n body: Record<string, unknown> = {},\n): Promise<T | null> {\n const { apiUrl, apiKey } = getSecureApiConfig()\n\n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n next: { revalidate: 60 },\n } as RequestInit)\n\n if (!response.ok) {\n let detail = response.statusText\n try {\n const err = await response.json().catch(() => ({}))\n if (err?.message) detail = err.message\n } catch {\n /* ignore */\n }\n console.error(\n `@sonordev/cms: API error ${response.status} ${endpoint}: ${detail}`,\n )\n return null\n }\n\n return await response.json()\n } catch (error) {\n console.error('@sonordev/cms: Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Cached Data Fetchers\n// ============================================\n\n/**\n * Fetch a published CMS page by path — cached per request.\n * Returns the full page with all sections and their Portable Text content.\n * @server-only\n */\nexport const getCmsPage = cache(\n async (path: string): Promise<CmsPageData | null> => {\n const result = await secureApiPost<{\n found: boolean\n page: CmsPageData | null\n }>('/api/public/cms/page', { path })\n\n if (!result?.found || !result.page) return null\n return result.page\n },\n)\n\n/**\n * Fetch a single published CMS section by ID — cached per request.\n * @server-only\n */\nexport const getCmsSection = cache(\n async (sectionId: string): Promise<CmsSectionData | null> => {\n const result = await secureApiPost<{\n found: boolean\n section: CmsSectionData | null\n }>('/api/public/cms/section', { sectionId })\n\n if (!result?.found || !result.section) return null\n return result.section\n },\n)\n\n/**\n * Fetch CMS page and return Next.js Metadata object.\n * Use in generateMetadata() for CMS-managed pages.\n *\n * @example\n * ```ts\n * import { getCmsPageMetadata } from '@sonordev/site-kit/cms/server'\n *\n * export async function generateMetadata({ params }) {\n * return getCmsPageMetadata(`/${params.slug}`)\n * }\n * ```\n * @server-only\n */\nexport const getCmsPageMetadata = cache(\n async (\n path: string,\n ): Promise<{\n title?: string\n description?: string\n robots?: { index: boolean }\n openGraph?: { title?: string; description?: string }\n } | null> => {\n const page = await getCmsPage(path)\n if (!page) return null\n\n const seo: CmsPageSeo = page.seo || {}\n\n return {\n title: seo.title || page.title,\n description: seo.description,\n robots: seo.noindex ? { index: false } : undefined,\n openGraph: {\n title: seo.title || page.title,\n description: seo.description,\n },\n }\n },\n)\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/images/ManagedFavicon.tsx"],"names":["jsxs","Fragment","jsx"],"mappings":"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","file":"chunk-DY4K6X3A.js","sourcesContent":["/**\n * ManagedFavicon Component\n * \n * Server component that renders favicon link tags using the project's logo.\n * When a logo is uploaded in Project Settings, it's automatically synced\n * to the 'favicon' slot in site_managed_images.\n * \n * Usage:\n * ```tsx\n * import { ManagedFavicon } from '@sonordev/site-kit/images'\n * \n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <head>\n * <ManagedFavicon />\n * </head>\n * <body>{children}</body>\n * </html>\n * )\n * }\n * ```\n * \n * Supports:\n * - SVG favicons (best for modern browsers, scales perfectly)\n * - PNG favicons with multiple sizes\n * - Apple touch icons\n * - Theme color for mobile browsers\n */\n\nimport React from 'react'\n\nexport interface ManagedFaviconProps {\n /**\n * API key for Portal API authentication\n * Defaults to SONOR_API_KEY env var\n */\n apiKey?: string\n \n /**\n * API URL (defaults to https://api.sonor.io)\n */\n apiUrl?: string\n \n /**\n * Fallback favicon URL if no managed favicon is set\n */\n fallback?: string\n \n /**\n * Theme color for mobile browser chrome\n * Defaults to #4bbf39 (Sonor brand primary)\n */\n themeColor?: string\n}\n\ninterface FaviconData {\n public_url?: string\n mime_type?: string\n is_placeholder?: boolean\n}\n\n/** If url is relative (e.g. /uploads/... from API), resolve against base so production can load it. */\nfunction toAbsoluteFaviconUrl(url: string | undefined, apiBase: string): string | undefined {\n if (!url) return undefined\n if (url.startsWith('http://') || url.startsWith('https://')) return url\n const base = apiBase.replace(/\\/$/, '')\n return url.startsWith('/') ? `${base}${url}` : `${base}/${url}`\n}\n\n/**\n * Server-side fetch of favicon data.\n * Exported for use in generateMetadata (single source for favicon URL).\n */\nexport async function fetchFaviconData(apiUrl: string, apiKey: string): Promise<FaviconData | null> {\n try {\n const res = await fetch(`${apiUrl}/public/images/slot/favicon`, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 3600 }, // Cache 1hr – favicon rarely changes, allows static generation\n })\n\n if (!res.ok) {\n console.warn('[ManagedFavicon] Failed to fetch:', res.status)\n return null\n }\n\n const data = await res.json()\n if (data.image && !data.is_placeholder) {\n const raw = data.image.public_url || data.image.external_url\n const public_url = toAbsoluteFaviconUrl(raw, apiUrl)\n return {\n public_url: public_url || undefined,\n mime_type: data.image.file?.mime_type,\n is_placeholder: false,\n }\n }\n return null\n } catch (err) {\n console.error('[ManagedFavicon] Error fetching favicon:', err)\n return null\n }\n}\n\n/**\n * Return the managed favicon URL for the project (from API key).\n * Use in generateMetadata to set metadata.icons so favicon is consistent across all sites.\n */\nexport async function getManagedFaviconUrl(\n apiKey?: string,\n apiUrl: string = process.env.SONOR_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.sonor.io'\n): Promise<string | null> {\n const key = apiKey ?? process.env.SONOR_API_KEY ?? process.env.UPTRADE_API_KEY ?? process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n if (!key) return null\n const data = await fetchFaviconData(apiUrl, key)\n return data?.public_url ?? null\n}\n\nexport async function ManagedFavicon({\n apiKey = process.env.SONOR_API_KEY || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY,\n apiUrl = process.env.SONOR_API_URL || process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.sonor.io',\n fallback = '/favicon.ico',\n themeColor = '#4bbf39',\n}: ManagedFaviconProps) {\n // Fetch favicon data during SSR\n const faviconData = apiKey && apiUrl ? await fetchFaviconData(apiUrl, apiKey) : null\n \n const faviconUrl = faviconData?.public_url || fallback\n const mimeType = faviconData?.mime_type || 'image/x-icon'\n const isSvg = mimeType === 'image/svg+xml' || faviconUrl.endsWith('.svg')\n\n return (\n <>\n {/* Primary favicon */}\n {isSvg ? (\n <link rel=\"icon\" type=\"image/svg+xml\" href={faviconUrl} />\n ) : (\n <>\n <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href={faviconUrl} />\n <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href={faviconUrl} />\n </>\n )}\n \n {/* Apple touch icon (for iOS home screen) */}\n <link rel=\"apple-touch-icon\" sizes=\"180x180\" href={faviconUrl} />\n \n {/* Theme color for mobile browsers */}\n <meta name=\"theme-color\" content={themeColor} />\n </>\n )\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/seo/routing.ts"],"names":["getRedirectData","getRobotsData","getSitemapEntries"],"mappings":"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","file":"chunk-ELDJDBQL.js","sourcesContent":["import { getRedirectData, getRobotsData, getSitemapEntries } from './server-api'\nimport type { \n GetRedirectOptions, \n RedirectResult, \n GetRobotsOptions, \n RobotsDirective,\n GetSitemapEntriesOptions,\n SitemapEntry \n} from './types'\n\n/**\n * Get redirect for a path if one exists\n * \n * Use in Next.js middleware to handle managed redirects\n * \n * @example\n * ```tsx\n * // middleware.ts\n * import { getRedirect } from '@sonordev/seo'\n * \n * export async function middleware(request) {\n * const redirect = await getRedirect({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: request.nextUrl.pathname\n * })\n * \n * if (redirect) {\n * return NextResponse.redirect(redirect.destination, redirect.statusCode)\n * }\n * }\n * ```\n */\nexport async function getRedirect(\n options: GetRedirectOptions\n): Promise<RedirectResult | null> {\n const { path } = options\n\n const redirect = await getRedirectData(path)\n\n if (!redirect) {\n return null\n }\n\n // Check if expired\n if (redirect.expires_at && new Date(redirect.expires_at) < new Date()) {\n return null\n }\n\n // Determine destination\n const destination = redirect.destination_url || redirect.destination_path\n const isExternal = destination.startsWith('http://') || destination.startsWith('https://')\n\n return {\n destination,\n statusCode: redirect.status_code,\n isExternal,\n }\n}\n\n/**\n * Parse robots directive string into structured object\n */\nfunction parseRobotsString(robots: string): RobotsDirective {\n const directive: RobotsDirective = {\n index: true,\n follow: true,\n }\n\n const parts = robots.toLowerCase().split(',').map(p => p.trim())\n\n for (const part of parts) {\n if (part === 'noindex') directive.index = false\n if (part === 'nofollow') directive.follow = false\n if (part === 'noarchive') directive.noarchive = true\n if (part === 'nosnippet') directive.nosnippet = true\n if (part === 'noimageindex') directive.noimageindex = true\n if (part.startsWith('max-snippet:')) {\n directive.max_snippet = parseInt(part.split(':')[1], 10)\n }\n if (part.startsWith('max-image-preview:')) {\n const value = part.split(':')[1] as 'none' | 'standard' | 'large'\n directive.max_image_preview = value\n }\n if (part.startsWith('max-video-preview:')) {\n directive.max_video_preview = parseInt(part.split(':')[1], 10)\n }\n }\n\n return directive\n}\n\n/**\n * Get robots directive for a page\n * \n * @example\n * ```tsx\n * const robots = await getRobotsDirective({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * path: '/private-page'\n * })\n * \n * if (!robots.index) {\n * // Page should not be indexed\n * }\n * ```\n */\nexport async function getRobotsDirective(\n options: GetRobotsOptions\n): Promise<RobotsDirective> {\n const { path } = options\n\n const robotsString = await getRobotsData(path)\n\n if (!robotsString) {\n // Default: index and follow\n return { index: true, follow: true }\n }\n\n return parseRobotsString(robotsString)\n}\n\n/**\n * Get sitemap entries for a project\n * \n * Use in sitemap.ts to generate dynamic sitemap\n * \n * @example\n * ```tsx\n * // app/sitemap.ts\n * import { generateSitemap } from '@sonordev/seo'\n * \n * export default async function sitemap() {\n * return generateSitemap({\n * projectId: process.env.UPTRADE_PROJECT_ID!,\n * baseUrl: 'https://example.com',\n * publishedOnly: true\n * })\n * }\n * ```\n */\nexport async function generateSitemap(\n options: GetSitemapEntriesOptions\n): Promise<SitemapEntry[]> {\n const { baseUrl, publishedOnly = true } = options\n\n const pages = await getSitemapEntries({ publishedOnly })\n\n const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n\n return pages.map((page: { path: string; lastmod?: string; changefreq?: string; priority?: number }) => ({\n path: page.path,\n url: `${normalizedBase}${page.path}`,\n lastmod: page.lastmod,\n changefreq: (page.changefreq || 'weekly') as SitemapEntry['changefreq'],\n priority: page.priority ?? 0.5,\n }))\n}\n\n/**\n * Register local sitemap entries with Sonor\n * \n * Call this at build time to sync your local routes to seo_pages.\n * This ensures analytics only tracks real pages.\n * \n * After registration, Signal AI will generate optimized meta titles\n * and descriptions for pages that don't have managed meta yet.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts\n * import { registerLocalSitemap } from '@sonordev/seo'\n * \n * // Option 1: Provide entries directly\n * await registerLocalSitemap({\n * entries: [\n * { path: '/', title: 'Home', priority: 1.0 },\n * { path: '/about', title: 'About Us', priority: 0.8 },\n * ]\n * })\n * \n * // Option 2: Auto-discover from Next.js app directory\n * await registerLocalSitemap({ autoDiscover: true })\n * \n * // Option 3: Skip Signal AI meta optimization\n * await registerLocalSitemap({ autoDiscover: true, optimize_meta: false })\n * ```\n */\nexport async function registerLocalSitemap(options: {\n entries?: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>\n autoDiscover?: boolean\n /** Trigger Signal AI to generate optimized meta titles/descriptions (default: true) */\n optimize_meta?: boolean\n}): Promise<{ \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 const { registerSitemap } = await import('./server-api')\n \n let entries = options.entries || []\n \n // Auto-discover from Next.js app directory if requested\n if (options.autoDiscover && entries.length === 0) {\n try {\n const fs = await import('fs')\n const path = await import('path')\n \n const appDir = path.join(process.cwd(), 'app')\n if (fs.existsSync(appDir)) {\n entries = discoverNextJsRoutes(appDir, fs, path)\n console.log(`[Sonor] Auto-discovered ${entries.length} routes from app directory`)\n }\n } catch (error) {\n console.error('[Sonor] Auto-discovery failed:', error)\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 result = await registerSitemap(entries)\n \n if (result.success) {\n console.log(`[Sonor] Sitemap registered: ${result.created} new, ${result.updated} updated`)\n }\n \n return result\n}\n\n/**\n * Discover routes from Next.js app directory\n */\nfunction discoverNextJsRoutes(\n appDir: string,\n fs: typeof import('fs'),\n path: typeof import('path'),\n basePath: string = ''\n): Array<{ path: string; priority: number }> {\n const entries: Array<{ path: string; priority: number }> = []\n \n const items = fs.readdirSync(appDir, { withFileTypes: true })\n \n for (const item of items) {\n // Skip private folders, api routes, and special files\n if (item.name.startsWith('_') || item.name.startsWith('.')) continue\n if (item.name === 'api') continue\n if (item.name === 'node_modules') continue\n \n const itemPath = path.join(appDir, item.name)\n \n if (item.isDirectory()) {\n // Check for page.tsx/page.js in this directory\n const hasPage = fs.existsSync(path.join(itemPath, 'page.tsx')) ||\n fs.existsSync(path.join(itemPath, 'page.js')) ||\n fs.existsSync(path.join(itemPath, 'page.jsx'))\n \n // Handle route groups (parentheses)\n const isRouteGroup = item.name.startsWith('(') && item.name.endsWith(')')\n \n // Handle dynamic segments [slug]\n const isDynamic = item.name.startsWith('[') && item.name.endsWith(']')\n \n let routePath = basePath\n if (!isRouteGroup && !isDynamic) {\n routePath = `${basePath}/${item.name}`\n }\n \n if (hasPage && !isDynamic) {\n const priority = routePath === '' ? 1.0 : 0.8\n entries.push({ path: routePath || '/', priority })\n }\n \n // Recurse into subdirectories (but not dynamic ones)\n if (!isDynamic) {\n const subEntries = discoverNextJsRoutes(itemPath, fs, path, isRouteGroup ? basePath : routePath)\n entries.push(...subEntries)\n }\n }\n }\n \n // Add root if app/page.tsx exists and we're at root\n if (basePath === '') {\n const hasRootPage = fs.existsSync(path.join(appDir, 'page.tsx')) ||\n fs.existsSync(path.join(appDir, 'page.js')) ||\n fs.existsSync(path.join(appDir, 'page.jsx'))\n if (hasRootPage) {\n entries.unshift({ path: '/', priority: 1.0 })\n }\n }\n \n return entries\n}\n\n/**\n * Check if a path should be indexed\n * \n * Quick helper to check indexability without full directive parsing\n */\nexport async function isIndexable(\n projectId: string,\n path: string\n): Promise<boolean> {\n const directive = await getRobotsDirective({ projectId, path })\n return directive.index\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/site-config/index.ts"],"names":[],"mappings":";;;AAeA,IAAM,eAAA,GAAkB,sBAAA;AACxB,IAAM,YAAA,GAAe,KAAK,EAAA,GAAK,GAAA;AAO/B,IAAM,KAAA,uBAAY,GAAA,EAAwB;AAE1C,SAAS,UAAU,OAAA,EAAoD;AACrE,EAAA,IAAI,OAAA,EAAS,MAAA,EAAQ,OAAO,OAAA,CAAQ,MAAA;AACpC,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OAAO,QAAQ,GAAA,CAAI,aAAA,IAAiB,QAAQ,GAAA,CAAI,eAAA,IAAmB,QAAQ,GAAA,CAAI,2BAAA;AAAA,EACjF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,UAAU,OAAA,EAAwC;AACzD,EAAA,IAAI,SAAS,MAAA,EAAQ,OAAO,QAAQ,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC5D,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,MAAM,CAAA,GAAI,QAAQ,GAAA,CAAI,aAAA,IAAiB,QAAQ,GAAA,CAAI,eAAA,IAAmB,QAAQ,GAAA,CAAI,2BAAA;AAClF,IAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,eAAA;AACT;AAOA,eAAsB,cACpB,OAAA,EAC4B;AAC5B,EAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AAEpB,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAC/B,EAAA,IAAI,MAAA,IAAU,GAAA,GAAM,MAAA,CAAO,MAAA,EAAQ;AACjC,IAAA,OAAO,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,MAAA,EAAQ,OAAO,MAAA,EAAO;AAAA,EAC5D;AAEA,EAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,EAAA,MAAM,GAAA,GAAM,GAAG,MAAM,CAAA,4BAAA,CAAA;AAErB,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAC3B,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,EAAE,UAAA,EAAY,GAAA;AAAI,KACzB,CAAA;AAED,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AAEpB,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA,KAAa,KAAK,cAAA,GAAiB,CAAA,QAAA,EAAW,OAAO,IAAA,CAAK,cAAc,CAAA,CAAE,OAAA,CAAQ,2BAA2B,EAAE,CAAA,CAAE,QAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,CAAA,GAAK,IAAA,CAAA;AAC9J,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA,KAAW,IAAA,CAAK,cAAA,GAAiB,OAAO,IAAA,CAAK,cAAc,CAAA,CAAE,OAAA,CAAQ,2BAA2B,EAAE,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,IAAA,CAAA;AAE7I,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,MAAA,IAAU,OAAO,aAAa,QAAA,IAAY,OAAO,MAAA,KAAW,QAAA,EAAU,OAAO,IAAA;AAE/F,IAAA,KAAA,CAAM,IAAI,MAAA,EAAQ;AAAA,MAChB,QAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAQ,GAAA,GAAM;AAAA,KACf,CAAA;AAED,IAAA,OAAO,EAAE,UAAU,MAAA,EAAO;AAAA,EAC5B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAKO,SAAS,oBAAA,GAA6B;AAC3C,EAAA,KAAA,CAAM,KAAA,EAAM;AACd","file":"chunk-EUNL6GAL.js","sourcesContent":["/**\n * Site config from Portal (project-info) by API key.\n * Resolves site_url and domain so consumers only need SONOR_API_KEY.\n */\n\nexport interface SiteConfig {\n site_url: string\n domain: string\n}\n\nexport interface GetSiteConfigOptions {\n apiKey?: string\n apiUrl?: string\n}\n\nconst DEFAULT_API_URL = 'https://api.sonor.io'\nconst CACHE_TTL_MS = 10 * 60 * 1000 // 10 minutes\n\ninterface CacheEntry {\n site_url: string\n domain: string\n expiry: number\n}\nconst cache = new Map<string, CacheEntry>()\n\nfunction getApiKey(options?: GetSiteConfigOptions): string | undefined {\n if (options?.apiKey) return options.apiKey\n if (typeof process !== 'undefined' && process.env) {\n return process.env.SONOR_API_KEY || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n }\n return undefined\n}\n\nfunction getApiUrl(options?: GetSiteConfigOptions): string {\n if (options?.apiUrl) return options.apiUrl.replace(/\\/$/, '')\n if (typeof process !== 'undefined' && process.env) {\n const u = process.env.SONOR_API_URL || process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL\n if (u) return u.replace(/\\/$/, '')\n }\n return DEFAULT_API_URL\n}\n\n/**\n * Fetch site_url and domain from Portal project-info for the given API key.\n * Uses in-memory cache (TTL 10 min) keyed by apiKey.\n * Safe for Edge (middleware) and Node (route handlers).\n */\nexport async function getSiteConfig(\n options?: GetSiteConfigOptions\n): Promise<SiteConfig | null> {\n const apiKey = getApiKey(options)\n if (!apiKey) return null\n\n const now = Date.now()\n const cached = cache.get(apiKey)\n if (cached && now < cached.expiry) {\n return { site_url: cached.site_url, domain: cached.domain }\n }\n\n const apiUrl = getApiUrl(options)\n const url = `${apiUrl}/api/public/seo/project-info`\n\n try {\n const res = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 600 },\n })\n\n if (!res.ok) return null\n\n const data = await res.json()\n const site_url = data.site_url ?? (data.project_domain ? `https://${String(data.project_domain).replace(/^(https?:\\/\\/)?(www\\.)?/, '').replace(/\\/$/, '')}` : null)\n const domain = data.domain ?? (data.project_domain ? String(data.project_domain).replace(/^(https?:\\/\\/)?(www\\.)?/, '').replace(/\\/$/, '') : null)\n\n if (!site_url || !domain || typeof site_url !== 'string' || typeof domain !== 'string') return null\n\n cache.set(apiKey, {\n site_url,\n domain,\n expiry: now + CACHE_TTL_MS,\n })\n\n return { site_url, domain }\n } catch {\n return null\n }\n}\n\n/**\n * Clear in-memory site config cache (e.g. for tests).\n */\nexport function clearSiteConfigCache(): void {\n cache.clear()\n}\n"]}
|