@riverbankcms/sdk 0.90.1 → 0.92.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 (113) hide show
  1. package/dist/{PreviewEditorSidebar-FNFRVSIM.mjs → PreviewEditorSidebar-3CI5MKV3.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-3WXJFQXG.mjs → PreviewEditorUI-DKEP636I.mjs} +3 -3
  3. package/dist/SdkPreviewModeRuntime-BRGRDQFH.mjs +8 -0
  4. package/dist/_dts/api/src/bookingConfig.d.ts +13 -1
  5. package/dist/_dts/api/src/bookingOperations.d.ts +1 -0
  6. package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +6 -6
  7. package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +4 -4
  8. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +6 -0
  9. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +32 -0
  10. package/dist/_dts/blocks/src/system/blocks/courses/shared/pricing.d.ts +12 -1
  11. package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +12 -0
  12. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +4 -1
  13. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +44 -0
  14. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +24 -0
  15. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +8 -1
  16. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -1
  17. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -0
  18. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
  19. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +40 -0
  20. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.reserved-fields.d.ts +1 -1
  21. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +29 -0
  22. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
  23. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/components.d.ts +6 -0
  24. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +8 -0
  25. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +8 -0
  26. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +1 -0
  27. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +1 -1
  28. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +1 -0
  29. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +9 -0
  30. package/dist/_dts/content-model/src/entry-slots/types.d.ts +110 -2
  31. package/dist/_dts/core/src/branded.d.ts +3 -0
  32. package/dist/_dts/core/src/event-pricing.d.ts +18 -1
  33. package/dist/_dts/core/src/money-input.d.ts +34 -4
  34. package/dist/_dts/core/src/string.d.ts +12 -0
  35. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +70 -0
  36. package/dist/_dts/media-core/src/fileAssetCompatibility.d.ts +1 -1
  37. package/dist/_dts/media-core/src/filePersistence.d.ts +5 -1
  38. package/dist/_dts/media-core/src/fileStorage.d.ts +1 -0
  39. package/dist/_dts/media-core/src/videoPrep.d.ts +15 -6
  40. package/dist/_dts/media-core/src/videoSlotPolicy.d.ts +5 -5
  41. package/dist/_dts/sdk/src/cli/commands/push/execute/diff.d.ts +2 -0
  42. package/dist/_dts/sdk/src/cli/commands/push/execute/localMediaReporting.d.ts +23 -0
  43. package/dist/_dts/sdk/src/cli/commands/push/scopes/commandBackedDatedOfferingScope.d.ts +54 -0
  44. package/dist/_dts/sdk/src/cli/commands/push/scopes/mediaPrep.d.ts +7 -2
  45. package/dist/_dts/sdk/src/cli/commands/push/scopes/types.d.ts +6 -0
  46. package/dist/_dts/sdk/src/cli/media/local-sync.d.ts +35 -0
  47. package/dist/_dts/sdk/src/cli/sync/validation.d.ts +2 -2
  48. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +23 -1
  49. package/dist/_dts/sdk/src/version.d.ts +1 -1
  50. package/dist/{chunk-SYYJZPKU.mjs → chunk-6D7PLF4M.mjs} +2 -2
  51. package/dist/{chunk-CR2VX432.mjs → chunk-I6EOKV6B.mjs} +568 -76
  52. package/dist/{chunk-FA6LVZ7C.mjs → chunk-LERKJM3E.mjs} +7 -7
  53. package/dist/{chunk-UG7I7S7W.mjs → chunk-U5YM4AWE.mjs} +1 -1
  54. package/dist/{chunk-H6TT5ZXI.mjs → chunk-UOMTCHZD.mjs} +1 -1
  55. package/dist/{chunk-BOQXMCSP.mjs → chunk-ZA2S7H34.mjs} +3 -3
  56. package/dist/cli/index.mjs +755 -414
  57. package/dist/cli/init-docs/content/workflow-add-block.md +48 -0
  58. package/dist/cli/init-docs/content/workflow-custom-block.md +10 -0
  59. package/dist/client/{accordion-4K7VGZ3I.mjs → accordion-BUDH2G3S.mjs} +2 -2
  60. package/dist/client/{bookingForm-3QXA3CIS.mjs → bookingForm-NQMCELVB.mjs} +90 -15
  61. package/dist/client/bookings.mjs +259 -32
  62. package/dist/client/{carousel-BEJKNGQ7.mjs → carousel-ONCEW6IJ.mjs} +3 -3
  63. package/dist/client/{cart-44BBM6XG.mjs → cart-V2TCK2GI.mjs} +7 -7
  64. package/dist/client/{checkout-THMHEYKF.mjs → checkout-ZI7SWNCS.mjs} +7 -7
  65. package/dist/client/{chunk-PEDNDLPB.mjs → chunk-AUMRQ242.mjs} +52 -5
  66. package/dist/client/{chunk-EJBHK74Y.mjs → chunk-B5UC2D6X.mjs} +7 -6
  67. package/dist/client/{chunk-DQIRKNZE.mjs → chunk-ERQDHUS2.mjs} +1 -1
  68. package/dist/client/{chunk-3H5CLFKT.mjs → chunk-GH6IIOOE.mjs} +39 -10
  69. package/dist/client/{chunk-ZIAF2DA4.mjs → chunk-HQWIJLYN.mjs} +1 -1
  70. package/dist/client/{chunk-4COPESPO.mjs → chunk-JXY6NHG6.mjs} +6 -6
  71. package/dist/client/{chunk-JV7ZNAOU.mjs → chunk-KXYEKEV6.mjs} +155 -17
  72. package/dist/client/{chunk-HIHOQGIP.mjs → chunk-LJCX6V7Q.mjs} +9 -9
  73. package/dist/client/{chunk-5AJIMWKS.mjs → chunk-N2WJPTF7.mjs} +3 -3
  74. package/dist/client/{chunk-KNTLBQ3N.mjs → chunk-QQNVQ62W.mjs} +1 -1
  75. package/dist/client/{chunk-B4H6QMPY.mjs → chunk-R3CZQLXF.mjs} +73 -8
  76. package/dist/client/{chunk-WHZQDPBZ.mjs → chunk-TNGL2WJF.mjs} +1 -0
  77. package/dist/client/{chunk-SLY6UDAS.mjs → chunk-ZJDBOLX7.mjs} +3 -3
  78. package/dist/client/client.mjs +548 -68
  79. package/dist/client/{courseRegistration-URX7RCCK.mjs → courseRegistration-JPWAQ6KM.mjs} +112 -12
  80. package/dist/client/{eventCalendar-GTENOQCE.mjs → eventCalendar-QDOCHBBV.mjs} +10 -10
  81. package/dist/client/{eventCombined-EZVB72MF.mjs → eventCombined-ZS2CXSIE.mjs} +10 -10
  82. package/dist/client/{eventDetails-CH4BJR5Z.mjs → eventDetails-5LOBMPLN.mjs} +10 -10
  83. package/dist/client/{eventListing-4BVOI5HS.mjs → eventListing-SBGY4I3L.mjs} +10 -10
  84. package/dist/client/{eventRegistration-37LPIKIE.mjs → eventRegistration-XGPIU3Z2.mjs} +10 -10
  85. package/dist/client/{form-FX3Y54YK.mjs → form-R7D4LZWW.mjs} +4 -4
  86. package/dist/client/{headerSection-UOZZGVYL.mjs → headerSection-RRLYUCGC.mjs} +3 -3
  87. package/dist/client/hooks.mjs +29 -9
  88. package/dist/client/{locationMap-VSIPKV35.mjs → locationMap-35ZJMRBZ.mjs} +3 -3
  89. package/dist/client/{newsletterForm-6FRJKNAF.mjs → newsletterForm-MJ2VCFUT.mjs} +4 -4
  90. package/dist/client/{productDetail-6AHMLXCO.mjs → productDetail-2O7YQNBX.mjs} +7 -7
  91. package/dist/client/{productList-M2CYIZVH.mjs → productList-FDP5BH7W.mjs} +7 -7
  92. package/dist/client/rendering/client.mjs +526 -64
  93. package/dist/client/rendering/islands.mjs +19 -19
  94. package/dist/client/rendering.mjs +547 -67
  95. package/dist/client/{shop-AUOT6GEX.mjs → shop-BGYJ3LDT.mjs} +7 -7
  96. package/dist/client/spam-protection.mjs +10 -10
  97. package/dist/preview-next/client/runtime.mjs +5 -5
  98. package/dist/{sdk-runtime-6GPJNLU6.mjs → sdk-runtime-B3TFXRXZ.mjs} +6 -6
  99. package/dist/server/components.mjs +179 -18
  100. package/dist/server/config-validation.mjs +30 -9
  101. package/dist/server/config.mjs +30 -9
  102. package/dist/server/data.mjs +29 -9
  103. package/dist/server/index.mjs +1 -1
  104. package/dist/server/navigation.mjs +2 -2
  105. package/dist/server/next.mjs +180 -19
  106. package/dist/server/page-converter.mjs +24 -7
  107. package/dist/server/prebuild.mjs +1 -1
  108. package/dist/server/rendering/server.mjs +179 -18
  109. package/dist/server/rendering.mjs +179 -18
  110. package/dist/server/routing.mjs +43 -19
  111. package/dist/server/server.mjs +30 -10
  112. package/package.json +1 -1
  113. package/dist/SdkPreviewModeRuntime-2UCIMKUB.mjs +0 -8
