@sonordev/site-kit 3.2.0 → 3.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 (142) hide show
  1. package/agent-manifest.json +1 -1
  2. package/dist/AnalyticsProvider-26VS3CQR.js +29 -0
  3. package/dist/{AnalyticsProvider-WK2Z6AIN.js.map → AnalyticsProvider-26VS3CQR.js.map} +1 -1
  4. package/dist/AnalyticsProvider-AMHG4DIE.mjs +8 -0
  5. package/dist/{AnalyticsProvider-CD635CHQ.mjs.map → AnalyticsProvider-AMHG4DIE.mjs.map} +1 -1
  6. package/dist/ChatWidget-NIYNSMLU.js +17 -0
  7. package/dist/{ChatWidget-AIOOZY6H.js.map → ChatWidget-NIYNSMLU.js.map} +1 -1
  8. package/dist/ChatWidget-UKPEQEHB.mjs +8 -0
  9. package/dist/{ChatWidget-UAAWDBNS.mjs.map → ChatWidget-UKPEQEHB.mjs.map} +1 -1
  10. package/dist/EngageWidget-33QCFWQW.js +16 -0
  11. package/dist/{EngageWidget-RWVWW56C.js.map → EngageWidget-33QCFWQW.js.map} +1 -1
  12. package/dist/EngageWidget-S76ZMDEF.mjs +7 -0
  13. package/dist/{EngageWidget-EZ5T6H3K.mjs.map → EngageWidget-S76ZMDEF.mjs.map} +1 -1
  14. package/dist/{SignalCore-4B4RNYLV.mjs → SignalCore-2AUGAOQT.mjs} +4 -4
  15. package/dist/{SignalCore-4B4RNYLV.mjs.map → SignalCore-2AUGAOQT.mjs.map} +1 -1
  16. package/dist/{SignalCore-AECW2JFP.js → SignalCore-2UXXM4FF.js} +8 -8
  17. package/dist/{SignalCore-AECW2JFP.js.map → SignalCore-2UXXM4FF.js.map} +1 -1
  18. package/dist/SitemapSync-RBHXPQAQ.mjs +6 -0
  19. package/dist/{SitemapSync-CIZCAZXK.mjs.map → SitemapSync-RBHXPQAQ.mjs.map} +1 -1
  20. package/dist/SitemapSync-WQJMHJNY.js +15 -0
  21. package/dist/{SitemapSync-AICU4SSV.js.map → SitemapSync-WQJMHJNY.js.map} +1 -1
  22. package/dist/analytics/index.js +11 -11
  23. package/dist/analytics/index.mjs +4 -4
  24. package/dist/brand.css +13 -3
  25. package/dist/{chunk-OTY7EWET.mjs → chunk-2RLG4KBJ.mjs} +4 -4
  26. package/dist/{chunk-OTY7EWET.mjs.map → chunk-2RLG4KBJ.mjs.map} +1 -1
  27. package/dist/{chunk-6HPNFWSC.mjs → chunk-5KVT66R6.mjs} +3 -3
  28. package/dist/{chunk-6HPNFWSC.mjs.map → chunk-5KVT66R6.mjs.map} +1 -1
  29. package/dist/{chunk-RFIWVH3D.mjs → chunk-6BDXN4X3.mjs} +3 -3
  30. package/dist/{chunk-RFIWVH3D.mjs.map → chunk-6BDXN4X3.mjs.map} +1 -1
  31. package/dist/{chunk-GCDVKOSM.js → chunk-6UK5JIKE.js} +3 -3
  32. package/dist/{chunk-GCDVKOSM.js.map → chunk-6UK5JIKE.js.map} +1 -1
  33. package/dist/{chunk-GN62H6EG.mjs → chunk-AXFM4MFK.mjs} +8 -8
  34. package/dist/{chunk-GN62H6EG.mjs.map → chunk-AXFM4MFK.mjs.map} +1 -1
  35. package/dist/{chunk-S3YQGTBF.js → chunk-BOTWTNHW.js} +12 -12
  36. package/dist/{chunk-S3YQGTBF.js.map → chunk-BOTWTNHW.js.map} +1 -1
  37. package/dist/{chunk-I2GTT2DG.js → chunk-BPKDRTEA.js} +107 -34
  38. package/dist/chunk-BPKDRTEA.js.map +1 -0
  39. package/dist/{chunk-4NTMIU6V.js → chunk-EL6ZMYD2.js} +6 -6
  40. package/dist/{chunk-4NTMIU6V.js.map → chunk-EL6ZMYD2.js.map} +1 -1
  41. package/dist/{chunk-UT2CF4FC.js → chunk-EM4DFSC5.js} +4 -4
  42. package/dist/{chunk-UT2CF4FC.js.map → chunk-EM4DFSC5.js.map} +1 -1
  43. package/dist/chunk-EOENN46G.js +8 -0
  44. package/dist/{chunk-WRZQS7O4.js.map → chunk-EOENN46G.js.map} +1 -1
  45. package/dist/{chunk-LZSCCJ4O.mjs → chunk-FO6Y27AH.mjs} +11 -5
  46. package/dist/chunk-FO6Y27AH.mjs.map +1 -0
  47. package/dist/{chunk-5OWZUNNE.js → chunk-FX3VR4BF.js} +7 -7
  48. package/dist/{chunk-5OWZUNNE.js.map → chunk-FX3VR4BF.js.map} +1 -1
  49. package/dist/{chunk-TE3W5REY.js → chunk-G4FJJK6J.js} +14 -14
  50. package/dist/{chunk-TE3W5REY.js.map → chunk-G4FJJK6J.js.map} +1 -1
  51. package/dist/{chunk-R5A64DCX.js → chunk-I2M533CW.js} +8 -8
  52. package/dist/{chunk-R5A64DCX.js.map → chunk-I2M533CW.js.map} +1 -1
  53. package/dist/{chunk-FMZOZQBV.mjs → chunk-ILLOVVVP.mjs} +107 -34
  54. package/dist/chunk-ILLOVVVP.mjs.map +1 -0
  55. package/dist/{chunk-HAZN43I6.js → chunk-K2P7KPEQ.js} +30 -28
  56. package/dist/chunk-K2P7KPEQ.js.map +1 -0
  57. package/dist/{chunk-EAASMIWX.js → chunk-M2EGCGIT.js} +15 -9
  58. package/dist/chunk-M2EGCGIT.js.map +1 -0
  59. package/dist/{chunk-2WYEJOGA.mjs → chunk-M4HLDK62.mjs} +3 -3
  60. package/dist/{chunk-2WYEJOGA.mjs.map → chunk-M4HLDK62.mjs.map} +1 -1
  61. package/dist/{chunk-T2DEEKVQ.mjs → chunk-NNPF4KRZ.mjs} +3 -3
  62. package/dist/{chunk-T2DEEKVQ.mjs.map → chunk-NNPF4KRZ.mjs.map} +1 -1
  63. package/dist/{chunk-NAVDN4AE.js → chunk-P3QZRG2Z.js} +29 -40
  64. package/dist/chunk-P3QZRG2Z.js.map +1 -0
  65. package/dist/{chunk-EIWRPGOK.mjs → chunk-PLQ4CUNI.mjs} +4 -4
  66. package/dist/{chunk-EIWRPGOK.mjs.map → chunk-PLQ4CUNI.mjs.map} +1 -1
  67. package/dist/{chunk-45QHDA7Q.mjs → chunk-PUGRSMAV.mjs} +3 -3
  68. package/dist/{chunk-45QHDA7Q.mjs.map → chunk-PUGRSMAV.mjs.map} +1 -1
  69. package/dist/{chunk-4FBV5BJW.js → chunk-QOFC3BYG.js} +5 -5
  70. package/dist/{chunk-4FBV5BJW.js.map → chunk-QOFC3BYG.js.map} +1 -1
  71. package/dist/chunk-S4FJIG6Y.mjs +6 -0
  72. package/dist/{chunk-SN2O72UF.mjs.map → chunk-S4FJIG6Y.mjs.map} +1 -1
  73. package/dist/{chunk-DSRPKUQI.mjs → chunk-SLOZWRWU.mjs} +28 -39
  74. package/dist/chunk-SLOZWRWU.mjs.map +1 -0
  75. package/dist/{chunk-TVCCZ7NR.js → chunk-WAYG3LS2.js} +14 -14
  76. package/dist/{chunk-TVCCZ7NR.js.map → chunk-WAYG3LS2.js.map} +1 -1
  77. package/dist/{chunk-N2HR2E4Z.mjs → chunk-WEHJRE3H.mjs} +25 -23
  78. package/dist/chunk-WEHJRE3H.mjs.map +1 -0
  79. package/dist/{chunk-NDHFU4HV.mjs → chunk-X72PFC4X.mjs} +4 -4
  80. package/dist/{chunk-NDHFU4HV.mjs.map → chunk-X72PFC4X.mjs.map} +1 -1
  81. package/dist/{chunk-SLWTG2LJ.js → chunk-XOCQANYF.js} +13 -13
  82. package/dist/{chunk-SLWTG2LJ.js.map → chunk-XOCQANYF.js.map} +1 -1
  83. package/dist/{chunk-57QV6NIY.mjs → chunk-ZCZEKWFW.mjs} +3 -3
  84. package/dist/{chunk-57QV6NIY.mjs.map → chunk-ZCZEKWFW.mjs.map} +1 -1
  85. package/dist/cli/index.js +2 -2
  86. package/dist/cli/index.mjs +1 -1
  87. package/dist/commerce/index.js +50 -50
  88. package/dist/commerce/index.mjs +5 -5
  89. package/dist/engage/index.js +8 -8
  90. package/dist/engage/index.mjs +5 -5
  91. package/dist/fleet/index.js +7 -7
  92. package/dist/fleet/index.mjs +3 -3
  93. package/dist/forms/index.js +18 -18
  94. package/dist/forms/index.js.map +1 -1
  95. package/dist/forms/index.mjs +10 -10
  96. package/dist/forms/index.mjs.map +1 -1
  97. package/dist/forms/styles.css +4 -2
  98. package/dist/images/index.js +10 -10
  99. package/dist/images/index.mjs +3 -3
  100. package/dist/index.js +67 -68
  101. package/dist/index.js.map +1 -1
  102. package/dist/index.mjs +14 -15
  103. package/dist/index.mjs.map +1 -1
  104. package/dist/layout/client.js +6 -6
  105. package/dist/layout/client.mjs +5 -5
  106. package/dist/layout/index.js +7 -7
  107. package/dist/layout/index.mjs +5 -5
  108. package/dist/maps/index.d.mts +4 -2
  109. package/dist/maps/index.d.ts +4 -2
  110. package/dist/maps/index.js +4 -4
  111. package/dist/maps/index.js.map +1 -1
  112. package/dist/maps/index.mjs +2 -2
  113. package/dist/maps/index.mjs.map +1 -1
  114. package/dist/seo/client.js +4 -4
  115. package/dist/seo/client.mjs +3 -3
  116. package/dist/seo/index.js +4 -4
  117. package/dist/seo/index.mjs +3 -3
  118. package/dist/signal/index.js +11 -11
  119. package/dist/signal/index.mjs +2 -2
  120. package/dist/sync/index.d.mts +10 -1
  121. package/dist/sync/index.d.ts +10 -1
  122. package/dist/sync/index.js +15 -13
  123. package/dist/sync/index.mjs +3 -1
  124. package/package.json +1 -1
  125. package/dist/AnalyticsProvider-CD635CHQ.mjs +0 -8
  126. package/dist/AnalyticsProvider-WK2Z6AIN.js +0 -29
  127. package/dist/ChatWidget-AIOOZY6H.js +0 -17
  128. package/dist/ChatWidget-UAAWDBNS.mjs +0 -8
  129. package/dist/EngageWidget-EZ5T6H3K.mjs +0 -7
  130. package/dist/EngageWidget-RWVWW56C.js +0 -16
  131. package/dist/SitemapSync-AICU4SSV.js +0 -15
  132. package/dist/SitemapSync-CIZCAZXK.mjs +0 -6
  133. package/dist/chunk-DSRPKUQI.mjs.map +0 -1
  134. package/dist/chunk-EAASMIWX.js.map +0 -1
  135. package/dist/chunk-FMZOZQBV.mjs.map +0 -1
  136. package/dist/chunk-HAZN43I6.js.map +0 -1
  137. package/dist/chunk-I2GTT2DG.js.map +0 -1
  138. package/dist/chunk-LZSCCJ4O.mjs.map +0 -1
  139. package/dist/chunk-N2HR2E4Z.mjs.map +0 -1
  140. package/dist/chunk-NAVDN4AE.js.map +0 -1
  141. package/dist/chunk-SN2O72UF.mjs +0 -6
  142. package/dist/chunk-WRZQS7O4.js +0 -8
