@sonordev/site-kit 8.2.0 → 8.3.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.
Files changed (192) hide show
  1. package/AGENTS.md +13 -1
  2. package/CHANGELOG.md +5 -0
  3. package/README.md +9 -5
  4. package/agent-manifest.json +47 -8
  5. package/dist/{AnalyticsProvider-6TAA3XYB.js → AnalyticsProvider-QXO33JUF.js} +6 -6
  6. package/dist/{ArticleFaqSection-3Q26DP7P.js → ArticleFaqSection-DEWE5B4Q.js} +1 -1
  7. package/dist/{ArticleViewTracker-H4N7YCLC.js → ArticleViewTracker-KN6ENIRS.js} +17 -6
  8. package/dist/{BlocksPopup-FJT5YQD3.js → BlocksPopup-3RPN6YVJ.js} +6 -6
  9. package/dist/{ChatWidget-THQHHTAA.js → ChatWidget-D2X445PO.js} +6 -6
  10. package/dist/{FileField-OZXXJGUM.js → FileField-UNGSNGJ5.js} +4 -4
  11. package/dist/{FormSpotlight-MLDJS246.js → FormSpotlight-JFH2ENKQ.js} +1 -1
  12. package/dist/{FormStage-6RVY7M3R.js → FormStage-RC3WHHXP.js} +1 -1
  13. package/dist/{ManagedForm-3VV54RVH.js → ManagedForm-FOQZ2IYG.js} +7 -7
  14. package/dist/{ManagedNewsletterForm-RTJDGMGG.js → ManagedNewsletterForm-NFNF33V3.js} +16 -7
  15. package/dist/{SignalCore-T7ZOCA44.js → SignalCore-5KABGX5C.js} +4 -4
  16. package/dist/SiteChat-JQ46ZIJ4.js +6 -0
  17. package/dist/SiteDesignReporter-N7L6DR4J.js +12 -0
  18. package/dist/{SitePopups-K6ADAWFK.js → SitePopups-WZBKX5Q3.js} +6 -6
  19. package/dist/SitemapSync-GY6UADRI.js +9 -0
  20. package/dist/_client/booking-widget.js +6 -6
  21. package/dist/_client/testimonial-section.js +3 -3
  22. package/dist/affiliates/index.js +4 -4
  23. package/dist/analytics/index.js +6 -6
  24. package/dist/{article-styles-GFXJJDLE.js → article-styles-7QONZJR5.js} +3 -3
  25. package/dist/article-tables-6XHVULPU.js +2 -0
  26. package/dist/articles/Article.d.ts +2 -89
  27. package/dist/articles/ArticleFAQ.d.ts +2 -41
  28. package/dist/articles/ArticleFaqSection.d.ts +2 -2
  29. package/dist/articles/ArticleList.d.ts +2 -79
  30. package/dist/articles/ArticleViewTracker.d.ts +2 -15
  31. package/dist/articles/AuthorCard.d.ts +2 -10
  32. package/dist/articles/AuthorPage.d.ts +2 -8
  33. package/dist/articles/ClusterLandingPage.d.ts +2 -40
  34. package/dist/articles/ClusterNavigation.d.ts +2 -37
  35. package/dist/articles/ManagedNewsletterForm.d.ts +3 -12
  36. package/dist/articles/NewsletterShell.d.ts +2 -17
  37. package/dist/articles/NewsletterWidget.d.ts +2 -30
  38. package/dist/articles/PublicationLayout.d.ts +2 -67
  39. package/dist/articles/PublicationSidebar.d.ts +2 -36
  40. package/dist/articles/RelatedPosts.d.ts +2 -22
  41. package/dist/articles/ServiceCallout.d.ts +2 -56
  42. package/dist/articles/TableOfContents.d.ts +2 -6
  43. package/dist/articles/article-photos.d.ts +2 -9
  44. package/dist/articles/article-styles.d.ts +2 -21
  45. package/dist/articles/article-tables.d.ts +2 -12
  46. package/dist/articles/artwork.d.ts +2 -13
  47. package/dist/articles/author-schema.d.ts +2 -72
  48. package/dist/articles/author-social.d.ts +2 -14
  49. package/dist/articles/excerpt.d.ts +2 -17
  50. package/dist/articles/index.d.ts +2 -79
  51. package/dist/articles/index.js +16 -11
  52. package/dist/articles/news-sitemap.d.ts +2 -46
  53. package/dist/articles/processArticleHtml.d.ts +2 -34
  54. package/dist/articles/public-reads.d.ts +2 -26
  55. package/dist/articles/reading-time.d.ts +2 -9
  56. package/dist/articles/routes.d.ts +2 -52
  57. package/dist/articles/server-core.d.ts +2 -461
  58. package/dist/articles/server-ui.d.ts +2 -30
  59. package/dist/articles/server-ui.js +26 -17
  60. package/dist/articles/server.d.ts +2 -461
  61. package/dist/articles/server.js +14 -5
  62. package/dist/articles/types.d.ts +2 -316
  63. package/dist/articles/widget-styles.d.ts +2 -8
  64. package/dist/chat/index.js +8 -8
  65. package/dist/{chunk-575L73NT.js → chunk-2JMCBJM5.js} +1 -1
  66. package/dist/chunk-34ZYJTQR.js +1 -0
  67. package/dist/{chunk-7FSB2EXS.js → chunk-3OY52UFM.js} +1 -1
  68. package/dist/{chunk-WMVK77ND.js → chunk-4K735O3J.js} +1 -1
  69. package/dist/{chunk-66G47P5C.js → chunk-4PVMUPC6.js} +2 -2
  70. package/dist/{chunk-L5UOHS6E.js → chunk-5D7ZISUP.js} +1 -1
  71. package/dist/{chunk-SMYX3AAO.js → chunk-5RYSTKVU.js} +1 -1
  72. package/dist/{chunk-6CJGZFOU.js → chunk-A4MPHIVP.js} +1 -1
  73. package/dist/chunk-B7T2SFUF.js +1 -0
  74. package/dist/{chunk-FV2VD7WM.js → chunk-BC7JMY4Z.js} +3 -3
  75. package/dist/{chunk-57K4GW3D.js → chunk-BOCYBDKV.js} +1 -1
  76. package/dist/{chunk-NFRJTOTB.js → chunk-BSQP6PRA.js} +1 -1
  77. package/dist/{chunk-GKGSXUVQ.js → chunk-BVB5FBAA.js} +1 -1
  78. package/dist/{chunk-Q72M5KBS.js → chunk-C2UROFGZ.js} +1 -1
  79. package/dist/{chunk-3EU6S5YC.js → chunk-C4AFNZT2.js} +1 -1
  80. package/dist/{chunk-WACWV5EP.js → chunk-D6ZIQMHB.js} +3 -3
  81. package/dist/{chunk-GYF2ULVO.js → chunk-DJAYFHVF.js} +1 -1
  82. package/dist/{chunk-JC2VS2SB.js → chunk-DPSNMOMZ.js} +1 -1
  83. package/dist/{chunk-NNEIBXGU.js → chunk-E3UR37RX.js} +2 -2
  84. package/dist/{chunk-Y3INC4QJ.js → chunk-E4PTMORJ.js} +1 -1
  85. package/dist/{chunk-EBILJHUF.js → chunk-EA6FZMYA.js} +2 -2
  86. package/dist/{chunk-X7VKRHFF.js → chunk-FHUTOXS7.js} +1 -1
  87. package/dist/{chunk-JBEUZJS3.js → chunk-GKJVSZ7H.js} +3 -3
  88. package/dist/chunk-H72ZFO3F.js +1 -0
  89. package/dist/{chunk-FVXFLVXF.js → chunk-HND6BDXC.js} +3 -3
  90. package/dist/chunk-IEGDPRQB.js +14 -0
  91. package/dist/{chunk-CAH4Y4PY.js → chunk-JO76F5WP.js} +1 -1
  92. package/dist/{chunk-FQUGGPBM.js → chunk-KJVUOJMW.js} +58 -58
  93. package/dist/{chunk-SC4MZGWZ.js → chunk-LBDWAXAO.js} +1 -1
  94. package/dist/{chunk-WSNG2K3T.js → chunk-LPKKSYKX.js} +3 -3
  95. package/dist/{chunk-HUBMKTPW.js → chunk-M5SF7NCC.js} +1 -1
  96. package/dist/{chunk-YBAFUM3Z.js → chunk-MQ4REMTH.js} +2 -2
  97. package/dist/{chunk-BQZPHICL.js → chunk-NA4Z4CQG.js} +1 -1
  98. package/dist/{chunk-727R7C5R.js → chunk-OIWFXUVD.js} +2 -2
  99. package/dist/{chunk-H4R2GPAB.js → chunk-QBCWVT2S.js} +2 -2
  100. package/dist/{chunk-WYZ4OUON.js → chunk-QCZHYO5M.js} +1 -1
  101. package/dist/{chunk-I6QFPSUU.js → chunk-QDILCQBL.js} +9 -9
  102. package/dist/{chunk-WK3N3Y7V.js → chunk-SCTVADDL.js} +2 -2
  103. package/dist/{chunk-QXMIKDOL.js → chunk-SNRE3ZVZ.js} +3 -3
  104. package/dist/{chunk-WBC5B3JD.js → chunk-TT4JZDKM.js} +3 -3
  105. package/dist/{chunk-5ZCY36TY.js → chunk-U7Y3QG3A.js} +1 -1
  106. package/dist/{chunk-3G7YABRA.js → chunk-W7OPEMGJ.js} +4 -1
  107. package/dist/{chunk-XWIRU6UT.js → chunk-WBUG7XRL.js} +2 -2
  108. package/dist/{chunk-ZM2FNWIQ.js → chunk-WSOZ3FQN.js} +1 -1
  109. package/dist/chunk-X4IJS7LV.js +319 -0
  110. package/dist/{chunk-JIH32RH2.js → chunk-XA7Q2VQA.js} +1 -1
  111. package/dist/{chunk-GWP2VBFH.js → chunk-XLAXYPTK.js} +3 -3
  112. package/dist/client/index.js +4 -16
  113. package/dist/fleet/index.js +6 -6
  114. package/dist/forms/index.js +9 -325
  115. package/dist/forms/server.js +2 -2
  116. package/dist/images/index.js +4 -4
  117. package/dist/index.js +1 -1
  118. package/dist/layout/client.js +9 -9
  119. package/dist/layout/index.js +10 -10
  120. package/dist/llms/index.js +8 -8
  121. package/dist/maps/index.js +4 -4
  122. package/dist/mcp/sonor.d.ts +42 -3
  123. package/dist/mcp/sonor.js +25 -20
  124. package/dist/mcp/transport.d.ts +1 -1
  125. package/dist/press-kit/articles/Article.d.ts +89 -0
  126. package/dist/press-kit/articles/ArticleFAQ.d.ts +41 -0
  127. package/dist/press-kit/articles/ArticleFaqSection.d.ts +2 -0
  128. package/dist/press-kit/articles/ArticleList.d.ts +79 -0
  129. package/dist/press-kit/articles/ArticleViewTracker.d.ts +15 -0
  130. package/dist/press-kit/articles/AuthorCard.d.ts +10 -0
  131. package/dist/press-kit/articles/AuthorPage.d.ts +8 -0
  132. package/dist/press-kit/articles/ClusterLandingPage.d.ts +40 -0
  133. package/dist/press-kit/articles/ClusterNavigation.d.ts +37 -0
  134. package/dist/press-kit/articles/ManagedNewsletterForm.d.ts +12 -0
  135. package/dist/press-kit/articles/NewsletterShell.d.ts +17 -0
  136. package/dist/press-kit/articles/NewsletterWidget.d.ts +30 -0
  137. package/dist/press-kit/articles/PublicationLayout.d.ts +67 -0
  138. package/dist/press-kit/articles/PublicationSidebar.d.ts +36 -0
  139. package/dist/press-kit/articles/RelatedPosts.d.ts +22 -0
  140. package/dist/press-kit/articles/ServiceCallout.d.ts +56 -0
  141. package/dist/press-kit/articles/TableOfContents.d.ts +6 -0
  142. package/dist/press-kit/articles/article-photos.d.ts +9 -0
  143. package/dist/press-kit/articles/article-styles.d.ts +21 -0
  144. package/dist/press-kit/articles/article-tables.d.ts +12 -0
  145. package/dist/press-kit/articles/artwork.d.ts +13 -0
  146. package/dist/press-kit/articles/author-schema.d.ts +72 -0
  147. package/dist/press-kit/articles/author-social.d.ts +14 -0
  148. package/dist/press-kit/articles/excerpt.d.ts +17 -0
  149. package/dist/press-kit/articles/index.d.ts +79 -0
  150. package/dist/press-kit/articles/news-sitemap.d.ts +46 -0
  151. package/dist/press-kit/articles/processArticleHtml.d.ts +34 -0
  152. package/dist/press-kit/articles/public-reads.d.ts +26 -0
  153. package/dist/press-kit/articles/reading-time.d.ts +9 -0
  154. package/dist/press-kit/articles/routes.d.ts +52 -0
  155. package/dist/press-kit/articles/server-core.d.ts +461 -0
  156. package/dist/press-kit/articles/server-ui.d.ts +31 -0
  157. package/dist/press-kit/articles/types.d.ts +316 -0
  158. package/dist/press-kit/articles/widget-styles.d.ts +8 -0
  159. package/dist/reputation/index.js +3 -3
  160. package/dist/reputation/server.js +2 -2
  161. package/dist/revalidate/index.js +2 -2
  162. package/dist/runtime/index.js +5 -4
  163. package/dist/seo/client.js +6 -6
  164. package/dist/seo/index.js +7 -7
  165. package/dist/seo/llms.js +8 -8
  166. package/dist/seo/register-sitemap-cli.js +1 -1
  167. package/dist/seo/sitemap.js +6 -6
  168. package/dist/server/index.js +3 -2
  169. package/dist/shared/build-entries.d.ts +2 -1
  170. package/dist/shared/clientApiConfig.d.ts +2 -0
  171. package/dist/shared/import-specifiers.d.ts +1 -1
  172. package/dist/shared/index.d.ts +6 -0
  173. package/dist/shared/index.js +8 -0
  174. package/dist/shared/version.d.ts +1 -1
  175. package/dist/signal/index.js +2 -2
  176. package/dist/sitemap/index.js +6 -6
  177. package/dist/sync/index.js +6 -6
  178. package/dist/website/images.js +4 -4
  179. package/dist/website/index.js +7 -7
  180. package/dist/website/popups.js +6 -6
  181. package/dist/{writeLLMsTxt-DGKLYXIW.js → writeLLMsTxt-VKHCM5IS.js} +5 -5
  182. package/docs/MIGRATING-TO-PRESS-KIT.md +83 -0
  183. package/docs.json +145 -29
  184. package/package.json +15 -5
  185. package/src/articles/README.md +5 -360
  186. package/src/mcp/README.md +16 -0
  187. package/src/og/README.md +1 -1
  188. package/src/runtime/README.md +4 -0
  189. package/dist/SiteChat-JSHPGAE3.js +0 -6
  190. package/dist/SiteDesignReporter-L2JBAKKK.js +0 -12
  191. package/dist/SitemapSync-VV2YSMIW.js +0 -9
  192. package/dist/article-tables-AXSZOGNW.js +0 -2
