@riverbankcms/sdk 0.60.9 → 0.60.12

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 (45) hide show
  1. package/dist/_dts/api/src/accessAdmin.d.ts +102 -0
  2. package/dist/_dts/api/src/common/envelope.d.ts +1 -1
  3. package/dist/_dts/api/src/domains.d.ts +14 -13
  4. package/dist/_dts/api/src/endpoints.d.ts +32 -0
  5. package/dist/_dts/api/src/index.d.ts +4 -3
  6. package/dist/_dts/api/src/navigation/linkValue.d.ts +15 -2
  7. package/dist/_dts/api/src/navigation.d.ts +2 -0
  8. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +15 -1
  9. package/dist/_dts/blocks/src/index.d.ts +1 -1
  10. package/dist/_dts/blocks/src/system/node/fragments/ctaButton.d.ts +2 -2
  11. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +2 -1
  12. package/dist/_dts/blocks/src/system/types/link.d.ts +7 -1
  13. package/dist/_dts/core/src/participant-identity.d.ts +72 -0
  14. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +96 -60
  15. package/dist/_dts/db/src/schemas/forms.d.ts +135 -24
  16. package/dist/_dts/sdk/src/contracts/content.d.ts +7 -1
  17. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -1
  18. package/dist/_dts/sdk/src/version.d.ts +1 -1
  19. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +21 -0
  20. package/dist/_dts/theme-core/src/buttons/index.d.ts +1 -0
  21. package/dist/_dts/theme-core/src/buttons/types.d.ts +1 -0
  22. package/dist/cli/index.mjs +188 -9
  23. package/dist/client/bookings.mjs +808 -149
  24. package/dist/client/client.mjs +553 -130
  25. package/dist/client/hooks.mjs +119 -0
  26. package/dist/client/rendering/client.mjs +412 -113
  27. package/dist/client/rendering/islands.mjs +4605 -4361
  28. package/dist/client/rendering.mjs +580 -157
  29. package/dist/preview-next/before-render.mjs +57 -0
  30. package/dist/preview-next/client/runtime.mjs +580 -151
  31. package/dist/preview-next/middleware.mjs +57 -0
  32. package/dist/server/components.mjs +293 -45
  33. package/dist/server/config-validation.mjs +119 -0
  34. package/dist/server/config.mjs +119 -0
  35. package/dist/server/data.mjs +119 -0
  36. package/dist/server/index.mjs +120 -1
  37. package/dist/server/next.mjs +300 -52
  38. package/dist/server/page-converter.mjs +62 -0
  39. package/dist/server/prebuild.mjs +1 -1
  40. package/dist/server/rendering/server.mjs +293 -45
  41. package/dist/server/rendering.mjs +293 -45
  42. package/dist/server/routing.mjs +159 -29
  43. package/dist/server/server.mjs +120 -1
  44. package/package.json +1 -1
  45. package/dist/_dts/blocks/src/system/runtime/shared/themedButtonClass.d.ts +0 -11
@@ -2095,6 +2095,63 @@ var ENDPOINT_DEFINITIONS = {
2095
2095
  auth: "user",
2096
2096
  responseKind: "json"
2097
2097
  },