@@ -1,15 +1,15 @@
1
- import { mountShopBlockIsland, ShopClient } from './chunk-4COPESPO.mjs';
2
- import './chunk-DQIRKNZE.mjs';
3
- import './chunk-EJBHK74Y.mjs';
1
+ import { mountShopBlockIsland, ShopClient } from './chunk-JXY6NHG6.mjs';
2
+ import './chunk-ERQDHUS2.mjs';
3
+ import './chunk-B5UC2D6X.mjs';
4
4
  import './chunk-6N7YRNYU.mjs';
5
5
  import './chunk-L4J5Y62O.mjs';
6
- import './chunk-SLY6UDAS.mjs';
6
+ import './chunk-ZJDBOLX7.mjs';
7
7
  import './chunk-3DCJ45Z2.mjs';
8
8
  import './chunk-WBQG7VJA.mjs';
9
- import './chunk-WHZQDPBZ.mjs';
9
+ import './chunk-TNGL2WJF.mjs';
10
10
  import './chunk-N7PBWBWQ.mjs';
11
- import { defineIslandPropsDecoder } from './chunk-B4H6QMPY.mjs';
12
- import './chunk-3H5CLFKT.mjs';
11
+ import { defineIslandPropsDecoder } from './chunk-R3CZQLXF.mjs';
12
+ import './chunk-GH6IIOOE.mjs';
13
13
 
14
14
  // src/rendering/islands/enhancers/shop.tsx
15
15
  var decode = defineIslandPropsDecoder("shop");