@@ -1,64 +1,12 @@
1
- import { insertArticlePhotos } from './chunk-HUBMKTPW.js';
2
- import { generateArticleAuthorNode, resolveArticleArtwork, withArticleAuthorIdentity } from './chunk-QXMIKDOL.js';
3
- import { resolveArticleUrl, createPublicationRoutes, resolvePublicationUrl, articleCategorySlug } from './chunk-WMVK77ND.js';
1
+ import { insertArticlePhotos } from './chunk-M5SF7NCC.js';
2
+ import { generateArticleAuthorNode, resolveArticleArtwork, withArticleAuthorIdentity } from './chunk-SNRE3ZVZ.js';
3
+ import { resolveArticleUrl, createPublicationRoutes, resolvePublicationUrl, articleCategorySlug } from './chunk-4K735O3J.js';
4
4
  import { withoutSchemaPlaceholders } from './chunk-VWWITFWM.js';
5
5
  import { withSiteParam, withSiteBody } from './chunk-MJP63SSS.js';
6
6
  import { resolveServerApiConfig } from './chunk-C7TLGL3R.js';
7
7
  import { notFound } from 'next/navigation';
8
8
 
9
- // src/articles/public-reads.ts
10
- async function fetchArticleBySlug({ apiUrl, apiKey, site }, slug) {
11
- try {
12
- const response = await fetch(withSiteParam(`${apiUrl}/public/articles/posts/${slug}`, site), {
13
- headers: { "x-api-key": apiKey },
14
- next: { revalidate: 60 }
15
- });
16
- if (!response.ok) {
17
- if (response.status !== 404) console.error("[Articles] Failed to fetch post:", response.statusText);
18
- return null;
19
- }
20
- const data = await response.json();
21
- return data.post || null;
22
- } catch (error) {
23
- console.error("[Articles] Error fetching post:", error);
24
- return null;
25
- }
26
- }
27
- async function fetchArticleCategories({ apiUrl, apiKey, site }) {
28
- try {
29
- const response = await fetch(withSiteParam(`${apiUrl}/public/articles/categories`, site), {
30
- headers: { "x-api-key": apiKey },
31
- next: { revalidate: 300 }
32
- });
33
- if (!response.ok) return [];
34
- const data = await response.json();
35
- return data.categories || [];
36
- } catch (error) {
37
- console.error("[Articles] Error fetching categories:", error);
38
- return [];
39
- }
40
- }
41
- async function fetchRelatedArticles({ apiUrl, apiKey, site }, currentPostId, limit, cache = {}) {
42
- try {
43
- const response = await fetch(`${apiUrl}/public/articles/related`, {
44
- method: "POST",
45
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
46
- body: JSON.stringify(withSiteBody({ current_post_id: currentPostId, limit }, site)),
47
- ...cache.revalidate !== void 0 ? { next: { revalidate: cache.revalidate } } : {}
48
- });
49
- if (!response.ok) {
50
- console.error("[Articles] Failed to fetch related posts:", response.statusText);
51
- return [];
52
- }
53
- const data = await response.json();
54
- return data.posts || [];
55
- } catch (error) {
56
- console.error("[Articles] Error fetching related posts:", error);
57
- return [];
58
- }
59
- }
60
-
61
- // src/articles/excerpt.ts
9
+ // packages/press-kit/src/articles/excerpt.ts
62
10
  function sanitizeExcerpt(raw, maxLength = 160) {
63
11
  if (!raw) return "";
64
12
  let text = String(raw).trim();
@@ -90,7 +38,7 @@ function sanitizeExcerpt(raw, maxLength = 160) {
90
38
  return `${(lastSpace > maxLength * 0.6 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—–-]+$/, "")}\u2026`;
91
39
  }
92
40
 
93
- // src/articles/news-sitemap.ts
41
+ // packages/press-kit/src/articles/news-sitemap.ts
94
42
  var NEWS_SITEMAP_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
95
43
  var NEWS_SITEMAP_MAX_URLS = 1e3;
96
44
  var FEED_DEFAULT_ITEMS = 20;
@@ -128,7 +76,59 @@ function buildNewsSitemapXml(posts, options, now = /* @__PURE__ */ new Date()) {
128
76
  ${items.join("\n")}${items.length ? "\n" : ""}</urlset>`;
129
77
  }
130
78
 
131
- // src/articles/server-core.ts
79
+ // packages/press-kit/src/articles/public-reads.ts
80
+ async function fetchArticleBySlug({ apiUrl, apiKey, site }, slug) {
81
+ try {
82
+ const response = await fetch(withSiteParam(`${apiUrl}/public/articles/posts/${slug}`, site), {
83
+ headers: { "x-api-key": apiKey },
84
+ next: { revalidate: 60 }
85
+ });
86
+ if (!response.ok) {
87
+ if (response.status !== 404) console.error("[Articles] Failed to fetch post:", response.statusText);
88
+ return null;
89
+ }
90
+ const data = await response.json();
91
+ return data.post || null;
92
+ } catch (error) {
93
+ console.error("[Articles] Error fetching post:", error);
94
+ return null;
95
+ }
96
+ }
97
+ async function fetchArticleCategories({ apiUrl, apiKey, site }) {
98
+ try {
99
+ const response = await fetch(withSiteParam(`${apiUrl}/public/articles/categories`, site), {
100
+ headers: { "x-api-key": apiKey },
101
+ next: { revalidate: 300 }
102
+ });
103
+ if (!response.ok) return [];
104
+ const data = await response.json();
105
+ return data.categories || [];
106
+ } catch (error) {
107
+ console.error("[Articles] Error fetching categories:", error);
108
+ return [];
109
+ }
110
+ }
111
+ async function fetchRelatedArticles({ apiUrl, apiKey, site }, currentPostId, limit, cache = {}) {
112
+ try {
113
+ const response = await fetch(`${apiUrl}/public/articles/related`, {
114
+ method: "POST",
115
+ headers: { "Content-Type": "application/json", "x-api-key": apiKey },
116
+ body: JSON.stringify(withSiteBody({ current_post_id: currentPostId, limit }, site)),
117
+ ...cache.revalidate !== void 0 ? { next: { revalidate: cache.revalidate } } : {}
118
+ });
119
+ if (!response.ok) {
120
+ console.error("[Articles] Failed to fetch related posts:", response.statusText);
121
+ return [];
122
+ }
123
+ const data = await response.json();
124
+ return data.posts || [];
125
+ } catch (error) {
126
+ console.error("[Articles] Error fetching related posts:", error);
127
+ return [];
128
+ }
129
+ }
130
+
131
+ // packages/press-kit/src/articles/server-core.ts
132
132
  var SEO_LIMITS = {
133
133
  title: { min: 30, max: 60, recommended: 55 },
134
134
  metaDescription: { min: 120, max: 160, recommended: 155 },
@@ -1,4 +1,4 @@
1
- import { widgetStyle, widgetTitleStyle } from './chunk-GYF2ULVO.js';
1
+ import { widgetStyle, widgetTitleStyle } from './chunk-DJAYFHVF.js';
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
3
 
4
4
  function NewsletterShell({
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { sanitizeFleetVersion, buildFleetHeartbeatPayload } from './chunk-ZTZQPYP6.js';
3
3
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
4
- import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
5
- import { sonorFetch } from './chunk-727R7C5R.js';
6
- import { SITE_KIT_VERSION } from './chunk-Q72M5KBS.js';
4
+ import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
5
+ import { sonorFetch } from './chunk-OIWFXUVD.js';
6
+ import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
7
7
  import { useRef, useEffect } from 'react';
8
8
 
9
9
  // src/fleet/heartbeat.ts
@@ -83,7 +83,7 @@ function resolveArticlePhotoPlacements(html, photos = []) {
83
83
  return { headings: headings.map(({ start: _start, end: _end, ...heading }) => heading), placements };
84
84
  }
85
85
 
86
- // src/articles/article-photos.ts
86
+ // packages/press-kit/src/articles/article-photos.ts
87
87
  var escape = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
88
88
  function photoUrl(value) {
89
89
  if (typeof value !== "string" || value.length > 2e3 || /[\s\\]/.test(value)) return null;
@@ -6,8 +6,8 @@ import { normalizeFormConfig, DEFAULT_FORM_SUCCESS_MESSAGE } from './chunk-5SQK3
6
6
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-NJCTQH2P.js';
7
7
  import { onPageLeave } from './chunk-L2V5PUFN.js';
8
8
  import { uuid } from './chunk-GJWI74ZZ.js';
9
- import { readPublishedApiConfig, getClientApiConfig } from './chunk-3G7YABRA.js';
10
- import { sonorFetch, sonorBeacon } from './chunk-727R7C5R.js';
9
+ import { sonorFetch, sonorBeacon } from './chunk-OIWFXUVD.js';
10
+ import { readPublishedApiConfig, getClientApiConfig } from './chunk-W7OPEMGJ.js';
11
11
  import { useRef, useCallback, useEffect, useState, useMemo } from 'react';
12
12
 
13
13
  // src/forms/field-interactions.ts
@@ -1,4 +1,4 @@
1
- import { FormEnhancer } from './chunk-SMYX3AAO.js';
1
+ import { FormEnhancer } from './chunk-5RYSTKVU.js';
2
2
  import { StaticForm } from './chunk-LNSF6BJC.js';
3
3
  import { serverApiFetch } from './chunk-C7TLGL3R.js';
4
4
  import { jsx } from 'react/jsx-runtime';
@@ -1,5 +1,5 @@
1
- import { isTokenMode, getFreshCredential, isSiteToken, refreshSiteToken, currentCredential, credentialBreakerId } from './chunk-3EU6S5YC.js';
2
- import { SITE_KIT_VERSION } from './chunk-Q72M5KBS.js';
1
+ import { isTokenMode, getFreshCredential, isSiteToken, refreshSiteToken, currentCredential, credentialBreakerId } from './chunk-C4AFNZT2.js';
2
+ import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
3
3
 
4
4
  // src/shared/fetchWithRetry.ts
5
5
  function backoffDelay(attempt, response) {
@@ -1,8 +1,8 @@
1
1
  'use client';
2
- import { getSiteDesignTokens, tokensForReport, shouldReportDesign, sendSiteDesign } from './chunk-WBC5B3JD.js';
2
+ import { getSiteDesignTokens, tokensForReport, shouldReportDesign, sendSiteDesign } from './chunk-TT4JZDKM.js';
3
3
  import { designTokensHash } from './chunk-IHG36STL.js';
4
4
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
5
- import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
5
+ import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
6
6
  import { useRef, useEffect } from 'react';
7
7
 
8
8
  var STAMP_KEY = (site) => `_sk_design_sent:${site}`;
@@ -54,7 +54,7 @@ function useSignal() {
54
54
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
55
55
  }
56
56
  var LazySignalCore = dynamic(
57
- () => import('./SignalCore-T7ZOCA44.js').then((m) => ({ default: m.SignalCore })),
57
+ () => import('./SignalCore-5KABGX5C.js').then((m) => ({ default: m.SignalCore })),
58
58
  { ssr: false }
59
59
  );
60
60
  function SignalBridge({
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
  import { SITE_EDIT_PARAM } from './chunk-6G43IRWR.js';
3
- import { publishSiteCredential } from './chunk-5ZCY36TY.js';
4
- import { FleetHeartbeat } from './chunk-WSNG2K3T.js';
3
+ import { publishSiteCredential } from './chunk-U7Y3QG3A.js';
4
+ import { FleetHeartbeat } from './chunk-LPKKSYKX.js';
5
5
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
6
6
  import { resolveSiteHost } from './chunk-FESKKJAS.js';
7
7
  import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZKADJNR2.js';
8
- import { announceFrameReady, isCrossOriginFrame } from './chunk-CAH4Y4PY.js';
9
- import { SignalBridge } from './chunk-WYZ4OUON.js';
8
+ import { announceFrameReady, isCrossOriginFrame } from './chunk-JO76F5WP.js';
9
+ import { SignalBridge } from './chunk-QCZHYO5M.js';
10
10
  import React, { useState, useRef, useCallback, useEffect, Suspense } from 'react';
11
11
  import dynamic from 'next/dynamic';
12
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -33,23 +33,23 @@ function startEditBridge() {
33
33
  };
34
34
  }
35
35
  var LazyAnalyticsProvider = dynamic(
36
- () => import('./AnalyticsProvider-6TAA3XYB.js').then((m) => ({ default: m.AnalyticsProvider })),
36
+ () => import('./AnalyticsProvider-QXO33JUF.js').then((m) => ({ default: m.AnalyticsProvider })),
37
37
  { ssr: false }
38
38
  );
39
39
  var LazySiteChat = dynamic(
40
- () => import('./SiteChat-JSHPGAE3.js').then((m) => ({ default: m.SiteChat })),
40
+ () => import('./SiteChat-JQ46ZIJ4.js').then((m) => ({ default: m.SiteChat })),
41
41
  { ssr: false }
42
42
  );
43
43
  var LazySitePopups = dynamic(
44
- () => import('./SitePopups-K6ADAWFK.js').then((m) => ({ default: m.SitePopups })),
44
+ () => import('./SitePopups-WZBKX5Q3.js').then((m) => ({ default: m.SitePopups })),
45
45
  { ssr: false }
46
46
  );
47
47
  var LazySiteDesignReporter = dynamic(
48
- () => import('./SiteDesignReporter-L2JBAKKK.js').then((m) => ({ default: m.SiteDesignReporter })),
48
+ () => import('./SiteDesignReporter-N7L6DR4J.js').then((m) => ({ default: m.SiteDesignReporter })),
49
49
  { ssr: false }
50
50
  );
51
51
  var LazySitemapSync = dynamic(
52
- () => import('./SitemapSync-VV2YSMIW.js').then((m) => ({ default: m.SitemapSync })),
52
+ () => import('./SitemapSync-GY6UADRI.js').then((m) => ({ default: m.SitemapSync })),
53
53
  { ssr: false }
54
54
  );
55
55
  function SiteKitClientProviders({
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { locToPath, isMalformedSitemapPath, inferPageType } from './chunk-YVKRYQRG.js';
3
- import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
4
- import { sonorFetch } from './chunk-727R7C5R.js';
3
+ import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
4
+ import { sonorFetch } from './chunk-OIWFXUVD.js';
5
5
  import { useRef, useEffect } from 'react';
6
6
 
7
7
  var SYNC_STAMP_KEY = "_sk_sitemap_synced_at";
@@ -1,6 +1,6 @@
1
- import { resolvePublicationUrl, createPublicationRoutes } from './chunk-WMVK77ND.js';
1
+ import { resolvePublicationUrl, createPublicationRoutes } from './chunk-4K735O3J.js';
2
2
 
3
- // src/articles/artwork.ts
3
+ // packages/press-kit/src/articles/artwork.ts
4
4
  function resolveArticleArtwork(post, placement = "card") {
5
5
  const editorial = placement === "article" && !!post.editorial_image;
6
6
  const src = (editorial ? post.editorial_image : post.featured_image) || void 0;
@@ -18,7 +18,7 @@ function articleArtworkImageStyle(artwork) {
18
18
  return artwork.composed ? { display: "block", height: "auto", maxHeight: "none", objectFit: "contain", transform: "none" } : void 0;
19
19
  }
20
20
 
21
- // src/articles/author-schema.ts
21
+ // packages/press-kit/src/articles/author-schema.ts
22
22
  var ARTICLE_TYPES = /* @__PURE__ */ new Set(["Article", "BlogPosting", "NewsArticle", "TechArticle", "Report", "ScholarlyArticle"]);
23
23
  function isAbsoluteUrl(value) {
24
24
  return /^https?:\/\//i.test(value);
@@ -1,8 +1,8 @@
1
1
  import { toHexColor, normalizeDesignTokens, designTokensHash } from './chunk-IHG36STL.js';
2
2
  import { contrastRatio, parseColor, relativeLuminance } from './chunk-S22FSH7C.js';
3
- import { resolveAnalyticsTarget } from './chunk-CAH4Y4PY.js';
4
- import { sonorFetch } from './chunk-727R7C5R.js';
5
- import { SITE_KIT_VERSION } from './chunk-Q72M5KBS.js';
3
+ import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
4
+ import { sonorFetch } from './chunk-OIWFXUVD.js';
5
+ import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
6
6
 
7
7
  // src/website/design.ts
8
8
  var SITE_DESIGN_PATH = "/api/public/site/design";
@@ -1,5 +1,5 @@
1
1
  import { resolveSiteHost } from './chunk-FESKKJAS.js';
2
- import { configureSiteCredential, currentCredential } from './chunk-3EU6S5YC.js';
2
+ import { configureSiteCredential, currentCredential } from './chunk-C4AFNZT2.js';
3
3
 
4
4
  // src/shared/publishCredential.ts
5
5
  function publishSiteCredential({
@@ -21,5 +21,8 @@ function getClientApiConfig(options = {}) {
21
21
  const published = readPublishedApiConfig();
22
22
  return { apiUrl: published.apiUrl || DEFAULT_SONOR_API_URL, apiKey: published.apiKey };
23
23
  }
24
+ function readPublishedSite() {
25
+ return siteKitWindow()?.__SITE_KIT_SITE__ || void 0;
26
+ }
24
27
 
25
- export { DEFAULT_SONOR_API_URL, getClientApiConfig, readPublishedApiConfig };
28
+ export { DEFAULT_SONOR_API_URL, getClientApiConfig, readPublishedApiConfig, readPublishedSite };
@@ -1,5 +1,5 @@
1
- import { getClientApiConfig } from './chunk-3G7YABRA.js';
2
- import { sonorFetch } from './chunk-727R7C5R.js';
1
+ import { sonorFetch } from './chunk-OIWFXUVD.js';
2
+ import { getClientApiConfig } from './chunk-W7OPEMGJ.js';
3
3
 
4
4
  // src/sync/api.ts
5
5
  function getApiConfig() {
@@ -1,7 +1,7 @@
1
1
  import { trackedFreshFetch } from './chunk-UAYAJPEP.js';
2
2
  import { isNextControlFlow } from './chunk-C7TLGL3R.js';
3
3
  import { monotonicMs } from './chunk-MH2DSGC6.js';
4
- import { SITE_KIT_VERSION } from './chunk-Q72M5KBS.js';
4
+ import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
5
5
  import 'server-only';
6
6
 
7
7
  var MINT_PATH = "/api/public/site-token";
@@ -0,0 +1,319 @@
1
+ import { sonorFetch } from './chunk-OIWFXUVD.js';
2
+ import { readPublishedApiConfig } from './chunk-W7OPEMGJ.js';
3
+
4
+ // src/forms/formsApi.ts
5
+ var config = null;
6
+ function configureFormsApi(options) {
7
+ config = options;
8
+ }
9
+ function getConfig() {
10
+ if (config) return config;
11
+ const { apiUrl, apiKey } = readPublishedApiConfig();
12
+ if (apiUrl && apiKey) {
13
+ return { baseUrl: apiUrl, apiKey };
14
+ }
15
+ throw new Error(
16
+ "Forms API not configured. Use SiteKitLayout in your root layout or call configureFormsApi() first."
17
+ );
18
+ }
19
+ async function apiRequest(method, path, body) {
20
+ const { baseUrl, apiKey, getAuthToken } = getConfig();
21
+ const headers = {
22
+ "Content-Type": "application/json"
23
+ };
24
+ if (apiKey) {
25
+ headers["x-api-key"] = apiKey;
26
+ } else if (getAuthToken) {
27
+ const token = await getAuthToken();
28
+ headers["Authorization"] = `Bearer ${token}`;
29
+ }
30
+ const response = await sonorFetch(`${baseUrl}${path}`, {
31
+ method,
32
+ headers,
33
+ body: body ? JSON.stringify(body) : void 0
34
+ }, { retries: 0 });
35
+ if (!response.ok) {
36
+ const error = await response.json().catch(() => ({ message: response.statusText }));
37
+ throw new Error(error.message || `API error: ${response.status}`);
38
+ }
39
+ if (response.status === 204) {
40
+ return void 0;
41
+ }
42
+ return response.json();
43
+ }
44
+ var formsApi = {
45
+ /**
46
+ * List all forms for a project
47
+ */
48
+ async list(options = {}) {
49
+ const params = new URLSearchParams();
50
+ if (options.projectId) params.set("projectId", options.projectId);
51
+ if (options.formType) params.set("formType", options.formType);
52
+ if (options.isActive !== void 0) params.set("isActive", String(options.isActive));
53
+ if (options.search) params.set("search", options.search);
54
+ const query = params.toString();
55
+ const result = await apiRequest("GET", `/forms${query ? `?${query}` : ""}`);
56
+ return result.data;
57
+ },
58
+ /**
59
+ * Get a single form by ID or slug
60
+ */
61
+ async get(idOrSlug) {
62
+ return apiRequest("GET", `/forms/${idOrSlug}`);
63
+ },
64
+ /**
65
+ * Create a new form
66
+ */
67
+ async create(input) {
68
+ return apiRequest("POST", "/forms", input);
69
+ },
70
+ /**
71
+ * Update an existing form
72
+ */
73
+ async update(id, input) {
74
+ return apiRequest("PUT", `/forms/${id}`, input);
75
+ },
76
+ /**
77
+ * Delete a form
78
+ */
79
+ async delete(id) {
80
+ return apiRequest("DELETE", `/forms/${id}`);
81
+ },
82
+ /**
83
+ * Add a field to an existing form
84
+ */
85
+ async addField(formId, field2) {
86
+ const form = await formsApi.get(formId);
87
+ const maxSortOrder = Math.max(0, ...(form.fields || []).map((f) => f.sortOrder || 0));
88
+ return formsApi.update(formId, {
89
+ fields: [
90
+ ...form.fields || [],
91
+ { ...field2, sortOrder: field2.sortOrder ?? maxSortOrder + 1 }
92
+ ]
93
+ });
94
+ },
95
+ /**
96
+ * Update a field in an existing form
97
+ */
98
+ async updateField(formId, fieldSlug, updates) {
99
+ const form = await formsApi.get(formId);
100
+ return formsApi.update(formId, {
101
+ fields: (form.fields || []).map(
102
+ (f) => f.slug === fieldSlug ? { ...f, ...updates } : f
103
+ )
104
+ });
105
+ },
106
+ /**
107
+ * Remove a field from a form
108
+ */
109
+ async removeField(formId, fieldSlug) {
110
+ const form = await formsApi.get(formId);
111
+ return formsApi.update(formId, {
112
+ fields: (form.fields || []).filter((f) => f.slug !== fieldSlug)
113
+ });
114
+ },
115
+ /**
116
+ * Reorder fields in a form
117
+ */
118
+ async reorderFields(formId, fieldSlugs) {
119
+ const form = await formsApi.get(formId);
120
+ const fieldsMap = new Map((form.fields || []).map((f) => [f.slug, f]));
121
+ const orderedFields = fieldSlugs.map((slug, index) => {
122
+ const field2 = fieldsMap.get(slug);
123
+ if (!field2) throw new Error(`Field not found: ${slug}`);
124
+ return { ...field2, sortOrder: index };
125
+ });
126
+ return formsApi.update(formId, { fields: orderedFields });
127
+ },
128
+ /**
129
+ * Clone a form
130
+ */
131
+ async clone(formId, newSlug, newName) {
132
+ const form = await formsApi.get(formId);
133
+ return formsApi.create({
134
+ projectId: form.projectId,
135
+ slug: newSlug,
136
+ name: newName || `${form.name} (Copy)`,
137
+ description: form.description,
138
+ formType: form.formType,
139
+ successMessage: form.successMessage,
140
+ redirectUrl: form.redirectUrl,
141
+ notificationEmails: form.notificationEmails,
142
+ submitButtonText: form.submitButtonText,
143
+ layout: form.layout,
144
+ showProgress: form.showProgress,
145
+ enableSaveDraft: form.enableSaveDraft,
146
+ isActive: false,
147
+ // Clone as inactive
148
+ fields: (form.fields || []).map(({ id, ...field2 }) => field2),
149
+ // Remove IDs
150
+ steps: (form.steps || []).map(({ id, ...step }) => step)
151
+ // Remove IDs
152
+ });
153
+ },
154
+ /**
155
+ * Activate or deactivate a form
156
+ */
157
+ async setActive(formId, isActive) {
158
+ return formsApi.update(formId, { isActive });
159
+ },
160
+ /**
161
+ * Sync a form definition to the backend
162
+ * Creates the form if it doesn't exist, updates if it does
163
+ * Perfect for defining forms in code during development
164
+ *
165
+ * @example
166
+ * ```tsx
167
+ * // In your app initialization or form component
168
+ * await formsApi.sync({
169
+ * slug: 'contact',
170
+ * name: 'Contact Form',
171
+ * formType: 'prospect',
172
+ * fields: [
173
+ * field.text('name', 'Your Name', { isRequired: true }),
174
+ * field.email('email', 'Email Address'),
175
+ * field.phone('phone', 'Phone Number'),
176
+ * field.textarea('message', 'Message'),
177
+ * ]
178
+ * })
179
+ * ```
180
+ */
181
+ async sync(input) {
182
+ return apiRequest(
183
+ "POST",
184
+ "/api/public/forms/sync",
185
+ input
186
+ );
187
+ },
188
+ /**
189
+ * Sync multiple forms at once
190
+ * Useful for initializing all forms in your app
191
+ *
192
+ * Runs sequentially to avoid bursting the API (many hosts throttle concurrent POSTs → 429).
193
+ */
194
+ async syncAll(forms) {
195
+ const results = [];
196
+ for (const form of forms) {
197
+ results.push(await formsApi.sync(form));
198
+ }
199
+ return results;
200
+ }
201
+ };
202
+ var field = {
203
+ text: (slug, label, options) => ({
204
+ slug,
205
+ label,
206
+ fieldType: "text",
207
+ ...options
208
+ }),
209
+ email: (slug, label, options) => ({
210
+ slug,
211
+ label,
212
+ fieldType: "email",
213
+ isRequired: true,
214
+ ...options
215
+ }),
216
+ phone: (slug, label, options) => ({
217
+ slug,
218
+ label,
219
+ fieldType: "phone",
220
+ ...options
221
+ }),
222
+ textarea: (slug, label, options) => ({
223
+ slug,
224
+ label,
225
+ fieldType: "textarea",
226
+ ...options
227
+ }),
228
+ select: (slug, label, choices, options) => ({
229
+ slug,
230
+ label,
231
+ fieldType: "select",
232
+ options: choices,
233
+ ...options
234
+ }),
235
+ radio: (slug, label, choices, options) => ({
236
+ slug,
237
+ label,
238
+ fieldType: "radio",
239
+ options: choices,
240
+ ...options
241
+ }),
242
+ checkbox: (slug, label, options) => ({
243
+ slug,
244
+ label,
245
+ fieldType: "checkbox",
246
+ ...options
247
+ }),
248
+ date: (slug, label, options) => ({
249
+ slug,
250
+ label,
251
+ fieldType: "date",
252
+ ...options
253
+ }),
254
+ number: (slug, label, options) => ({
255
+ slug,
256
+ label,
257
+ fieldType: "number",
258
+ ...options
259
+ }),
260
+ rating: (slug, label, options) => ({
261
+ slug,
262
+ label,
263
+ fieldType: "rating",
264
+ ...options
265
+ }),
266
+ file: (slug, label, options) => ({
267
+ slug,
268
+ label,
269
+ fieldType: "file",
270
+ ...options
271
+ }),
272
+ hidden: (slug, defaultValue) => ({
273
+ slug,
274
+ label: "",
275
+ fieldType: "hidden",
276
+ defaultValue
277
+ }),
278
+ heading: (slug, label) => ({
279
+ slug,
280
+ label,
281
+ fieldType: "heading"
282
+ }),
283
+ paragraph: (slug, label) => ({
284
+ slug,
285
+ label,
286
+ fieldType: "paragraph"
287
+ })
288
+ };
289
+ function defineForm(definition) {
290
+ const fieldsWithOrder = definition.fields.map((f, index) => ({
291
+ ...f,
292
+ sortOrder: f.sortOrder ?? index
293
+ }));
294
+ return {
295
+ ...definition,
296
+ fields: fieldsWithOrder,
297
+ formType: definition.formType || "contact",
298
+ successMessage: definition.successMessage || "Thank you for your submission!",
299
+ submitButtonText: definition.submitButtonText || "Submit",
300
+ layout: definition.layout || "stacked",
301
+ isActive: definition.isActive ?? true
302
+ };
303
+ }
304
+ async function initializeForms(forms) {
305
+ if (typeof window === "undefined") {
306
+ console.log(`[Site-Kit] ${forms.length} form(s) ready to sync: ${forms.map((f) => f.slug).join(", ")}`);
307
+ return;
308
+ }
309
+ try {
310
+ const results = await formsApi.syncAll(forms);
311
+ const created = results.filter((r) => r.created).length;
312
+ const updated = results.filter((r) => r.updated).length;
313
+ console.log(`[Site-Kit] Forms synced: ${created} created, ${updated} updated`);
314
+ } catch (error) {
315
+ console.error("[Site-Kit] Failed to sync forms:", error);
316
+ }
317
+ }
318
+
319
+ export { configureFormsApi, defineForm, field, formsApi, initializeForms };