@@ -1,40 +1,40 @@
1
1
  'use strict';
2
2
 
3
- var chunkTVCCZ7NR_js = require('../chunk-TVCCZ7NR.js');
3
+ var chunkWAYG3LS2_js = require('../chunk-WAYG3LS2.js');
4
4
  var chunkGCPPXUAI_js = require('../chunk-GCPPXUAI.js');
5
- require('../chunk-EAASMIWX.js');
6
- require('../chunk-WRZQS7O4.js');
5
+ require('../chunk-M2EGCGIT.js');
6
+ require('../chunk-EOENN46G.js');
7
7
  require('../chunk-ZSMWDLMK.js');
8
8
 
9
9
 
10
10
 
11
11
  Object.defineProperty(exports, "ManagedImage", {
12
12
  enumerable: true,
13
- get: function () { return chunkTVCCZ7NR_js.ManagedImage; }
13
+ get: function () { return chunkWAYG3LS2_js.ManagedImage; }
14
14
  });
15
15
  Object.defineProperty(exports, "assignImageToSlot", {
16
16
  enumerable: true,
17
- get: function () { return chunkTVCCZ7NR_js.assignImageToSlot; }
17
+ get: function () { return chunkWAYG3LS2_js.assignImageToSlot; }
18
18
  });
19
19
  Object.defineProperty(exports, "clearImageSlot", {
20
20
  enumerable: true,
21
- get: function () { return chunkTVCCZ7NR_js.clearImageSlot; }
21
+ get: function () { return chunkWAYG3LS2_js.clearImageSlot; }
22
22
  });
23
23
  Object.defineProperty(exports, "fetchManagedImage", {
24
24
  enumerable: true,
25
- get: function () { return chunkTVCCZ7NR_js.fetchManagedImage; }
25
+ get: function () { return chunkWAYG3LS2_js.fetchManagedImage; }
26
26
  });
27
27
  Object.defineProperty(exports, "fetchManagedImages", {
28
28
  enumerable: true,
29
- get: function () { return chunkTVCCZ7NR_js.fetchManagedImages; }
29
+ get: function () { return chunkWAYG3LS2_js.fetchManagedImages; }
30
30
  });
31
31
  Object.defineProperty(exports, "listImageFiles", {
32
32
  enumerable: true,
33
- get: function () { return chunkTVCCZ7NR_js.listImageFiles; }
33
+ get: function () { return chunkWAYG3LS2_js.listImageFiles; }
34
34
  });
35
35
  Object.defineProperty(exports, "uploadImage", {
36
36
  enumerable: true,
37
- get: function () { return chunkTVCCZ7NR_js.uploadImage; }
37
+ get: function () { return chunkWAYG3LS2_js.uploadImage; }
38
38
  });