2098
+ updateRegisteredDomainContact: {
2099
+ path: "/domains/{domainId}/registrar/contact",
2100
+ method: "POST",
2101
+ errors: [
2102
+ "validation:invalid_input",
2103
+ "resource:not_found",
2104
+ "auth:forbidden",
2105
+ "external:service_error",
2106
+ "external:registrar_orphaned_contact_profile",
2107
+ "server:internal_error"
2108
+ ],
2109
+ tags: ["domains", "domain-{domainId}", "domain-registrar"],
2110
+ auth: "user",
2111
+ responseKind: "json"
2112
+ },
2113
+ setRegisteredDomainPrivacy: {
2114
+ path: "/domains/{domainId}/registrar/privacy",
2115
+ method: "POST",
2116
+ errors: [
2117
+ "validation:invalid_input",
2118
+ "resource:not_found",
2119
+ "auth:forbidden",
2120
+ "external:service_error",
2121
+ "server:internal_error"
2122
+ ],
2123
+ tags: ["domains", "domain-{domainId}", "domain-registrar"],
2124
+ auth: "user",
2125
+ responseKind: "json"
2126
+ },
2127
+ setRegisteredDomainAutoRenew: {
2128
+ path: "/domains/{domainId}/registrar/auto-renew",
2129
+ method: "POST",
2130
+ errors: [
2131
+ "validation:invalid_input",
2132
+ "resource:not_found",
2133
+ "auth:forbidden",
2134
+ "external:service_error",
2135
+ "server:internal_error"
2136
+ ],
2137
+ tags: ["domains", "domain-{domainId}", "domain-registrar"],
2138
+ auth: "user",
2139
+ responseKind: "json"
2140
+ },
2141
+ getRegisteredDomainRenewalPosture: {
2142
+ path: "/domains/{domainId}/registrar/renewal",
2143
+ method: "GET",
2144
+ errors: [
2145
+ "validation:invalid_input",
2146
+ "resource:not_found",
2147
+ "auth:forbidden",
2148
+ "external:service_error",
2149
+ "server:internal_error"
2150
+ ],
2151
+ tags: ["domains", "domain-{domainId}", "domain-registrar"],
2152
+ auth: "user",
2153
+ responseKind: "json"
2154
+ },
2098
2155
  retryDomainVercel: {
2099
2156
  path: "/domains/{domainId}/vercel",
2100
2157
  method: "POST",
@@ -6037,6 +6094,68 @@ function toLocationCoordinates(value) {
6037
6094
  };
6038
6095
  }
6039
6096
 
6097
+ // ../core/src/participant-identity.ts
6098
+ var PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD = {
6099
+ participant_id: {
6100
+ field: "participant_id",
6101
+ role: "canonical_link",
6102
+ canonicalSource: "booking_participants.id",
6103
+ contractAction: "tighten_in_839",
6104
+ notes: "Canonical person-subject link for a participation. #839 should enforce this once preflight is clean."
6105
+ },
6106
+ display_name: {
6107
+ field: "display_name",
6108
+ role: "contextual_snapshot",
6109
+ canonicalSource: "booking_participants.display_name for live identity",
6110
+ contractAction: "retain_as_snapshot",
6111
+ notes: "Participation-time display context. Readers must not treat it as mutable live participant identity."
6112
+ },
6113
+ email: {
6114
+ field: "email",
6115
+ role: "contextual_snapshot",
6116
+ canonicalSource: "booking_participants.email_normalized for live email identity",
6117
+ contractAction: "retain_as_snapshot",
6118
+ notes: "Participation-time contact snapshot used for notifications/context. Live identity belongs to the participant row."
6119
+ },
6120
+ email_normalized: {
6121
+ field: "email_normalized",
6122
+ role: "contextual_snapshot",
6123
+ canonicalSource: "booking_participants.email_normalized for live email identity",
6124
+ contractAction: "retain_as_snapshot",
6125
+ notes: "Normalized snapshot/dedupe helper for the participation slot, not live person authority."
6126
+ },
6127
+ phone: {
6128
+ field: "phone",
6129
+ role: "contextual_snapshot",
6130
+ canonicalSource: "booking_participants.phone for live phone identity",
6131
+ contractAction: "retain_as_snapshot",
6132
+ notes: "Participation-time phone context. Live identity belongs to the participant row."
6133
+ },
6134
+ identity_state: {
6135
+ field: "identity_state",
6136
+ role: "materialization_state",
6137
+ canonicalSource: "booking_participants.identity_state for subject state",
6138
+ contractAction: "review_for_later_contract_cleanup",
6139
+ notes: "Slot materialization state: booker_supplied, contactable, portal_claimed, or staff_verified."
6140
+ },
6141
+ event_attendee_guest_id: {
6142
+ field: "event_attendee_guest_id",
6143
+ role: "compatibility_projection",
6144
+ canonicalSource: "canonical participant slot plus #838 event guest compatibility projection",
6145
+ contractAction: "retain_as_projection",
6146
+ notes: "Compatibility FK for event guest read models. It is not person identity authority."
6147
+ }
6148
+ };
6149
+ var PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATIONS = [
6150
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.participant_id,
6151
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.display_name,
6152
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.email,
6153
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.email_normalized,
6154
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.phone,
6155
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.identity_state,
6156
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.event_attendee_guest_id
6157
+ ];
6158
+
6040
6159
  // ../media-core/src/typeGuards.ts
6041
6160
  function isRecord(value) {
6042
6161
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -8374,6 +8493,9 @@ function validationContext(options = {}) {
8374
8493
  allowIncomplete: isDraft || (options.allowIncomplete ?? false)
8375
8494
  };
8376
8495
  }
