@sonordev/site-kit 1.2.7
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/README.md +376 -0
- package/dist/SetupWizard-Cki06kB0.d.mts +12 -0
- package/dist/SetupWizard-Cki06kB0.d.ts +12 -0
- package/dist/analytics/index.d.mts +93 -0
- package/dist/analytics/index.d.ts +93 -0
- package/dist/analytics/index.js +89 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/index.mjs +71 -0
- package/dist/analytics/index.mjs.map +1 -0
- package/dist/api-CWtoFJCO.d.mts +137 -0
- package/dist/api-CWtoFJCO.d.ts +137 -0
- package/dist/blog/index.d.mts +305 -0
- package/dist/blog/index.d.ts +305 -0
- package/dist/blog/index.js +1578 -0
- package/dist/blog/index.js.map +1 -0
- package/dist/blog/index.mjs +1562 -0
- package/dist/blog/index.mjs.map +1 -0
- package/dist/blog/server.d.mts +229 -0
- package/dist/blog/server.d.ts +229 -0
- package/dist/blog/server.js +692 -0
- package/dist/blog/server.js.map +1 -0
- package/dist/blog/server.mjs +666 -0
- package/dist/blog/server.mjs.map +1 -0
- package/dist/chunk-24277A3Q.mjs +968 -0
- package/dist/chunk-24277A3Q.mjs.map +1 -0
- package/dist/chunk-373TK6TZ.js +321 -0
- package/dist/chunk-373TK6TZ.js.map +1 -0
- package/dist/chunk-3MYZS6PD.js +30 -0
- package/dist/chunk-3MYZS6PD.js.map +1 -0
- package/dist/chunk-43GBM4SX.js +283 -0
- package/dist/chunk-43GBM4SX.js.map +1 -0
- package/dist/chunk-4XPGGLVP.mjs +53 -0
- package/dist/chunk-4XPGGLVP.mjs.map +1 -0
- package/dist/chunk-622GAQP5.js +2008 -0
- package/dist/chunk-622GAQP5.js.map +1 -0
- package/dist/chunk-6BIPAKL4.mjs +28 -0
- package/dist/chunk-6BIPAKL4.mjs.map +1 -0
- package/dist/chunk-6ZCISNAB.mjs +343 -0
- package/dist/chunk-6ZCISNAB.mjs.map +1 -0
- package/dist/chunk-72MQFHYJ.js +1429 -0
- package/dist/chunk-72MQFHYJ.js.map +1 -0
- package/dist/chunk-7557OTHW.js +62 -0
- package/dist/chunk-7557OTHW.js.map +1 -0
- package/dist/chunk-7FUV73JZ.js +981 -0
- package/dist/chunk-7FUV73JZ.js.map +1 -0
- package/dist/chunk-7RF6PVHA.mjs +324 -0
- package/dist/chunk-7RF6PVHA.mjs.map +1 -0
- package/dist/chunk-7RYCHO6D.mjs +134 -0
- package/dist/chunk-7RYCHO6D.mjs.map +1 -0
- package/dist/chunk-7UKPRW25.mjs +1999 -0
- package/dist/chunk-7UKPRW25.mjs.map +1 -0
- package/dist/chunk-7URAOG2M.js +14864 -0
- package/dist/chunk-7URAOG2M.js.map +1 -0
- package/dist/chunk-AFAO3TGS.mjs +810 -0
- package/dist/chunk-AFAO3TGS.mjs.map +1 -0
- package/dist/chunk-BYLIU6XG.js +343 -0
- package/dist/chunk-BYLIU6XG.js.map +1 -0
- package/dist/chunk-D63MUKZ6.mjs +4423 -0
- package/dist/chunk-D63MUKZ6.mjs.map +1 -0
- package/dist/chunk-DDKW2FNA.js +390 -0
- package/dist/chunk-DDKW2FNA.js.map +1 -0
- package/dist/chunk-DQYMKR27.mjs +341 -0
- package/dist/chunk-DQYMKR27.mjs.map +1 -0
- package/dist/chunk-DW5UJKHH.js +221 -0
- package/dist/chunk-DW5UJKHH.js.map +1 -0
- package/dist/chunk-EEZCR6E6.js +50 -0
- package/dist/chunk-EEZCR6E6.js.map +1 -0
- package/dist/chunk-GCJXQ4AG.mjs +59 -0
- package/dist/chunk-GCJXQ4AG.mjs.map +1 -0
- package/dist/chunk-JGNQK2G6.mjs +14845 -0
- package/dist/chunk-JGNQK2G6.mjs.map +1 -0
- package/dist/chunk-JTLOJLWQ.mjs +563 -0
- package/dist/chunk-JTLOJLWQ.mjs.map +1 -0
- package/dist/chunk-K23A4G76.mjs +202 -0
- package/dist/chunk-K23A4G76.mjs.map +1 -0
- package/dist/chunk-KKU3K7RG.js +336 -0
- package/dist/chunk-KKU3K7RG.js.map +1 -0
- package/dist/chunk-KUGMH4ZF.js +571 -0
- package/dist/chunk-KUGMH4ZF.js.map +1 -0
- package/dist/chunk-LBVWVP72.js +110 -0
- package/dist/chunk-LBVWVP72.js.map +1 -0
- package/dist/chunk-LIVWLY2P.js +138 -0
- package/dist/chunk-LIVWLY2P.js.map +1 -0
- package/dist/chunk-M2T6R7BA.mjs +1003 -0
- package/dist/chunk-M2T6R7BA.mjs.map +1 -0
- package/dist/chunk-MV3QN7PW.mjs +47 -0
- package/dist/chunk-MV3QN7PW.mjs.map +1 -0
- package/dist/chunk-OB7E654K.js +72 -0
- package/dist/chunk-OB7E654K.js.map +1 -0
- package/dist/chunk-OIIKTGRL.mjs +380 -0
- package/dist/chunk-OIIKTGRL.mjs.map +1 -0
- package/dist/chunk-P3UWIUJS.mjs +1427 -0
- package/dist/chunk-P3UWIUJS.mjs.map +1 -0
- package/dist/chunk-PKN27UMH.mjs +136 -0
- package/dist/chunk-PKN27UMH.mjs.map +1 -0
- package/dist/chunk-QXV4667R.mjs +105 -0
- package/dist/chunk-QXV4667R.mjs.map +1 -0
- package/dist/chunk-S7FRYNSU.mjs +315 -0
- package/dist/chunk-S7FRYNSU.mjs.map +1 -0
- package/dist/chunk-TFLQX7K7.mjs +68 -0
- package/dist/chunk-TFLQX7K7.mjs.map +1 -0
- package/dist/chunk-UWE5PCYJ.mjs +279 -0
- package/dist/chunk-UWE5PCYJ.mjs.map +1 -0
- package/dist/chunk-UYFDNX2F.js +4469 -0
- package/dist/chunk-UYFDNX2F.js.map +1 -0
- package/dist/chunk-W4PALSGM.js +350 -0
- package/dist/chunk-W4PALSGM.js.map +1 -0
- package/dist/chunk-WECQ6KOB.js +1008 -0
- package/dist/chunk-WECQ6KOB.js.map +1 -0
- package/dist/chunk-XQQWI6WB.js +814 -0
- package/dist/chunk-XQQWI6WB.js.map +1 -0
- package/dist/chunk-XZJOZJB6.js +140 -0
- package/dist/chunk-XZJOZJB6.js.map +1 -0
- package/dist/chunk-ZSMWDLMK.js +63 -0
- package/dist/chunk-ZSMWDLMK.js.map +1 -0
- package/dist/cli/index.js +37243 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +37209 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/commerce/index.d.mts +170 -0
- package/dist/commerce/index.d.ts +170 -0
- package/dist/commerce/index.js +174 -0
- package/dist/commerce/index.js.map +1 -0
- package/dist/commerce/index.mjs +5 -0
- package/dist/commerce/index.mjs.map +1 -0
- package/dist/commerce/server.d.mts +107 -0
- package/dist/commerce/server.d.ts +107 -0
- package/dist/commerce/server.js +187 -0
- package/dist/commerce/server.js.map +1 -0
- package/dist/commerce/server.mjs +177 -0
- package/dist/commerce/server.mjs.map +1 -0
- package/dist/config/index.d.mts +43 -0
- package/dist/config/index.d.ts +43 -0
- package/dist/config/index.js +66 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +64 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/engage/index.d.mts +33 -0
- package/dist/engage/index.d.ts +33 -0
- package/dist/engage/index.js +22 -0
- package/dist/engage/index.js.map +1 -0
- package/dist/engage/index.mjs +5 -0
- package/dist/engage/index.mjs.map +1 -0
- package/dist/forms/index.d.mts +437 -0
- package/dist/forms/index.d.ts +437 -0
- package/dist/forms/index.js +1168 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/forms/index.mjs +1142 -0
- package/dist/forms/index.mjs.map +1 -0
- package/dist/generators-2XKQMPKH.mjs +4 -0
- package/dist/generators-2XKQMPKH.mjs.map +1 -0
- package/dist/generators-DTMO36DV.js +33 -0
- package/dist/generators-DTMO36DV.js.map +1 -0
- package/dist/images/index.d.mts +4 -0
- package/dist/images/index.d.ts +4 -0
- package/dist/images/index.js +46 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/index.mjs +5 -0
- package/dist/images/index.mjs.map +1 -0
- package/dist/images/server.d.mts +69 -0
- package/dist/images/server.d.ts +69 -0
- package/dist/images/server.js +21 -0
- package/dist/images/server.js.map +1 -0
- package/dist/images/server.mjs +4 -0
- package/dist/images/server.mjs.map +1 -0
- package/dist/index.d.mts +846 -0
- package/dist/index.d.ts +846 -0
- package/dist/index.js +2623 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2416 -0
- package/dist/index.mjs.map +1 -0
- package/dist/layout/index.d.mts +53 -0
- package/dist/layout/index.d.ts +53 -0
- package/dist/layout/index.js +187 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/index.mjs +185 -0
- package/dist/layout/index.mjs.map +1 -0
- package/dist/llms/index.d.mts +448 -0
- package/dist/llms/index.d.ts +448 -0
- package/dist/llms/index.js +581 -0
- package/dist/llms/index.js.map +1 -0
- package/dist/llms/index.mjs +529 -0
- package/dist/llms/index.mjs.map +1 -0
- package/dist/manifest/index.d.mts +62 -0
- package/dist/manifest/index.d.ts +62 -0
- package/dist/manifest/index.js +85 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/index.mjs +83 -0
- package/dist/manifest/index.mjs.map +1 -0
- package/dist/middleware/index.d.mts +63 -0
- package/dist/middleware/index.d.ts +63 -0
- package/dist/middleware/index.js +54 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/index.mjs +51 -0
- package/dist/middleware/index.mjs.map +1 -0
- package/dist/migrator-2MQHOFDQ.mjs +4 -0
- package/dist/migrator-2MQHOFDQ.mjs.map +1 -0
- package/dist/migrator-THJCF6MZ.js +37 -0
- package/dist/migrator-THJCF6MZ.js.map +1 -0
- package/dist/redirects/index.d.mts +78 -0
- package/dist/redirects/index.d.ts +78 -0
- package/dist/redirects/index.js +26 -0
- package/dist/redirects/index.js.map +1 -0
- package/dist/redirects/index.mjs +5 -0
- package/dist/redirects/index.mjs.map +1 -0
- package/dist/reputation/index.d.mts +57 -0
- package/dist/reputation/index.d.ts +57 -0
- package/dist/reputation/index.js +21 -0
- package/dist/reputation/index.js.map +1 -0
- package/dist/reputation/index.mjs +4 -0
- package/dist/reputation/index.mjs.map +1 -0
- package/dist/robots/index.d.mts +38 -0
- package/dist/robots/index.d.ts +38 -0
- package/dist/robots/index.js +52 -0
- package/dist/robots/index.js.map +1 -0
- package/dist/robots/index.mjs +50 -0
- package/dist/robots/index.mjs.map +1 -0
- package/dist/routing-B5XS-6_W.d.mts +118 -0
- package/dist/routing-DZYzyDHw.d.ts +118 -0
- package/dist/scanner-GAF5PO5F.js +53 -0
- package/dist/scanner-GAF5PO5F.js.map +1 -0
- package/dist/scanner-LKJKW7IT.mjs +4 -0
- package/dist/scanner-LKJKW7IT.mjs.map +1 -0
- package/dist/securityHeaders-nwZ6nP4g.d.mts +24 -0
- package/dist/securityHeaders-nwZ6nP4g.d.ts +24 -0
- package/dist/seo/index.d.mts +600 -0
- package/dist/seo/index.d.ts +600 -0
- package/dist/seo/index.js +883 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/index.mjs +773 -0
- package/dist/seo/index.mjs.map +1 -0
- package/dist/seo/register-sitemap-cli.js +151 -0
- package/dist/seo/register-sitemap-cli.js.map +1 -0
- package/dist/seo/register-sitemap-cli.mjs +144 -0
- package/dist/seo/register-sitemap-cli.mjs.map +1 -0
- package/dist/seo/server.d.mts +107 -0
- package/dist/seo/server.d.ts +107 -0
- package/dist/seo/server.js +207 -0
- package/dist/seo/server.js.map +1 -0
- package/dist/seo/server.mjs +186 -0
- package/dist/seo/server.mjs.map +1 -0
- package/dist/server-api-EWXKOQZA.mjs +4 -0
- package/dist/server-api-EWXKOQZA.mjs.map +1 -0
- package/dist/server-api-GJPNRYUP.js +81 -0
- package/dist/server-api-GJPNRYUP.js.map +1 -0
- package/dist/setup/client.d.mts +60 -0
- package/dist/setup/client.d.ts +60 -0
- package/dist/setup/client.js +31 -0
- package/dist/setup/client.js.map +1 -0
- package/dist/setup/client.mjs +6 -0
- package/dist/setup/client.mjs.map +1 -0
- package/dist/setup/index.d.mts +5 -0
- package/dist/setup/index.d.ts +5 -0
- package/dist/setup/index.js +35 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/index.mjs +6 -0
- package/dist/setup/index.mjs.map +1 -0
- package/dist/setup/server.d.mts +14 -0
- package/dist/setup/server.d.ts +14 -0
- package/dist/setup/server.js +13 -0
- package/dist/setup/server.js.map +1 -0
- package/dist/setup/server.mjs +4 -0
- package/dist/setup/server.mjs.map +1 -0
- package/dist/site-config/index.d.mts +24 -0
- package/dist/site-config/index.d.ts +24 -0
- package/dist/site-config/index.js +17 -0
- package/dist/site-config/index.js.map +1 -0
- package/dist/site-config/index.mjs +4 -0
- package/dist/site-config/index.mjs.map +1 -0
- package/dist/sitemap/index.d.mts +96 -0
- package/dist/sitemap/index.d.ts +96 -0
- package/dist/sitemap/index.js +288 -0
- package/dist/sitemap/index.js.map +1 -0
- package/dist/sitemap/index.mjs +285 -0
- package/dist/sitemap/index.mjs.map +1 -0
- package/dist/socket-loader-J26QHHOB.js +16 -0
- package/dist/socket-loader-J26QHHOB.js.map +1 -0
- package/dist/socket-loader-R7S2YJ2J.mjs +14 -0
- package/dist/socket-loader-R7S2YJ2J.mjs.map +1 -0
- package/dist/types-0dmq3k20.d.mts +168 -0
- package/dist/types-0dmq3k20.d.ts +168 -0
- package/dist/types-Blb2QNkV.d.mts +263 -0
- package/dist/types-Blb2QNkV.d.ts +263 -0
- package/dist/types-BnCwwUX3.d.mts +250 -0
- package/dist/types-BnCwwUX3.d.ts +250 -0
- package/dist/types-CGlnp43R.d.mts +312 -0
- package/dist/types-CGlnp43R.d.ts +312 -0
- package/dist/types-D08004rU.d.mts +179 -0
- package/dist/types-D08004rU.d.ts +179 -0
- package/dist/types-DNSYU7qI.d.mts +127 -0
- package/dist/types-DNSYU7qI.d.ts +127 -0
- package/dist/types-KZP_VWZp.d.mts +266 -0
- package/dist/types-KZP_VWZp.d.ts +266 -0
- package/dist/useEventModal-BVTx69XE.d.mts +274 -0
- package/dist/useEventModal-Dx1dItTJ.d.ts +274 -0
- package/dist/web-vitals-444RLW3B.js +252 -0
- package/dist/web-vitals-444RLW3B.js.map +1 -0
- package/dist/web-vitals-KPICZIEF.mjs +241 -0
- package/dist/web-vitals-KPICZIEF.mjs.map +1 -0
- package/package.json +192 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export { g as generateSitemap, r as registerLocalSitemap } from '../routing-DZYzyDHw.js';
|
|
2
|
+
export { A as ABTest, j as ABTestResult, F as FAQItem, k as GetABVariantOptions, G as GetManagedMetadataOptions, m as GetRedirectOptions, q as GetRobotsOptions, s as GetSitemapEntriesOptions, g as ManagedContentBlock, h as ManagedContentProps, c as ManagedFAQData, d as ManagedFAQProps, f as ManagedInternalLinksProps, e as ManagedLink, M as ManagedMetadataResult, l as ManagedRedirect, b as ManagedSchemaProps, n as ManagedScript, o as ManagedScriptsProps, R as RedirectResult, p as RobotsDirective, i as SEOEntity, S as SEOPageData, a as SchemaMarkup, r as SitemapEntry, U as UptradeSEOConfig } from '../types-KZP_VWZp.js';
|
|
3
|
+
import 'next';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @sonordev/site-kit/seo - API Functions
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ DEPRECATED: This file exposes API keys in client bundles.
|
|
9
|
+
* Use `server-api.ts` instead for server-side operations.
|
|
10
|
+
*
|
|
11
|
+
* This file is kept for backward compatibility but will be removed in a future version.
|
|
12
|
+
*
|
|
13
|
+
* Migration guide:
|
|
14
|
+
* - Replace: import { getSEOPageData } from '@sonordev/seo/api'
|
|
15
|
+
* - With: import { getSEOPageData } from '@sonordev/seo/server'
|
|
16
|
+
* - Use private env vars: UPTRADE_API_KEY instead of NEXT_PUBLIC_UPTRADE_API_KEY
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Fetch SEO page data - cached per request
|
|
20
|
+
*/
|
|
21
|
+
declare const getSEOPageData: (projectId: string, path: string) => Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetch schema markups for a page - cached per request
|
|
24
|
+
*/
|
|
25
|
+
declare const getSchemaMarkups: (projectId: string, path: string, options?: {
|
|
26
|
+
includeTypes?: string[];
|
|
27
|
+
excludeTypes?: string[];
|
|
28
|
+
}) => Promise<any[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Fetch FAQ data for a page - cached per request
|
|
31
|
+
*/
|
|
32
|
+
declare const getFAQData: (projectId: string, path: string) => Promise<any>;
|
|
33
|
+
/**
|
|
34
|
+
* Fetch internal links for a page - cached per request
|
|
35
|
+
*/
|
|
36
|
+
declare const getInternalLinks: (projectId: string, sourcePath: string, options?: {
|
|
37
|
+
position?: string;
|
|
38
|
+
limit?: number;
|
|
39
|
+
}) => Promise<any[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetch content block - cached per request
|
|
42
|
+
*/
|
|
43
|
+
declare const getContentBlock: (projectId: string, path: string, section: string) => Promise<any>;
|
|
44
|
+
/**
|
|
45
|
+
* Fetch A/B test and determine variant - cached per request
|
|
46
|
+
*/
|
|
47
|
+
declare const getABTest: (projectId: string, path: string, field: string) => Promise<any>;
|
|
48
|
+
/**
|
|
49
|
+
* Record A/B test impression
|
|
50
|
+
*/
|
|
51
|
+
declare function recordABImpression(testId: string, variant: 'a' | 'b', sessionId?: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Fetch redirect for a path - cached per request
|
|
54
|
+
*/
|
|
55
|
+
declare const getRedirectData: (projectId: string, path: string) => Promise<any>;
|
|
56
|
+
/**
|
|
57
|
+
* Fetch managed scripts - cached per request
|
|
58
|
+
*/
|
|
59
|
+
declare const getManagedScripts: (projectId: string, position: string, currentPath?: string) => Promise<any[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Fetch robots directive for a page - cached per request
|
|
62
|
+
*/
|
|
63
|
+
declare const getRobotsData: (projectId: string, path: string) => Promise<any>;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch sitemap entries - cached per request
|
|
66
|
+
*/
|
|
67
|
+
declare const getSitemapEntries: (projectId: string, options?: {
|
|
68
|
+
publishedOnly?: boolean;
|
|
69
|
+
}) => Promise<any[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Register/sync sitemap entries from the client site
|
|
72
|
+
* Call this at build time to populate seo_pages from your sitemap.xml
|
|
73
|
+
*
|
|
74
|
+
* After registration, Signal AI will automatically generate optimized
|
|
75
|
+
* meta titles and descriptions for pages that don't have them yet.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // scripts/register-sitemap.ts (run at build time)
|
|
80
|
+
* import { registerSitemap } from '@sonordev/seo/server'
|
|
81
|
+
*
|
|
82
|
+
* await registerSitemap([
|
|
83
|
+
* { path: '/', priority: 1.0, changefreq: 'daily' },
|
|
84
|
+
* { path: '/about', priority: 0.8, changefreq: 'weekly' },
|
|
85
|
+
* ], { optimize_meta: true })
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function registerSitemap(entries: Array<{
|
|
89
|
+
path: string;
|
|
90
|
+
title?: string;
|
|
91
|
+
priority?: number;
|
|
92
|
+
changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
93
|
+
}>, options?: {
|
|
94
|
+
/** Trigger Signal AI to generate optimized meta titles/descriptions (default: true) */
|
|
95
|
+
optimize_meta?: boolean;
|
|
96
|
+
}): Promise<{
|
|
97
|
+
success: boolean;
|
|
98
|
+
created: number;
|
|
99
|
+
updated: number;
|
|
100
|
+
removed?: number;
|
|
101
|
+
meta_optimization?: {
|
|
102
|
+
triggered: boolean;
|
|
103
|
+
pages_queued: number;
|
|
104
|
+
} | null;
|
|
105
|
+
}>;
|
|
106
|
+
|
|
107
|
+
export { getABTest, getContentBlock, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkXZJOZJB6_js = require('../chunk-XZJOZJB6.js');
|
|
4
|
+
require('../chunk-DW5UJKHH.js');
|
|
5
|
+
require('../chunk-ZSMWDLMK.js');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
|
|
8
|
+
if (process.env.NODE_ENV === "development") {
|
|
9
|
+
console.warn(
|
|
10
|
+
"@sonordev/seo: WARNING - You are using the deprecated api.ts which exposes API keys. Please migrate to server-api.ts for better security. See: packages/site-kit/src/seo/README.md#migration"
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
function getApiConfig() {
|
|
14
|
+
const apiUrl = process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com";
|
|
15
|
+
const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "";
|
|
16
|
+
return { apiUrl, apiKey };
|
|
17
|
+
}
|
|
18
|
+
async function apiPost(endpoint, body = {}) {
|
|
19
|
+
const { apiUrl, apiKey } = getApiConfig();
|
|
20
|
+
if (!apiKey) {
|
|
21
|
+
console.error("@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.");
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
"x-api-key": apiKey
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify(body),
|
|
32
|
+
next: { revalidate: 60 }
|
|
33
|
+
// Cache for 60 seconds
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
console.error(`@sonordev/seo: API error: ${response.statusText}`);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return await response.json();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error("@sonordev/seo: Network error:", error);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
var getSEOPageData = react.cache(async (projectId, path) => {
|
|
46
|
+
const result = await apiPost("/api/public/seo/page", { path });
|
|
47
|
+
return result?.page || null;
|
|
48
|
+
});
|
|
49
|
+
var getSchemaMarkups = react.cache(async (projectId, path, options) => {
|
|
50
|
+
const result = await apiPost("/api/public/seo/schemas", {
|
|
51
|
+
path,
|
|
52
|
+
includeTypes: options?.includeTypes,
|
|
53
|
+
excludeTypes: options?.excludeTypes
|
|
54
|
+
});
|
|
55
|
+
return result?.schemas || [];
|
|
56
|
+
});
|
|
57
|
+
var getFAQData = react.cache(async (projectId, path) => {
|
|
58
|
+
const result = await apiPost("/api/public/seo/faq", { path });
|
|
59
|
+
return result?.faq || null;
|
|
60
|
+
});
|
|
61
|
+
var getInternalLinks = react.cache(async (projectId, sourcePath, options) => {
|
|
62
|
+
const result = await apiPost("/api/public/seo/internal-links", {
|
|
63
|
+
sourcePath,
|
|
64
|
+
position: options?.position,
|
|
65
|
+
limit: options?.limit
|
|
66
|
+
});
|
|
67
|
+
return result?.links || [];
|
|
68
|
+
});
|
|
69
|
+
var getContentBlock = react.cache(async (projectId, path, section) => {
|
|
70
|
+
const result = await apiPost("/api/public/seo/content", { path, section });
|
|
71
|
+
return result?.content || null;
|
|
72
|
+
});
|
|
73
|
+
var getABTest = react.cache(async (projectId, path, field) => {
|
|
74
|
+
const result = await apiPost("/api/public/seo/ab-test", { path, field });
|
|
75
|
+
return result?.test || null;
|
|
76
|
+
});
|
|
77
|
+
async function recordABImpression(testId, variant, sessionId) {
|
|
78
|
+
await apiPost("/api/public/seo/ab-impression", { testId, variant, sessionId });
|
|
79
|
+
}
|
|
80
|
+
var getRedirectData = react.cache(async (projectId, path) => {
|
|
81
|
+
const result = await apiPost("/api/public/seo/redirect", { path });
|
|
82
|
+
return result?.redirect || null;
|
|
83
|
+
});
|
|
84
|
+
var getManagedScripts = react.cache(async (projectId, position, currentPath) => {
|
|
85
|
+
const result = await apiPost("/api/public/seo/scripts", {
|
|
86
|
+
position,
|
|
87
|
+
currentPath
|
|
88
|
+
});
|
|
89
|
+
return result?.scripts || [];
|
|
90
|
+
});
|
|
91
|
+
var getRobotsData = react.cache(async (projectId, path) => {
|
|
92
|
+
const result = await apiPost("/api/public/seo/page", { path });
|
|
93
|
+
return result?.page?.managed_robots || null;
|
|
94
|
+
});
|
|
95
|
+
var getSitemapEntries = react.cache(async (projectId, options) => {
|
|
96
|
+
const result = await apiPost("/api/public/seo/sitemap", {
|
|
97
|
+
publishedOnly: options?.publishedOnly
|
|
98
|
+
});
|
|
99
|
+
return result?.entries || [];
|
|
100
|
+
});
|
|
101
|
+
async function registerSitemap(entries, options) {
|
|
102
|
+
const { apiUrl, apiKey } = getApiConfig();
|
|
103
|
+
if (!apiKey) {
|
|
104
|
+
console.error("@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.");
|
|
105
|
+
return { success: false, created: 0, updated: 0 };
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {
|
|
109
|
+
method: "POST",
|
|
110
|
+
headers: {
|
|
111
|
+
"Content-Type": "application/json",
|
|
112
|
+
"x-api-key": apiKey
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
entries,
|
|
116
|
+
optimize_meta: options?.optimize_meta !== false
|
|
117
|
+
// Default to true
|
|
118
|
+
})
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
console.error(`@sonordev/seo: Sitemap registration failed: ${response.statusText}`);
|
|
122
|
+
return { success: false, created: 0, updated: 0 };
|
|
123
|
+
}
|
|
124
|
+
return await response.json();
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("@sonordev/seo: Sitemap registration error:", error);
|
|
127
|
+
return { success: false, created: 0, updated: 0 };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function getSignalApiConfig() {
|
|
131
|
+
const apiUrl = process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || "https://signal.uptrademedia.com";
|
|
132
|
+
const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "";
|
|
133
|
+
return { apiUrl, apiKey };
|
|
134
|
+
}
|
|
135
|
+
async function signalApiGet(endpoint) {
|
|
136
|
+
const { apiUrl, apiKey } = getSignalApiConfig();
|
|
137
|
+
if (!apiKey) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
142
|
+
method: "GET",
|
|
143
|
+
headers: {
|
|
144
|
+
"Content-Type": "application/json",
|
|
145
|
+
"x-api-key": apiKey
|
|
146
|
+
},
|
|
147
|
+
next: { revalidate: 300 }
|
|
148
|
+
// Cache for 5 minutes
|
|
149
|
+
});
|
|
150
|
+
if (!response.ok) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const result = await response.json();
|
|
154
|
+
return result?.data || result;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error("@sonordev/seo: Signal API error:", error);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
react.cache(async (projectId, options) => {
|
|
161
|
+
let endpoint = `/skills/seo/entities/${projectId}`;
|
|
162
|
+
if (options?.type) {
|
|
163
|
+
endpoint += `?type=${options.type}`;
|
|
164
|
+
}
|
|
165
|
+
const result = await signalApiGet(endpoint);
|
|
166
|
+
return result || [];
|
|
167
|
+
});
|
|
168
|
+
react.cache(async (projectId) => {
|
|
169
|
+
return signalApiGet(`/skills/seo/entities/${projectId}/primary`);
|
|
170
|
+
});
|
|
171
|
+
react.cache(async (projectId, pagePath) => {
|
|
172
|
+
const result = await signalApiGet(
|
|
173
|
+
`/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`
|
|
174
|
+
);
|
|
175
|
+
return result?.schemas || [];
|
|
176
|
+
});
|
|
177
|
+
react.cache(async (projectId, pagePath) => {
|
|
178
|
+
const result = await signalApiGet(`/skills/seo/visibility/${projectId}`);
|
|
179
|
+
if (!result) return null;
|
|
180
|
+
return result.find((s) => s.page_path === pagePath) || null;
|
|
181
|
+
});
|
|
182
|
+
react.cache(async (projectId) => {
|
|
183
|
+
return signalApiGet(`/skills/seo/visibility/${projectId}/summary`);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
Object.defineProperty(exports, "generateSitemap", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
get: function () { return chunkXZJOZJB6_js.generateSitemap; }
|
|
189
|
+
});
|
|
190
|
+
Object.defineProperty(exports, "registerLocalSitemap", {
|
|
191
|
+
enumerable: true,
|
|
192
|
+
get: function () { return chunkXZJOZJB6_js.registerLocalSitemap; }
|
|
193
|
+
});
|
|
194
|
+
exports.getABTest = getABTest;
|
|
195
|
+
exports.getContentBlock = getContentBlock;
|
|
196
|
+
exports.getFAQData = getFAQData;
|
|
197
|
+
exports.getInternalLinks = getInternalLinks;
|
|
198
|
+
exports.getManagedScripts = getManagedScripts;
|
|
199
|
+
exports.getRedirectData = getRedirectData;
|
|
200
|
+
exports.getRobotsData = getRobotsData;
|
|
201
|
+
exports.getSEOPageData = getSEOPageData;
|
|
202
|
+
exports.getSchemaMarkups = getSchemaMarkups;
|
|
203
|
+
exports.getSitemapEntries = getSitemapEntries;
|
|
204
|
+
exports.recordABImpression = recordABImpression;
|
|
205
|
+
exports.registerSitemap = registerSitemap;
|
|
206
|
+
//# sourceMappingURL=server.js.map
|
|
207
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/seo/api.ts"],"names":["cache"],"mappings":"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","file":"server.js","sourcesContent":["/**\n * @sonordev/site-kit/seo - API Functions\n * \n * ⚠️ DEPRECATED: This file exposes API keys in client bundles.\n * Use `server-api.ts` instead for server-side operations.\n * \n * This file is kept for backward compatibility but will be removed in a future version.\n * \n * Migration guide:\n * - Replace: import { getSEOPageData } from '@sonordev/seo/api'\n * - With: import { getSEOPageData } from '@sonordev/seo/server'\n * - Use private env vars: UPTRADE_API_KEY instead of NEXT_PUBLIC_UPTRADE_API_KEY\n */\n\nimport { cache } from 'react'\n\n// Show deprecation warning in development\nif (process.env.NODE_ENV === 'development') {\n console.warn(\n '@sonordev/seo: WARNING - You are using the deprecated api.ts which exposes API keys. ' +\n 'Please migrate to server-api.ts for better security. ' +\n 'See: packages/site-kit/src/seo/README.md#migration'\n )\n}\n\n// ============================================\n// API Config (DEPRECATED)\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function apiPost<T>(endpoint: string, body: Record<string, any> = {}): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n next: { revalidate: 60 }, // Cache for 60 seconds\n })\n \n if (!response.ok) {\n console.error(`@sonordev/seo: API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('@sonordev/seo: Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Cached Data Fetchers\n// ============================================\n\n/**\n * Fetch SEO page data - cached per request\n */\nexport const getSEOPageData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ page: any }>('/api/public/seo/page', { path })\n return result?.page || null\n})\n\n/**\n * Fetch schema markups for a page - cached per request\n */\nexport const getSchemaMarkups = cache(async (\n projectId: string,\n path: string,\n options?: { includeTypes?: string[]; excludeTypes?: string[] }\n) => {\n const result = await apiPost<{ schemas: any[] }>('/api/public/seo/schemas', {\n path,\n includeTypes: options?.includeTypes,\n excludeTypes: options?.excludeTypes,\n })\n return result?.schemas || []\n})\n\n/**\n * Fetch FAQ data for a page - cached per request\n */\nexport const getFAQData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ faq: any }>('/api/public/seo/faq', { path })\n return result?.faq || null\n})\n\n/**\n * Fetch internal links for a page - cached per request\n */\nexport const getInternalLinks = cache(async (\n projectId: string,\n sourcePath: string,\n options?: { position?: string; limit?: number }\n) => {\n const result = await apiPost<{ links: any[] }>('/api/public/seo/internal-links', {\n sourcePath,\n position: options?.position,\n limit: options?.limit,\n })\n return result?.links || []\n})\n\n/**\n * Fetch content block - cached per request\n */\nexport const getContentBlock = cache(async (\n projectId: string,\n path: string,\n section: string\n) => {\n const result = await apiPost<{ content: any }>('/api/public/seo/content', { path, section })\n return result?.content || null\n})\n\n/**\n * Fetch A/B test and determine variant - cached per request\n */\nexport const getABTest = cache(async (\n projectId: string,\n path: string,\n field: string\n) => {\n const result = await apiPost<{ test: any }>('/api/public/seo/ab-test', { path, field })\n return result?.test || null\n})\n\n/**\n * Record A/B test impression\n */\nexport async function recordABImpression(\n testId: string,\n variant: 'a' | 'b',\n sessionId?: string\n): Promise<void> {\n await apiPost('/api/public/seo/ab-impression', { testId, variant, sessionId })\n}\n\n/**\n * Fetch redirect for a path - cached per request\n */\nexport const getRedirectData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ redirect: any }>('/api/public/seo/redirect', { path })\n return result?.redirect || null\n})\n\n/**\n * Fetch managed scripts - cached per request\n */\nexport const getManagedScripts = cache(async (\n projectId: string,\n position: string,\n currentPath?: string\n) => {\n const result = await apiPost<{ scripts: any[] }>('/api/public/seo/scripts', {\n position,\n currentPath,\n })\n return result?.scripts || []\n})\n\n/**\n * Fetch robots directive for a page - cached per request\n */\nexport const getRobotsData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ page: any }>('/api/public/seo/page', { path })\n return result?.page?.managed_robots || null\n})\n\n/**\n * Fetch sitemap entries - cached per request\n */\nexport const getSitemapEntries = cache(async (\n projectId: string,\n options?: { publishedOnly?: boolean }\n) => {\n const result = await apiPost<{ entries: any[] }>('/api/public/seo/sitemap', {\n publishedOnly: options?.publishedOnly,\n })\n return result?.entries || []\n})\n\n/**\n * Register/sync sitemap entries from the client site\n * Call this at build time to populate seo_pages from your sitemap.xml\n * \n * After registration, Signal AI will automatically generate optimized\n * meta titles and descriptions for pages that don't have them yet.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts (run at build time)\n * import { registerSitemap } from '@sonordev/seo/server'\n * \n * await registerSitemap([\n * { path: '/', priority: 1.0, changefreq: 'daily' },\n * { path: '/about', priority: 0.8, changefreq: 'weekly' },\n * ], { optimize_meta: true })\n * ```\n */\nexport async function registerSitemap(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>,\n options?: {\n /** Trigger Signal AI to generate optimized meta titles/descriptions (default: true) */\n optimize_meta?: boolean\n }\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 { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.')\n return { success: false, created: 0, updated: 0 }\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({ \n entries,\n optimize_meta: options?.optimize_meta !== false, // Default to true\n }),\n })\n \n if (!response.ok) {\n console.error(`@sonordev/seo: Sitemap registration failed: ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n \n return await response.json()\n } catch (error) {\n console.error('@sonordev/seo: Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n// ============================================\n// AI Visibility & Entity Graph API\n// ============================================\n\n/**\n * Get Signal API config for AI visibility features\n */\nfunction getSignalApiConfig() {\n const apiUrl = process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.uptrademedia.com'\n const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function signalApiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getSignalApiConfig()\n \n if (!apiKey) {\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 300 }, // Cache for 5 minutes\n })\n \n if (!response.ok) {\n return null\n }\n \n const result = await response.json()\n return result?.data || result\n } catch (error) {\n console.error('@sonordev/seo: Signal API error:', error)\n return null\n }\n}\n\n/**\n * Entity types for the knowledge graph\n */\nexport type EntityType = \n | 'organization'\n | 'person'\n | 'service'\n | 'product'\n | 'location'\n | 'concept'\n | 'credential'\n\n/**\n * Entity from the knowledge graph\n */\nexport interface SEOEntity {\n id: string\n project_id: string\n entity_type: EntityType\n name: string\n slug: string\n properties: Record<string, unknown>\n knows_about: string[]\n same_as: string[]\n schema_type?: string\n is_primary: boolean\n}\n\n/**\n * Fetch entities for a project - cached per request\n * Returns the entity graph for enhanced schema markup\n */\nexport const getEntities = cache(async (\n projectId: string,\n options?: { type?: EntityType }\n): Promise<SEOEntity[]> => {\n let endpoint = `/skills/seo/entities/${projectId}`\n if (options?.type) {\n endpoint += `?type=${options.type}`\n }\n const result = await signalApiGet<SEOEntity[]>(endpoint)\n return result || []\n})\n\n/**\n * Fetch primary entity (the business) - cached per request\n */\nexport const getPrimaryEntity = cache(async (\n projectId: string\n): Promise<SEOEntity | null> => {\n return signalApiGet<SEOEntity>(`/skills/seo/entities/${projectId}/primary`)\n})\n\n/**\n * Fetch entity-enhanced schema for a page\n * Returns Organization schema with knowsAbout, areaServed, employee, etc.\n */\nexport const getEntityEnhancedSchema = cache(async (\n projectId: string,\n pagePath: string\n): Promise<object[]> => {\n const result = await signalApiGet<{ schemas: object[] }>(\n `/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`\n )\n return result?.schemas || []\n})\n\n/**\n * Get AI visibility score for a page\n */\nexport const getVisibilityScore = cache(async (\n projectId: string,\n pagePath: string\n): Promise<{\n overall_score: number\n entity_coverage: number\n answer_density: number\n chunk_readability: number\n authority_signals: number\n schema_completeness: number\n} | null> => {\n const result = await signalApiGet<any[]>(`/skills/seo/visibility/${projectId}`)\n if (!result) return null\n return result.find(s => s.page_path === pagePath) || null\n})\n\n/**\n * Get AI visibility summary for project\n */\nexport const getVisibilitySummary = cache(async (\n projectId: string\n): Promise<{\n overall_score: number\n total_entities: number\n pages_analyzed: number\n top_recommendations: Array<{ priority: string; type: string; message: string }>\n} | null> => {\n return signalApiGet(`/skills/seo/visibility/${projectId}/summary`)\n})\n"]}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
export { generateSitemap, registerLocalSitemap } from '../chunk-7RYCHO6D.mjs';
|
|
2
|
+
import '../chunk-K23A4G76.mjs';
|
|
3
|
+
import '../chunk-4XPGGLVP.mjs';
|
|
4
|
+
import { cache } from 'react';
|
|
5
|
+
|
|
6
|
+
if (process.env.NODE_ENV === "development") {
|
|
7
|
+
console.warn(
|
|
8
|
+
"@sonordev/seo: WARNING - You are using the deprecated api.ts which exposes API keys. Please migrate to server-api.ts for better security. See: packages/site-kit/src/seo/README.md#migration"
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
function getApiConfig() {
|
|
12
|
+
const apiUrl = process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com";
|
|
13
|
+
const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "";
|
|
14
|
+
return { apiUrl, apiKey };
|
|
15
|
+
}
|
|
16
|
+
async function apiPost(endpoint, body = {}) {
|
|
17
|
+
const { apiUrl, apiKey } = getApiConfig();
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
console.error("@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.");
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
"x-api-key": apiKey
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify(body),
|
|
30
|
+
next: { revalidate: 60 }
|
|
31
|
+
// Cache for 60 seconds
|
|
32
|
+
});
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
console.error(`@sonordev/seo: API error: ${response.statusText}`);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return await response.json();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error("@sonordev/seo: Network error:", error);
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var getSEOPageData = cache(async (projectId, path) => {
|
|
44
|
+
const result = await apiPost("/api/public/seo/page", { path });
|
|
45
|
+
return result?.page || null;
|
|
46
|
+
});
|
|
47
|
+
var getSchemaMarkups = cache(async (projectId, path, options) => {
|
|
48
|
+
const result = await apiPost("/api/public/seo/schemas", {
|
|
49
|
+
path,
|
|
50
|
+
includeTypes: options?.includeTypes,
|
|
51
|
+
excludeTypes: options?.excludeTypes
|
|
52
|
+
});
|
|
53
|
+
return result?.schemas || [];
|
|
54
|
+
});
|
|
55
|
+
var getFAQData = cache(async (projectId, path) => {
|
|
56
|
+
const result = await apiPost("/api/public/seo/faq", { path });
|
|
57
|
+
return result?.faq || null;
|
|
58
|
+
});
|
|
59
|
+
var getInternalLinks = cache(async (projectId, sourcePath, options) => {
|
|
60
|
+
const result = await apiPost("/api/public/seo/internal-links", {
|
|
61
|
+
sourcePath,
|
|
62
|
+
position: options?.position,
|
|
63
|
+
limit: options?.limit
|
|
64
|
+
});
|
|
65
|
+
return result?.links || [];
|
|
66
|
+
});
|
|
67
|
+
var getContentBlock = cache(async (projectId, path, section) => {
|
|
68
|
+
const result = await apiPost("/api/public/seo/content", { path, section });
|
|
69
|
+
return result?.content || null;
|
|
70
|
+
});
|
|
71
|
+
var getABTest = cache(async (projectId, path, field) => {
|
|
72
|
+
const result = await apiPost("/api/public/seo/ab-test", { path, field });
|
|
73
|
+
return result?.test || null;
|
|
74
|
+
});
|
|
75
|
+
async function recordABImpression(testId, variant, sessionId) {
|
|
76
|
+
await apiPost("/api/public/seo/ab-impression", { testId, variant, sessionId });
|
|
77
|
+
}
|
|
78
|
+
var getRedirectData = cache(async (projectId, path) => {
|
|
79
|
+
const result = await apiPost("/api/public/seo/redirect", { path });
|
|
80
|
+
return result?.redirect || null;
|
|
81
|
+
});
|
|
82
|
+
var getManagedScripts = cache(async (projectId, position, currentPath) => {
|
|
83
|
+
const result = await apiPost("/api/public/seo/scripts", {
|
|
84
|
+
position,
|
|
85
|
+
currentPath
|
|
86
|
+
});
|
|
87
|
+
return result?.scripts || [];
|
|
88
|
+
});
|
|
89
|
+
var getRobotsData = cache(async (projectId, path) => {
|
|
90
|
+
const result = await apiPost("/api/public/seo/page", { path });
|
|
91
|
+
return result?.page?.managed_robots || null;
|
|
92
|
+
});
|
|
93
|
+
var getSitemapEntries = cache(async (projectId, options) => {
|
|
94
|
+
const result = await apiPost("/api/public/seo/sitemap", {
|
|
95
|
+
publishedOnly: options?.publishedOnly
|
|
96
|
+
});
|
|
97
|
+
return result?.entries || [];
|
|
98
|
+
});
|
|
99
|
+
async function registerSitemap(entries, options) {
|
|
100
|
+
const { apiUrl, apiKey } = getApiConfig();
|
|
101
|
+
if (!apiKey) {
|
|
102
|
+
console.error("@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.");
|
|
103
|
+
return { success: false, created: 0, updated: 0 };
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: {
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
"x-api-key": apiKey
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
entries,
|
|
114
|
+
optimize_meta: options?.optimize_meta !== false
|
|
115
|
+
// Default to true
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
console.error(`@sonordev/seo: Sitemap registration failed: ${response.statusText}`);
|
|
120
|
+
return { success: false, created: 0, updated: 0 };
|
|
121
|
+
}
|
|
122
|
+
return await response.json();
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error("@sonordev/seo: Sitemap registration error:", error);
|
|
125
|
+
return { success: false, created: 0, updated: 0 };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function getSignalApiConfig() {
|
|
129
|
+
const apiUrl = process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || "https://signal.uptrademedia.com";
|
|
130
|
+
const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "";
|
|
131
|
+
return { apiUrl, apiKey };
|
|
132
|
+
}
|
|
133
|
+
async function signalApiGet(endpoint) {
|
|
134
|
+
const { apiUrl, apiKey } = getSignalApiConfig();
|
|
135
|
+
if (!apiKey) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const response = await fetch(`${apiUrl}${endpoint}`, {
|
|
140
|
+
method: "GET",
|
|
141
|
+
headers: {
|
|
142
|
+
"Content-Type": "application/json",
|
|
143
|
+
"x-api-key": apiKey
|
|
144
|
+
},
|
|
145
|
+
next: { revalidate: 300 }
|
|
146
|
+
// Cache for 5 minutes
|
|
147
|
+
});
|
|
148
|
+
if (!response.ok) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const result = await response.json();
|
|
152
|
+
return result?.data || result;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error("@sonordev/seo: Signal API error:", error);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
cache(async (projectId, options) => {
|
|
159
|
+
let endpoint = `/skills/seo/entities/${projectId}`;
|
|
160
|
+
if (options?.type) {
|
|
161
|
+
endpoint += `?type=${options.type}`;
|
|
162
|
+
}
|
|
163
|
+
const result = await signalApiGet(endpoint);
|
|
164
|
+
return result || [];
|
|
165
|
+
});
|
|
166
|
+
cache(async (projectId) => {
|
|
167
|
+
return signalApiGet(`/skills/seo/entities/${projectId}/primary`);
|
|
168
|
+
});
|
|
169
|
+
cache(async (projectId, pagePath) => {
|
|
170
|
+
const result = await signalApiGet(
|
|
171
|
+
`/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`
|
|
172
|
+
);
|
|
173
|
+
return result?.schemas || [];
|
|
174
|
+
});
|
|
175
|
+
cache(async (projectId, pagePath) => {
|
|
176
|
+
const result = await signalApiGet(`/skills/seo/visibility/${projectId}`);
|
|
177
|
+
if (!result) return null;
|
|
178
|
+
return result.find((s) => s.page_path === pagePath) || null;
|
|
179
|
+
});
|
|
180
|
+
cache(async (projectId) => {
|
|
181
|
+
return signalApiGet(`/skills/seo/visibility/${projectId}/summary`);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
export { getABTest, getContentBlock, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap };
|
|
185
|
+
//# sourceMappingURL=server.mjs.map
|
|
186
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/seo/api.ts"],"names":[],"mappings":"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","file":"server.mjs","sourcesContent":["/**\n * @sonordev/site-kit/seo - API Functions\n * \n * ⚠️ DEPRECATED: This file exposes API keys in client bundles.\n * Use `server-api.ts` instead for server-side operations.\n * \n * This file is kept for backward compatibility but will be removed in a future version.\n * \n * Migration guide:\n * - Replace: import { getSEOPageData } from '@sonordev/seo/api'\n * - With: import { getSEOPageData } from '@sonordev/seo/server'\n * - Use private env vars: UPTRADE_API_KEY instead of NEXT_PUBLIC_UPTRADE_API_KEY\n */\n\nimport { cache } from 'react'\n\n// Show deprecation warning in development\nif (process.env.NODE_ENV === 'development') {\n console.warn(\n '@sonordev/seo: WARNING - You are using the deprecated api.ts which exposes API keys. ' +\n 'Please migrate to server-api.ts for better security. ' +\n 'See: packages/site-kit/src/seo/README.md#migration'\n )\n}\n\n// ============================================\n// API Config (DEPRECATED)\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com'\n const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function apiPost<T>(endpoint: string, body: Record<string, any> = {}): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n next: { revalidate: 60 }, // Cache for 60 seconds\n })\n \n if (!response.ok) {\n console.error(`@sonordev/seo: API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('@sonordev/seo: Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Cached Data Fetchers\n// ============================================\n\n/**\n * Fetch SEO page data - cached per request\n */\nexport const getSEOPageData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ page: any }>('/api/public/seo/page', { path })\n return result?.page || null\n})\n\n/**\n * Fetch schema markups for a page - cached per request\n */\nexport const getSchemaMarkups = cache(async (\n projectId: string,\n path: string,\n options?: { includeTypes?: string[]; excludeTypes?: string[] }\n) => {\n const result = await apiPost<{ schemas: any[] }>('/api/public/seo/schemas', {\n path,\n includeTypes: options?.includeTypes,\n excludeTypes: options?.excludeTypes,\n })\n return result?.schemas || []\n})\n\n/**\n * Fetch FAQ data for a page - cached per request\n */\nexport const getFAQData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ faq: any }>('/api/public/seo/faq', { path })\n return result?.faq || null\n})\n\n/**\n * Fetch internal links for a page - cached per request\n */\nexport const getInternalLinks = cache(async (\n projectId: string,\n sourcePath: string,\n options?: { position?: string; limit?: number }\n) => {\n const result = await apiPost<{ links: any[] }>('/api/public/seo/internal-links', {\n sourcePath,\n position: options?.position,\n limit: options?.limit,\n })\n return result?.links || []\n})\n\n/**\n * Fetch content block - cached per request\n */\nexport const getContentBlock = cache(async (\n projectId: string,\n path: string,\n section: string\n) => {\n const result = await apiPost<{ content: any }>('/api/public/seo/content', { path, section })\n return result?.content || null\n})\n\n/**\n * Fetch A/B test and determine variant - cached per request\n */\nexport const getABTest = cache(async (\n projectId: string,\n path: string,\n field: string\n) => {\n const result = await apiPost<{ test: any }>('/api/public/seo/ab-test', { path, field })\n return result?.test || null\n})\n\n/**\n * Record A/B test impression\n */\nexport async function recordABImpression(\n testId: string,\n variant: 'a' | 'b',\n sessionId?: string\n): Promise<void> {\n await apiPost('/api/public/seo/ab-impression', { testId, variant, sessionId })\n}\n\n/**\n * Fetch redirect for a path - cached per request\n */\nexport const getRedirectData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ redirect: any }>('/api/public/seo/redirect', { path })\n return result?.redirect || null\n})\n\n/**\n * Fetch managed scripts - cached per request\n */\nexport const getManagedScripts = cache(async (\n projectId: string,\n position: string,\n currentPath?: string\n) => {\n const result = await apiPost<{ scripts: any[] }>('/api/public/seo/scripts', {\n position,\n currentPath,\n })\n return result?.scripts || []\n})\n\n/**\n * Fetch robots directive for a page - cached per request\n */\nexport const getRobotsData = cache(async (\n projectId: string,\n path: string\n) => {\n const result = await apiPost<{ page: any }>('/api/public/seo/page', { path })\n return result?.page?.managed_robots || null\n})\n\n/**\n * Fetch sitemap entries - cached per request\n */\nexport const getSitemapEntries = cache(async (\n projectId: string,\n options?: { publishedOnly?: boolean }\n) => {\n const result = await apiPost<{ entries: any[] }>('/api/public/seo/sitemap', {\n publishedOnly: options?.publishedOnly,\n })\n return result?.entries || []\n})\n\n/**\n * Register/sync sitemap entries from the client site\n * Call this at build time to populate seo_pages from your sitemap.xml\n * \n * After registration, Signal AI will automatically generate optimized\n * meta titles and descriptions for pages that don't have them yet.\n * \n * @example\n * ```ts\n * // scripts/register-sitemap.ts (run at build time)\n * import { registerSitemap } from '@sonordev/seo/server'\n * \n * await registerSitemap([\n * { path: '/', priority: 1.0, changefreq: 'daily' },\n * { path: '/about', priority: 0.8, changefreq: 'weekly' },\n * ], { optimize_meta: true })\n * ```\n */\nexport async function registerSitemap(\n entries: Array<{\n path: string\n title?: string\n priority?: number\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n }>,\n options?: {\n /** Trigger Signal AI to generate optimized meta titles/descriptions (default: true) */\n optimize_meta?: boolean\n }\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 { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@sonordev/seo: No API key configured. Set UPTRADE_API_KEY.')\n return { success: false, created: 0, updated: 0 }\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({ \n entries,\n optimize_meta: options?.optimize_meta !== false, // Default to true\n }),\n })\n \n if (!response.ok) {\n console.error(`@sonordev/seo: Sitemap registration failed: ${response.statusText}`)\n return { success: false, created: 0, updated: 0 }\n }\n \n return await response.json()\n } catch (error) {\n console.error('@sonordev/seo: Sitemap registration error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n// ============================================\n// AI Visibility & Entity Graph API\n// ============================================\n\n/**\n * Get Signal API config for AI visibility features\n */\nfunction getSignalApiConfig() {\n const apiUrl = process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.uptrademedia.com'\n const apiKey = process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function signalApiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getSignalApiConfig()\n \n if (!apiKey) {\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 300 }, // Cache for 5 minutes\n })\n \n if (!response.ok) {\n return null\n }\n \n const result = await response.json()\n return result?.data || result\n } catch (error) {\n console.error('@sonordev/seo: Signal API error:', error)\n return null\n }\n}\n\n/**\n * Entity types for the knowledge graph\n */\nexport type EntityType = \n | 'organization'\n | 'person'\n | 'service'\n | 'product'\n | 'location'\n | 'concept'\n | 'credential'\n\n/**\n * Entity from the knowledge graph\n */\nexport interface SEOEntity {\n id: string\n project_id: string\n entity_type: EntityType\n name: string\n slug: string\n properties: Record<string, unknown>\n knows_about: string[]\n same_as: string[]\n schema_type?: string\n is_primary: boolean\n}\n\n/**\n * Fetch entities for a project - cached per request\n * Returns the entity graph for enhanced schema markup\n */\nexport const getEntities = cache(async (\n projectId: string,\n options?: { type?: EntityType }\n): Promise<SEOEntity[]> => {\n let endpoint = `/skills/seo/entities/${projectId}`\n if (options?.type) {\n endpoint += `?type=${options.type}`\n }\n const result = await signalApiGet<SEOEntity[]>(endpoint)\n return result || []\n})\n\n/**\n * Fetch primary entity (the business) - cached per request\n */\nexport const getPrimaryEntity = cache(async (\n projectId: string\n): Promise<SEOEntity | null> => {\n return signalApiGet<SEOEntity>(`/skills/seo/entities/${projectId}/primary`)\n})\n\n/**\n * Fetch entity-enhanced schema for a page\n * Returns Organization schema with knowsAbout, areaServed, employee, etc.\n */\nexport const getEntityEnhancedSchema = cache(async (\n projectId: string,\n pagePath: string\n): Promise<object[]> => {\n const result = await signalApiGet<{ schemas: object[] }>(\n `/skills/seo/schema/${projectId}/entity-enhanced?pagePath=${encodeURIComponent(pagePath)}`\n )\n return result?.schemas || []\n})\n\n/**\n * Get AI visibility score for a page\n */\nexport const getVisibilityScore = cache(async (\n projectId: string,\n pagePath: string\n): Promise<{\n overall_score: number\n entity_coverage: number\n answer_density: number\n chunk_readability: number\n authority_signals: number\n schema_completeness: number\n} | null> => {\n const result = await signalApiGet<any[]>(`/skills/seo/visibility/${projectId}`)\n if (!result) return null\n return result.find(s => s.page_path === pagePath) || null\n})\n\n/**\n * Get AI visibility summary for project\n */\nexport const getVisibilitySummary = cache(async (\n projectId: string\n): Promise<{\n overall_score: number\n total_entities: number\n pages_analyzed: number\n top_recommendations: Array<{ priority: string; type: string; message: string }>\n} | null> => {\n return signalApiGet(`/skills/seo/visibility/${projectId}/summary`)\n})\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ensureMetadata, getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from './chunk-K23A4G76.mjs';
|
|
2
|
+
import './chunk-4XPGGLVP.mjs';
|
|
3
|
+
//# sourceMappingURL=server-api-EWXKOQZA.mjs.map
|
|
4
|
+
//# sourceMappingURL=server-api-EWXKOQZA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"server-api-EWXKOQZA.mjs"}
|