39
39
  Object.defineProperty(exports, "ManagedFavicon", {
40
40
  enumerable: true,
@@ -1,7 +1,7 @@
1
- export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-RFIWVH3D.mjs';
1
+ export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-6BDXN4X3.mjs';
2
2
  export { ManagedFavicon, getManagedFaviconUrl } from '../chunk-CU6OGBKK.mjs';
3
- import '../chunk-LZSCCJ4O.mjs';
4
- import '../chunk-SN2O72UF.mjs';
3
+ import '../chunk-FO6Y27AH.mjs';
4
+ import '../chunk-S4FJIG6Y.mjs';
5
5
  import '../chunk-4XPGGLVP.mjs';
6
6
  //# sourceMappingURL=index.mjs.map
7
7
  //# sourceMappingURL=index.mjs.map
package/dist/index.js CHANGED
@@ -1,21 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var chunkI2GTT2DG_js = require('./chunk-I2GTT2DG.js');
3
+ var chunkBPKDRTEA_js = require('./chunk-BPKDRTEA.js');
4
4
  var chunkW6K7MQCC_js = require('./chunk-W6K7MQCC.js');
5
5
  require('./chunk-JP5WGL75.js');
6
- var chunkTVCCZ7NR_js = require('./chunk-TVCCZ7NR.js');
6
+ var chunkWAYG3LS2_js = require('./chunk-WAYG3LS2.js');
7
7
  require('./chunk-GCPPXUAI.js');
8
8
  var chunkEHJANA5C_js = require('./chunk-EHJANA5C.js');
9
9
  var chunkGSRT66PA_js = require('./chunk-GSRT66PA.js');
10
- var chunkR5A64DCX_js = require('./chunk-R5A64DCX.js');
11
- var chunkGCDVKOSM_js = require('./chunk-GCDVKOSM.js');
12
- var chunkTE3W5REY_js = require('./chunk-TE3W5REY.js');
13
- require('./chunk-UT2CF4FC.js');
14
- require('./chunk-SLWTG2LJ.js');
10
+ var chunkI2M533CW_js = require('./chunk-I2M533CW.js');
11
+ var chunk6UK5JIKE_js = require('./chunk-6UK5JIKE.js');
12
+ var chunkG4FJJK6J_js = require('./chunk-G4FJJK6J.js');
13
+ require('./chunk-EM4DFSC5.js');
14
+ require('./chunk-XOCQANYF.js');
15
15
  require('./chunk-HMFFAUCD.js');
16
16
  require('./chunk-3BNFUMLL.js');
17
- require('./chunk-EAASMIWX.js');
18
- require('./chunk-WRZQS7O4.js');
17
+ var chunkM2EGCGIT_js = require('./chunk-M2EGCGIT.js');
18
+ require('./chunk-EOENN46G.js');
19
19
  require('./chunk-ZSMWDLMK.js');
20
20
  var react = require('react');
21
21
  var jsxRuntime = require('react/jsx-runtime');
@@ -33,12 +33,11 @@ async function apiGet(endpoint) {
33
33
  return null;
34
34
  }
35
35
  try {
36
- const response = await fetch(`${apiUrl}${endpoint}`, {
37
- method: "GET",
38
- headers: {
39
- "x-api-key": apiKey
40
- }
41
- });
36
+ const response = await chunkM2EGCGIT_js.sonorFetch(
37
+ `${apiUrl}${endpoint}`,
38
+ { method: "GET" },
39
+ { apiKey, retries: 0 }
40
+ );
42
41
  if (!response.ok) {
43
42
  console.error(`[Affiliates] API error: ${response.statusText}`);
44
43
  return null;
@@ -163,51 +162,51 @@ function AffiliatesWidget({
163
162
 
164
163
  Object.defineProperty(exports, "BookingWidget", {
165
164
  enumerable: true,
166
- get: function () { return chunkI2GTT2DG_js.BookingWidget; }
165
+ get: function () { return chunkBPKDRTEA_js.BookingWidget; }
167
166
  });
168
167
  Object.defineProperty(exports, "createBooking", {
169
168
  enumerable: true,
170
- get: function () { return chunkI2GTT2DG_js.createBooking; }
169
+ get: function () { return chunkBPKDRTEA_js.createBooking; }
171
170
  });
172
171
  Object.defineProperty(exports, "createSlotHold", {
173
172
  enumerable: true,
174
- get: function () { return chunkI2GTT2DG_js.createSlotHold; }
173
+ get: function () { return chunkBPKDRTEA_js.createSlotHold; }
175
174
  });
176
175
  Object.defineProperty(exports, "detectTimezone", {
177
176
  enumerable: true,
178
- get: function () { return chunkI2GTT2DG_js.detectTimezone; }
177
+ get: function () { return chunkBPKDRTEA_js.detectTimezone; }
179
178
  });
180
179
  Object.defineProperty(exports, "fetchAvailability", {
181
180
  enumerable: true,
182
- get: function () { return chunkI2GTT2DG_js.fetchAvailability; }
181
+ get: function () { return chunkBPKDRTEA_js.fetchAvailability; }
183
182
  });
184
183
  Object.defineProperty(exports, "fetchAvailableDates", {
185
184
  enumerable: true,
186
- get: function () { return chunkI2GTT2DG_js.fetchAvailableDates; }
185
+ get: function () { return chunkBPKDRTEA_js.fetchAvailableDates; }
187
186
  });
188
187
  Object.defineProperty(exports, "fetchBookingTypeDetails", {
189
188
  enumerable: true,
190
- get: function () { return chunkI2GTT2DG_js.fetchBookingTypeDetails; }
189
+ get: function () { return chunkBPKDRTEA_js.fetchBookingTypeDetails; }
191
190
  });
192
191
  Object.defineProperty(exports, "fetchBookingTypes", {
193
192
  enumerable: true,
194
- get: function () { return chunkI2GTT2DG_js.fetchBookingTypes; }
193
+ get: function () { return chunkBPKDRTEA_js.fetchBookingTypes; }
195
194
  });
196
195
  Object.defineProperty(exports, "formatBookingDate", {
197
196
  enumerable: true,
198
- get: function () { return chunkI2GTT2DG_js.formatDate; }
197
+ get: function () { return chunkBPKDRTEA_js.formatDate; }
199
198
  });
200
199
  Object.defineProperty(exports, "formatBookingTime", {
201
200
  enumerable: true,
202
- get: function () { return chunkI2GTT2DG_js.formatTime; }
201
+ get: function () { return chunkBPKDRTEA_js.formatTime; }
203
202
  });
204
203
  Object.defineProperty(exports, "formatDuration", {
205
204
  enumerable: true,
206
- get: function () { return chunkI2GTT2DG_js.formatDuration; }
205
+ get: function () { return chunkBPKDRTEA_js.formatDuration; }
207
206
  });
208
207
  Object.defineProperty(exports, "releaseSlotHold", {
209
208
  enumerable: true,
210
- get: function () { return chunkI2GTT2DG_js.releaseSlotHold; }
209
+ get: function () { return chunkBPKDRTEA_js.releaseSlotHold; }
211
210
  });
212
211
  Object.defineProperty(exports, "clearRedirectCache", {
213
212
  enumerable: true,
@@ -227,31 +226,31 @@ Object.defineProperty(exports, "handleManagedRedirects", {
227
226
  });
228
227
  Object.defineProperty(exports, "ManagedImage", {
229
228
  enumerable: true,
230
- get: function () { return chunkTVCCZ7NR_js.ManagedImage; }
229
+ get: function () { return chunkWAYG3LS2_js.ManagedImage; }
231
230
  });
232
231
  Object.defineProperty(exports, "assignImageToSlot", {
233
232
  enumerable: true,
234
- get: function () { return chunkTVCCZ7NR_js.assignImageToSlot; }
233
+ get: function () { return chunkWAYG3LS2_js.assignImageToSlot; }
235
234
  });
236
235
  Object.defineProperty(exports, "clearImageSlot", {
237
236
  enumerable: true,
238
- get: function () { return chunkTVCCZ7NR_js.clearImageSlot; }
237
+ get: function () { return chunkWAYG3LS2_js.clearImageSlot; }
239
238
  });
240
239
  Object.defineProperty(exports, "fetchManagedImage", {
241
240
  enumerable: true,
242
- get: function () { return chunkTVCCZ7NR_js.fetchManagedImage; }
241
+ get: function () { return chunkWAYG3LS2_js.fetchManagedImage; }
243
242
  });
244
243
  Object.defineProperty(exports, "fetchManagedImages", {
245
244
  enumerable: true,
246
- get: function () { return chunkTVCCZ7NR_js.fetchManagedImages; }
245
+ get: function () { return chunkWAYG3LS2_js.fetchManagedImages; }
247
246
  });
248
247
  Object.defineProperty(exports, "listImageFiles", {
249
248
  enumerable: true,
250
- get: function () { return chunkTVCCZ7NR_js.listImageFiles; }
249
+ get: function () { return chunkWAYG3LS2_js.listImageFiles; }
251
250
  });
252
251
  Object.defineProperty(exports, "uploadImage", {
253
252
  enumerable: true,
254
- get: function () { return chunkTVCCZ7NR_js.uploadImage; }
253
+ get: function () { return chunkWAYG3LS2_js.uploadImage; }
255
254
  });
256
255
  Object.defineProperty(exports, "TestimonialSection", {
257
256
  enumerable: true,
@@ -267,139 +266,139 @@ Object.defineProperty(exports, "fetchReviews", {
267
266
  });
268
267
  Object.defineProperty(exports, "ExperimentConversion", {
269
268
  enumerable: true,
270
- get: function () { return chunkR5A64DCX_js.ExperimentConversion; }
269
+ get: function () { return chunkI2M533CW_js.ExperimentConversion; }
271
270
  });
272
271
  Object.defineProperty(exports, "SignalExperiment", {
273
272
  enumerable: true,
274
- get: function () { return chunkR5A64DCX_js.SignalExperiment; }
273
+ get: function () { return chunkI2M533CW_js.SignalExperiment; }
275
274
  });
276
275
  Object.defineProperty(exports, "useExperimentVariant", {
277
276
  enumerable: true,
278
- get: function () { return chunkR5A64DCX_js.useExperimentVariant; }
277
+ get: function () { return chunkI2M533CW_js.useExperimentVariant; }
279
278
  });
280
279
  Object.defineProperty(exports, "SignalBridge", {
281
280
  enumerable: true,
282
- get: function () { return chunkGCDVKOSM_js.SignalBridge; }
281
+ get: function () { return chunk6UK5JIKE_js.SignalBridge; }
283
282
  });
284
283
  Object.defineProperty(exports, "useSignal", {
285
284
  enumerable: true,
286
- get: function () { return chunkGCDVKOSM_js.useSignal; }
285
+ get: function () { return chunk6UK5JIKE_js.useSignal; }
287
286
  });
288
287
  Object.defineProperty(exports, "useSignalConfig", {
289
288
  enumerable: true,
290
- get: function () { return chunkGCDVKOSM_js.useSignalConfig; }
289
+ get: function () { return chunk6UK5JIKE_js.useSignalConfig; }
291
290
  });
292
291
  Object.defineProperty(exports, "useSignalEvent", {
293
292
  enumerable: true,
294
- get: function () { return chunkGCDVKOSM_js.useSignalEvent; }
293
+ get: function () { return chunk6UK5JIKE_js.useSignalEvent; }
295
294
  });
296
295
  Object.defineProperty(exports, "useSignalExperiment", {
297
296
  enumerable: true,
298
- get: function () { return chunkGCDVKOSM_js.useSignalExperiment; }
297
+ get: function () { return chunk6UK5JIKE_js.useSignalExperiment; }
299
298
  });
300
299
  Object.defineProperty(exports, "useSignalOutcome", {
301
300
  enumerable: true,
302
- get: function () { return chunkGCDVKOSM_js.useSignalOutcome; }
301
+ get: function () { return chunk6UK5JIKE_js.useSignalOutcome; }
303
302
  });
304
303
  Object.defineProperty(exports, "CalendarView", {
305
304
  enumerable: true,
306
- get: function () { return chunkTE3W5REY_js.CalendarView; }
305
+ get: function () { return chunkG4FJJK6J_js.CalendarView; }
307
306
  });
308
307
  Object.defineProperty(exports, "CheckoutForm", {
309
308
  enumerable: true,
310
- get: function () { return chunkTE3W5REY_js.CheckoutForm; }
309
+ get: function () { return chunkG4FJJK6J_js.CheckoutForm; }
311
310
  });
312
311
  Object.defineProperty(exports, "EventCalendar", {
313
312
  enumerable: true,
314
- get: function () { return chunkTE3W5REY_js.EventCalendar; }
313
+ get: function () { return chunkG4FJJK6J_js.EventCalendar; }
315
314
  });
316
315
  Object.defineProperty(exports, "EventCheckout", {
317
316
  enumerable: true,
318
- get: function () { return chunkTE3W5REY_js.EventCheckout; }
317
+ get: function () { return chunkG4FJJK6J_js.EventCheckout; }
319
318
  });
320
319
  Object.defineProperty(exports, "EventEmbed", {
321
320
  enumerable: true,
322
- get: function () { return chunkTE3W5REY_js.EventEmbed; }
321
+ get: function () { return chunkG4FJJK6J_js.EventEmbed; }
323
322
  });
324
323
  Object.defineProperty(exports, "EventModal", {
325
324
  enumerable: true,
326
- get: function () { return chunkTE3W5REY_js.EventModal; }
325
+ get: function () { return chunkG4FJJK6J_js.EventModal; }
327
326
  });
328
327
  Object.defineProperty(exports, "EventTile", {
329
328
  enumerable: true,
330
- get: function () { return chunkTE3W5REY_js.EventTile; }
329
+ get: function () { return chunkG4FJJK6J_js.EventTile; }
331
330
  });
332
331
  Object.defineProperty(exports, "OfferingCard", {
333
332
  enumerable: true,
334
- get: function () { return chunkTE3W5REY_js.OfferingCard; }
333
+ get: function () { return chunkG4FJJK6J_js.OfferingCard; }
335
334
  });
336
335
  Object.defineProperty(exports, "OfferingList", {
337
336
  enumerable: true,
338
- get: function () { return chunkTE3W5REY_js.OfferingList; }
337
+ get: function () { return chunkG4FJJK6J_js.OfferingList; }
339
338
  });
340
339
  Object.defineProperty(exports, "ProductEmbed", {
341
340
  enumerable: true,
342
- get: function () { return chunkTE3W5REY_js.ProductEmbed; }
341
+ get: function () { return chunkG4FJJK6J_js.ProductEmbed; }
343
342
  });
344
343
  Object.defineProperty(exports, "RegistrationForm", {
345
344
  enumerable: true,
346
- get: function () { return chunkTE3W5REY_js.RegistrationForm; }
345
+ get: function () { return chunkG4FJJK6J_js.RegistrationForm; }
347
346
  });
348
347
  Object.defineProperty(exports, "UpcomingEvents", {
349
348
  enumerable: true,
350
- get: function () { return chunkTE3W5REY_js.UpcomingEvents; }
349
+ get: function () { return chunkG4FJJK6J_js.UpcomingEvents; }
351
350
  });
352
351
  Object.defineProperty(exports, "createCheckoutSession", {
353
352
  enumerable: true,
354
- get: function () { return chunkTE3W5REY_js.createCheckoutSession; }
353
+ get: function () { return chunkG4FJJK6J_js.createCheckoutSession; }
355
354
  });
356
355
  Object.defineProperty(exports, "fetchNextEvent", {
357
356
  enumerable: true,
358
- get: function () { return chunkTE3W5REY_js.fetchNextEvent; }
357
+ get: function () { return chunkG4FJJK6J_js.fetchNextEvent; }
359
358
  });
360
359
  Object.defineProperty(exports, "fetchOffering", {
361
360
  enumerable: true,
362
- get: function () { return chunkTE3W5REY_js.fetchOffering; }
361
+ get: function () { return chunkG4FJJK6J_js.fetchOffering; }
363
362
  });
364
363
  Object.defineProperty(exports, "fetchOfferings", {
365
364
  enumerable: true,
366
- get: function () { return chunkTE3W5REY_js.fetchOfferings; }
365
+ get: function () { return chunkG4FJJK6J_js.fetchOfferings; }
367
366
  });
368
367
  Object.defineProperty(exports, "fetchProducts", {
369
368
  enumerable: true,
370
- get: function () { return chunkTE3W5REY_js.fetchProducts; }
369
+ get: function () { return chunkG4FJJK6J_js.fetchProducts; }
371
370
  });
372
371
  Object.defineProperty(exports, "fetchServices", {
373
372
  enumerable: true,
374
- get: function () { return chunkTE3W5REY_js.fetchServices; }
373
+ get: function () { return chunkG4FJJK6J_js.fetchServices; }
375
374
  });
376
375
  Object.defineProperty(exports, "fetchUpcomingEvents", {
377
376
  enumerable: true,
378
- get: function () { return chunkTE3W5REY_js.fetchUpcomingEvents; }
377
+ get: function () { return chunkG4FJJK6J_js.fetchUpcomingEvents; }
379
378
  });
380
379
  Object.defineProperty(exports, "formatDate", {
381
380
  enumerable: true,
382
- get: function () { return chunkTE3W5REY_js.formatDate; }
381
+ get: function () { return chunkG4FJJK6J_js.formatDate; }
383
382
  });
384
383
  Object.defineProperty(exports, "formatDateTime", {
385
384
  enumerable: true,
386
- get: function () { return chunkTE3W5REY_js.formatDateTime; }
385
+ get: function () { return chunkG4FJJK6J_js.formatDateTime; }
387
386
  });
388
387
  Object.defineProperty(exports, "formatPrice", {
389
388
  enumerable: true,
390
- get: function () { return chunkTE3W5REY_js.formatPrice; }
389
+ get: function () { return chunkG4FJJK6J_js.formatPrice; }
391
390
  });
392
391
  Object.defineProperty(exports, "getOfferingUrl", {
393
392
  enumerable: true,
394
- get: function () { return chunkTE3W5REY_js.getOfferingUrl; }
393
+ get: function () { return chunkG4FJJK6J_js.getOfferingUrl; }
395
394
  });
396
395
  Object.defineProperty(exports, "registerForEvent", {
397
396
  enumerable: true,
398
- get: function () { return chunkTE3W5REY_js.registerForEvent; }
397
+ get: function () { return chunkG4FJJK6J_js.registerForEvent; }
399
398
  });
400
399
  Object.defineProperty(exports, "useEventModal", {
401
400
  enumerable: true,
402
- get: function () { return chunkTE3W5REY_js.useEventModal; }
401
+ get: function () { return chunkG4FJJK6J_js.useEventModal; }
403
402
  });
404
403
  exports.AffiliateCard = AffiliateCard;
405
404
  exports.AffiliatesWidget = AffiliatesWidget;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/affiliates/api.ts","../src/affiliates/useAffiliates.ts","../src/affiliates/AffiliatesWidget.tsx"],"names":["useState","useEffect","getTrackingUrl","jsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @sonordev/site-kit/affiliates - Affiliates API\n * \n * API functions for fetching affiliate data for client sites.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\nimport type { Affiliate, AffiliateWithOffers, FetchAffiliatesOptions } from './types'\n\n// ============================================\n// API Config Helpers\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : ''\n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('[Affiliates] No API key configured')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'x-api-key': apiKey,\n },\n })\n \n if (!response.ok) {\n console.error(`[Affiliates] API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('[Affiliates] Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Fetch Affiliates\n// ============================================\n\n/**\n * Fetch all active affiliates for the project\n * \n * @example\n * ```ts\n * const affiliates = await fetchAffiliates()\n * ```\n */\nexport async function fetchAffiliates(\n options: FetchAffiliatesOptions = {}\n): Promise<AffiliateWithOffers[]> {\n const result = await apiGet<{ affiliates: AffiliateWithOffers[] }>(\n '/api/public/affiliates'\n )\n \n return result?.affiliates || []\n}\n\n/**\n * Build a tracking URL for an affiliate offer\n * When clicked, this redirects through our tracking endpoint and then to the destination\n * \n * @example\n * ```ts\n * const trackingUrl = getTrackingUrl(affiliate.id, offer.id)\n * // Returns: https://api.sonor.io/a/{affiliateId}/{offerId}\n * ```\n */\nexport function getTrackingUrl(affiliateId: string, offerId: string): string {\n const { apiUrl } = getApiConfig()\n return `${apiUrl}/a/${affiliateId}/${offerId}`\n}\n","/**\n * @sonordev/site-kit/affiliates - useAffiliates Hook\n * \n * React hook for fetching and displaying affiliates on client sites.\n */\n\n'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { AffiliateWithOffers } from './types'\nimport { fetchAffiliates, getTrackingUrl } from './api'\n\nexport interface UseAffiliatesResult {\n affiliates: AffiliateWithOffers[]\n isLoading: boolean\n error: string | null\n getTrackingUrl: (affiliateId: string, offerId: string) => string\n}\n\n/**\n * Hook to fetch affiliates for display on client sites\n * \n * @example\n * ```tsx\n * function AffiliatesSection() {\n * const { affiliates, isLoading } = useAffiliates()\n * \n * if (isLoading) return <div>Loading...</div>\n * \n * return (\n * <div className=\"grid grid-cols-3 gap-4\">\n * {affiliates.map(affiliate => (\n * <AffiliateCard key={affiliate.id} affiliate={affiliate} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function useAffiliates(): UseAffiliatesResult {\n const [affiliates, setAffiliates] = useState<AffiliateWithOffers[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n async function load() {\n try {\n setIsLoading(true)\n setError(null)\n const data = await fetchAffiliates()\n setAffiliates(data)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load affiliates')\n } finally {\n setIsLoading(false)\n }\n }\n \n load()\n }, [])\n\n return {\n affiliates,\n isLoading,\n error,\n getTrackingUrl,\n }\n}\n","/**\n * @sonordev/site-kit/affiliates - AffiliatesWidget Component\n * \n * Unstyled, headless component for displaying affiliates.\n * Client sites can wrap this or use it directly with their own styling.\n */\n\n'use client'\n\nimport React from 'react'\nimport { useAffiliates } from './useAffiliates'\nimport type { AffiliateWithOffers, AffiliateOffer } from './types'\n\n// ============================================\n// Affiliate Card (Unstyled)\n// ============================================\n\nexport interface AffiliateCardProps {\n affiliate: AffiliateWithOffers\n className?: string\n /** Optional custom render for the logo */\n renderLogo?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Show offers as links below the card */\n showOffers?: boolean\n}\n\n/**\n * Single affiliate card - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * <AffiliateCard \n * affiliate={affiliate}\n * className=\"p-4 bg-white rounded-lg shadow\"\n * showOffers\n * />\n * ```\n */\nexport function AffiliateCard({\n affiliate,\n className = '',\n renderLogo,\n showOffers = false,\n}: AffiliateCardProps) {\n const { getTrackingUrl } = useAffiliates()\n \n const defaultLogo = (\n <div data-affiliate-logo className=\"affiliate-logo\">\n {affiliate.logo_url ? (\n <img \n src={affiliate.logo_url} \n alt={affiliate.name}\n loading=\"lazy\"\n />\n ) : (\n <span>{affiliate.name.charAt(0)}</span>\n )}\n </div>\n )\n\n return (\n <div className={className} data-affiliate-card data-affiliate-id={affiliate.id}>\n {/* Logo */}\n {renderLogo ? renderLogo(affiliate) : defaultLogo}\n \n {/* Name */}\n <div data-affiliate-name className=\"affiliate-name\">\n {affiliate.name}\n </div>\n \n {/* Website link */}\n {affiliate.website_url && (\n <a \n href={affiliate.website_url}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-website\n className=\"affiliate-website\"\n >\n Visit Website\n </a>\n )}\n \n {/* Offers */}\n {showOffers && affiliate.offers && affiliate.offers.length > 0 && (\n <div data-affiliate-offers className=\"affiliate-offers\">\n {affiliate.offers.map(offer => (\n <a\n key={offer.id}\n href={getTrackingUrl(affiliate.id, offer.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-offer\n data-offer-id={offer.id}\n className=\"affiliate-offer\"\n >\n {offer.name}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ============================================\n// Affiliates Grid (Unstyled)\n// ============================================\n\nexport interface AffiliatesWidgetProps {\n className?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n /** Custom empty state component */\n emptyComponent?: React.ReactNode\n /** Custom error component */\n errorComponent?: React.ReactNode\n /** Show offers on each card */\n showOffers?: boolean\n /** Custom render function for each affiliate */\n renderAffiliate?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Maximum number to display */\n limit?: number\n}\n\n/**\n * Display a grid of affiliates - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * // Basic usage\n * <AffiliatesWidget className=\"grid grid-cols-3 gap-4\" />\n * \n * // With custom rendering\n * <AffiliatesWidget\n * renderAffiliate={(affiliate) => (\n * <MyCustomCard key={affiliate.id} data={affiliate} />\n * )}\n * />\n * ```\n */\nexport function AffiliatesWidget({\n className = '',\n loadingComponent,\n emptyComponent,\n errorComponent,\n showOffers = false,\n renderAffiliate,\n limit,\n}: AffiliatesWidgetProps) {\n const { affiliates, isLoading, error, getTrackingUrl } = useAffiliates()\n \n if (isLoading) {\n return loadingComponent || <div data-affiliates-loading>Loading affiliates...</div>\n }\n \n if (error) {\n return errorComponent || <div data-affiliates-error>{error}</div>\n }\n \n const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates\n \n if (displayAffiliates.length === 0) {\n return emptyComponent || null\n }\n \n return (\n <div className={className} data-affiliates-widget>\n {displayAffiliates.map(affiliate => \n renderAffiliate \n ? renderAffiliate(affiliate)\n : <AffiliateCard \n key={affiliate.id} \n affiliate={affiliate} \n showOffers={showOffers}\n />\n )}\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/affiliates/api.ts","../src/affiliates/useAffiliates.ts","../src/affiliates/AffiliatesWidget.tsx"],"names":["sonorFetch","useState","useEffect","getTrackingUrl","jsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @sonordev/site-kit/affiliates - Affiliates API\n * \n * API functions for fetching affiliate data for client sites.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport type { Affiliate, AffiliateWithOffers, FetchAffiliatesOptions } from './types'\n\n// ============================================\n// API Config Helpers\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : ''\n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('[Affiliates] No API key configured')\n return null\n }\n \n try {\n // Route through sonorFetch (the canonical transport) — NOT bare fetch — so a\n // stale build-time seed token is transparently refreshed and a 401 triggers\n // one refresh+retry. The credential goes via options.apiKey, never a header:\n // sonorFetch injects the freshest token as x-api-key; a hand-set header would\n // pin the stale seed and 401.\n const response = await sonorFetch(\n `${apiUrl}${endpoint}`,\n { method: 'GET' },\n { apiKey, retries: 0 },\n )\n\n if (!response.ok) {\n console.error(`[Affiliates] API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('[Affiliates] Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Fetch Affiliates\n// ============================================\n\n/**\n * Fetch all active affiliates for the project\n * \n * @example\n * ```ts\n * const affiliates = await fetchAffiliates()\n * ```\n */\nexport async function fetchAffiliates(\n options: FetchAffiliatesOptions = {}\n): Promise<AffiliateWithOffers[]> {\n const result = await apiGet<{ affiliates: AffiliateWithOffers[] }>(\n '/api/public/affiliates'\n )\n \n return result?.affiliates || []\n}\n\n/**\n * Build a tracking URL for an affiliate offer\n * When clicked, this redirects through our tracking endpoint and then to the destination\n * \n * @example\n * ```ts\n * const trackingUrl = getTrackingUrl(affiliate.id, offer.id)\n * // Returns: https://api.sonor.io/a/{affiliateId}/{offerId}\n * ```\n */\nexport function getTrackingUrl(affiliateId: string, offerId: string): string {\n const { apiUrl } = getApiConfig()\n return `${apiUrl}/a/${affiliateId}/${offerId}`\n}\n","/**\n * @sonordev/site-kit/affiliates - useAffiliates Hook\n * \n * React hook for fetching and displaying affiliates on client sites.\n */\n\n'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { AffiliateWithOffers } from './types'\nimport { fetchAffiliates, getTrackingUrl } from './api'\n\nexport interface UseAffiliatesResult {\n affiliates: AffiliateWithOffers[]\n isLoading: boolean\n error: string | null\n getTrackingUrl: (affiliateId: string, offerId: string) => string\n}\n\n/**\n * Hook to fetch affiliates for display on client sites\n * \n * @example\n * ```tsx\n * function AffiliatesSection() {\n * const { affiliates, isLoading } = useAffiliates()\n * \n * if (isLoading) return <div>Loading...</div>\n * \n * return (\n * <div className=\"grid grid-cols-3 gap-4\">\n * {affiliates.map(affiliate => (\n * <AffiliateCard key={affiliate.id} affiliate={affiliate} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function useAffiliates(): UseAffiliatesResult {\n const [affiliates, setAffiliates] = useState<AffiliateWithOffers[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n async function load() {\n try {\n setIsLoading(true)\n setError(null)\n const data = await fetchAffiliates()\n setAffiliates(data)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load affiliates')\n } finally {\n setIsLoading(false)\n }\n }\n \n load()\n }, [])\n\n return {\n affiliates,\n isLoading,\n error,\n getTrackingUrl,\n }\n}\n","/**\n * @sonordev/site-kit/affiliates - AffiliatesWidget Component\n * \n * Unstyled, headless component for displaying affiliates.\n * Client sites can wrap this or use it directly with their own styling.\n */\n\n'use client'\n\nimport React from 'react'\nimport { useAffiliates } from './useAffiliates'\nimport type { AffiliateWithOffers, AffiliateOffer } from './types'\n\n// ============================================\n// Affiliate Card (Unstyled)\n// ============================================\n\nexport interface AffiliateCardProps {\n affiliate: AffiliateWithOffers\n className?: string\n /** Optional custom render for the logo */\n renderLogo?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Show offers as links below the card */\n showOffers?: boolean\n}\n\n/**\n * Single affiliate card - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * <AffiliateCard \n * affiliate={affiliate}\n * className=\"p-4 bg-white rounded-lg shadow\"\n * showOffers\n * />\n * ```\n */\nexport function AffiliateCard({\n affiliate,\n className = '',\n renderLogo,\n showOffers = false,\n}: AffiliateCardProps) {\n const { getTrackingUrl } = useAffiliates()\n \n const defaultLogo = (\n <div data-affiliate-logo className=\"affiliate-logo\">\n {affiliate.logo_url ? (\n <img \n src={affiliate.logo_url} \n alt={affiliate.name}\n loading=\"lazy\"\n />\n ) : (\n <span>{affiliate.name.charAt(0)}</span>\n )}\n </div>\n )\n\n return (\n <div className={className} data-affiliate-card data-affiliate-id={affiliate.id}>\n {/* Logo */}\n {renderLogo ? renderLogo(affiliate) : defaultLogo}\n \n {/* Name */}\n <div data-affiliate-name className=\"affiliate-name\">\n {affiliate.name}\n </div>\n \n {/* Website link */}\n {affiliate.website_url && (\n <a \n href={affiliate.website_url}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-website\n className=\"affiliate-website\"\n >\n Visit Website\n </a>\n )}\n \n {/* Offers */}\n {showOffers && affiliate.offers && affiliate.offers.length > 0 && (\n <div data-affiliate-offers className=\"affiliate-offers\">\n {affiliate.offers.map(offer => (\n <a\n key={offer.id}\n href={getTrackingUrl(affiliate.id, offer.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-offer\n data-offer-id={offer.id}\n className=\"affiliate-offer\"\n >\n {offer.name}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ============================================\n// Affiliates Grid (Unstyled)\n// ============================================\n\nexport interface AffiliatesWidgetProps {\n className?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n /** Custom empty state component */\n emptyComponent?: React.ReactNode\n /** Custom error component */\n errorComponent?: React.ReactNode\n /** Show offers on each card */\n showOffers?: boolean\n /** Custom render function for each affiliate */\n renderAffiliate?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Maximum number to display */\n limit?: number\n}\n\n/**\n * Display a grid of affiliates - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * // Basic usage\n * <AffiliatesWidget className=\"grid grid-cols-3 gap-4\" />\n * \n * // With custom rendering\n * <AffiliatesWidget\n * renderAffiliate={(affiliate) => (\n * <MyCustomCard key={affiliate.id} data={affiliate} />\n * )}\n * />\n * ```\n */\nexport function AffiliatesWidget({\n className = '',\n loadingComponent,\n emptyComponent,\n errorComponent,\n showOffers = false,\n renderAffiliate,\n limit,\n}: AffiliatesWidgetProps) {\n const { affiliates, isLoading, error, getTrackingUrl } = useAffiliates()\n \n if (isLoading) {\n return loadingComponent || <div data-affiliates-loading>Loading affiliates...</div>\n }\n \n if (error) {\n return errorComponent || <div data-affiliates-error>{error}</div>\n }\n \n const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates\n \n if (displayAffiliates.length === 0) {\n return emptyComponent || null\n }\n \n return (\n <div className={className} data-affiliates-widget>\n {displayAffiliates.map(affiliate => \n renderAffiliate \n ? renderAffiliate(affiliate)\n : <AffiliateCard \n key={affiliate.id} \n affiliate={affiliate} \n showOffers={showOffers}\n />\n )}\n </div>\n )\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,19 +1,19 @@
1
- export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate as formatBookingDate, formatTime as formatBookingTime, formatDuration, releaseSlotHold } from './chunk-FMZOZQBV.mjs';
1
+ export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate as formatBookingDate, formatTime as formatBookingTime, formatDuration, releaseSlotHold } from './chunk-ILLOVVVP.mjs';
2
2
  export { clearRedirectCache, fetchRedirectRules, generateNextRedirects, handleManagedRedirects } from './chunk-7LAOWIWE.mjs';
3
3
  import './chunk-B22WSN4L.mjs';
4
- export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from './chunk-RFIWVH3D.mjs';
4
+ export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from './chunk-6BDXN4X3.mjs';
5
5
  import './chunk-CU6OGBKK.mjs';
6
6
  export { TestimonialSection } from './chunk-VIGRGMWR.mjs';
7
7
  export { fetchReviewStats, fetchReviews } from './chunk-MU7DTEUF.mjs';
8
- export { ExperimentConversion, SignalExperiment, useExperimentVariant } from './chunk-6HPNFWSC.mjs';
9
- export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome } from './chunk-57QV6NIY.mjs';
10
- export { CalendarView, CheckoutForm, EventCalendar, EventCheckout, EventEmbed, EventModal, EventTile, OfferingCard, OfferingList, ProductEmbed, RegistrationForm, UpcomingEvents, createCheckoutSession, fetchNextEvent, fetchOffering, fetchOfferings, fetchProducts, fetchServices, fetchUpcomingEvents, formatDate, formatDateTime, formatPrice, getOfferingUrl, registerForEvent, useEventModal } from './chunk-EIWRPGOK.mjs';
11
- import './chunk-45QHDA7Q.mjs';
12
- import './chunk-T2DEEKVQ.mjs';
8
+ export { ExperimentConversion, SignalExperiment, useExperimentVariant } from './chunk-5KVT66R6.mjs';
9
+ export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome } from './chunk-ZCZEKWFW.mjs';
10
+ export { CalendarView, CheckoutForm, EventCalendar, EventCheckout, EventEmbed, EventModal, EventTile, OfferingCard, OfferingList, ProductEmbed, RegistrationForm, UpcomingEvents, createCheckoutSession, fetchNextEvent, fetchOffering, fetchOfferings, fetchProducts, fetchServices, fetchUpcomingEvents, formatDate, formatDateTime, formatPrice, getOfferingUrl, registerForEvent, useEventModal } from './chunk-PLQ4CUNI.mjs';
11
+ import './chunk-PUGRSMAV.mjs';
12
+ import './chunk-NNPF4KRZ.mjs';
13
13
  import './chunk-3DPXOZAU.mjs';
14
14
  import './chunk-EE6SFAZP.mjs';
15
- import './chunk-LZSCCJ4O.mjs';
16
- import './chunk-SN2O72UF.mjs';
15
+ import { sonorFetch } from './chunk-FO6Y27AH.mjs';
16
+ import './chunk-S4FJIG6Y.mjs';
17
17
  import './chunk-4XPGGLVP.mjs';
18
18
  import { useState, useEffect } from 'react';
19
19
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -31,12 +31,11 @@ async function apiGet(endpoint) {
31
31
  return null;
32
32
  }
33
33
  try {
34
- const response = await fetch(`${apiUrl}${endpoint}`, {
35
- method: "GET",
36
- headers: {
37
- "x-api-key": apiKey
38
- }
39
- });
34
+ const response = await sonorFetch(
35
+ `${apiUrl}${endpoint}`,
36
+ { method: "GET" },
37
+ { apiKey, retries: 0 }
38
+ );
40
39
  if (!response.ok) {
41
40
  console.error(`[Affiliates] API error: ${response.statusText}`);
42
41
  return null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/affiliates/api.ts","../src/affiliates/useAffiliates.ts","../src/affiliates/AffiliatesWidget.tsx"],"names":["getTrackingUrl"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/affiliates - Affiliates API\n * \n * API functions for fetching affiliate data for client sites.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\nimport type { Affiliate, AffiliateWithOffers, FetchAffiliatesOptions } from './types'\n\n// ============================================\n// API Config Helpers\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : ''\n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('[Affiliates] No API key configured')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'x-api-key': apiKey,\n },\n })\n \n if (!response.ok) {\n console.error(`[Affiliates] API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('[Affiliates] Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Fetch Affiliates\n// ============================================\n\n/**\n * Fetch all active affiliates for the project\n * \n * @example\n * ```ts\n * const affiliates = await fetchAffiliates()\n * ```\n */\nexport async function fetchAffiliates(\n options: FetchAffiliatesOptions = {}\n): Promise<AffiliateWithOffers[]> {\n const result = await apiGet<{ affiliates: AffiliateWithOffers[] }>(\n '/api/public/affiliates'\n )\n \n return result?.affiliates || []\n}\n\n/**\n * Build a tracking URL for an affiliate offer\n * When clicked, this redirects through our tracking endpoint and then to the destination\n * \n * @example\n * ```ts\n * const trackingUrl = getTrackingUrl(affiliate.id, offer.id)\n * // Returns: https://api.sonor.io/a/{affiliateId}/{offerId}\n * ```\n */\nexport function getTrackingUrl(affiliateId: string, offerId: string): string {\n const { apiUrl } = getApiConfig()\n return `${apiUrl}/a/${affiliateId}/${offerId}`\n}\n","/**\n * @sonordev/site-kit/affiliates - useAffiliates Hook\n * \n * React hook for fetching and displaying affiliates on client sites.\n */\n\n'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { AffiliateWithOffers } from './types'\nimport { fetchAffiliates, getTrackingUrl } from './api'\n\nexport interface UseAffiliatesResult {\n affiliates: AffiliateWithOffers[]\n isLoading: boolean\n error: string | null\n getTrackingUrl: (affiliateId: string, offerId: string) => string\n}\n\n/**\n * Hook to fetch affiliates for display on client sites\n * \n * @example\n * ```tsx\n * function AffiliatesSection() {\n * const { affiliates, isLoading } = useAffiliates()\n * \n * if (isLoading) return <div>Loading...</div>\n * \n * return (\n * <div className=\"grid grid-cols-3 gap-4\">\n * {affiliates.map(affiliate => (\n * <AffiliateCard key={affiliate.id} affiliate={affiliate} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function useAffiliates(): UseAffiliatesResult {\n const [affiliates, setAffiliates] = useState<AffiliateWithOffers[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n async function load() {\n try {\n setIsLoading(true)\n setError(null)\n const data = await fetchAffiliates()\n setAffiliates(data)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load affiliates')\n } finally {\n setIsLoading(false)\n }\n }\n \n load()\n }, [])\n\n return {\n affiliates,\n isLoading,\n error,\n getTrackingUrl,\n }\n}\n","/**\n * @sonordev/site-kit/affiliates - AffiliatesWidget Component\n * \n * Unstyled, headless component for displaying affiliates.\n * Client sites can wrap this or use it directly with their own styling.\n */\n\n'use client'\n\nimport React from 'react'\nimport { useAffiliates } from './useAffiliates'\nimport type { AffiliateWithOffers, AffiliateOffer } from './types'\n\n// ============================================\n// Affiliate Card (Unstyled)\n// ============================================\n\nexport interface AffiliateCardProps {\n affiliate: AffiliateWithOffers\n className?: string\n /** Optional custom render for the logo */\n renderLogo?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Show offers as links below the card */\n showOffers?: boolean\n}\n\n/**\n * Single affiliate card - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * <AffiliateCard \n * affiliate={affiliate}\n * className=\"p-4 bg-white rounded-lg shadow\"\n * showOffers\n * />\n * ```\n */\nexport function AffiliateCard({\n affiliate,\n className = '',\n renderLogo,\n showOffers = false,\n}: AffiliateCardProps) {\n const { getTrackingUrl } = useAffiliates()\n \n const defaultLogo = (\n <div data-affiliate-logo className=\"affiliate-logo\">\n {affiliate.logo_url ? (\n <img \n src={affiliate.logo_url} \n alt={affiliate.name}\n loading=\"lazy\"\n />\n ) : (\n <span>{affiliate.name.charAt(0)}</span>\n )}\n </div>\n )\n\n return (\n <div className={className} data-affiliate-card data-affiliate-id={affiliate.id}>\n {/* Logo */}\n {renderLogo ? renderLogo(affiliate) : defaultLogo}\n \n {/* Name */}\n <div data-affiliate-name className=\"affiliate-name\">\n {affiliate.name}\n </div>\n \n {/* Website link */}\n {affiliate.website_url && (\n <a \n href={affiliate.website_url}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-website\n className=\"affiliate-website\"\n >\n Visit Website\n </a>\n )}\n \n {/* Offers */}\n {showOffers && affiliate.offers && affiliate.offers.length > 0 && (\n <div data-affiliate-offers className=\"affiliate-offers\">\n {affiliate.offers.map(offer => (\n <a\n key={offer.id}\n href={getTrackingUrl(affiliate.id, offer.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-offer\n data-offer-id={offer.id}\n className=\"affiliate-offer\"\n >\n {offer.name}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ============================================\n// Affiliates Grid (Unstyled)\n// ============================================\n\nexport interface AffiliatesWidgetProps {\n className?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n /** Custom empty state component */\n emptyComponent?: React.ReactNode\n /** Custom error component */\n errorComponent?: React.ReactNode\n /** Show offers on each card */\n showOffers?: boolean\n /** Custom render function for each affiliate */\n renderAffiliate?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Maximum number to display */\n limit?: number\n}\n\n/**\n * Display a grid of affiliates - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * // Basic usage\n * <AffiliatesWidget className=\"grid grid-cols-3 gap-4\" />\n * \n * // With custom rendering\n * <AffiliatesWidget\n * renderAffiliate={(affiliate) => (\n * <MyCustomCard key={affiliate.id} data={affiliate} />\n * )}\n * />\n * ```\n */\nexport function AffiliatesWidget({\n className = '',\n loadingComponent,\n emptyComponent,\n errorComponent,\n showOffers = false,\n renderAffiliate,\n limit,\n}: AffiliatesWidgetProps) {\n const { affiliates, isLoading, error, getTrackingUrl } = useAffiliates()\n \n if (isLoading) {\n return loadingComponent || <div data-affiliates-loading>Loading affiliates...</div>\n }\n \n if (error) {\n return errorComponent || <div data-affiliates-error>{error}</div>\n }\n \n const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates\n \n if (displayAffiliates.length === 0) {\n return emptyComponent || null\n }\n \n return (\n <div className={className} data-affiliates-widget>\n {displayAffiliates.map(affiliate => \n renderAffiliate \n ? renderAffiliate(affiliate)\n : <AffiliateCard \n key={affiliate.id} \n affiliate={affiliate} \n showOffers={showOffers}\n />\n )}\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/affiliates/api.ts","../src/affiliates/useAffiliates.ts","../src/affiliates/AffiliatesWidget.tsx"],"names":["getTrackingUrl"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/affiliates - Affiliates API\n * \n * API functions for fetching affiliate data for client sites.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport type { Affiliate, AffiliateWithOffers, FetchAffiliatesOptions } from './types'\n\n// ============================================\n// API Config Helpers\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : ''\n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('[Affiliates] No API key configured')\n return null\n }\n \n try {\n // Route through sonorFetch (the canonical transport) — NOT bare fetch — so a\n // stale build-time seed token is transparently refreshed and a 401 triggers\n // one refresh+retry. The credential goes via options.apiKey, never a header:\n // sonorFetch injects the freshest token as x-api-key; a hand-set header would\n // pin the stale seed and 401.\n const response = await sonorFetch(\n `${apiUrl}${endpoint}`,\n { method: 'GET' },\n { apiKey, retries: 0 },\n )\n\n if (!response.ok) {\n console.error(`[Affiliates] API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('[Affiliates] Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Fetch Affiliates\n// ============================================\n\n/**\n * Fetch all active affiliates for the project\n * \n * @example\n * ```ts\n * const affiliates = await fetchAffiliates()\n * ```\n */\nexport async function fetchAffiliates(\n options: FetchAffiliatesOptions = {}\n): Promise<AffiliateWithOffers[]> {\n const result = await apiGet<{ affiliates: AffiliateWithOffers[] }>(\n '/api/public/affiliates'\n )\n \n return result?.affiliates || []\n}\n\n/**\n * Build a tracking URL for an affiliate offer\n * When clicked, this redirects through our tracking endpoint and then to the destination\n * \n * @example\n * ```ts\n * const trackingUrl = getTrackingUrl(affiliate.id, offer.id)\n * // Returns: https://api.sonor.io/a/{affiliateId}/{offerId}\n * ```\n */\nexport function getTrackingUrl(affiliateId: string, offerId: string): string {\n const { apiUrl } = getApiConfig()\n return `${apiUrl}/a/${affiliateId}/${offerId}`\n}\n","/**\n * @sonordev/site-kit/affiliates - useAffiliates Hook\n * \n * React hook for fetching and displaying affiliates on client sites.\n */\n\n'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { AffiliateWithOffers } from './types'\nimport { fetchAffiliates, getTrackingUrl } from './api'\n\nexport interface UseAffiliatesResult {\n affiliates: AffiliateWithOffers[]\n isLoading: boolean\n error: string | null\n getTrackingUrl: (affiliateId: string, offerId: string) => string\n}\n\n/**\n * Hook to fetch affiliates for display on client sites\n * \n * @example\n * ```tsx\n * function AffiliatesSection() {\n * const { affiliates, isLoading } = useAffiliates()\n * \n * if (isLoading) return <div>Loading...</div>\n * \n * return (\n * <div className=\"grid grid-cols-3 gap-4\">\n * {affiliates.map(affiliate => (\n * <AffiliateCard key={affiliate.id} affiliate={affiliate} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function useAffiliates(): UseAffiliatesResult {\n const [affiliates, setAffiliates] = useState<AffiliateWithOffers[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n async function load() {\n try {\n setIsLoading(true)\n setError(null)\n const data = await fetchAffiliates()\n setAffiliates(data)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load affiliates')\n } finally {\n setIsLoading(false)\n }\n }\n \n load()\n }, [])\n\n return {\n affiliates,\n isLoading,\n error,\n getTrackingUrl,\n }\n}\n","/**\n * @sonordev/site-kit/affiliates - AffiliatesWidget Component\n * \n * Unstyled, headless component for displaying affiliates.\n * Client sites can wrap this or use it directly with their own styling.\n */\n\n'use client'\n\nimport React from 'react'\nimport { useAffiliates } from './useAffiliates'\nimport type { AffiliateWithOffers, AffiliateOffer } from './types'\n\n// ============================================\n// Affiliate Card (Unstyled)\n// ============================================\n\nexport interface AffiliateCardProps {\n affiliate: AffiliateWithOffers\n className?: string\n /** Optional custom render for the logo */\n renderLogo?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Show offers as links below the card */\n showOffers?: boolean\n}\n\n/**\n * Single affiliate card - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * <AffiliateCard \n * affiliate={affiliate}\n * className=\"p-4 bg-white rounded-lg shadow\"\n * showOffers\n * />\n * ```\n */\nexport function AffiliateCard({\n affiliate,\n className = '',\n renderLogo,\n showOffers = false,\n}: AffiliateCardProps) {\n const { getTrackingUrl } = useAffiliates()\n \n const defaultLogo = (\n <div data-affiliate-logo className=\"affiliate-logo\">\n {affiliate.logo_url ? (\n <img \n src={affiliate.logo_url} \n alt={affiliate.name}\n loading=\"lazy\"\n />\n ) : (\n <span>{affiliate.name.charAt(0)}</span>\n )}\n </div>\n )\n\n return (\n <div className={className} data-affiliate-card data-affiliate-id={affiliate.id}>\n {/* Logo */}\n {renderLogo ? renderLogo(affiliate) : defaultLogo}\n \n {/* Name */}\n <div data-affiliate-name className=\"affiliate-name\">\n {affiliate.name}\n </div>\n \n {/* Website link */}\n {affiliate.website_url && (\n <a \n href={affiliate.website_url}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-website\n className=\"affiliate-website\"\n >\n Visit Website\n </a>\n )}\n \n {/* Offers */}\n {showOffers && affiliate.offers && affiliate.offers.length > 0 && (\n <div data-affiliate-offers className=\"affiliate-offers\">\n {affiliate.offers.map(offer => (\n <a\n key={offer.id}\n href={getTrackingUrl(affiliate.id, offer.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-offer\n data-offer-id={offer.id}\n className=\"affiliate-offer\"\n >\n {offer.name}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ============================================\n// Affiliates Grid (Unstyled)\n// ============================================\n\nexport interface AffiliatesWidgetProps {\n className?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n /** Custom empty state component */\n emptyComponent?: React.ReactNode\n /** Custom error component */\n errorComponent?: React.ReactNode\n /** Show offers on each card */\n showOffers?: boolean\n /** Custom render function for each affiliate */\n renderAffiliate?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Maximum number to display */\n limit?: number\n}\n\n/**\n * Display a grid of affiliates - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * // Basic usage\n * <AffiliatesWidget className=\"grid grid-cols-3 gap-4\" />\n * \n * // With custom rendering\n * <AffiliatesWidget\n * renderAffiliate={(affiliate) => (\n * <MyCustomCard key={affiliate.id} data={affiliate} />\n * )}\n * />\n * ```\n */\nexport function AffiliatesWidget({\n className = '',\n loadingComponent,\n emptyComponent,\n errorComponent,\n showOffers = false,\n renderAffiliate,\n limit,\n}: AffiliatesWidgetProps) {\n const { affiliates, isLoading, error, getTrackingUrl } = useAffiliates()\n \n if (isLoading) {\n return loadingComponent || <div data-affiliates-loading>Loading affiliates...</div>\n }\n \n if (error) {\n return errorComponent || <div data-affiliates-error>{error}</div>\n }\n \n const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates\n \n if (displayAffiliates.length === 0) {\n return emptyComponent || null\n }\n \n return (\n <div className={className} data-affiliates-widget>\n {displayAffiliates.map(affiliate => \n renderAffiliate \n ? renderAffiliate(affiliate)\n : <AffiliateCard \n key={affiliate.id} \n affiliate={affiliate} \n showOffers={showOffers}\n />\n )}\n </div>\n )\n}\n"]}
@@ -1,22 +1,22 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkS3YQGTBF_js = require('../chunk-S3YQGTBF.js');
5
- require('../chunk-5OWZUNNE.js');
4
+ var chunkBOTWTNHW_js = require('../chunk-BOTWTNHW.js');
5
+ require('../chunk-FX3VR4BF.js');
6
6
  require('../chunk-HGNSJXWT.js');
7
7
  require('../chunk-Q2NBD54V.js');
8
8
  require('../chunk-WZHWWOUC.js');
9
- require('../chunk-GCDVKOSM.js');
9
+ require('../chunk-6UK5JIKE.js');
10
10
  require('../chunk-3BNFUMLL.js');
11
- require('../chunk-EAASMIWX.js');
12
- require('../chunk-WRZQS7O4.js');
11
+ require('../chunk-M2EGCGIT.js');
12
+ require('../chunk-EOENN46G.js');
13
13
  require('../chunk-ZSMWDLMK.js');
14
14
 
15
15
 
16
16
 
17
17
  Object.defineProperty(exports, "SiteKitClientProviders", {
18
18
  enumerable: true,
19
- get: function () { return chunkS3YQGTBF_js.SiteKitClientProviders; }
19
+ get: function () { return chunkBOTWTNHW_js.SiteKitClientProviders; }
20
20
  });
21
21
  //# sourceMappingURL=client.js.map
22
22
  //# sourceMappingURL=client.js.map
@@ -1,13 +1,13 @@
1
1
  'use client';
2
- export { SiteKitClientProviders } from '../chunk-GN62H6EG.mjs';
3
- import '../chunk-NDHFU4HV.mjs';
2
+ export { SiteKitClientProviders } from '../chunk-AXFM4MFK.mjs';
3
+ import '../chunk-X72PFC4X.mjs';
4
4
  import '../chunk-ZVBLXXNJ.mjs';
5
5
  import '../chunk-ZPLN537Q.mjs';
6
6
  import '../chunk-X4OPM3SK.mjs';
7
- import '../chunk-57QV6NIY.mjs';
7
+ import '../chunk-ZCZEKWFW.mjs';
8
8
  import '../chunk-EE6SFAZP.mjs';
9
- import '../chunk-LZSCCJ4O.mjs';
10
- import '../chunk-SN2O72UF.mjs';
9
+ import '../chunk-FO6Y27AH.mjs';
10
+ import '../chunk-S4FJIG6Y.mjs';
11
11
  import '../chunk-4XPGGLVP.mjs';
12
12
  //# sourceMappingURL=client.mjs.map
13
13
  //# sourceMappingURL=client.mjs.map