@sonordev/site-kit 7.4.0 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/AGENTS.md +40 -12
  2. package/CHANGELOG.md +72 -0
  3. package/README.md +44 -18
  4. package/agent-manifest.json +111 -56
  5. package/dist/AnalyticsProvider-EGCZ2MVM.js +13 -0
  6. package/dist/{ArticleViewTracker-3DH53RSB.js → ArticleViewTracker-ATNVMT45.js} +6 -5
  7. package/dist/{BlocksPopup-FGWYVHCH.js → BlocksPopup-F636XNO4.js} +6 -5
  8. package/dist/{ChatWidget-CDQZCLVH.js → ChatWidget-EQTLKPJX.js} +8 -5
  9. package/dist/{FileField-IPJ7L2W6.js → FileField-BUD2YGN5.js} +5 -5
  10. package/dist/{FormSpotlight-CQI2DBWI.js → FormSpotlight-NGH56TGC.js} +3 -3
  11. package/dist/{FormStage-4WHD6ED4.js → FormStage-XZRC54SY.js} +3 -3
  12. package/dist/ManagedForm-CQDQ4CUN.js +19 -0
  13. package/dist/{ManagedNewsletterForm-3D2BK3KQ.js → ManagedNewsletterForm-KCN3BTKA.js} +9 -6
  14. package/dist/{SignalCore-HEQYITTM.js → SignalCore-RDQPM2L2.js} +7 -7
  15. package/dist/SiteChat-QBDOQ5ZZ.js +6 -0
  16. package/dist/SiteDesignReporter-426TUCUF.js +12 -0
  17. package/dist/SitePopups-KLUD6XIE.js +13 -0
  18. package/dist/SitemapSync-QOIMV5GO.js +9 -0
  19. package/dist/_client/booking-widget.js +6 -5
  20. package/dist/_client/testimonial-section.js +3 -2
  21. package/dist/affiliates/index.js +6 -6
  22. package/dist/analytics/index.js +73 -7
  23. package/dist/articles/index.js +2 -2
  24. package/dist/articles/server-ui.js +3 -3
  25. package/dist/articles/server.js +2 -2
  26. package/dist/brand.css +1 -1
  27. package/dist/chat/index.d.ts +1 -1
  28. package/dist/chat/index.js +39 -8
  29. package/dist/{chunk-CSN45MHO.js → chunk-3222QBUS.js} +13 -16
  30. package/dist/chunk-3G7YABRA.js +25 -0
  31. package/dist/{chunk-CGWUXUYZ.js → chunk-3RDJKIYO.js} +2 -2
  32. package/dist/{chunk-J4FSB4OG.js → chunk-3YKQLC7J.js} +5 -2
  33. package/dist/{chunk-3E3PPSNR.js → chunk-55JLUMAC.js} +2 -2
  34. package/dist/{chunk-EHR4NIMX.js → chunk-5GB2HHVJ.js} +3 -3
  35. package/dist/chunk-5ROTTMBL.js +19 -0
  36. package/dist/chunk-5TM3WPCI.js +7 -0
  37. package/dist/{chunk-DA5XC7Y6.js → chunk-6BXUSAOJ.js} +1 -1
  38. package/dist/{chunk-7HPZSWS4.js → chunk-6CJGZFOU.js} +1 -1
  39. package/dist/{chunk-RYVDGXC2.js → chunk-6KU7STM3.js} +3 -1
  40. package/dist/{chunk-JRCNUUNG.js → chunk-6KUCA5HG.js} +1 -1
  41. package/dist/{chunk-MDP7EB4J.js → chunk-7BSC6HF3.js} +5 -5
  42. package/dist/{chunk-YCFW2OQO.js → chunk-AGJODJ4V.js} +2 -2
  43. package/dist/{chunk-OOD6GMT4.js → chunk-B7QRRLTU.js} +6 -4
  44. package/dist/{chunk-X6F6SO4S.js → chunk-C7TLGL3R.js} +21 -1
  45. package/dist/{chunk-PQDJNIHR.js → chunk-CAF53GKN.js} +2 -2
  46. package/dist/{chunk-43OCZ3JA.js → chunk-CAH4Y4PY.js} +4 -2
  47. package/dist/{chunk-XA2BNW5M.js → chunk-DWNS6ZJM.js} +1 -1
  48. package/dist/{chunk-PXKIGZ2F.js → chunk-EATJPSTS.js} +1 -1
  49. package/dist/{chunk-XEMHGJEG.js → chunk-EE6IG5GK.js} +10 -10
  50. package/dist/{chunk-D2RGEWHS.js → chunk-FIGIJK5F.js} +2 -2
  51. package/dist/{chunk-PF64OEXC.js → chunk-GMXY2OOY.js} +2 -2
  52. package/dist/{chunk-IE5SSOCN.js → chunk-H3SDOSVU.js} +3 -11
  53. package/dist/{chunk-GK7TV7EK.js → chunk-IY6G67EF.js} +1 -1
  54. package/dist/{chunk-CG4ETW5Y.js → chunk-J6N5DCGW.js} +3 -3
  55. package/dist/{chunk-ATE6IFVK.js → chunk-JCFQGEG7.js} +1 -1
  56. package/dist/{chunk-4BHRA7TI.js → chunk-JIH32RH2.js} +3 -3
  57. package/dist/{chunk-ZTLMPUO6.js → chunk-LNSF6BJC.js} +1 -1
  58. package/dist/{chunk-5O62CER4.js → chunk-M62U7TJF.js} +1 -1
  59. package/dist/{chunk-EDYHROQ7.js → chunk-NFRJTOTB.js} +3 -3
  60. package/dist/{chunk-6LLTLLEJ.js → chunk-NKFRW2VB.js} +6 -5
  61. package/dist/{chunk-CKW4HFJG.js → chunk-OCKGB734.js} +3 -3
  62. package/dist/{chunk-4DJMJ4V5.js → chunk-OE3NXEOF.js} +1 -1
  63. package/dist/{chunk-KHQ5GD6T.js → chunk-S5G3A7OZ.js} +1 -1
  64. package/dist/{chunk-4NTBQNHA.js → chunk-TYAVHRWH.js} +80 -81
  65. package/dist/{chunk-ZTLU3BSW.js → chunk-TZ5RTANX.js} +2 -2
  66. package/dist/{chunk-4YTYGG2C.js → chunk-URJN75ZG.js} +29 -16
  67. package/dist/{chunk-FUQTV5O6.js → chunk-VQQV7FOX.js} +3 -3
  68. package/dist/{chunk-PKGN32AU.js → chunk-XPTJRVL2.js} +1 -1
  69. package/dist/{chunk-662ILEZ6.js → chunk-Y35BWW2C.js} +3 -7
  70. package/dist/{chunk-MHGAZ3LL.js → chunk-YGXWG54S.js} +3 -5
  71. package/dist/{chunk-AH4AXO4P.js → chunk-Z4MK4VOG.js} +1 -1
  72. package/dist/{chunk-AV4QAK5F.js → chunk-Z6PVFZRI.js} +5 -4
  73. package/dist/chunk-ZKADJNR2.js +52 -0
  74. package/dist/client/index.js +6 -5
  75. package/dist/contracts/entries.d.ts +1 -1
  76. package/dist/contracts/knowledge.d.ts +84 -0
  77. package/dist/contracts/sentences.d.ts +46 -0
  78. package/dist/contracts/site-cache.d.ts +2 -0
  79. package/dist/cta-bar/index.js +1 -1
  80. package/dist/fleet/index.js +6 -5
  81. package/dist/forms/field-autocomplete.d.ts +16 -8
  82. package/dist/forms/index.d.ts +5 -0
  83. package/dist/forms/index.js +17 -17
  84. package/dist/forms/server.js +7 -7
  85. package/dist/forms/static.js +2 -2
  86. package/dist/forms/submitForm.d.ts +5 -0
  87. package/dist/images/index.js +4 -4
  88. package/dist/index.d.ts +3 -7
  89. package/dist/index.js +1 -1
  90. package/dist/layout/SiteKitLayout.d.ts +2 -1
  91. package/dist/layout/client.js +11 -9
  92. package/dist/layout/index.js +13 -11
  93. package/dist/llms/index.js +7 -6
  94. package/dist/maps/index.js +6 -6
  95. package/dist/mcp/sonor.d.ts +47 -3
  96. package/dist/mcp/sonor.js +30 -20
  97. package/dist/proxy/index.d.ts +3 -3
  98. package/dist/proxy/index.js +1 -1
  99. package/dist/reputation/index.js +3 -2
  100. package/dist/reputation/server.js +2 -1
  101. package/dist/revalidate/index.js +3 -3
  102. package/dist/robots/indexnow.js +2 -2
  103. package/dist/runtime/index.d.ts +32 -0
  104. package/dist/runtime/index.js +7 -0
  105. package/dist/seo/api.d.ts +0 -4
  106. package/dist/seo/client.js +6 -5
  107. package/dist/seo/getManagedMetadata.d.ts +24 -0
  108. package/dist/seo/index.d.ts +2 -3
  109. package/dist/seo/index.js +14 -132
  110. package/dist/seo/indexnow.js +2 -2
  111. package/dist/seo/llms.js +7 -6
  112. package/dist/seo/register-sitemap-cli.js +2 -2
  113. package/dist/seo/server-api.d.ts +0 -6
  114. package/dist/seo/server.d.ts +1 -1
  115. package/dist/seo/server.js +4 -4
  116. package/dist/seo/sitemap.js +4 -3
  117. package/dist/seo/types.d.ts +9 -30
  118. package/dist/server/index.d.ts +8 -1
  119. package/dist/server/index.js +4 -3
  120. package/dist/server/mint-site-token.d.ts +0 -11
  121. package/dist/server/server-fetch.d.ts +19 -0
  122. package/dist/server-api-EGOKC7Q3.js +9 -0
  123. package/dist/shared/build-entries.d.ts +21 -9
  124. package/dist/shared/clientApiConfig.d.ts +56 -0
  125. package/dist/shared/identity-reader.d.ts +26 -0
  126. package/dist/shared/identity-storage.d.ts +30 -0
  127. package/dist/shared/identity.d.ts +13 -13
  128. package/dist/shared/import-specifiers.d.ts +74 -0
  129. package/dist/shared/sonorFetch.d.ts +4 -3
  130. package/dist/shared/source-graph.d.ts +4 -1
  131. package/dist/shared/version.d.ts +1 -1
  132. package/dist/signal/index.js +2 -2
  133. package/dist/sitemap/index.js +4 -3
  134. package/dist/slots/index.js +3 -3
  135. package/dist/sync/index.js +6 -5
  136. package/dist/types.d.ts +0 -1
  137. package/dist/website/cta-bar.js +1 -1
  138. package/dist/website/images.js +4 -4
  139. package/dist/website/index.js +7 -6
  140. package/dist/website/popups.js +10 -7
  141. package/dist/website/slots.js +3 -3
  142. package/dist/{writeLLMsTxt-OL4KQERZ.js → writeLLMsTxt-UZGN6IBU.js} +3 -2
  143. package/docs/MIGRATING-TO-7.md +5 -2
  144. package/docs/MIGRATING-TO-8.md +183 -0
  145. package/docs.json +4 -8
  146. package/package.json +18 -45
  147. package/skills/site-kit/SKILL.md +41 -11
  148. package/src/analytics/README.md +14 -14
  149. package/src/chat/README.md +7 -7
  150. package/src/forms/README.md +61 -6
  151. package/src/mcp/README.md +61 -20
  152. package/src/proxy/README.md +5 -4
  153. package/src/revalidate/README.md +2 -2
  154. package/src/runtime/README.md +51 -0
  155. package/src/seo/README.md +24 -8
  156. package/src/sync/README.md +2 -2
  157. package/src/website/README.md +3 -2
  158. package/dist/AnalyticsProvider-BQXV3ZF3.js +0 -11
  159. package/dist/ManagedForm-7FZNH4L2.js +0 -16
  160. package/dist/SiteChat-DMPDXY3W.js +0 -5
  161. package/dist/SiteDesignReporter-Y2IOJE52.js +0 -11
  162. package/dist/SitePopups-HD2LDKVU.js +0 -10
  163. package/dist/SitemapSync-OKPZHRX6.js +0 -8
  164. package/dist/chunk-24QZEO3Q.js +0 -41
  165. package/dist/chunk-BU66S5B7.js +0 -1
  166. package/dist/chunk-G3NHWMP5.js +0 -233
  167. package/dist/chunk-HODO5BX5.js +0 -28
  168. package/dist/chunk-L3AQCDCY.js +0 -386
  169. package/dist/chunk-P5GB6NEO.js +0 -66
  170. package/dist/chunk-SWKE6FWH.js +0 -47
  171. package/dist/cms/CmsPage.d.ts +0 -17
  172. package/dist/cms/CmsPreview.d.ts +0 -37
  173. package/dist/cms/CmsSection.d.ts +0 -8
  174. package/dist/cms/PortableTextRenderer.d.ts +0 -7
  175. package/dist/cms/index.d.ts +0 -37
  176. package/dist/cms/index.js +0 -5
  177. package/dist/cms/sanity-image.d.ts +0 -47
  178. package/dist/cms/sections/CtaSection.d.ts +0 -3
  179. package/dist/cms/sections/CustomSection.d.ts +0 -7
  180. package/dist/cms/sections/FaqSection.d.ts +0 -3
  181. package/dist/cms/sections/FormSection.d.ts +0 -8
  182. package/dist/cms/sections/GallerySection.d.ts +0 -3
  183. package/dist/cms/sections/HeroSection.d.ts +0 -3
  184. package/dist/cms/sections/RichTextSection.d.ts +0 -3
  185. package/dist/cms/sections/TestimonialsSection.d.ts +0 -3
  186. package/dist/cms/sections/index.d.ts +0 -8
  187. package/dist/cms/server-api.d.ts +0 -49
  188. package/dist/cms/server.d.ts +0 -1
  189. package/dist/cms/server.js +0 -5
  190. package/dist/cms/types.d.ts +0 -104
  191. package/dist/commerce/CalendarView.d.ts +0 -43
  192. package/dist/commerce/CheckoutForm.d.ts +0 -11
  193. package/dist/commerce/EventCalendar.d.ts +0 -26
  194. package/dist/commerce/EventCheckout.d.ts +0 -42
  195. package/dist/commerce/EventEmbed.d.ts +0 -11
  196. package/dist/commerce/EventModal.d.ts +0 -43
  197. package/dist/commerce/EventTile.d.ts +0 -10
  198. package/dist/commerce/EventsAgenda.d.ts +0 -38
  199. package/dist/commerce/EventsWidget.d.ts +0 -84
  200. package/dist/commerce/OfferingCard.d.ts +0 -9
  201. package/dist/commerce/OfferingList.d.ts +0 -9
  202. package/dist/commerce/ProductDetail.d.ts +0 -38
  203. package/dist/commerce/ProductEmbed.d.ts +0 -11
  204. package/dist/commerce/ProductGrid.d.ts +0 -41
  205. package/dist/commerce/ProductPage.d.ts +0 -39
  206. package/dist/commerce/RegistrationForm.d.ts +0 -9
  207. package/dist/commerce/SizeChart.d.ts +0 -8
  208. package/dist/commerce/UpcomingEvents.d.ts +0 -9
  209. package/dist/commerce/api.d.ts +0 -179
  210. package/dist/commerce/events-extras.d.ts +0 -60
  211. package/dist/commerce/index.d.ts +0 -33
  212. package/dist/commerce/index.js +0 -8022
  213. package/dist/commerce/server.d.ts +0 -161
  214. package/dist/commerce/server.js +0 -2
  215. package/dist/commerce/types.d.ts +0 -340
  216. package/dist/commerce/useEventModal.d.ts +0 -20
  217. package/dist/commerce/utils.d.ts +0 -17
  218. package/dist/engage/EngageWidget.d.ts +0 -21
  219. package/dist/engage/index.d.ts +0 -14
  220. package/dist/engage/index.js +0 -45
  221. package/dist/engage/types.d.ts +0 -33
  222. package/dist/seo/ManagedContent.d.ts +0 -14
  223. package/dist/server-api-BVCBLJKL.js +0 -9
  224. package/dist/website/cms/server.d.ts +0 -2
  225. package/dist/website/cms/server.js +0 -5
  226. package/dist/website/cms-server.d.ts +0 -2
  227. package/dist/website/cms.d.ts +0 -2
  228. package/dist/website/cms.js +0 -5
  229. package/src/commerce/README.md +0 -109