8496
+ function formatFieldPath(path) {
8497
+ return path.map((segment) => String(segment)).join(".");
8498
+ }
8377
8499
  function fieldIssueToMessage(issue2) {
8378
8500
  switch (issue2.kind) {
8379
8501
  case "required":
@@ -8597,7 +8719,7 @@ function normalizeRepeaterItems(plan, value, ctx) {
8597
8719
  return normalizeObjectChildren(fields3, itemRecord, ctx);
8598
8720
  });
8599
8721
  }
8600
- function normalizeNumberInput(value, allowNull) {
8722
+ function normalizeNumberInput(value, _allowNull) {
8601
8723
  if (value === "") return void 0;
8602
8724
  if (typeof value === "string" && value.trim() !== "") return Number(value);
8603
8725
  return value;
@@ -8729,7 +8851,7 @@ function validateRepeaterItem(plan, item, index, ctx) {
8729
8851
  const fields3 = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === itemType)?.fields : plan.repeatedItemPlan;
8730
8852
  if (!fields3) return [];
8731
8853
  return fields3.flatMap((childPlan) => {
8732
- const indexedPlan = withIndexedPath(childPlan, plan.path, index);
8854
+ const indexedPlan = materializeRepeaterItemPlan(childPlan, plan.path, index);
8733
8855
  return validateNormalizedFieldValue(indexedPlan, item[childPlan.fieldId], ctx);
8734
8856
  });
8735
8857
  }
@@ -8741,12 +8863,58 @@ function validateGroupPlan(plan, value, ctx) {
8741
8863
  function childValidationContext(plan, ctx) {
8742
8864
  return plan.allowNullChildren ? { ...ctx, allowNull: true } : ctx;
8743
8865
  }
8744
- function withIndexedPath(plan, parentPath, index) {
8745
- const suffix = plan.path.slice(parentPath.length + 1);
8746
- return {
8747
- ...plan,
8748
- path: [...parentPath, index, plan.fieldId, ...suffix]
8749
- };
8866
+ function materializeRepeaterItemPlan(plan, parentPath, index) {
8867
+ return rebaseFieldPlanPath(plan, [...parentPath, 0], [...parentPath, index]);
8868
+ }
8869
+ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
8870
+ const path = rebaseFieldPath(plan.path, fromPrefix, toPrefix);
8871
+ switch (plan.kind) {
8872
+ case "group":
8873
+ return {
8874
+ ...plan,
8875
+ path,
8876
+ children: plan.children.map((childPlan) => rebaseFieldPlanPath(childPlan, fromPrefix, toPrefix))
8877
+ };
8878
+ case "repeater":
8879
+ return {
8880
+ ...plan,
8881
+ path,
8882
+ ...plan.repeatedItemVariants ? {
8883
+ repeatedItemVariants: plan.repeatedItemVariants.map((variant) => ({
8884
+ ...variant,
8885
+ fields: variant.fields.map((fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix))
8886
+ }))
8887
+ } : {},
8888
+ ...plan.repeatedItemPlan ? {
8889
+ repeatedItemPlan: plan.repeatedItemPlan.map(
8890
+ (fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix)
8891
+ )
8892
+ } : {}
8893
+ };
8894
+ case "string":
8895
+ case "number":
8896
+ case "boolean":
8897
+ case "richText":
8898
+ case "media":
8899
+ case "link":
8900
+ case "select":
8901
+ case "passthrough":
8902
+ return {
8903
+ ...plan,
8904
+ path
8905
+ };
8906
+ default:
8907
+ return assertNever2(plan);
8908
+ }
8909
+ }
8910
+ function rebaseFieldPath(path, fromPrefix, toPrefix) {
8911
+ if (!startsWithFieldPath(path, fromPrefix)) {
8912
+ throw new Error(`Cannot rebase field path ${formatFieldPath(path)} from ${formatFieldPath(fromPrefix)}`);
8913
+ }
8914
+ return [...toPrefix, ...path.slice(fromPrefix.length)];
8915
+ }
8916
+ function startsWithFieldPath(path, prefix) {
8917
+ return prefix.every((segment, index) => path[index] === segment);
8750
8918
  }
8751
8919
  function issue(plan, kind, extra) {
8752
8920
  return {
@@ -9257,6 +9425,15 @@ var VARIANT_ROLES = [
9257
9425
  "tertiary",
9258
9426
  "accent"
9259
9427
  ];
9428
+ function isVariantRole(value) {
9429
+ return VARIANT_ROLES.includes(value);
9430
+ }
9431
+ function asSpecialVariantId(value) {
9432
+ if (value.length === 0) {
9433
+ throw new Error("SpecialVariantId must be a non-empty string");
9434
+ }
9435
+ return value;
9436
+ }
9260
9437
  var DEFAULT_VARIANT_ALIAS_ID = "default";
9261
9438
  var cornerStyleSchema = z11.enum(["square", "rounded", "pill"]);
9262
9439
  var shadowSizeSchema = z11.enum(["none", "low", "medium", "high"]);
@@ -10007,6 +10184,42 @@ var mediaSchema = z14.object({
10007
10184
  transform: transformSchema.optional()
10008
10185
  });
10009
10186
 
10187
+ // ../theme-core/src/buttons/classNames.ts
10188
+ function parseThemeButtonVariantId(value) {
10189
+ const normalized = value?.trim() ?? "";
10190
+ if (normalized.length === 0) {
10191
+ return null;
10192
+ }
10193
+ if (normalized === DEFAULT_VARIANT_ALIAS_ID) {
10194
+ return DEFAULT_VARIANT_ALIAS_ID;
10195
+ }
10196
+ return isVariantRole(normalized) ? normalized : asSpecialVariantId(normalized);
10197
+ }
10198
+ function themeButtonVariantClassNames(variant) {
10199
+ if (variant === DEFAULT_VARIANT_ALIAS_ID) {
10200
+ return [variant];
10201
+ }
10202
+ return [variant, `button-${variant}`];
10203
+ }
10204
+ function themeButtonSizeClassName(size) {
10205
+ return `btn-${size}`;
10206
+ }
10207
+ function themeButtonSelector(variant, size) {
10208
+ const baseSelector = `.${variant}`;
10209
+ if (!size) {
10210
+ return baseSelector;
10211
+ }
10212
+ return `${baseSelector}.${themeButtonSizeClassName(size)}`;
10213
+ }
10214
+ function themeButtonClassName(spec) {
10215
+ const classes = [
10216
+ ...themeButtonVariantClassNames(spec.variant),
10217
+ themeButtonSizeClassName(spec.size),
10218
+ spec.extraClassName
10219
+ ];
10220
+ return classes.filter(Boolean).join(" ");
10221
+ }
10222
+
10010
10223
  // ../theme-core/src/tokens/resolver.ts
10011
10224
  var TokenResolver = class {
10012
10225
  constructor(theme) {
@@ -11578,17 +11791,25 @@ function resolveAliasSource(enabled) {
11578
11791
  }
11579
11792
  function variantChunks(variant, global, themeSizes, themeId, tokens, theme) {
11580
11793
  const out = [];
11581
- out.push(variantBaseRule(variant, global, themeId, tokens, theme));
11582
- const hoverBg = variantHoverBackgroundRule(variant, global, themeId, tokens);
11794
+ const variantId = parseButtonVariantIdForCss(variant.id);
11795
+ out.push(variantBaseRule(variant, variantId, global, themeId, tokens, theme));
11796
+ const hoverBg = variantHoverBackgroundRule(variant, variantId, global, themeId, tokens);
11583
11797
  if (hoverBg) out.push(hoverBg);
11584
11798
  const effects = variantEffectsCss(variant, themeId, tokens, theme);
11585
11799
  if (effects) out.push({ raw: effects });
11586
- out.push(...variantDisabledRules(variant, themeId));
11587
- out.push(...variantSizeRules(variant, themeSizes, themeId));
11800
+ out.push(...variantDisabledRules(variantId, themeId));
11801
+ out.push(...variantSizeRules(variant, variantId, themeSizes, themeId));
11588
11802
  return out;
11589
11803
  }
11590
- function variantBaseRule(variant, global, themeId, tokens, theme) {
11591
- const selector = `:where([data-theme-scope="${themeId}"]) .${variant.id}`;
11804
+ function parseButtonVariantIdForCss(value) {
11805
+ const variantId = parseThemeButtonVariantId(value);
11806
+ if (!variantId) {
11807
+ throw new Error("Button variant id must be a non-empty string");
11808
+ }
11809
+ return variantId;
11810
+ }
11811
+ function variantBaseRule(variant, variantId, global, themeId, tokens, theme) {
11812
+ const selector = `:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId)}`;
11592
11813
  const decls = [];
11593
11814
  decls.push(["font-weight", String(global.fontWeight)]);
11594
11815
  decls.push(["font-family", resolveFontFamily(global)]);
@@ -11621,13 +11842,13 @@ function variantBaseRule(variant, global, themeId, tokens, theme) {
11621
11842
  }
11622
11843
  return rule(selector, decls);
11623
11844
  }
11624
- function variantHoverBackgroundRule(variant, global, themeId, tokens) {
11845
+ function variantHoverBackgroundRule(variant, variantId, global, themeId, tokens) {
11625
11846
  let hoverToken = variant.hoverBackgroundToken;
11626
11847
  if (!hoverToken && global.hoverColor === "token" && global.hoverColorToken) {
11627
11848
  hoverToken = global.hoverColorToken;
11628
11849
  }
11629
11850
  if (!hoverToken) return null;
11630
- return rule(`:where([data-theme-scope="${themeId}"]) .${variant.id}:hover`, [
11851
+ return rule(`:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId)}:hover`, [
11631
11852
  ["background-color", tokens.getColor(hoverToken)]
11632
11853
  ]);
11633
11854
  }
@@ -11647,8 +11868,8 @@ function variantEffectsCss(variant, themeId, tokens, theme) {
11647
11868
  theme
11648
11869
  });
11649
11870
  }
11650
- function variantDisabledRules(variant, themeId) {
11651
- const base = `:where([data-theme-scope="${themeId}"]) .${variant.id}:disabled`;
11871
+ function variantDisabledRules(variantId, themeId) {
11872
+ const base = `:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId)}:disabled`;
11652
11873
  const disabledSelectors = [base, `${base}:hover`, `${base}:active`, `${base}:focus`];
11653
11874
  const pseudoSelectors = [`${base}::before`, `${base}::after`];
11654
11875
  return [
@@ -11666,12 +11887,12 @@ function variantDisabledRules(variant, themeId) {
11666
11887
  ])
11667
11888
  ];
11668
11889
  }
11669
- function variantSizeRules(variant, themeSizes, themeId) {
11890
+ function variantSizeRules(variant, variantId, themeSizes, themeId) {
11670
11891
  const borderWidth = variant.border ? BORDER_WIDTH_MAP[variant.border.widthClass] || "1px" : "0px";
11671
11892
  const rules = [];
11672
11893
  for (const sizeName of BUTTON_SIZE_NAMES) {
11673
11894
  const config = resolveSizeConfig(variant, sizeName, themeSizes);
11674
- const selector = `:where([data-theme-scope="${themeId}"]) .${variant.id}.btn-${sizeName}`;
11895
+ const selector = `:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId, sizeName)}`;
11675
11896
  const decls = [];
11676
11897
  for (const decl of paddingDeclarations(config.padding, borderWidth)) decls.push(decl);
11677
11898
  if (config.fontSize) {
@@ -26741,14 +26962,6 @@ function CalendarIcon({
26741
26962
  );
26742
26963
  }
26743
26964
 
26744
- // ../blocks/src/system/runtime/shared/themedButtonClass.ts
26745
- function themedButtonClass(spec) {
26746
- const { variant, size, extraClassName } = spec;
26747
- const normalizedVariant = variant.trim();
26748
- const variantClasses = normalizedVariant ? [normalizedVariant, `button-${normalizedVariant}`] : [];
26749
- return [...variantClasses, `btn-${size}`, extraClassName].filter(Boolean).join(" ");
26750
- }
26751
-
26752
26965
  // ../blocks/src/system/runtime/nodes/events/shared/EventCard.tsx
26753
26966
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
26754
26967
  var EventCard = ({
@@ -26776,7 +26989,7 @@ var EventCard = ({
26776
26989
  const isSoldOut = cta.hidden;
26777
26990
  const { available: spotsLeft } = getEventAvailability(event);
26778
26991
  const cardClass = `card-${cardVariant}`;
26779
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
26992
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
26780
26993
  const title = event.title;
26781
26994
  const summary = event.presentation?.summary ?? event.description;
26782
26995
  const image = event.presentation?.image ?? null;
@@ -26895,7 +27108,7 @@ var EventCompactRow = ({
26895
27108
  const price = formatEventPrice(event);
26896
27109
  const teacherLine = formatEventTeacherLine(event);
26897
27110
  const cta = resolveEventCta(event, buttonText);
26898
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "sm" });
27111
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "sm" });
26899
27112
  return /* @__PURE__ */ jsxs3("div", { className: "event-compact-row", children: [
26900
27113
  /* @__PURE__ */ jsxs3("div", { className: "event-compact-row-content", children: [
26901
27114
  /* @__PURE__ */ jsxs3("div", { className: "event-compact-row-top", children: [
@@ -33582,11 +33795,12 @@ var ButtonNode = ({
33582
33795
  }
33583
33796
  return null;
33584
33797
  }
33585
- const resolvedVariantId = typeof variantId === "string" ? variantId.trim() : "";
33586
- const normalizedVariantId = resolvedVariantId === DEFAULT_VARIANT_ALIAS_ID ? "" : resolvedVariantId;
33587
- const variantClasses = normalizedVariantId ? [normalizedVariantId, `button-${normalizedVariantId}`] : [];
33588
- const sizeClass = `btn-${size}`;
33589
- const combinedClassName = [...variantClasses, sizeClass, className].filter(Boolean).join(" ");
33798
+ const resolvedVariantId = parseThemeButtonVariantId(variantId);
33799
+ const combinedClassName = resolvedVariantId ? themeButtonClassName({
33800
+ variant: resolvedVariantId,
33801
+ size,
33802
+ extraClassName: className
33803
+ }) : className;
33590
33804
  if (resolvedHref) {
33591
33805
  return /* @__PURE__ */ jsx15(
33592
33806
  "a",
@@ -34160,7 +34374,7 @@ function FileDownloadNode({
34160
34374
  {
34161
34375
  href,
34162
34376
  download: filename,
34163
- className: themedButtonClass({
34377
+ className: themeButtonClassName({
34164
34378
  variant,
34165
34379
  size: "md",
34166
34380
  extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2"
@@ -35852,7 +36066,7 @@ var EventSpotlight = ({
35852
36066
  }
35853
36067
  const containerClass = getContainerClass(layout, columns);
35854
36068
  const cardOrientation = getCardOrientation(layout);
35855
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
36069
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
35856
36070
  return /* @__PURE__ */ jsxs19("div", { className: `event-spotlight-section ${className || ""}`, "data-block": "event-spotlight", children: [
35857
36071
  /* @__PURE__ */ jsx32("div", { className: `event-spotlight ${containerClass}`, children: normalizedEvents.map((event) => /* @__PURE__ */ jsx32(
35858
36072
  EventCard,
@@ -36345,7 +36559,16 @@ function CheckoutShellView(props2) {
36345
36559
  import { Fragment as Fragment5, jsx as jsx36, jsxs as jsxs22 } from "react/jsx-runtime";
36346
36560
  function renderServerPendingAction(label, soldOut) {
36347
36561
  return /* @__PURE__ */ jsxs22(Fragment5, { children: [
36348
- /* @__PURE__ */ jsx36("button", { type: "button", className: "default", disabled: true, "aria-disabled": "true", children: soldOut ? "Sold out" : label }),
36562
+ /* @__PURE__ */ jsx36(
36563
+ "button",
36564
+ {
36565
+ type: "button",
36566
+ className: themeButtonClassName({ variant: "default", size: "md" }),
36567
+ disabled: true,
36568
+ "aria-disabled": "true",
36569
+ children: soldOut ? "Sold out" : label
36570
+ }
36571
+ ),
36349
36572
  !soldOut ? /* @__PURE__ */ jsx36("p", { className: "rb-caption status-muted", children: "Cart actions become interactive after page load." }) : null
36350
36573
  ] });
36351
36574
  }
@@ -36365,7 +36588,14 @@ function ProductListServerContent(props2) {
36365
36588
  ),
36366
36589
  actions: /* @__PURE__ */ jsxs22(Fragment5, { children: [
36367
36590
  renderServerPendingAction(card.actionLabel, card.soldOut),
36368
- card.path ? /* @__PURE__ */ jsx36("a", { href: card.path, className: "secondary btn-sm", children: "View details" }) : null
36591
+ card.path ? /* @__PURE__ */ jsx36(
36592
+ "a",
36593
+ {
36594
+ href: card.path,
36595
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
36596
+ children: "View details"
36597
+ }
36598
+ ) : null
36369
36599
  ] })
36370
36600
  },
36371
36601
  card.productId
@@ -36898,7 +37128,7 @@ function renderCalendarGrid(display) {
36898
37128
  "button",
36899
37129
  {
36900
37130
  type: "button",
36901
- className: themedButtonClass({
37131
+ className: themeButtonClassName({
36902
37132
  variant: display.buttonVariant,
36903
37133
  size: "sm"
36904
37134
  }),
@@ -36984,7 +37214,7 @@ function renderTimetableSsr(display) {
36984
37214
  "button",
36985
37215
  {
36986
37216
  type: "button",
36987
- className: themedButtonClass({
37217
+ className: themeButtonClassName({
36988
37218
  variant: display.buttonVariant,
36989
37219
  size: "sm"
36990
37220
  }),
@@ -37341,7 +37571,7 @@ var FormNodeSSR = ({
37341
37571
  "button",
37342
37572
  {
37343
37573
  type: "submit",
37344
- className: themedButtonClass({
37574
+ className: themeButtonClassName({
37345
37575
  variant: "primary",
37346
37576
  size: "md",
37347
37577
  extraClassName: "rb-w-full rb-sm-w-auto"
@@ -37432,7 +37662,7 @@ function NewsletterFormSSR({
37432
37662
  "button",
37433
37663
  {
37434
37664
  type: "submit",
37435
- className: themedButtonClass({ variant: "primary", size: "md" }),
37665
+ className: themeButtonClassName({ variant: "primary", size: "md" }),
37436
37666
  children: display.buttonLabel
37437
37667
  }
37438
37668
  ) })
@@ -37552,7 +37782,16 @@ function ShopSSR({
37552
37782
  PassCardView,
37553
37783
  {
37554
37784
  display: pass,
37555
- action: /* @__PURE__ */ jsx49("button", { type: "button", className: "default", disabled: true, "aria-disabled": "true", children: pass.actionLabel })
37785
+ action: /* @__PURE__ */ jsx49(
37786
+ "button",
37787
+ {
37788
+ type: "button",
37789
+ className: themeButtonClassName({ variant: "default", size: "md" }),
37790
+ disabled: true,
37791
+ "aria-disabled": "true",
37792
+ children: pass.actionLabel
37793
+ }
37794
+ )
37556
37795
  },
37557
37796
  pass.id
37558
37797
  )),
@@ -37560,7 +37799,16 @@ function ShopSSR({
37560
37799
  MembershipCardView,
37561
37800
  {
37562
37801
  display: membership,
37563
- action: /* @__PURE__ */ jsx49("button", { type: "button", className: "default", disabled: true, "aria-disabled": "true", children: membership.actionLabel })
37802
+ action: /* @__PURE__ */ jsx49(
37803
+ "button",
37804
+ {
37805
+ type: "button",
37806
+ className: themeButtonClassName({ variant: "default", size: "md" }),
37807
+ disabled: true,
37808
+ "aria-disabled": "true",
37809
+ children: membership.actionLabel
37810
+ }
37811
+ )
37564
37812
  },
37565
37813
  membership.id
37566
37814
  ))
@@ -41893,13 +42141,13 @@ function hydrateValue(value, context) {
41893
42141
  return isUnchanged ? value : resolvedItems;
41894
42142
  }
41895
42143
  if (isRecord3(value)) {
41896
- if (isInternalLink2(value)) {
42144
+ if (isInternalLink(value)) {
41897
42145
  return hydrateInternalLink(value, context.routes);
41898
42146
  }
41899
- if (isPageLink2(value)) {
42147
+ if (isPageLink(value)) {
41900
42148
  return hydratePageLink(value, context);
41901
42149
  }
41902
- if (isEntryLink2(value)) {
42150
+ if (isEntryLink(value)) {
41903
42151
  return hydrateEntryLink(value, context);
41904
42152
  }
41905
42153
  const resolvedEntries = Object.entries(value).map(([key, entry]) => [key, hydrateValue(entry, context)]);
@@ -41929,7 +42177,7 @@ function hydrateInternalLink(link2, routes) {
41929
42177
  }
41930
42178
  return Object.keys(updates).length > 0 ? { ...link2, ...updates } : link2;
41931
42179
  }
41932
- function isInternalLink2(value) {
42180
+ function isInternalLink(value) {
41933
42181
  if (value.kind !== "internal") {
41934
42182
  return false;
41935
42183
  }
@@ -41938,7 +42186,7 @@ function isInternalLink2(value) {
41938
42186
  }
41939
42187
  return true;
41940
42188
  }
41941
- function isPageLink2(value) {
42189
+ function isPageLink(value) {
41942
42190
  if (value.kind !== "page") {
41943
42191
  return false;
41944
42192
  }
@@ -41954,7 +42202,7 @@ function hydratePageLink(link2, context) {
41954
42202
  }
41955
42203
  return { ...link2, href: resolved.href, routeId: resolved.routeId };
41956
42204
  }
41957
- function isEntryLink2(value) {
42205
+ function isEntryLink(value) {
41958
42206
  if (value.kind !== "entry") {
41959
42207
  return false;
41960
42208
  }
@@ -53760,7 +54008,7 @@ var SimpleCache = class {
53760
54008
  };
53761
54009
 
53762
54010
  // src/version.ts
53763
- var SDK_VERSION = "0.60.9";
54011
+ var SDK_VERSION = "0.60.12";
53764
54012
 
53765
54013
  // src/client/error.ts
53766
54014
  var RiverbankApiError = class _RiverbankApiError extends Error {
@@ -69,6 +69,68 @@ function toLocationCoordinates(value) {
69
69
  };
70
70
  }
71
71
 
72
+ // ../core/src/participant-identity.ts
73
+ var PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD = {
74
+ participant_id: {
75
+ field: "participant_id",
76
+ role: "canonical_link",
77
+ canonicalSource: "booking_participants.id",
78
+ contractAction: "tighten_in_839",
79
+ notes: "Canonical person-subject link for a participation. #839 should enforce this once preflight is clean."
80
+ },
81
+ display_name: {
82
+ field: "display_name",
83
+ role: "contextual_snapshot",
84
+ canonicalSource: "booking_participants.display_name for live identity",
85
+ contractAction: "retain_as_snapshot",
86
+ notes: "Participation-time display context. Readers must not treat it as mutable live participant identity."
87
+ },
88
+ email: {
89
+ field: "email",
90
+ role: "contextual_snapshot",
91
+ canonicalSource: "booking_participants.email_normalized for live email identity",
92
+ contractAction: "retain_as_snapshot",
93
+ notes: "Participation-time contact snapshot used for notifications/context. Live identity belongs to the participant row."
94
+ },
95
+ email_normalized: {
96
+ field: "email_normalized",
97
+ role: "contextual_snapshot",
98
+ canonicalSource: "booking_participants.email_normalized for live email identity",
99
+ contractAction: "retain_as_snapshot",
100
+ notes: "Normalized snapshot/dedupe helper for the participation slot, not live person authority."
101
+ },
102
+ phone: {
103
+ field: "phone",
104
+ role: "contextual_snapshot",
105
+ canonicalSource: "booking_participants.phone for live phone identity",
106
+ contractAction: "retain_as_snapshot",
107
+ notes: "Participation-time phone context. Live identity belongs to the participant row."
108
+ },
109
+ identity_state: {
110
+ field: "identity_state",
111
+ role: "materialization_state",
112
+ canonicalSource: "booking_participants.identity_state for subject state",
113
+ contractAction: "review_for_later_contract_cleanup",
114
+ notes: "Slot materialization state: booker_supplied, contactable, portal_claimed, or staff_verified."
115
+ },
116
+ event_attendee_guest_id: {
117
+ field: "event_attendee_guest_id",
118
+ role: "compatibility_projection",
119
+ canonicalSource: "canonical participant slot plus #838 event guest compatibility projection",
120
+ contractAction: "retain_as_projection",
121
+ notes: "Compatibility FK for event guest read models. It is not person identity authority."
122
+ }
123
+ };
124
+ var PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATIONS = [
125
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.participant_id,
126
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.display_name,
127
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.email,
128
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.email_normalized,
129
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.phone,
130
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.identity_state,
131
+ PARTICIPANT_PARTICIPATION_IDENTITY_FIELD_CLASSIFICATION_BY_FIELD.event_attendee_guest_id
132
+ ];
133
+
72
134
  // ../media-core/src/aspectTransforms.ts
73
135
  function parseAspectRatioValue(value) {
74
136
  if (typeof value === "number") {
@@ -4,7 +4,7 @@ import * as path from "path";
4
4
  import * as crypto from "crypto";
5
5
 
6
6
  // src/version.ts
7
- var SDK_VERSION = "0.60.9";
7
+ var SDK_VERSION = "0.60.12";
8
8
 
9
9
  // src/constants.ts
10
10
  var PREBUILD_PAGE_SIZE = 50;