@@ -2781,22 +2781,22 @@ function AltchaWidget({
2781
2781
  if (typeof window === "undefined") return;
2782
2782
  let widget = null;
2783
2783
  Promise.resolve().then(() => (init_altcha(), altcha_exports)).then(() => {
2784
- if (!containerRef.current) return;
2784
+ if (containerRef.current === null) return;
2785
2785
  widget = document.createElement("altcha-widget");
2786
2786
  widget.setAttribute("challengeurl", challengeUrl);
2787
- if (auto) {
2787
+ if (auto === true) {
2788
2788
  widget.setAttribute("auto", "onload");
2789
2789
  }
2790
- if (hidelogo) {
2790
+ if (hidelogo === true) {
2791
2791
  widget.setAttribute("hidelogo", "true");
2792
2792
  }
2793
2793
  widget.setAttribute("hidefooter", "true");
2794
- if (className) {
2794
+ if (className !== void 0 && className.length > 0) {
2795
2795
  widget.className = className;
2796
2796
  }
2797
2797
  widget.addEventListener("statechange", ((event) => {
2798
2798
  const { state, payload } = event.detail;
2799
- if (state === "verified" && payload) {
2799
+ if (state === "verified" && payload !== void 0 && payload.length > 0) {
2800
2800
  onSolutionChange?.(payload);
2801
2801
  } else if (state === "error" || state === "expired") {
2802
2802
  onSolutionChange?.(null);
@@ -2807,7 +2807,7 @@ function AltchaWidget({
2807
2807
  console.error("Failed to load ALTCHA widget:", err);
2808
2808
  });
2809
2809
  return () => {
2810
- if (widget && containerRef.current) {
2810
+ if (widget !== null && containerRef.current !== null) {
2811
2811
  containerRef.current.removeChild(widget);
2812
2812
  }
2813
2813
  };
@@ -2821,22 +2821,22 @@ var encoder = new TextEncoder();
2821
2821
  // ../altcha/src/index.ts
2822
2822
  function getHmacKey() {
2823
2823
  const key = process.env.ALTCHA_HMAC_KEY;
2824
- return key && key.trim().length > 0 ? key : null;
2824
+ return key !== void 0 && key.trim().length > 0 ? key : null;
2825
2825
  }
2826
2826
  function hasSpamProtection() {
2827
2827
  return getHmacKey() !== null;
2828
2828
  }
2829
2829
  function getCmsApiUrl() {
2830
2830
  const env = process.env.RIVERBANK_ENV;
2831
- if (env) {
2831
+ if (env !== void 0 && env.length > 0) {
2832
2832
  const envKey = `RIVERBANK_${env.toUpperCase()}_DASHBOARD_URL`;
2833
2833
  const dashboardUrl2 = process.env[envKey];
2834
- if (dashboardUrl2) {
2834
+ if (dashboardUrl2 !== void 0 && dashboardUrl2.length > 0) {
2835
2835
  return `${dashboardUrl2.replace(/\/$/, "")}/api`;
2836
2836
  }
2837
2837
  }
2838
2838
  const dashboardUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL;
2839
- if (dashboardUrl) {
2839
+ if (dashboardUrl !== void 0 && dashboardUrl.length > 0) {
2840
2840
  return `${dashboardUrl.replace(/\/$/, "")}/api`;
2841
2841
  }
2842
2842
  throw new Error("Dashboard URL not configured. Set NEXT_PUBLIC_DASHBOARD_URL");
@@ -1,24 +1,24 @@
1
1
  "use client";
2
- export { PreviewLayoutProvider, PreviewQueryProvider, createPreviewQueryClient, useOptionalPreviewLayout, usePreviewLayout } from '../../chunk-UG7I7S7W.mjs';
3
- import '../../chunk-BOQXMCSP.mjs';
2
+ export { PreviewLayoutProvider, PreviewQueryProvider, createPreviewQueryClient, useOptionalPreviewLayout, usePreviewLayout } from '../../chunk-U5YM4AWE.mjs';
3
+ import '../../chunk-ZA2S7H34.mjs';
4
4
  import '../../chunk-R7POPVJR.mjs';
5
5
  import React from 'react';
6
6
  import { jsx } from 'react/jsx-runtime';
7
7
 
8
8
  var LazySdkPreviewMode = React.lazy(async () => {
9
- const mod = await import('../../SdkPreviewModeRuntime-2UCIMKUB.mjs');
9
+ const mod = await import('../../SdkPreviewModeRuntime-BRGRDQFH.mjs');
10
10
  return {
11
11
  default: mod.SdkPreviewModeRuntime
12
12
  };
13
13
  });
14
14
  var LazyPreviewShell = React.lazy(async () => {
15
- const mod = await import('../../sdk-runtime-6GPJNLU6.mjs');
15
+ const mod = await import('../../sdk-runtime-B3TFXRXZ.mjs');
16
16
  return {
17
17
  default: mod.PreviewShell
18
18
  };
19
19
  });
20
20
  var LazyPreviewShellLayout = React.lazy(async () => {
21
- const mod = await import('../../sdk-runtime-6GPJNLU6.mjs');
21
+ const mod = await import('../../sdk-runtime-B3TFXRXZ.mjs');
22
22
  return {
23
23
  default: mod.PreviewShellLayout
24
24
  };
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- export { PreviewShell, PreviewShellLayout, SdkPreviewModeRuntime as SdkPreviewMode } from './chunk-FA6LVZ7C.mjs';
3
- export { PreviewLayoutProvider, PreviewQueryProvider, createPreviewQueryClient, useOptionalPreviewLayout, usePreviewLayout } from './chunk-UG7I7S7W.mjs';
4
- import './chunk-H6TT5ZXI.mjs';
5
- import './chunk-SYYJZPKU.mjs';
6
- import './chunk-CR2VX432.mjs';
7
- import './chunk-BOQXMCSP.mjs';
2
+ export { PreviewShell, PreviewShellLayout, SdkPreviewModeRuntime as SdkPreviewMode } from './chunk-LERKJM3E.mjs';
3
+ export { PreviewLayoutProvider, PreviewQueryProvider, createPreviewQueryClient, useOptionalPreviewLayout, usePreviewLayout } from './chunk-U5YM4AWE.mjs';
4
+ import './chunk-UOMTCHZD.mjs';
5
+ import './chunk-6D7PLF4M.mjs';
6
+ import './chunk-I6EOKV6B.mjs';
7
+ import './chunk-ZA2S7H34.mjs';
8
8
  import './chunk-R7POPVJR.mjs';
@@ -126,6 +126,8 @@ function err(error) {
126
126
 
127
127
  // ../core/src/branded.ts
128
128
  var unsafeAsMediaAssetId = (id) => id;
129
+ var unsafeAsStorageBucketName = (value) => value;
130
+ var unsafeAsStoragePath = (value) => value;
129
131
 
130
132
  // ../core/src/assert-never.ts
131
133
  function assertNever(value, message = "Unexpected variant") {
@@ -180,6 +182,7 @@ function publicEventPricingType(pricing) {
180
182
  return "free";
181
183
  case "single_paid":
182
184
  case "ticket_types":
185
+ case "sliding_scale":
183
186
  case "course":
184
187
  return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
185
188
  case "external":
@@ -192,6 +195,7 @@ function publicEventPricingCurrency(pricing) {
192
195
  case "free_registration":
193
196
  case "single_paid":
194
197
  case "ticket_types":
198
+ case "sliding_scale":
195
199
  return pricing.currency;
196
200
  case "course":
197
201
  return pricing.display.display.currency;
@@ -223,6 +227,8 @@ function formatCoursePriceDisplayLabel(display, options) {
223
227
  return `Course (${formatCurrencyAmount(display.amount, display.currency, options)})`;
224
228
  case "from":
225
229
  return `Course (From ${formatCurrencyAmount(display.amount, display.currency, options)})`;
230
+ case "range":
231
+ return `Course (${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)})`;
226
232
  default:
227
233
  return assertNever(display);
228
234
  }
@@ -266,11 +272,11 @@ function isValidTimeZone(timeZone) {
266
272
  }
267
273
  function getSafeTimeZone(timeZone) {
268
274
  const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
269
- return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
275
+ return normalized.length > 0 && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
270
276
  }
271
277
  function parseStrictBookingTimeZone(timeZone) {
272
278
  const normalized = timeZone.trim();
273
- if (!normalized || !isValidTimeZone(normalized)) {
279
+ if (normalized.length === 0 || !isValidTimeZone(normalized)) {
274
280
  return null;
275
281
  }
276
282
  return normalized;
@@ -347,7 +353,7 @@ function parseScheduledBookingDateTime(input) {
347
353
  try {
348
354
  const startsAt = toUtcIsoDateTimeString(input.startsAt);
349
355
  const timeZone = parseStrictBookingTimeZone(input.timeZone);
350
- if (!timeZone) {
356
+ if (timeZone === null) {
351
357
  return {
352
358
  ok: false,
353
359
  field: "timeZone",
@@ -482,10 +488,10 @@ function normalizeLocationAddressText(value) {
482
488
  return null;
483
489
  }
484
490
  const trimmed = value.trim();
485
- return trimmed ? trimmed : null;
491
+ return trimmed.length > 0 ? trimmed : null;
486
492
  }
487
493
  function hasLocationCoordinates(value) {
488
- return typeof value?.lat === "number" && typeof value?.lng === "number";
494
+ return value != null && typeof value.lat === "number" && typeof value.lng === "number";
489
495
  }
490
496
  function toLocationCoordinates(value) {
491
497
  if (!hasLocationCoordinates(value)) {
@@ -514,6 +520,77 @@ function resolvePlanningDateInput(input = {}) {
514
520
  return resolvePlanningNowDate(input);
515
521
  }
516
522
 
523
+ // ../media-core/src/fileSafety.ts
524
+ var CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/u;
525
+ function containsUnsafePathSegmentCharacter(value) {
526
+ return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN.test(value);
527
+ }
528
+ function isReservedPathSegment(value) {
529
+ return value === "." || value === "..";
530
+ }
531
+ function isUnsafePathSegment(segment) {
532
+ return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
533
+ }
534
+
535
+ // ../media-core/src/fileStorage.ts
536
+ var FILE_STORAGE_BUCKETS = {
537
+ publicSite: unsafeAsStorageBucketName("media"),
538
+ privateSite: unsafeAsStorageBucketName("site-files-private"),
539
+ temporary: unsafeAsStorageBucketName("temp-uploads")
540
+ };
541
+ var PUBLIC_SITE_FILE_STORAGE_BUCKETS = [
542
+ FILE_STORAGE_BUCKETS.publicSite,
543
+ // Existing site logo and font uploads predate the unified file buckets.
544
+ unsafeAsStorageBucketName("site-assets"),
545
+ unsafeAsStorageBucketName("site-fonts")
546
+ ];
547
+ var PRIVATE_SITE_FILE_BUCKET_MIME_TYPES = [
548
+ "application/pdf",
549
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
550
+ "text/plain",
551
+ "application/rtf",
552
+ "text/rtf",
553
+ "image/jpeg",
554
+ "image/png",
555
+ "image/webp",
556
+ "image/gif",
557
+ "image/avif",
558
+ "image/heic",
559
+ "image/heif",
560
+ "image/svg+xml",
561
+ "text/csv",
562
+ "application/csv",
563
+ "application/vnd.ms-excel",
564
+ "application/zip",
565
+ "application/x-zip-compressed",
566
+ "audio/mpeg",
567
+ "audio/mp4",
568
+ "audio/wav",
569
+ "audio/x-wav",
570
+ "audio/ogg",
571
+ "audio/webm",
572
+ "audio/flac",
573
+ "video/mp4",
574
+ "video/webm",
575
+ "video/quicktime"
576
+ ];
577
+ var TEMP_UPLOAD_BUCKET_MIME_TYPES = [
578
+ ...PRIVATE_SITE_FILE_BUCKET_MIME_TYPES,
579
+ "font/woff2",
580
+ "application/font-woff2",
581
+ "application/x-font-woff2",
582
+ "application/octet-stream"
583
+ ];
584
+ function parseStoragePath(value) {
585
+ return joinStoragePathSegments(value.split("/"));
586
+ }
587
+ function joinStoragePathSegments(segments) {
588
+ if (segments.some(isUnsafePathSegment)) {
589
+ return err("unsafe-path-segment");
590
+ }
591
+ return ok(unsafeAsStoragePath(segments.join("/")));
592
+ }
593
+
517
594
  // ../media-core/src/typeGuards.ts
518
595
  function isRecord(value) {
519
596
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -530,10 +607,10 @@ var RELATIVE_STORAGE_PATH_PREFIXES = [
530
607
  "imports/"
531
608
  ];
532
609
  function isRelativeDirectImageStoragePath(storagePath) {
533
- return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix));
610
+ return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix)) && parseStoragePath(storagePath).ok;
534
611
  }
535
612
  function isSiteScopedDirectImageStoragePath(storagePath) {
536
- return storagePath.startsWith("sites/");
613
+ return storagePath.startsWith("sites/") && parseStoragePath(storagePath).ok;
537
614
  }
538
615
  function encodeStoragePath(storagePath) {
539
616
  return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
@@ -3006,6 +3083,21 @@ function fieldPlanToZod(plan, options = {}) {
3006
3083
  }
3007
3084
  });
3008
3085
  }
3086
+ function fieldPresenceForPlan(plan) {
3087
+ return plan.required ? { kind: "required" } : { kind: "optional" };
3088
+ }
3089
+ function fieldPlanToObjectPropertyZod(plan, options = {}) {
3090
+ const schema = fieldPlanToZod(plan, options);
3091
+ const presence = fieldPresenceForPlan(plan);
3092
+ switch (presence.kind) {
3093
+ case "required":
3094
+ return schema;
3095
+ case "optional":
3096
+ return schema.optional();
3097
+ default:
3098
+ return assertNever2(presence);
3099
+ }
3100
+ }
3009
3101
  function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
3010
3102
  const message = fieldIssueToMessage(validationIssue);
3011
3103
  const path = relativeZodIssuePath(validationIssue.path, rootPath);
@@ -3218,7 +3310,7 @@ function createManifestValidator(manifestOrFields, options = {}) {
3218
3310
  function deriveContentZodFromPlans(plans, options) {
3219
3311
  const shape = {};
3220
3312
  for (const plan of plans) {
3221
- shape[plan.fieldId] = fieldPlanToZod(plan, options);
3313
+ shape[plan.fieldId] = fieldPlanToObjectPropertyZod(plan, options);
3222
3314
  }
3223
3315
  return z5.object(shape).catchall(z5.unknown()).passthrough();
3224
3316
  }
@@ -26327,9 +26419,12 @@ var coursePricingOptionSchema = z43.object({
26327
26419
  });
26328
26420
  var coursePricingSchema = z43.object({
26329
26421
  bookingRequirement: z43.enum(["none", "required"]),
26330
- pricingStrategy: z43.enum(["free", "single", "tiered"]),
26422
+ pricingStrategy: z43.enum(["free", "single", "tiered", "sliding_scale"]),
26331
26423
  currency: z43.string(),
26332
26424
  singlePriceAmount: z43.number().nullable(),
26425
+ slidingMinAmount: z43.number().nullable().optional(),
26426
+ slidingMaxAmount: z43.number().nullable().optional(),
26427
+ slidingSuggestedAmount: z43.number().nullable().optional(),
26333
26428
  paymentTerms: blockBookingPaymentTermsSchema,
26334
26429
  options: z43.array(coursePricingOptionSchema)
26335
26430
  });
@@ -26483,6 +26578,19 @@ var publicEventPricingSchema = z44.discriminatedUnion("kind", [
26483
26578
  ticketTypes: z44.array(publicEventTicketTypeSchema),
26484
26579
  display: publicEventTicketTypePriceDisplaySchema
26485
26580
  }),
26581
+ z44.object({
26582
+ kind: z44.literal("sliding_scale"),
26583
+ minAmount: z44.number(),
26584
+ maxAmount: z44.number(),
26585
+ suggestedAmount: z44.number().nullable(),
26586
+ currency: z44.string(),
26587
+ display: z44.object({
26588
+ kind: z44.literal("range"),
26589
+ minAmount: z44.number(),
26590
+ maxAmount: z44.number(),
26591
+ currency: z44.string()
26592
+ })
26593
+ }),
26486
26594
  z44.object({
26487
26595
  kind: z44.literal("course"),
26488
26596
  display: z44.object({ kind: z44.literal("course"), display: publicCoursePriceDisplaySchema })
@@ -26899,7 +27007,7 @@ function isRecord6(value) {
26899
27007
  }
26900
27008
  function isPublicEventPricing(value) {
26901
27009
  if (!isRecord6(value) || typeof value.kind !== "string") return false;
26902
- return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
27010
+ return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
26903
27011
  }
26904
27012
  function isPublicEventTicketType(value) {
26905
27013
  return isRecord6(value) && typeof value.id === "string";
@@ -27516,7 +27624,9 @@ function getSelectableCoursePricingOptionsForNow(course, now) {
27516
27624
  return left.name.localeCompare(right.name);
27517
27625
  });
27518
27626
  }
27519
- function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {}) {
27627
+ function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
27628
+ const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
27629
+ const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
27520
27630
  const currency = course.pricing?.currency ?? course.currency;
27521
27631
  if (!course.pricing) {
27522
27632
  const legacyAmount = course.priceCents ?? 0;
@@ -27526,6 +27636,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
27526
27636
  selectableOptions: [],
27527
27637
  requiresSelection: false,
27528
27638
  selectedOption: null,
27639
+ slidingScale: null,
27640
+ selectedSlidingAmount: null,
27529
27641
  selectedPriceAmount: legacyAmount,
27530
27642
  selectedRequiresPayment: legacyAmount > 0,
27531
27643
  hasPaidSelection: legacyAmount > 0,
@@ -27540,6 +27652,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
27540
27652
  selectableOptions: [],
27541
27653
  requiresSelection: false,
27542
27654
  selectedOption: null,
27655
+ slidingScale: null,
27656
+ selectedSlidingAmount: null,
27543
27657
  selectedPriceAmount: 0,
27544
27658
  selectedRequiresPayment: false,
27545
27659
  hasPaidSelection: false,
@@ -27553,6 +27667,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
27553
27667
  selectableOptions: [],
27554
27668
  requiresSelection: false,
27555
27669
  selectedOption: null,
27670
+ slidingScale: null,
27671
+ selectedSlidingAmount: null,
27556
27672
  selectedPriceAmount: amount,
27557
27673
  selectedRequiresPayment: amount > 0,
27558
27674
  hasPaidSelection: amount > 0,
@@ -27562,7 +27678,7 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
27562
27678
  case "tiered": {
27563
27679
  const selectableOptions = getSelectableCoursePricingOptionsForNow(
27564
27680
  course,
27565
- resolvePlanningDateInput(nowInput)
27681
+ resolvePlanningDateInput(effectiveNowInput)
27566
27682
  );
27567
27683
  const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
27568
27684
  const lowestAmount = selectableOptions.reduce((lowest, option) => {
@@ -27578,12 +27694,51 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
27578
27694
  selectableOptions,
27579
27695
  requiresSelection: selectableOptions.length > 1,
27580
27696
  selectedOption,
27697
+ slidingScale: null,
27698
+ selectedSlidingAmount: null,
27581
27699
  selectedPriceAmount: selectedOption?.priceAmount ?? null,
27582
27700
  selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
27583
27701
  hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
27584
27702
  hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
27585
27703
  };
27586
27704
  }
27705
+ case "sliding_scale": {
27706
+ const minAmount = course.pricing.slidingMinAmount ?? null;
27707
+ const maxAmount = course.pricing.slidingMaxAmount ?? null;
27708
+ if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) {
27709
+ return {
27710
+ currency,
27711
+ display: { kind: "unavailable", currency },
27712
+ selectableOptions: [],
27713
+ requiresSelection: true,
27714
+ selectedOption: null,
27715
+ slidingScale: null,
27716
+ selectedSlidingAmount: null,
27717
+ selectedPriceAmount: null,
27718
+ selectedRequiresPayment: false,
27719
+ hasPaidSelection: false,
27720
+ hasFreeSelection: false
27721
+ };
27722
+ }
27723
+ const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
27724
+ return {
27725
+ currency,
27726
+ display: { kind: "range", minAmount, maxAmount, currency },
27727
+ selectableOptions: [],
27728
+ requiresSelection: normalizedSelectedAmount === null,
27729
+ selectedOption: null,
27730
+ slidingScale: {
27731
+ minAmount,
27732
+ maxAmount,
27733
+ suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
27734
+ },
27735
+ selectedSlidingAmount: normalizedSelectedAmount,
27736
+ selectedPriceAmount: normalizedSelectedAmount,
27737
+ selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
27738
+ hasPaidSelection: maxAmount > 0,
27739
+ hasFreeSelection: minAmount === 0
27740
+ };
27741
+ }
27587
27742
  }
27588
27743
  }
27589
27744
  function formatCoursePriceDisplay(display, locale) {
@@ -28510,7 +28665,7 @@ function formatCalendarTitle(viewDate, view, days, monthNames = MONTH_NAMES) {
28510
28665
  if (view === "week") {
28511
28666
  const weekStart = days[0];
28512
28667
  const weekEnd = days[6];
28513
- if (!weekStart || !weekEnd) {
28668
+ if (weekStart === void 0 || weekEnd === void 0) {
28514
28669
  return `${monthNames[viewDate.getMonth()] ?? ""} ${viewDate.getFullYear()}`;
28515
28670
  }
28516
28671
  const startMonth = monthNames[weekStart.getMonth()] ?? "";
@@ -28616,7 +28771,9 @@ function getLocalDateKey(isoTimestamp, timeZone) {
28616
28771
  const year = parts.find((part) => part.type === "year")?.value;
28617
28772
  const month = parts.find((part) => part.type === "month")?.value;
28618
28773
  const day = parts.find((part) => part.type === "day")?.value;
28619
- if (!year || !month || !day) return null;
28774
+ if (year === void 0 || year.length === 0) return null;
28775
+ if (month === void 0 || month.length === 0) return null;
28776
+ if (day === void 0 || day.length === 0) return null;
28620
28777
  return `${year}-${month}-${day}`;
28621
28778
  }
28622
28779
  var validTimeZoneCache = /* @__PURE__ */ new Map();
@@ -28873,7 +29030,7 @@ function enumerateDateKeys(startDateKey, endDateKey) {
28873
29030
  }
28874
29031
  function parseDateKey(dateKey) {
28875
29032
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateKey);
28876
- if (!match) {
29033
+ if (match === null) {
28877
29034
  throw new Error(`Invalid timetable date key: ${dateKey}`);
28878
29035
  }
28879
29036
  const [, year, month, day] = match;
@@ -28893,7 +29050,7 @@ function groupItemsByDate(items, accessors) {
28893
29050
  const dateKey = getLocalDateKey(startsAt, timeZone);
28894
29051
  if (dateKey == null) continue;
28895
29052
  const existing = grouped.get(dateKey);
28896
- if (existing) {
29053
+ if (existing !== void 0) {
28897
29054
  existing.push(item);
28898
29055
  } else {
28899
29056
  grouped.set(dateKey, [item]);
@@ -37964,11 +38121,11 @@ function extractRouteUpdatedAt(candidate) {
37964
38121
  }
37965
38122
  function resolveRouteTargetForStage(routeIdValue, routes, stageInput) {
37966
38123
  const routeId = typeof routeIdValue === "string" ? routeIdValue : null;
37967
- if (!routeId || !routes) return null;
38124
+ if (routeId === null || routeId.length === 0 || routes === void 0) return null;
37968
38125
  const routeEntry = routes[routeId];
37969
38126
  if (!isRouteVisibleInStage(routeEntry, stageInput)) return null;
37970
38127
  const href = extractRouteHref(routeEntry, stageInput);
37971
- if (!href) return null;
38128
+ if (href === null) return null;
37972
38129
  return {
37973
38130
  routeId,
37974
38131
  href,
@@ -39899,6 +40056,7 @@ var bookingServiceSchema = z64.object({
39899
40056
  title: z64.string(),
39900
40057
  description: z64.string().nullable().optional().transform((value) => value ?? void 0),
39901
40058
  durationMinutes: z64.number().optional(),
40059
+ pricing: z64.custom().optional(),
39902
40060
  priceAmount: z64.number().nullable().optional(),
39903
40061
  priceCurrency: z64.string().nullable().optional(),
39904
40062
  paymentTerms: blockBookingPaymentTermsSchema.optional(),
@@ -67712,6 +67870,7 @@ var CANONICAL_REFUND_CONFLICT_CODES = [
67712
67870
  ];
67713
67871
  var CANONICAL_REFUND_PLANNER_ERROR_CODES = [
67714
67872
  ...CANONICAL_REFUND_CONFLICT_CODES,
67873
+ "invalid_amount",
67715
67874
  "amount_exceeds_remaining",
67716
67875
  "pass_revoke_requires_full_refund",
67717
67876
  "refund_failed"
@@ -67738,6 +67897,7 @@ var CUSTOMER_MEMBERSHIP_PAYMENT_REFUND_FAILED_CODES = [
67738
67897
  // ../api/src/bookingRefundOutcomes.ts
67739
67898
  var STANDARD_LINE_ITEM_REFUND_INVALID_CODES = [
67740
67899
  "missing_amount",
67900
+ "invalid_amount",
67741
67901
  "amount_exceeds_remaining",
67742
67902
  "credit_refunds_disabled",
67743
67903
  "missing_credit_customer",
@@ -67752,6 +67912,7 @@ var EVENT_ATTENDEE_REFUND_INVALID_CODES = [
67752
67912
  var MANAGED_PRODUCT_REFUND_INVALID_CODES = [
67753
67913
  "credit_refunds_disabled",
67754
67914
  "not_refundable",
67915
+ "invalid_amount",
67755
67916
  "amount_exceeds_remaining"
67756
67917
  ];
67757
67918
  var CUSTOMER_PASS_REFUND_INVALID_CODES = [
@@ -6493,6 +6493,7 @@ function publicEventPricingType(pricing) {
6493
6493
  return "free";
6494
6494
  case "single_paid":
6495
6495
  case "ticket_types":
6496
+ case "sliding_scale":
6496
6497
  case "course":
6497
6498
  return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
6498
6499
  case "external":
@@ -6528,11 +6529,11 @@ function isValidTimeZone(timeZone) {
6528
6529
  }
6529
6530
  function getSafeTimeZone(timeZone) {
6530
6531
  const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
6531
- return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
6532
+ return normalized.length > 0 && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
6532
6533
  }
6533
6534
  function parseStrictBookingTimeZone(timeZone) {
6534
6535
  const normalized = timeZone.trim();
6535
- if (!normalized || !isValidTimeZone(normalized)) {
6536
+ if (normalized.length === 0 || !isValidTimeZone(normalized)) {
6536
6537
  return null;
6537
6538
  }
6538
6539
  return normalized;
@@ -6606,7 +6607,7 @@ function parseScheduledBookingDateTime(input) {
6606
6607
  try {
6607
6608
  const startsAt = toUtcIsoDateTimeString(input.startsAt);
6608
6609
  const timeZone = parseStrictBookingTimeZone(input.timeZone);
6609
- if (!timeZone) {
6610
+ if (timeZone === null) {
6610
6611
  return {
6611
6612
  ok: false,
6612
6613
  field: "timeZone",
@@ -6652,10 +6653,10 @@ function normalizeLocationAddressText(value) {
6652
6653
  return null;
6653
6654
  }
6654
6655
  const trimmed = value.trim();
6655
- return trimmed ? trimmed : null;
6656
+ return trimmed.length > 0 ? trimmed : null;
6656
6657
  }
6657
6658
  function hasLocationCoordinates(value) {
6658
- return typeof value?.lat === "number" && typeof value?.lng === "number";
6659
+ return value != null && typeof value.lat === "number" && typeof value.lng === "number";
6659
6660
  }
6660
6661
  function toLocationCoordinates(value) {
6661
6662
  if (!hasLocationCoordinates(value)) {
@@ -28058,9 +28059,12 @@ var coursePricingOptionSchema = z42.object({
28058
28059
  });
28059
28060
  var coursePricingSchema = z42.object({
28060
28061
  bookingRequirement: z42.enum(["none", "required"]),
28061
- pricingStrategy: z42.enum(["free", "single", "tiered"]),
28062
+ pricingStrategy: z42.enum(["free", "single", "tiered", "sliding_scale"]),
28062
28063
  currency: z42.string(),
28063
28064
  singlePriceAmount: z42.number().nullable(),
28065
+ slidingMinAmount: z42.number().nullable().optional(),
28066
+ slidingMaxAmount: z42.number().nullable().optional(),
28067
+ slidingSuggestedAmount: z42.number().nullable().optional(),
28064
28068
  paymentTerms: blockBookingPaymentTermsSchema,
28065
28069
  options: z42.array(coursePricingOptionSchema)
28066
28070
  });
@@ -28214,6 +28218,19 @@ var publicEventPricingSchema = z43.discriminatedUnion("kind", [
28214
28218
  ticketTypes: z43.array(publicEventTicketTypeSchema),
28215
28219
  display: publicEventTicketTypePriceDisplaySchema
28216
28220
  }),
28221
+ z43.object({
28222
+ kind: z43.literal("sliding_scale"),
28223
+ minAmount: z43.number(),
28224
+ maxAmount: z43.number(),
28225
+ suggestedAmount: z43.number().nullable(),
28226
+ currency: z43.string(),
28227
+ display: z43.object({
28228
+ kind: z43.literal("range"),
28229
+ minAmount: z43.number(),
28230
+ maxAmount: z43.number(),
28231
+ currency: z43.string()
28232
+ })
28233
+ }),
28217
28234
  z43.object({
28218
28235
  kind: z43.literal("course"),
28219
28236
  display: z43.object({ kind: z43.literal("course"), display: publicCoursePriceDisplaySchema })
@@ -28630,7 +28647,7 @@ function isRecord4(value) {
28630
28647
  }
28631
28648
  function isPublicEventPricing(value) {
28632
28649
  if (!isRecord4(value) || typeof value.kind !== "string") return false;
28633
- return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
28650
+ return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
28634
28651
  }
28635
28652
  function isPublicEventTicketType(value) {
28636
28653
  return isRecord4(value) && typeof value.id === "string";
@@ -37058,11 +37075,11 @@ function extractRouteUpdatedAt(candidate) {
37058
37075
  }
37059
37076
  function resolveRouteTargetForStage(routeIdValue, routes, stageInput) {
37060
37077
  const routeId = typeof routeIdValue === "string" ? routeIdValue : null;
37061
- if (!routeId || !routes) return null;
37078
+ if (routeId === null || routeId.length === 0 || routes === void 0) return null;
37062
37079
  const routeEntry = routes[routeId];
37063
37080
  if (!isRouteVisibleInStage(routeEntry, stageInput)) return null;
37064
37081
  const href = extractRouteHref(routeEntry, stageInput);
37065
- if (!href) return null;
37082
+ if (href === null) return null;
37066
37083
  return {
37067
37084
  routeId,
37068
37085
  href,
@@ -37210,6 +37227,7 @@ var BOOKING_FORM_DATA_RESERVED_KEY_VALUES = [
37210
37227
  "selectedDate",
37211
37228
  "selectedSlot",
37212
37229
  "discountCode",
37230
+ "selectedSlidingAmountInput",
37213
37231
  "selectedCollectionOptionKind",
37214
37232
  "selectedAppointmentPackageId"
37215
37233
  ];
@@ -38391,6 +38409,7 @@ var CANONICAL_REFUND_CONFLICT_CODES = [
38391
38409
  ];
38392
38410
  var CANONICAL_REFUND_PLANNER_ERROR_CODES = [
38393
38411
  ...CANONICAL_REFUND_CONFLICT_CODES,
38412
+ "invalid_amount",
38394
38413
  "amount_exceeds_remaining",
38395
38414
  "pass_revoke_requires_full_refund",
38396
38415
  "refund_failed"
@@ -38417,6 +38436,7 @@ var CUSTOMER_MEMBERSHIP_PAYMENT_REFUND_FAILED_CODES = [
38417
38436
  // ../api/src/bookingRefundOutcomes.ts
38418
38437
  var STANDARD_LINE_ITEM_REFUND_INVALID_CODES = [
38419
38438
  "missing_amount",
38439
+ "invalid_amount",
38420
38440
  "amount_exceeds_remaining",
38421
38441
  "credit_refunds_disabled",
38422
38442
  "missing_credit_customer",
@@ -38431,6 +38451,7 @@ var EVENT_ATTENDEE_REFUND_INVALID_CODES = [
38431
38451
  var MANAGED_PRODUCT_REFUND_INVALID_CODES = [
38432
38452
  "credit_refunds_disabled",
38433
38453
  "not_refundable",
38454
+ "invalid_amount",
38434
38455
  "amount_exceeds_remaining"
38435
38456
  ];
38436
38457
  var CUSTOMER_PASS_REFUND_INVALID_CODES = [