@@ -1,233 +0,0 @@
1
- // src/commerce/server.ts
2
- function isFrameworkSignal(err) {
3
- const digest = err?.digest;
4
- return typeof digest === "string" && (digest === "DYNAMIC_SERVER_USAGE" || digest.startsWith("NEXT_"));
5
- }
6
- async function apiFetch(config, endpoint) {
7
- try {
8
- const response = await fetch(`${config.apiUrl}${endpoint}`, {
9
- headers: {
10
- "X-API-Key": config.apiKey,
11
- "X-Project-ID": config.projectId,
12
- "Content-Type": "application/json"
13
- }
14
- });
15
- if (!response.ok) {
16
- console.error(`[site-kit/commerce] GET ${endpoint} failed: ${response.status}`);
17
- return { ok: false, data: null };
18
- }
19
- return { ok: true, data: await response.json() };
20
- } catch (error) {
21
- if (isFrameworkSignal(error)) throw error;
22
- console.error(`[site-kit/commerce] GET ${endpoint} failed:`, error);
23
- return { ok: false, data: null };
24
- }
25
- }
26
- async function apiPost(config, endpoint, body) {
27
- try {
28
- const response = await fetch(`${config.apiUrl}${endpoint}`, {
29
- method: "POST",
30
- headers: {
31
- "X-API-Key": config.apiKey,
32
- "X-Project-ID": config.projectId,
33
- "Content-Type": "application/json"
34
- },
35
- body: JSON.stringify(body)
36
- });
37
- if (!response.ok) {
38
- console.error(`[site-kit/commerce] POST ${endpoint} failed: ${response.status}`);
39
- return { ok: false, data: null };
40
- }
41
- return { ok: true, data: await response.json() };
42
- } catch (error) {
43
- if (isFrameworkSignal(error)) throw error;
44
- console.error(`[site-kit/commerce] POST ${endpoint} failed:`, error);
45
- return { ok: false, data: null };
46
- }
47
- }
48
- function transformOffering(data) {
49
- return {
50
- id: data.id,
51
- project_id: data.project_id,
52
- type: data.type,
53
- status: data.status,
54
- name: data.name,
55
- slug: data.slug,
56
- description: data.description,
57
- short_description: data.short_description,
58
- long_description: data.long_description,
59
- featured_image_url: data.featured_image_url,
60
- gallery_images: data.gallery_image_urls || [],
61
- price_type: data.price_type || "fixed",
62
- price: data.price,
63
- compare_at_price: data.compare_at_price,
64
- currency: data.currency || "USD",
65
- price_is_public: data.price_is_public ?? true,
66
- billing_period: data.billing_period,
67
- track_inventory: data.track_inventory,
68
- inventory_count: data.inventory_count,
69
- allow_backorder: data.allow_backorder,
70
- duration_minutes: data.duration_minutes,
71
- capacity: data.capacity,
72
- location: data.location,
73
- is_virtual: data.is_virtual,
74
- virtual_meeting_url: data.virtual_meeting_url,
75
- requires_booking: data.requires_booking,
76
- booking_lead_time_hours: data.booking_lead_time_hours,
77
- category: data.category,
78
- category_id: data.category_id,
79
- tags: data.tags || [],
80
- seo_title: data.seo_title,
81
- seo_description: data.seo_description,
82
- features: data.features || [],
83
- specifications: data.specifications || {},
84
- schedules: data.schedules || [],
85
- variants: data.variants || [],
86
- created_at: data.created_at,
87
- updated_at: data.updated_at
88
- };
89
- }
90
- async function getProductPaths(config) {
91
- const { ok, data } = await apiFetch(
92
- config,
93
- `/api/public/commerce/offerings?type=product&status=active&fields=slug`
94
- );
95
- if (!ok) console.error("[site-kit/commerce] getProductPaths failed \u2014 0 product pages will be prerendered");
96
- if (!data?.offerings) return [];
97
- return data.offerings.map((item) => ({ params: { slug: item.slug } }));
98
- }
99
- async function getEventPaths(config) {
100
- const { ok, data } = await apiFetch(
101
- config,
102
- `/api/public/commerce/offerings?type=event&status=active&fields=slug`
103
- );
104
- if (!ok) console.error("[site-kit/commerce] getEventPaths failed \u2014 0 event pages will be prerendered");
105
- if (!data?.offerings) return [];
106
- return data.offerings.map((item) => ({ params: { slug: item.slug } }));
107
- }
108
- async function getOfferingPaths(config, type) {
109
- let typeParam = "";
110
- if (type) {
111
- if (Array.isArray(type)) {
112
- typeParam = `&type=${type.join(",")}`;
113
- } else {
114
- typeParam = `&type=${type}`;
115
- }
116
- }
117
- const { ok, data } = await apiFetch(
118
- config,
119
- `/api/public/commerce/offerings?status=active&fields=slug${typeParam}`
120
- );
121
- if (!ok) console.error("[site-kit/commerce] getOfferingPaths failed \u2014 0 pages will be prerendered");
122
- if (!data?.offerings) return [];
123
- return data.offerings.map((item) => ({ params: { slug: item.slug } }));
124
- }
125
- async function getOfferingBySlug(config, slug) {
126
- return (await getOfferingBySlugResult(config, slug)).data;
127
- }
128
- async function getOfferingBySlugResult(config, slug) {
129
- const { ok, data } = await apiFetch(
130
- config,
131
- `/api/public/commerce/offerings/${slug}`
132
- );
133
- if (!data?.offering) return { ok, data: null };
134
- return { ok: true, data: transformOffering(data.offering) };
135
- }
136
- async function getOfferings(config, options = {}) {
137
- return (await getOfferingsResult(config, options)).data;
138
- }
139
- async function getOfferingsResult(config, options = {}) {
140
- const params = new URLSearchParams();
141
- params.set("status", options.status || "active");
142
- if (options.type) {
143
- if (Array.isArray(options.type)) {
144
- params.set("type", options.type.join(","));
145
- } else {
146
- params.set("type", options.type);
147
- }
148
- }
149
- if (options.category) {
150
- params.set("category", options.category);
151
- }
152
- if (options.limit) {
153
- params.set("limit", options.limit.toString());
154
- }
155
- const { ok, data } = await apiFetch(
156
- config,
157
- `/api/public/commerce/offerings?${params.toString()}`
158
- );
159
- if (!data?.offerings) return { ok, data: [] };
160
- return { ok: true, data: data.offerings.map(transformOffering) };
161
- }
162
- async function getUpcomingEvents(config, options = {}) {
163
- return (await getUpcomingEventsResult(config, options)).data;
164
- }
165
- async function getUpcomingEventsResult(config, options = {}) {
166
- const primary = await apiPost(
167
- config,
168
- "/api/public/commerce/events",
169
- {
170
- type: "event",
171
- category: options.category,
172
- limit: options.limit,
173
- includePast: false
174
- }
175
- );
176
- if (primary.ok && primary.data?.events) {
177
- return { ok: true, data: primary.data.events.map(transformOffering) };
178
- }
179
- const params = new URLSearchParams();
180
- params.set("type", "event");
181
- params.set("status", "active");
182
- params.set("upcoming", "true");
183
- if (options.category) {
184
- params.set("category", options.category);
185
- }
186
- if (options.limit) {
187
- params.set("limit", options.limit.toString());
188
- }
189
- const legacy = await apiFetch(
190
- config,
191
- `/api/public/commerce/offerings?${params.toString()}`
192
- );
193
- if (legacy.ok && legacy.data?.offerings) {
194
- return { ok: true, data: legacy.data.offerings.map(transformOffering) };
195
- }
196
- return { ok: primary.ok || legacy.ok, data: [] };
197
- }
198
- async function getNextEvent(config, category) {
199
- return (await getNextEventResult(config, category)).data;
200
- }
201
- async function getNextEventResult(config, category) {
202
- const { ok, data } = await getUpcomingEventsResult(config, { limit: 1, category });
203
- return { ok, data: data[0] || null };
204
- }
205
- function generateOfferingMetadata(offering, siteUrl) {
206
- if (!offering) return null;
207
- const title = offering.seo_title || offering.name;
208
- const description = offering.seo_description || offering.short_description || offering.description || "";
209
- const images = offering.featured_image_url ? [offering.featured_image_url] : [];
210
- const typeMap = {
211
- product: "product",
212
- service: "website",
213
- event: "website",
214
- class: "website",
215
- subscription: "product"
216
- };
217
- return {
218
- title,
219
- description,
220
- openGraph: {
221
- title,
222
- description,
223
- images,
224
- type: typeMap[offering.type] || "website",
225
- url: `${siteUrl}/${offering.type}s/${offering.slug}`
226
- }
227
- };
228
- }
229
- function createServerConfig(apiUrl, apiKey, projectId) {
230
- return { apiUrl, apiKey, projectId };
231
- }
232
-
233
- export { createServerConfig, generateOfferingMetadata, getEventPaths, getNextEvent, getNextEventResult, getOfferingBySlug, getOfferingBySlugResult, getOfferingPaths, getOfferings, getOfferingsResult, getProductPaths, getUpcomingEvents, getUpcomingEventsResult };
@@ -1,28 +0,0 @@
1
- // src/chat/echo-config.ts
2
- var SONOR_PUBLIC_ECHO_DEFAULTS = {
3
- signalUrl: "https://signal.sonor.io",
4
- welcomeMessage: "Hi! I'm Echo, Sonor's AI assistant. I can answer questions about our platform, help you understand pricing, or get you started with a demo. What would you like to know?",
5
- suggestedQuestions: [
6
- "What does Sonor do?",
7
- "How does Signal AI work?",
8
- "What are the pricing plans?",
9
- "Can I migrate from HubSpot?",
10
- "How does the SEO module work?"
11
- ],
12
- brandColor: "#2563eb",
13
- // blue-600 (~5.2:1 on white, AA); overridden by --sk-primary CSS var or API brand_primary
14
- assistantName: "Echo"
15
- };
16
- function getEchoWidgetProps(config = SONOR_PUBLIC_ECHO_DEFAULTS) {
17
- return {
18
- signal_enabled: true,
19
- signal_url: config.signalUrl || SONOR_PUBLIC_ECHO_DEFAULTS.signalUrl,
20
- welcome_message: config.welcomeMessage || SONOR_PUBLIC_ECHO_DEFAULTS.welcomeMessage,
21
- suggested_questions: config.suggestedQuestions || SONOR_PUBLIC_ECHO_DEFAULTS.suggestedQuestions,
22
- brand_color: config.brandColor || SONOR_PUBLIC_ECHO_DEFAULTS.brandColor,
23
- assistant_name: config.assistantName || SONOR_PUBLIC_ECHO_DEFAULTS.assistantName,
24
- assistant_avatar: config.assistantAvatar
25
- };
26
- }
27
-
28
- export { SONOR_PUBLIC_ECHO_DEFAULTS, getEchoWidgetProps };
@@ -1,386 +0,0 @@
1
- 'use client';
2
- import { getCmsPage } from './chunk-SWKE6FWH.js';
3
- import { PortableText } from '@portabletext/react';
4
- import imageUrlBuilder from '@sanity/image-url';
5
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import { useState, useEffect } from 'react';
7
-
8
- var _builder = null;
9
- var DEFAULT_CONFIG = {
10
- projectId: "l55lyemx",
11
- dataset: "production"
12
- };
13
- function configureSanityImages(config) {
14
- _builder = imageUrlBuilder(config);
15
- }
16
- function getBuilder() {
17
- if (!_builder) {
18
- _builder = imageUrlBuilder(DEFAULT_CONFIG);
19
- }
20
- return _builder;
21
- }
22
- function sanityImageUrl(image, options = {}) {
23
- if (!image?.asset?._ref) return "";
24
- let builder = getBuilder().image(image).auto("format");
25
- if (options.width) builder = builder.width(options.width);
26
- if (options.height) builder = builder.height(options.height);
27
- if (options.dpr) builder = builder.dpr(options.dpr);
28
- if (options.quality) builder = builder.quality(options.quality);
29
- if (options.format) builder = builder.format(options.format);
30
- if (options.fit) builder = builder.fit(options.fit);
31
- if (options.blur) builder = builder.blur(options.blur);
32
- return builder.url();
33
- }
34
- function sanityImageSrcSet(image, widths = [400, 800, 1200, 1600], options = {}) {
35
- if (!image?.asset?._ref) return "";
36
- return widths.map((w) => `${sanityImageUrl(image, { ...options, width: w })} ${w}w`).join(", ");
37
- }
38
- function hotspotToObjectPosition(image) {
39
- if (!image?.hotspot) return void 0;
40
- return `${(image.hotspot.x * 100).toFixed(1)}% ${(image.hotspot.y * 100).toFixed(1)}%`;
41
- }
42
- var defaultComponents = {
43
- block: {
44
- h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: "sonor-cms-h1", children }),
45
- h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "sonor-cms-h2", children }),
46
- h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: "sonor-cms-h3", children }),
47
- h4: ({ children }) => /* @__PURE__ */ jsx("h4", { className: "sonor-cms-h4", children }),
48
- normal: ({ children }) => /* @__PURE__ */ jsx("p", { className: "sonor-cms-p", children }),
49
- blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { className: "sonor-cms-blockquote", children })
50
- },
51
- marks: {
52
- strong: ({ children }) => /* @__PURE__ */ jsx("strong", { children }),
53
- em: ({ children }) => /* @__PURE__ */ jsx("em", { children }),
54
- code: ({ children }) => /* @__PURE__ */ jsx("code", { className: "sonor-cms-code", children }),
55
- underline: ({ children }) => /* @__PURE__ */ jsx("u", { children }),
56
- "strike-through": ({ children }) => /* @__PURE__ */ jsx("s", { children }),
57
- link: ({ children, value }) => {
58
- const href = value?.href || "#";
59
- const isExternal = href.startsWith("http");
60
- return /* @__PURE__ */ jsx(
61
- "a",
62
- {
63
- href,
64
- className: "sonor-cms-link",
65
- ...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : {},
66
- children
67
- }
68
- );
69
- },
70
- highlight: ({ children }) => /* @__PURE__ */ jsx("mark", { className: "sonor-cms-highlight", children })
71
- },
72
- list: {
73
- bullet: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "sonor-cms-ul", children }),
74
- number: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "sonor-cms-ol", children })
75
- },
76
- listItem: {
77
- bullet: ({ children }) => /* @__PURE__ */ jsx("li", { children }),
78
- number: ({ children }) => /* @__PURE__ */ jsx("li", { children })
79
- },
80
- types: {
81
- image: ({ value }) => {
82
- if (!value?.asset?._ref && !value?.url) return null;
83
- const src = value.url || sanityImageUrl(value, { width: 1200 });
84
- const srcSet = !value.url ? sanityImageSrcSet(value, [400, 800, 1200, 1600]) : void 0;
85
- const objectPosition = hotspotToObjectPosition(value);
86
- return /* @__PURE__ */ jsxs("figure", { className: "sonor-cms-figure", children: [
87
- /* @__PURE__ */ jsx(
88
- "img",
89
- {
90
- src,
91
- srcSet,
92
- sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 80vw, 1200px",
93
- alt: value.alt || "",
94
- className: "sonor-cms-img",
95
- loading: "lazy",
96
- style: objectPosition ? { objectPosition } : void 0
97
- }
98
- ),
99
- value.caption && /* @__PURE__ */ jsx("figcaption", { className: "sonor-cms-figcaption", children: typeof value.caption === "string" ? value.caption : null })
100
- ] });
101
- }
102
- }
103
- };
104
- function PortableTextRenderer({
105
- value,
106
- components: overrides,
107
- className
108
- }) {
109
- if (!value || !Array.isArray(value) || value.length === 0) return null;
110
- const merged = overrides ? {
111
- ...defaultComponents,
112
- block: { ...defaultComponents.block, ...overrides.block },
113
- marks: { ...defaultComponents.marks, ...overrides.marks },
114
- types: { ...defaultComponents.types, ...overrides.types },
115
- list: { ...defaultComponents.list, ...overrides.list },
116
- listItem: { ...defaultComponents.listItem, ...overrides.listItem }
117
- } : defaultComponents;
118
- return /* @__PURE__ */ jsx("div", { className: className || "sonor-cms-content", children: /* @__PURE__ */ jsx(PortableText, { value, components: merged }) });
119
- }
120
- function HeroSection({ data, portableTextComponents }) {
121
- const headline = data.headline;
122
- const subheadline = data.subheadline;
123
- const ctaText = data.ctaText;
124
- const ctaLink = data.ctaLink;
125
- const bgImage = data.backgroundImage;
126
- const bgUrl = sanityImageUrl(bgImage, { width: 1920, quality: 80 });
127
- const bgPosition = hotspotToObjectPosition(bgImage) || "50% 50%";
128
- return /* @__PURE__ */ jsxs(
129
- "section",
130
- {
131
- className: "sonor-cms-hero",
132
- style: bgUrl ? { backgroundImage: `url(${bgUrl})`, backgroundPosition: bgPosition, backgroundSize: "cover" } : void 0,
133
- children: [
134
- headline && /* @__PURE__ */ jsx(PortableTextRenderer, { value: headline, components: portableTextComponents, className: "sonor-cms-hero-headline" }),
135
- subheadline && /* @__PURE__ */ jsx(PortableTextRenderer, { value: subheadline, components: portableTextComponents, className: "sonor-cms-hero-subheadline" }),
136
- ctaText && ctaLink && /* @__PURE__ */ jsx("a", { href: ctaLink, className: "sonor-cms-hero-cta", children: ctaText })
137
- ]
138
- }
139
- );
140
- }
141
- function RichTextSection({ data, portableTextComponents }) {
142
- const content = data.content;
143
- if (!content) return null;
144
- return /* @__PURE__ */ jsx("section", { className: "sonor-cms-richtext", children: /* @__PURE__ */ jsx(PortableTextRenderer, { value: content, components: portableTextComponents }) });
145
- }
146
- function CtaSection({ data, portableTextComponents }) {
147
- const headline = data.headline;
148
- const description = data.description;
149
- const buttonText = data.buttonText;
150
- const buttonLink = data.buttonLink;
151
- return /* @__PURE__ */ jsxs("section", { className: "sonor-cms-cta", children: [
152
- headline && /* @__PURE__ */ jsx(PortableTextRenderer, { value: headline, components: portableTextComponents, className: "sonor-cms-cta-headline" }),
153
- description && /* @__PURE__ */ jsx(PortableTextRenderer, { value: description, components: portableTextComponents, className: "sonor-cms-cta-description" }),
154
- buttonText && buttonLink && /* @__PURE__ */ jsx("a", { href: buttonLink, className: "sonor-cms-cta-button", children: buttonText })
155
- ] });
156
- }
157
- function GallerySection({ data, portableTextComponents }) {
158
- const images = data.images || [];
159
- const layout = data.layout || "grid";
160
- const caption = data.caption;
161
- if (images.length === 0) return null;
162
- return /* @__PURE__ */ jsxs("section", { className: "sonor-cms-gallery", children: [
163
- /* @__PURE__ */ jsx("div", { className: `sonor-cms-gallery-${layout}`, children: images.map((img, i) => {
164
- const objectPosition = hotspotToObjectPosition(img);
165
- return /* @__PURE__ */ jsx("figure", { className: "sonor-cms-gallery-item", children: /* @__PURE__ */ jsx(
166
- "img",
167
- {
168
- src: sanityImageUrl(img, { width: 800 }),
169
- srcSet: sanityImageSrcSet(img, [400, 800, 1200]),
170
- sizes: "(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw",
171
- alt: img.alt || "",
172
- loading: "lazy",
173
- style: objectPosition ? { objectPosition } : void 0
174
- }
175
- ) }, img.asset?._ref || i);
176
- }) }),
177
- caption && /* @__PURE__ */ jsx(PortableTextRenderer, { value: caption, components: portableTextComponents, className: "sonor-cms-gallery-caption" })
178
- ] });
179
- }
180
- function TestimonialsSection({ data, portableTextComponents }) {
181
- const items = data.items || [];
182
- const layout = data.layout || "grid";
183
- if (items.length === 0) return null;
184
- return /* @__PURE__ */ jsx("section", { className: `sonor-cms-testimonials sonor-cms-testimonials-${layout}`, children: items.map((item, i) => /* @__PURE__ */ jsxs("blockquote", { className: "sonor-cms-testimonial", children: [
185
- /* @__PURE__ */ jsx(PortableTextRenderer, { value: item.quote, components: portableTextComponents, className: "sonor-cms-testimonial-quote" }),
186
- /* @__PURE__ */ jsxs("footer", { className: "sonor-cms-testimonial-footer", children: [
187
- item.avatar?.asset?._ref && /* @__PURE__ */ jsx(
188
- "img",
189
- {
190
- src: sanityImageUrl(item.avatar, { width: 80, height: 80, fit: "crop" }),
191
- alt: item.avatar.alt || item.author,
192
- className: "sonor-cms-testimonial-avatar",
193
- width: 80,
194
- height: 80,
195
- loading: "lazy"
196
- }
197
- ),
198
- /* @__PURE__ */ jsxs("cite", { className: "sonor-cms-testimonial-author", children: [
199
- item.author,
200
- item.role && /* @__PURE__ */ jsxs("span", { className: "sonor-cms-testimonial-role", children: [
201
- ", ",
202
- item.role
203
- ] })
204
- ] })
205
- ] })
206
- ] }, i)) });
207
- }
208
- function FaqSection({ data, portableTextComponents }) {
209
- const items = data.items || [];
210
- if (items.length === 0) return null;
211
- return /* @__PURE__ */ jsx("section", { className: "sonor-cms-faq", children: items.map((item, i) => /* @__PURE__ */ jsxs("details", { className: "sonor-cms-faq-item", children: [
212
- /* @__PURE__ */ jsx("summary", { className: "sonor-cms-faq-question", children: item.question }),
213
- /* @__PURE__ */ jsx("div", { className: "sonor-cms-faq-answer", children: /* @__PURE__ */ jsx(PortableTextRenderer, { value: item.answer, components: portableTextComponents }) })
214
- ] }, i)) });
215
- }
216
- function FormSection({ data, portableTextComponents }) {
217
- const formSlug = data.formSlug;
218
- const heading = data.heading;
219
- return /* @__PURE__ */ jsxs("section", { className: "sonor-cms-form", children: [
220
- heading && /* @__PURE__ */ jsx(PortableTextRenderer, { value: heading, components: portableTextComponents, className: "sonor-cms-form-heading" }),
221
- formSlug ? /* @__PURE__ */ jsx(
222
- "div",
223
- {
224
- className: "sonor-cms-form-embed",
225
- "data-form-slug": formSlug
226
- }
227
- ) : /* @__PURE__ */ jsx("p", { className: "sonor-cms-form-placeholder", children: "Form not configured" })
228
- ] });
229
- }
230
- function CustomSection({ data, displayName }) {
231
- const componentName = data.componentName;
232
- data.props || {};
233
- return /* @__PURE__ */ jsx("section", { className: "sonor-cms-custom", "data-component": componentName, children: /* @__PURE__ */ jsxs("div", { className: "sonor-cms-custom-placeholder", children: [
234
- "Custom component: ",
235
- componentName || displayName
236
- ] }) });
237
- }
238
- var defaultRenderers = {
239
- hero: HeroSection,
240
- richText: RichTextSection,
241
- cta: CtaSection,
242
- gallery: GallerySection,
243
- testimonials: TestimonialsSection,
244
- faq: FaqSection,
245
- form: FormSection,
246
- custom: CustomSection
247
- };
248
- function CmsSection({ section, sectionComponents, portableTextComponents }) {
249
- const Renderer = sectionComponents?.[section.sectionType] || defaultRenderers[section.sectionType];
250
- if (!Renderer) {
251
- if (process.env.NODE_ENV === "development") {
252
- console.warn(`@sonordev/cms: No renderer for section type: ${section.sectionType}`);
253
- }
254
- return null;
255
- }
256
- return /* @__PURE__ */ jsx(
257
- "div",
258
- {
259
- className: `sonor-cms-section sonor-cms-section-${section.sectionType}`,
260
- "data-section-id": section._id,
261
- "data-section-type": section.sectionType,
262
- children: /* @__PURE__ */ jsx(
263
- Renderer,
264
- {
265
- data: section.data,
266
- sectionType: section.sectionType,
267
- displayName: section.displayName,
268
- portableTextComponents
269
- }
270
- )
271
- }
272
- );
273
- }
274
- async function CmsPage({
275
- path,
276
- sectionComponents,
277
- portableTextComponents,
278
- fallback,
279
- className
280
- }) {
281
- const page = await getCmsPage(path);
282
- if (!page) {
283
- if (fallback) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
284
- return null;
285
- }
286
- if (!page.sections || page.sections.length === 0) {
287
- if (fallback) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
288
- return null;
289
- }
290
- return /* @__PURE__ */ jsx(
291
- "div",
292
- {
293
- className: className || "sonor-cms-page",
294
- "data-cms-page-id": page._id,
295
- "data-cms-path": page.path,
296
- children: page.sections.map((section) => /* @__PURE__ */ jsx(
297
- CmsSection,
298
- {
299
- section,
300
- sectionComponents,
301
- portableTextComponents
302
- },
303
- section._id
304
- ))
305
- }
306
- );
307
- }
308
- function CmsPreview({
309
- apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io",
310
- apiKey,
311
- path,
312
- pollInterval = 3e3,
313
- sectionComponents,
314
- portableTextComponents,
315
- className
316
- }) {
317
- const [page, setPage] = useState(null);
318
- const [error, setError] = useState(null);
319
- useEffect(() => {
320
- let cancelled = false;
321
- async function fetchPage() {
322
- try {
323
- const res = await fetch(`${apiUrl}/api/public/cms/page`, {
324
- method: "POST",
325
- headers: {
326
- "Content-Type": "application/json",
327
- "x-api-key": apiKey
328
- },
329
- body: JSON.stringify({ path })
330
- });
331
- if (!res.ok) {
332
- setError(`Error ${res.status}`);
333
- return;
334
- }
335
- const data = await res.json();
336
- if (!cancelled && data?.found && data.page) {
337
- setPage(data.page);
338
- setError(null);
339
- }
340
- } catch (err) {
341
- if (!cancelled) {
342
- setError("Failed to load preview");
343
- }
344
- }
345
- }
346
- fetchPage();
347
- if (pollInterval > 0) {
348
- const interval = setInterval(fetchPage, pollInterval);
349
- return () => {
350
- cancelled = true;
351
- clearInterval(interval);
352
- };
353
- }
354
- return () => {
355
- cancelled = true;
356
- };
357
- }, [apiUrl, apiKey, path, pollInterval]);
358
- if (error) {
359
- return /* @__PURE__ */ jsx("div", { className: "sonor-cms-preview-error", children: /* @__PURE__ */ jsxs("p", { children: [
360
- "Preview error: ",
361
- error
362
- ] }) });
363
- }
364
- if (!page) {
365
- return /* @__PURE__ */ jsx("div", { className: "sonor-cms-preview-loading", children: /* @__PURE__ */ jsx("p", { children: "Loading preview..." }) });
366
- }
367
- return /* @__PURE__ */ jsx(
368
- "div",
369
- {
370
- className: className || "sonor-cms-page sonor-cms-preview",
371
- "data-cms-preview": "true",
372
- "data-cms-path": page.path,
373
- children: page.sections?.map((section) => /* @__PURE__ */ jsx(
374
- CmsSection,
375
- {
376
- section,
377
- sectionComponents,
378
- portableTextComponents
379
- },
380
- section._id
381
- ))
382
- }
383
- );
384
- }
385
-
386
- export { CmsPage, CmsPreview, CmsSection, CtaSection, CustomSection, FaqSection, FormSection, GallerySection, HeroSection, PortableTextRenderer, RichTextSection, TestimonialsSection, configureSanityImages, hotspotToObjectPosition, sanityImageSrcSet, sanityImageUrl };