riverbankcms 0.9.0 → 0.10.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.
- package/dist/acceptance/matrix.mjs +3 -3
- package/dist/cli/index.mjs +872 -652
- package/dist/{eventUpsertInputSchema-CqHIJp9H.mjs → eventUpsertInputSchema-yErCHdr6.mjs} +2 -2
- package/dist/load-config-BToL9PfS.mjs +4 -0
- package/dist/{load-config-Cf5uPEAn.mjs → load-config-Bzc6Qo24.mjs} +2 -2
- package/dist/{local-sync-DF-2DL_D.mjs → local-sync-3ZG1khGb.mjs} +2 -2
- package/dist/{plan-By0bjnd3.mjs → plan-C1Frmu6F.mjs} +1 -1
- package/dist/scaffold/index.mjs +2 -2
- package/dist/{sdk-event-upsert-BNxbxaA0.mjs → sdk-event-upsert-DhdlT2ko.mjs} +2187 -1806
- package/dist/{src-DbmhanBI.mjs → src-DIAVNRwo.mjs} +120 -1
- package/dist/testing.mjs +3 -3
- package/package.json +1 -1
- package/dist/load-config-CKBdp8M0.mjs +0 -4
package/dist/cli/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as
|
|
3
|
-
import { $ as
|
|
4
|
-
import { $ as sdkUpsertEventResponseSchema, A as resolveMediaTransformForAspect, B as asRecord$1, C as walkAndCollectImageAttrs, D as normalizeWidthCandidates, E as rotateNormalizedPoint, F as buildMediaIdentifierFromFilename, G as parseSafeDownloadFilename, H as FILE_SIZE_LIMITS, I as parseMediaIdentifier, J as createHttpClient, K as ManagementApiError, L as deriveVideoSlotPolicy, M as getDirectImageUrlForSiteScopedPath, N as getImageUrl, O as isExplicitRectCrop, P as isSiteScopedDirectImageStoragePath, Q as sdkListEventsResponseSchema, R as resolveVideoSelectionIntentForMediaField, S as buildRenderableMediaAssetIndex, T as looksLikeUuid$1, U as classifyKnownMimeType, V as parseRelativeStoragePath, W as managementMediaLibraryUploadLimitForMimeType, X as sdkConfigureBookingVerticalResponseSchema, Y as is404Error, Z as sdkGetEventResponseSchema, _ as buildSettingsUpdateInput, _t as sdkConfiguredBookingVerticalConfigSchema, a as prepareLocalMediaForPush, at as externalLinkSchema$1, b as isMediaValue, c as writeBinaryFileAtomic, ct as internalRouteOnlyLinkSchema, d as normalizeMediaValueToIdentifierOnly, dt as linkSchema, et as sdkSettingsUpdateSchema, f as walkLocalContentMedia, ft as pageLinkSchema$1, g as SETTINGS_FILE_FIELDS, gt as sdkReorderResponseSchema, h as extractMediaIdentifiers, ht as sdkListEventOccurrencesResponseSchema, i as applyLocalMediaPush, it as entryLinkSchema$1, j as getDirectImageUrlForRelativePath, k as parseAspectRatioValue, l as sha256, lt as isInternalResolvedLinkValue, m as downloadMedia, mt as sdkEventOccurrenceResponseSchema, nt as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, o as admitBinaryWriteDestination, ot as internalLinkSchema, p as buildStorageUrl, pt as sdkDeleteEventOccurrenceResponseSchema, q as buildRequestInfo, r as syncLocalMediaForPull, rt as customLinkSchema$1, s as readStableBinaryFile, st as internalResolvedLinkSchema, t as revalidateLocalMediaPushPlan, tt as linkPayloadSchema, u as normalizeMediaIdentifierInput, ut as isResolvedInternalLinkEntityType, v as hasOwnSettingsField, w as deleteEnvSpecificKeys, x as attachRenderableMediaAssetFields, y as writeMediaManifest, z as getMimeType } from "../local-sync-
|
|
5
|
-
import { n as CliSdkPeerError, r as CLI_VERSION, t as loadConfigFile } from "../load-config-
|
|
6
|
-
import { a as RichTextDocSchema, c as isRecord$17, i as findUnfilledSentinels, n as buildEntryScaffold, o as isRichTextDoc, r as validateEntryInstance, s as isObjectRecord, t as eventUpsertInputSchema } from "../eventUpsertInputSchema-
|
|
7
|
-
import { a as prepareScaffoldExecution, c as LOCAL_PACKAGE_VENDOR_DIR, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, n as createScaffoldCompletion, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan } from "../plan-
|
|
2
|
+
import { $ as resolveContextualButtonRole, $n as footerModeSchema, $t as getComponentBorderWidthPx, A as boundaryLayout, An as surfaceToneFromForegroundToken, At as headerVariantValues, B as require_jsx_runtime, Bn as oklchToHexGamut, Bt as defineBlockDesignCapability, C as mergeHeaderNavTypographyPreference, Cn as borderColorStyle, Ct as BREAKPOINT_SM, D as GRADIENT_PRESET_IDS, Dn as textColorStyle, Dt as MQ_SM_DOWN, E as gradientToCss, En as rgbColorValue, Et as MQ_MD_DOWN, F as transitionCatalogueEntries, Fn as defaultThemeTokens, Ft as pageDesignEditorBackgroundOverrideOwner, G as PUBLIC_BUTTON_ROLES, Gn as generateShadowValue$1, Gt as featureCardCompositionTreatmentValues, H as pickShadeTowardBackground, Hn as surfaceForegroundDeclarations, Ht as defineNoBlockDesignCapability, I as backgroundAppearanceColorTokenNames, In as ORDINARY_TEXT_MIN_CONTRAST_RATIO, It as stripStaleTransitionStyleGroup, J as resolvedButtonColourDeclarations, Jn as normalizeCardRole, Jt as makeBoundaryId, K as generateButtonCss, Kn as cardRoleSchema, Kt as headingDecorationColorTokenValues, L as backgroundAppearanceQuickColorTokenNames, Ln as contrastRatio, M as sectionFactsForContent, Mn as isOnColorBackgroundCandidateToken, Mt as resolveOnColorForThemeToken, N as boundaryRuntimeMetricsForDecorativeTransition, Nn as onColorTokenName, Nt as resolveThemeColorReferenceValue, O as getGradientPreset, On as textColorValue, Ot as MQ_SM_UP, P as anglePolygonCss, Pn as buildThemeTokens, Pt as resolveTokenOrCssColorValue, Q as deriveButtonSurfaceContext, Qn as persistableMediaSchema, Qt as visibleHeadingDecorationFamilyValues, R as parseBackgroundAppearanceColorToken, Rn as featuresFromHex, Rt as asDesignBlockId, Sn as backgroundColorStyle, St as BREAKPOINT_MD, T as getCuratedSiteStyle, Tn as mergeStyles, Tt as MQ_LG_UP, U as generateCssVars, Un as surfaceForegroundStyle, Ut as eventListTreatmentValues, V as require_react, Vn as DEFAULT_SURFACE_TEXT_COLOR, Vt as defineFrameCapability, Wn as surfaceForegroundValue, Wt as eyebrowTreatmentValues, X as contextualButtonSurfaceResetStyles, Xn as mediaSchema, Xt as testimonialsCompositionTreatmentValues, Y as resolvedButtonFocusDeclarations, Yn as mediaIdentifierSchema, Yt as offeringsPreviewCompositionTreatmentValues, Z as contextualButtonSurfaceStyles, Zn as mediaTypeDiscriminants, Zt as tileTreatmentValues, _ as entryIdentifierForCommand, _n as ICON_SIZE_PX, _r as slugPart, _t as generateHeaderScrollTreatmentStyles, a as classifySdkEventBookingOffer, an as NAV_LINK_PADDING_MAP, ar as createBlocksRef, at as themeButtonExtraClassesWithTrailingIcon, b as pagePathForCommand, bn as generateCardCss, bt as renderHeaderPaintTargetRules, c as stableStringify, cn as FONT_WEIGHT_MAP, cr as createEventCategoryRef, ct as parseThemeForPersistence, d as mapEventCommandContent, dn as LABEL_FONT_SIZE_MAP, dr as createFormRef, dt as generateShadowValue, en as getComponentShadowVar, er as VARIANT_ROLES, et as generateDefaultButtonSystem, f as evaluateSiteCommandBatchExposure, fn as ACCORDION_OPEN_ACCENT_THICKNESS, fr as createNavigationRef, ft as expandPalette, g as blockOrderIdentifiersForCommand, gn as ICON_CONFIG, gr as refSlug, gt as boxBackgroundSchema, h as blockIdentifierForCommand, hn as ACCORDION_TRIGGER_LETTER_SPACING, hr as createVenueRef, ht as boxBackgroundOverlaySchema, in as NAV_LINK_LETTER_SPACING_MAP, ir as createBlockRef, it as parseThemeButtonVariantId, j as composeBoundary, jn as resolveSurfaceForeground, jt as isCssColorLiteral, k as parseGradientPresetId, kn as selectLogoVariant, kt as MQ_TABLET_ONLY, l as createDryRunReport, ln as INPUT_FONT_SIZE_MAP, lr as createEventSeriesRef, lt as compileButtonColourStates, m as getSiteCommandMetadata, mn as ACCORDION_TRIGGER_FONT_SCALE, mr as createSiteCommandSiteRef, mt as themeSchema, nn as parseCustomCssRules, nr as unsafeAsOpaqueButtonColourToken, nt as generateBaseInteractiveCSS, o as venueManagementFields, on as NAV_LINK_PADDING_X_MAP, or as createCommandRef, ot as themeButtonSizeClassName, p as evaluateSiteCommandExposure, pn as ACCORDION_SPACING_MAP, pr as createPageRef, pt as getTextColorForBackground, q as RESOLVED_BUTTON_DISABLED_DECLARATIONS, qn as cardVariantRoleValues, qt as introCompositionTreatmentValues, rn as NAV_LINK_BORDER_RADIUS_MAP, rr as parseBlockColorToken, rt as generateInteractiveChildInheritanceCSS, s as sortRecord, sn as NAV_LINK_TEXT_SIZE_MAP, sr as createContentEntryRef, st as themeButtonVariantClassNames, t as classifySdkEventTiming, tn as parseBlockCustomCssRules, tr as buttonVariantIdSchema, tt as generateEffectsCSS, u as parseAndPlanCommandBatchForTypes, un as INPUT_SPACING_MAP, ur as createFooterRef, ut as formatButtonColourContractError, v as pageIdentifierForBlockCommand, vn as generateCardCoreCss, vr as __toESM, vt as generateMobileOverlayBackdropFilterFix, w as readHeaderNavFontSizePreference, wn as cssVarValue, wt as BREAKPOINT_XL, x as hasConfiguredBookingVertical, xn as TokenResolver, xt as BREAKPOINT_LG, y as pageIdentifierForCommand, yn as getDefaultCardVariants, yt as getHeaderPaintTargets, z as defineBlockDesignMetadata, zn as hexToRgb, zt as assertNever$4 } from "../sdk-event-upsert-DhdlT2ko.mjs";
|
|
3
|
+
import { $ as formatBookingPriceDisplay, A as parseFooterCompositionV1, At as unsafeAsPositiveByteCount, B as formatBookingDateParts, C as parseMailingListContentVersionId, D as DEFAULT_MAILING_LIST_SUCCESS_MESSAGE, Dt as unsafeAsMediaAssetId, E as planMailingListChoicePresentation, F as normalizeLocationAddressText, G as getLocalScheduleDate, H as formatLocalScheduleDate, Ht as err, I as toLocationCoordinates, J as toBookingTimeZone, K as getLocalScheduleTime, L as selectCategoryView, Lt as unsafeAsStaffMemberId, N as assertAllowedPublicUrl, O as parseMailingListProviderScope, Q as parseEventPageSurfaceSubject, R as buildBookingUtcDateWindow, S as parseMailingListBlockId, T as parseMailingListRuntimeContext, U as formatLocalScheduleTime, Ut as ok, V as formatBookingTime, W as getBookingLocalDateKey, X as toScheduledBookingDateTime, Y as toScheduledBookingDateRange, _ as createSecret, _t as unsafeAsAppointmentResourceId, at as resolveExactOrFreePriceDisplay, c as DEFAULT_EVENT_TYPE_PRESETS, d as SURFACE_EVENT_PRESET_VALUES, dt as parseApiKeyId, et as formatEventPricing, f as WHOLE_SERIES_EVENT_PRESET_VALUES, ft as parseEventSeriesId, g as resolveWholeSeriesBookingPhase, gt as parseUserId, h as orderedLiveRunSessions, ht as parseSiteId, it as publicEventPricingType, j as parseMailingListPlacementTargeting, l as EVENT_PRESET_VALUES, lt as formatCurrencyAmount, m as CANCELLED_SESSION_STATUS, mt as parsePageId, n as NAVIGATION_LOCATIONS, nt as publicEventPricingCurrency, ot as resolvePricingOptionsPriceDisplay, p as publicReadFreshnessSeconds, pt as parseMediaAssetId, r as areConfiguredBookingVerticalConfigsEqual, rt as publicEventPricingDisplay, s as resolveSiteVerticalBookingConfig, t as resolveEventCatalogue, tt as isPublicEventPricingOptionDisplayable, ut as assertNever, v as exposeSecret, w as parseMailingListSignedSourceToken, x as buildMailingListSignupBlockSourceRef, xt as unsafeAsDemoCapability, y as parseManagementKey, z as formatBookingDate } from "../src-DIAVNRwo.mjs";
|
|
4
|
+
import { $ as sdkUpsertEventResponseSchema, A as resolveMediaTransformForAspect, B as asRecord$1, C as walkAndCollectImageAttrs, D as normalizeWidthCandidates, E as rotateNormalizedPoint, F as buildMediaIdentifierFromFilename, G as parseSafeDownloadFilename, H as FILE_SIZE_LIMITS, I as parseMediaIdentifier, J as createHttpClient, K as ManagementApiError, L as deriveVideoSlotPolicy, M as getDirectImageUrlForSiteScopedPath, N as getImageUrl, O as isExplicitRectCrop, P as isSiteScopedDirectImageStoragePath, Q as sdkListEventsResponseSchema, R as resolveVideoSelectionIntentForMediaField, S as buildRenderableMediaAssetIndex, T as looksLikeUuid$1, U as classifyKnownMimeType, V as parseRelativeStoragePath, W as managementMediaLibraryUploadLimitForMimeType, X as sdkConfigureBookingVerticalResponseSchema, Y as is404Error, Z as sdkGetEventResponseSchema, _ as buildSettingsUpdateInput, _t as sdkConfiguredBookingVerticalConfigSchema, a as prepareLocalMediaForPush, at as externalLinkSchema$1, b as isMediaValue, c as writeBinaryFileAtomic, ct as internalRouteOnlyLinkSchema, d as normalizeMediaValueToIdentifierOnly, dt as linkSchema, et as sdkSettingsUpdateSchema, f as walkLocalContentMedia, ft as pageLinkSchema$1, g as SETTINGS_FILE_FIELDS, gt as sdkReorderResponseSchema, h as extractMediaIdentifiers, ht as sdkListEventOccurrencesResponseSchema, i as applyLocalMediaPush, it as entryLinkSchema$1, j as getDirectImageUrlForRelativePath, k as parseAspectRatioValue, l as sha256, lt as isInternalResolvedLinkValue, m as downloadMedia, mt as sdkEventOccurrenceResponseSchema, nt as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, o as admitBinaryWriteDestination, ot as internalLinkSchema, p as buildStorageUrl, pt as sdkDeleteEventOccurrenceResponseSchema, q as buildRequestInfo, r as syncLocalMediaForPull, rt as customLinkSchema$1, s as readStableBinaryFile, st as internalResolvedLinkSchema, t as revalidateLocalMediaPushPlan, tt as linkPayloadSchema, u as normalizeMediaIdentifierInput, ut as isResolvedInternalLinkEntityType, v as hasOwnSettingsField, w as deleteEnvSpecificKeys, x as attachRenderableMediaAssetFields, y as writeMediaManifest, z as getMimeType } from "../local-sync-3ZG1khGb.mjs";
|
|
5
|
+
import { n as CliSdkPeerError, r as CLI_VERSION, t as loadConfigFile } from "../load-config-Bzc6Qo24.mjs";
|
|
6
|
+
import { a as RichTextDocSchema, c as isRecord$17, i as findUnfilledSentinels, n as buildEntryScaffold, o as isRichTextDoc, r as validateEntryInstance, s as isObjectRecord, t as eventUpsertInputSchema } from "../eventUpsertInputSchema-yErCHdr6.mjs";
|
|
7
|
+
import { a as prepareScaffoldExecution, c as LOCAL_PACKAGE_VENDOR_DIR, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, n as createScaffoldCompletion, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan } from "../plan-C1Frmu6F.mjs";
|
|
8
8
|
import { config } from "dotenv";
|
|
9
9
|
import { Command, CommanderError } from "commander";
|
|
10
10
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -176,16 +176,16 @@ var BlockPatchStaleContentError = class extends ManagementApiError {
|
|
|
176
176
|
function isBlockPatchStaleContentError(error$1) {
|
|
177
177
|
return error$1 instanceof BlockPatchStaleContentError;
|
|
178
178
|
}
|
|
179
|
-
function isRecord$
|
|
179
|
+
function isRecord$37(value) {
|
|
180
180
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
181
181
|
}
|
|
182
182
|
function extractStaleContentCurrentHash(error$1) {
|
|
183
183
|
if (error$1.statusCode !== 409) return null;
|
|
184
|
-
if (!isRecord$
|
|
184
|
+
if (!isRecord$37(error$1.details)) return null;
|
|
185
185
|
const fieldErrors = error$1.details.fieldErrors;
|
|
186
186
|
if (!Array.isArray(fieldErrors)) return null;
|
|
187
187
|
for (const fieldError of fieldErrors) {
|
|
188
|
-
if (isRecord$
|
|
188
|
+
if (isRecord$37(fieldError) && fieldError.field === SDK_PATCH_STALE_CONTENT_FIELD && fieldError.code === SDK_PATCH_STALE_CONTENT_CODE && typeof fieldError.message === "string") {
|
|
189
189
|
return fieldError.message;
|
|
190
190
|
}
|
|
191
191
|
}
|
|
@@ -2524,6 +2524,77 @@ function parsePublicProductCategorySelector(value) {
|
|
|
2524
2524
|
return undefined;
|
|
2525
2525
|
}
|
|
2526
2526
|
|
|
2527
|
+
//#endregion
|
|
2528
|
+
//#region ../api/src/defineEndpointDefinitions.ts
|
|
2529
|
+
/**
|
|
2530
|
+
* Validates extracted endpoint descriptors while preserving each literal path,
|
|
2531
|
+
* method, and parameter contract for the typed URL builders.
|
|
2532
|
+
*/
|
|
2533
|
+
function defineEndpointDefinitions(definitions$1) {
|
|
2534
|
+
return definitions$1;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
//#endregion
|
|
2538
|
+
//#region ../api/src/publicNewsletterEndpointDefinitions.ts
|
|
2539
|
+
const PUBLIC_NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
|
|
2540
|
+
subscribeNewsletter: {
|
|
2541
|
+
path: "/public/sites/{siteId}/newsletter/subscribe",
|
|
2542
|
+
method: "POST",
|
|
2543
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2544
|
+
auth: "public",
|
|
2545
|
+
responseKind: "json"
|
|
2546
|
+
},
|
|
2547
|
+
confirmNewsletter: {
|
|
2548
|
+
path: "/public/sites/{siteId}/newsletter/confirm/{token}",
|
|
2549
|
+
method: "GET",
|
|
2550
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2551
|
+
auth: "public",
|
|
2552
|
+
responseKind: "text"
|
|
2553
|
+
},
|
|
2554
|
+
unsubscribeNewsletter: {
|
|
2555
|
+
path: "/public/sites/{siteId}/newsletter/unsubscribe/{token}",
|
|
2556
|
+
method: "GET",
|
|
2557
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2558
|
+
auth: "public",
|
|
2559
|
+
responseKind: "text"
|
|
2560
|
+
},
|
|
2561
|
+
unsubscribeNewsletterPost: {
|
|
2562
|
+
path: "/public/sites/{siteId}/newsletter/unsubscribe/{token}",
|
|
2563
|
+
method: "POST",
|
|
2564
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2565
|
+
auth: "public",
|
|
2566
|
+
responseKind: "text"
|
|
2567
|
+
},
|
|
2568
|
+
confirmNewsletterPost: {
|
|
2569
|
+
path: "/public/sites/{siteId}/newsletter/confirm/{token}",
|
|
2570
|
+
method: "POST",
|
|
2571
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2572
|
+
auth: "public",
|
|
2573
|
+
responseKind: "text"
|
|
2574
|
+
},
|
|
2575
|
+
getNewsletterPreferences: {
|
|
2576
|
+
path: "/public/sites/{siteId}/newsletter/preferences/{token}",
|
|
2577
|
+
method: "GET",
|
|
2578
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2579
|
+
auth: "public",
|
|
2580
|
+
responseKind: "text"
|
|
2581
|
+
},
|
|
2582
|
+
saveNewsletterPreferences: {
|
|
2583
|
+
path: "/public/sites/{siteId}/newsletter/preferences/{token}",
|
|
2584
|
+
method: "POST",
|
|
2585
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2586
|
+
auth: "public",
|
|
2587
|
+
responseKind: "text"
|
|
2588
|
+
},
|
|
2589
|
+
getNewsletterArchive: {
|
|
2590
|
+
path: "/public/sites/{siteId}/newsletter/archive/{token}",
|
|
2591
|
+
method: "GET",
|
|
2592
|
+
tags: ["public-newsletter-{siteId}"],
|
|
2593
|
+
auth: "public",
|
|
2594
|
+
responseKind: "text"
|
|
2595
|
+
}
|
|
2596
|
+
});
|
|
2597
|
+
|
|
2527
2598
|
//#endregion
|
|
2528
2599
|
//#region ../api/src/apiEndpointTypes.ts
|
|
2529
2600
|
function allowedDemoMutationPolicy() {
|
|
@@ -2783,18 +2854,89 @@ const SDK_ENTRY_READ_ENDPOINTS = {
|
|
|
2783
2854
|
};
|
|
2784
2855
|
|
|
2785
2856
|
//#endregion
|
|
2786
|
-
//#region ../api/src/
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2857
|
+
//#region ../api/src/appointmentServiceCategoryEndpoints.ts
|
|
2858
|
+
const APPOINTMENT_SERVICE_CATEGORY_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
|
|
2859
|
+
listGroupedAppointmentServices: {
|
|
2860
|
+
path: "/sites/{siteId}/bookings/services/grouped",
|
|
2861
|
+
method: "GET",
|
|
2862
|
+
auth: "user",
|
|
2863
|
+
responseKind: "json",
|
|
2864
|
+
errors: ["server:internal_error"]
|
|
2865
|
+
},
|
|
2866
|
+
reorderAppointmentServices: {
|
|
2867
|
+
path: "/sites/{siteId}/bookings/services/order",
|
|
2868
|
+
method: "PUT",
|
|
2869
|
+
auth: "user",
|
|
2870
|
+
responseKind: "json",
|
|
2871
|
+
errors: [
|
|
2872
|
+
"validation:invalid_input",
|
|
2873
|
+
"auth:forbidden",
|
|
2874
|
+
"resource:not_found",
|
|
2875
|
+
"resource:conflict",
|
|
2876
|
+
"server:internal_error"
|
|
2877
|
+
]
|
|
2878
|
+
},
|
|
2879
|
+
listAppointmentServiceCategories: {
|
|
2880
|
+
path: "/sites/{siteId}/bookings/service-categories",
|
|
2881
|
+
method: "GET",
|
|
2882
|
+
auth: "user",
|
|
2883
|
+
responseKind: "json",
|
|
2884
|
+
errors: ["server:internal_error"]
|
|
2885
|
+
},
|
|
2886
|
+
createAppointmentServiceCategory: {
|
|
2887
|
+
path: "/sites/{siteId}/bookings/service-categories",
|
|
2888
|
+
method: "POST",
|
|
2889
|
+
auth: "user",
|
|
2890
|
+
responseKind: "json",
|
|
2891
|
+
errors: [
|
|
2892
|
+
"validation:invalid_input",
|
|
2893
|
+
"auth:forbidden",
|
|
2894
|
+
"resource:conflict",
|
|
2895
|
+
"server:internal_error"
|
|
2896
|
+
]
|
|
2897
|
+
},
|
|
2898
|
+
updateAppointmentServiceCategory: {
|
|
2899
|
+
path: "/sites/{siteId}/bookings/service-categories/{categoryId}",
|
|
2900
|
+
method: "PUT",
|
|
2901
|
+
auth: "user",
|
|
2902
|
+
responseKind: "json",
|
|
2903
|
+
errors: [
|
|
2904
|
+
"validation:invalid_input",
|
|
2905
|
+
"auth:forbidden",
|
|
2906
|
+
"resource:not_found",
|
|
2907
|
+
"resource:conflict",
|
|
2908
|
+
"server:internal_error"
|
|
2909
|
+
]
|
|
2910
|
+
},
|
|
2911
|
+
deleteAppointmentServiceCategory: {
|
|
2912
|
+
path: "/sites/{siteId}/bookings/service-categories/{categoryId}",
|
|
2913
|
+
method: "DELETE",
|
|
2914
|
+
auth: "user",
|
|
2915
|
+
responseKind: "json",
|
|
2916
|
+
errors: [
|
|
2917
|
+
"auth:forbidden",
|
|
2918
|
+
"resource:not_found",
|
|
2919
|
+
"server:internal_error"
|
|
2920
|
+
]
|
|
2921
|
+
},
|
|
2922
|
+
reorderAppointmentServiceCategories: {
|
|
2923
|
+
path: "/sites/{siteId}/bookings/service-categories/order",
|
|
2924
|
+
method: "PUT",
|
|
2925
|
+
auth: "user",
|
|
2926
|
+
responseKind: "json",
|
|
2927
|
+
errors: [
|
|
2928
|
+
"validation:invalid_input",
|
|
2929
|
+
"auth:forbidden",
|
|
2930
|
+
"resource:conflict",
|
|
2931
|
+
"server:internal_error"
|
|
2932
|
+
]
|
|
2933
|
+
}
|
|
2934
|
+
});
|
|
2794
2935
|
|
|
2795
2936
|
//#endregion
|
|
2796
2937
|
//#region ../api/src/appointmentEndpointDefinitions.ts
|
|
2797
2938
|
const APPOINTMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
|
|
2939
|
+
...APPOINTMENT_SERVICE_CATEGORY_ENDPOINT_DEFINITIONS,
|
|
2798
2940
|
listAppointmentResources: {
|
|
2799
2941
|
path: "/sites/{siteId}/bookings/resources",
|
|
2800
2942
|
method: "GET",
|
|
@@ -3945,39 +4087,6 @@ const NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
|
|
|
3945
4087
|
auth: "user",
|
|
3946
4088
|
responseKind: "json",
|
|
3947
4089
|
demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
|
|
3948
|
-
},
|
|
3949
|
-
listNewsletterSendJobs: {
|
|
3950
|
-
path: "/sites/{siteId}/newsletter/jobs",
|
|
3951
|
-
method: "GET",
|
|
3952
|
-
tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
|
|
3953
|
-
auth: "user",
|
|
3954
|
-
responseKind: "json"
|
|
3955
|
-
},
|
|
3956
|
-
retryNewsletterSendJob: {
|
|
3957
|
-
path: "/sites/{siteId}/newsletter/jobs/{jobId}/retry",
|
|
3958
|
-
method: "POST",
|
|
3959
|
-
errors: [
|
|
3960
|
-
"validation:invalid_input",
|
|
3961
|
-
"resource:not_found",
|
|
3962
|
-
"auth:forbidden",
|
|
3963
|
-
"server:internal_error"
|
|
3964
|
-
],
|
|
3965
|
-
tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
|
|
3966
|
-
auth: "user",
|
|
3967
|
-
responseKind: "json"
|
|
3968
|
-
},
|
|
3969
|
-
cancelNewsletterSendJob: {
|
|
3970
|
-
path: "/sites/{siteId}/newsletter/jobs/{jobId}/cancel",
|
|
3971
|
-
method: "POST",
|
|
3972
|
-
errors: [
|
|
3973
|
-
"validation:invalid_input",
|
|
3974
|
-
"resource:not_found",
|
|
3975
|
-
"auth:forbidden",
|
|
3976
|
-
"server:internal_error"
|
|
3977
|
-
],
|
|
3978
|
-
tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
|
|
3979
|
-
auth: "user",
|
|
3980
|
-
responseKind: "json"
|
|
3981
4090
|
}
|
|
3982
4091
|
});
|
|
3983
4092
|
|
|
@@ -4757,6 +4866,7 @@ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
|
|
|
4757
4866
|
//#endregion
|
|
4758
4867
|
//#region ../api/src/endpoints.ts
|
|
4759
4868
|
const ENDPOINT_DEFINITIONS = {
|
|
4869
|
+
...PUBLIC_NEWSLETTER_ENDPOINT_DEFINITIONS,
|
|
4760
4870
|
...ACCOUNT_ENDPOINT_DEFINITIONS,
|
|
4761
4871
|
...PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS,
|
|
4762
4872
|
...PUBLIC_EVENT_ENDPOINT_DEFINITIONS,
|
|
@@ -7891,41 +8001,6 @@ const ENDPOINT_DEFINITIONS = {
|
|
|
7891
8001
|
"server:internal_error"
|
|
7892
8002
|
]
|
|
7893
8003
|
},
|
|
7894
|
-
subscribeNewsletter: {
|
|
7895
|
-
path: "/public/sites/{siteId}/newsletter/subscribe",
|
|
7896
|
-
method: "POST",
|
|
7897
|
-
tags: ["public-newsletter-{siteId}"],
|
|
7898
|
-
auth: "public",
|
|
7899
|
-
responseKind: "json"
|
|
7900
|
-
},
|
|
7901
|
-
confirmNewsletter: {
|
|
7902
|
-
path: "/public/sites/{siteId}/newsletter/confirm/{token}",
|
|
7903
|
-
method: "GET",
|
|
7904
|
-
tags: ["public-newsletter-{siteId}"],
|
|
7905
|
-
auth: "public",
|
|
7906
|
-
responseKind: "text"
|
|
7907
|
-
},
|
|
7908
|
-
unsubscribeNewsletter: {
|
|
7909
|
-
path: "/public/sites/{siteId}/newsletter/unsubscribe/{token}",
|
|
7910
|
-
method: "GET",
|
|
7911
|
-
tags: ["public-newsletter-{siteId}"],
|
|
7912
|
-
auth: "public",
|
|
7913
|
-
responseKind: "text"
|
|
7914
|
-
},
|
|
7915
|
-
unsubscribeNewsletterPost: {
|
|
7916
|
-
path: "/public/sites/{siteId}/newsletter/unsubscribe/{token}",
|
|
7917
|
-
method: "POST",
|
|
7918
|
-
tags: ["public-newsletter-{siteId}"],
|
|
7919
|
-
auth: "public",
|
|
7920
|
-
responseKind: "text"
|
|
7921
|
-
},
|
|
7922
|
-
getNewsletterArchive: {
|
|
7923
|
-
path: "/public/sites/{siteId}/newsletter/archive/{token}",
|
|
7924
|
-
method: "GET",
|
|
7925
|
-
tags: ["public-newsletter-{siteId}"],
|
|
7926
|
-
auth: "public",
|
|
7927
|
-
responseKind: "text"
|
|
7928
|
-
},
|
|
7929
8004
|
listSiteContentTypes: {
|
|
7930
8005
|
path: "/sites/{siteId}/content-types",
|
|
7931
8006
|
method: "GET",
|
|
@@ -10424,6 +10499,12 @@ function matchSurfaceSiteRootHost(host) {
|
|
|
10424
10499
|
}
|
|
10425
10500
|
return matchSurfaceHost(host, SURFACE_SITE_ROOT_HOSTS);
|
|
10426
10501
|
}
|
|
10502
|
+
function resolveSurfaceSiteHostContext(value) {
|
|
10503
|
+
if (value === null || value === undefined || typeof value === "string" && value.length === 0) return null;
|
|
10504
|
+
const normalizedHost = normalizeHostLike(value instanceof URL ? value.toString() : value);
|
|
10505
|
+
if (normalizedHost === null) return null;
|
|
10506
|
+
return matchSurfaceSiteRootHost(normalizedHost);
|
|
10507
|
+
}
|
|
10427
10508
|
function resolveSurfaceHostContext(value) {
|
|
10428
10509
|
if (value === null || value === undefined || typeof value === "string" && value.length === 0) return null;
|
|
10429
10510
|
const normalizedHost = normalizeHostLike(value instanceof URL ? value.toString() : value);
|
|
@@ -10500,7 +10581,7 @@ function extractSurfaceAwareSiteSlug(value) {
|
|
|
10500
10581
|
return null;
|
|
10501
10582
|
}
|
|
10502
10583
|
const hostname$1 = parsed.hostname.toLowerCase();
|
|
10503
|
-
const context =
|
|
10584
|
+
const context = resolveSurfaceSiteHostContext(hostname$1);
|
|
10504
10585
|
if (context === null) return null;
|
|
10505
10586
|
if (hostname$1 === context.surfaceRootHost) return null;
|
|
10506
10587
|
if (!hostname$1.endsWith(`.${context.surfaceRootHost}`)) return null;
|
|
@@ -10665,20 +10746,20 @@ function isApiError(result) {
|
|
|
10665
10746
|
function isApiSuccess(result) {
|
|
10666
10747
|
return result.success === true;
|
|
10667
10748
|
}
|
|
10668
|
-
function isRecord$
|
|
10749
|
+
function isRecord$36(value) {
|
|
10669
10750
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10670
10751
|
}
|
|
10671
10752
|
function isFieldError(value) {
|
|
10672
|
-
return isRecord$
|
|
10753
|
+
return isRecord$36(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
|
|
10673
10754
|
}
|
|
10674
10755
|
function fieldErrorsFromUnknown(value) {
|
|
10675
10756
|
if (!Array.isArray(value)) return null;
|
|
10676
10757
|
return value.every(isFieldError) ? value : null;
|
|
10677
10758
|
}
|
|
10678
10759
|
function extractEnvelopeErrorObject(body) {
|
|
10679
|
-
if (!isRecord$
|
|
10760
|
+
if (!isRecord$36(body)) return null;
|
|
10680
10761
|
const error$1 = body.error;
|
|
10681
|
-
if (!isRecord$
|
|
10762
|
+
if (!isRecord$36(error$1)) return null;
|
|
10682
10763
|
if ("success" in body && body.success !== false) {
|
|
10683
10764
|
return null;
|
|
10684
10765
|
}
|
|
@@ -11288,7 +11369,7 @@ const DEFAULT_CONFIG_PATH = "./riverbank.config.ts";
|
|
|
11288
11369
|
function formatPushConfigActionFailure() {
|
|
11289
11370
|
return "push-config failed";
|
|
11290
11371
|
}
|
|
11291
|
-
function isRecord$
|
|
11372
|
+
function isRecord$35(value) {
|
|
11292
11373
|
return typeof value === "object" && value !== null;
|
|
11293
11374
|
}
|
|
11294
11375
|
function parseErrorDetails(value) {
|
|
@@ -11296,10 +11377,10 @@ function parseErrorDetails(value) {
|
|
|
11296
11377
|
if (typeof value === "string") {
|
|
11297
11378
|
return { message: value };
|
|
11298
11379
|
}
|
|
11299
|
-
if (!isRecord$
|
|
11380
|
+
if (!isRecord$35(value)) return {};
|
|
11300
11381
|
const message = typeof value.message === "string" ? value.message : undefined;
|
|
11301
11382
|
const fieldErrorsRaw = value.fieldErrors;
|
|
11302
|
-
const fieldErrors = Array.isArray(fieldErrorsRaw) ? fieldErrorsRaw.filter(isRecord$
|
|
11383
|
+
const fieldErrors = Array.isArray(fieldErrorsRaw) ? fieldErrorsRaw.filter(isRecord$35).map((d) => ({
|
|
11303
11384
|
field: typeof d.field === "string" ? d.field : "",
|
|
11304
11385
|
message: typeof d.message === "string" ? d.message : ""
|
|
11305
11386
|
})).filter((d) => d.field.length > 0 && d.message.length > 0) : undefined;
|
|
@@ -11314,7 +11395,7 @@ function formatFieldErrors(fieldErrors) {
|
|
|
11314
11395
|
}
|
|
11315
11396
|
function getDashboardErrorMessage(responseJson, fallback) {
|
|
11316
11397
|
if (!responseJson) return fallback;
|
|
11317
|
-
if (isRecord$
|
|
11398
|
+
if (isRecord$35(responseJson) && "error" in responseJson) {
|
|
11318
11399
|
const parsed = parseErrorDetails(responseJson.error);
|
|
11319
11400
|
const msg = parsed.message ?? fallback;
|
|
11320
11401
|
return msg + formatFieldErrors(parsed.fieldErrors);
|
|
@@ -14618,7 +14699,8 @@ const siteOptionSources = [
|
|
|
14618
14699
|
"eventCategories",
|
|
14619
14700
|
"eventSeries",
|
|
14620
14701
|
"venues",
|
|
14621
|
-
"staffMembers"
|
|
14702
|
+
"staffMembers",
|
|
14703
|
+
"appointmentServiceCategories"
|
|
14622
14704
|
];
|
|
14623
14705
|
const mediaDeliverySchema = z.object({
|
|
14624
14706
|
sizes: z.string().optional(),
|
|
@@ -20504,7 +20586,7 @@ const teamMemberFragment = defineFragment({
|
|
|
20504
20586
|
//#region ../blocks/src/system/data/linkedContentEntries.ts
|
|
20505
20587
|
const LINKED_CONTENT_ENTRY_META_KEY = "__rbLinkedContentEntry";
|
|
20506
20588
|
function coerceLinkedContentEntriesPayload(payload) {
|
|
20507
|
-
if (!isRecord$
|
|
20589
|
+
if (!isRecord$34(payload)) return payload;
|
|
20508
20590
|
const response = payload;
|
|
20509
20591
|
if (!Array.isArray(response.entries)) return payload;
|
|
20510
20592
|
const contentType = parsePublicContentTypeMeta(response.contentType);
|
|
@@ -20512,16 +20594,16 @@ function coerceLinkedContentEntriesPayload(payload) {
|
|
|
20512
20594
|
return response.entries.map((entry) => enrichLinkedContentEntry(entry, contentType));
|
|
20513
20595
|
}
|
|
20514
20596
|
function getLinkedContentEntryMeta(value) {
|
|
20515
|
-
if (!isRecord$
|
|
20597
|
+
if (!isRecord$34(value)) return null;
|
|
20516
20598
|
const candidate = value[LINKED_CONTENT_ENTRY_META_KEY];
|
|
20517
20599
|
return isLinkedContentEntryMeta(candidate) ? candidate : null;
|
|
20518
20600
|
}
|
|
20519
20601
|
function buildLinkedContentEditTarget(input) {
|
|
20520
20602
|
const { entry, sourceBlockId, sourceBlockKind, itemIndex } = input;
|
|
20521
|
-
if (!isRecord$
|
|
20603
|
+
if (!isRecord$34(entry)) return null;
|
|
20522
20604
|
const meta = getLinkedContentEntryMeta(entry);
|
|
20523
20605
|
if (!meta || meta.support.kind !== "supported") return null;
|
|
20524
|
-
const content = isRecord$
|
|
20606
|
+
const content = isRecord$34(entry.content) ? entry.content : {};
|
|
20525
20607
|
return {
|
|
20526
20608
|
kind: "linked-content-entry",
|
|
20527
20609
|
entryId: meta.entryId,
|
|
@@ -20595,12 +20677,12 @@ function resolveLinkedEntryInlineFieldEligibility(input) {
|
|
|
20595
20677
|
};
|
|
20596
20678
|
}
|
|
20597
20679
|
function enrichLinkedContentEntry(entry, contentType) {
|
|
20598
|
-
if (!isRecord$
|
|
20680
|
+
if (!isRecord$34(entry)) return entry;
|
|
20599
20681
|
const entryId = typeof entry.id === "string" ? entry.id : null;
|
|
20600
20682
|
if (!entryId) return entry;
|
|
20601
20683
|
const title = typeof entry.title === "string" && entry.title.trim().length > 0 ? entry.title : entryId;
|
|
20602
20684
|
const optimisticHash = typeof entry.optimisticHash === "string" && entry.optimisticHash.length > 0 ? entry.optimisticHash : null;
|
|
20603
|
-
const content = isRecord$
|
|
20685
|
+
const content = isRecord$34(entry.content) ? entry.content : {};
|
|
20604
20686
|
const meta = {
|
|
20605
20687
|
kind: "linked-content-entry",
|
|
20606
20688
|
entryId,
|
|
@@ -20709,7 +20791,7 @@ function capitalize(value) {
|
|
|
20709
20791
|
return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
|
|
20710
20792
|
}
|
|
20711
20793
|
function parsePublicContentTypeMeta(value) {
|
|
20712
|
-
if (!isRecord$
|
|
20794
|
+
if (!isRecord$34(value)) return null;
|
|
20713
20795
|
if (typeof value.key !== "string" || value.key.trim().length === 0) return null;
|
|
20714
20796
|
return {
|
|
20715
20797
|
key: value.key,
|
|
@@ -20719,7 +20801,7 @@ function parsePublicContentTypeMeta(value) {
|
|
|
20719
20801
|
};
|
|
20720
20802
|
}
|
|
20721
20803
|
function parsePublicContentTypeLinkedEntryEditing(value) {
|
|
20722
|
-
if (!isRecord$
|
|
20804
|
+
if (!isRecord$34(value) || typeof value.kind !== "string") return null;
|
|
20723
20805
|
switch (value.kind) {
|
|
20724
20806
|
case "generic": return { kind: "generic" };
|
|
20725
20807
|
case "unsupported-domain-backed": return {
|
|
@@ -20730,7 +20812,7 @@ function parsePublicContentTypeLinkedEntryEditing(value) {
|
|
|
20730
20812
|
}
|
|
20731
20813
|
}
|
|
20732
20814
|
function parsePublicContentTypeFieldMeta(value) {
|
|
20733
|
-
if (!isRecord$
|
|
20815
|
+
if (!isRecord$34(value)) return [];
|
|
20734
20816
|
if (typeof value.id !== "string" || typeof value.type !== "string") return [];
|
|
20735
20817
|
return [{
|
|
20736
20818
|
id: value.id,
|
|
@@ -20745,14 +20827,14 @@ function parseStringArray(value) {
|
|
|
20745
20827
|
return value.filter((item) => typeof item === "string");
|
|
20746
20828
|
}
|
|
20747
20829
|
function isLinkedContentEntryMeta(value) {
|
|
20748
|
-
if (!isRecord$
|
|
20830
|
+
if (!isRecord$34(value)) return false;
|
|
20749
20831
|
if (value.kind !== "linked-content-entry") return false;
|
|
20750
20832
|
if (typeof value.entryId !== "string") return false;
|
|
20751
20833
|
if (typeof value.contentTypeKey !== "string") return false;
|
|
20752
20834
|
if (typeof value.contentTypeLabel !== "string") return false;
|
|
20753
20835
|
if (typeof value.title !== "string") return false;
|
|
20754
20836
|
if (!(value.optimisticHash === null || typeof value.optimisticHash === "string")) return false;
|
|
20755
|
-
if (!isRecord$
|
|
20837
|
+
if (!isRecord$34(value.contentType)) return false;
|
|
20756
20838
|
if (!isLinkedEntryFieldSourceArray(value.fieldSources)) return false;
|
|
20757
20839
|
return isLinkedContentEditSupport(value.support);
|
|
20758
20840
|
}
|
|
@@ -20760,7 +20842,7 @@ function isLinkedEntryFieldSourceArray(value) {
|
|
|
20760
20842
|
return Array.isArray(value) && value.every(isLinkedEntryFieldSource);
|
|
20761
20843
|
}
|
|
20762
20844
|
function isLinkedEntryFieldSource(value) {
|
|
20763
|
-
if (!isRecord$
|
|
20845
|
+
if (!isRecord$34(value)) return false;
|
|
20764
20846
|
if (typeof value.displayPath !== "string") return false;
|
|
20765
20847
|
switch (value.kind) {
|
|
20766
20848
|
case "content-field": return typeof value.fieldPath === "string" && (value.fieldType === "text" || value.fieldType === "richText");
|
|
@@ -20781,7 +20863,7 @@ function isLinkedEntryInlineFieldReadOnlyReason(value) {
|
|
|
20781
20863
|
}
|
|
20782
20864
|
}
|
|
20783
20865
|
function isLinkedContentEditSupport(value) {
|
|
20784
|
-
if (!isRecord$
|
|
20866
|
+
if (!isRecord$34(value) || typeof value.kind !== "string") return false;
|
|
20785
20867
|
switch (value.kind) {
|
|
20786
20868
|
case "supported": return true;
|
|
20787
20869
|
case "unsupported-domain-backed":
|
|
@@ -20790,7 +20872,7 @@ function isLinkedContentEditSupport(value) {
|
|
|
20790
20872
|
default: return false;
|
|
20791
20873
|
}
|
|
20792
20874
|
}
|
|
20793
|
-
function isRecord$
|
|
20875
|
+
function isRecord$34(value) {
|
|
20794
20876
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20795
20877
|
}
|
|
20796
20878
|
function describeLinkedContentEditSupport(support) {
|
|
@@ -26324,11 +26406,11 @@ function assertSafePathSegments(segments) {
|
|
|
26324
26406
|
}
|
|
26325
26407
|
}
|
|
26326
26408
|
}
|
|
26327
|
-
function isRecord$
|
|
26409
|
+
function isRecord$33(value) {
|
|
26328
26410
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26329
26411
|
}
|
|
26330
26412
|
function isPathContainer(value) {
|
|
26331
|
-
return Array.isArray(value) || isRecord$
|
|
26413
|
+
return Array.isArray(value) || isRecord$33(value);
|
|
26332
26414
|
}
|
|
26333
26415
|
function createPathContainer(nextIsIndex) {
|
|
26334
26416
|
return nextIsIndex ? [] : {};
|
|
@@ -28188,7 +28270,7 @@ function parseApprovedIconExampleSetId(value) {
|
|
|
28188
28270
|
//#endregion
|
|
28189
28271
|
//#region ../blocks/src/system/icons/value.ts
|
|
28190
28272
|
const NO_BLOCK_ICON_VALUE = { kind: "none" };
|
|
28191
|
-
function isRecord$
|
|
28273
|
+
function isRecord$32(value) {
|
|
28192
28274
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28193
28275
|
}
|
|
28194
28276
|
function parseBlockIconValue(value) {
|
|
@@ -28198,7 +28280,7 @@ function parseBlockIconValue(value) {
|
|
|
28198
28280
|
iconId: value
|
|
28199
28281
|
};
|
|
28200
28282
|
}
|
|
28201
|
-
if (!isRecord$
|
|
28283
|
+
if (!isRecord$32(value)) {
|
|
28202
28284
|
return NO_BLOCK_ICON_VALUE;
|
|
28203
28285
|
}
|
|
28204
28286
|
switch (value.kind) {
|
|
@@ -28291,7 +28373,7 @@ function buildGeneratedBlockIconRenderAssetLookupFromUnknown(value) {
|
|
|
28291
28373
|
}
|
|
28292
28374
|
const inputs = [];
|
|
28293
28375
|
for (const [index, item] of value.entries()) {
|
|
28294
|
-
if (!isRecord$
|
|
28376
|
+
if (!isRecord$32(item)) {
|
|
28295
28377
|
return {
|
|
28296
28378
|
kind: "invalid_asset_entry",
|
|
28297
28379
|
index,
|
|
@@ -28359,7 +28441,7 @@ function resolveBlockIconRenderValue(value, generatedAssets = new Map()) {
|
|
|
28359
28441
|
}
|
|
28360
28442
|
}
|
|
28361
28443
|
function getGeneratedBlockIconStyleState(value, currentStyleGuideVersionId) {
|
|
28362
|
-
if (isRecord$
|
|
28444
|
+
if (isRecord$32(value) && value.kind === "generated" && parseBlockIconValue(value).kind !== "generated") {
|
|
28363
28445
|
return { kind: "invalid_generated" };
|
|
28364
28446
|
}
|
|
28365
28447
|
const parsed = parseBlockIconValue(value);
|
|
@@ -28445,11 +28527,11 @@ function resolveFeatureCardGeneratedIconSizePx(value) {
|
|
|
28445
28527
|
const parsed = parseFeatureCardGeneratedIconSizePx(value);
|
|
28446
28528
|
return parsed.ok ? parsed.value : unsafeAsFeatureCardGeneratedIconSizePx(FEATURE_CARD_GENERATED_ICON_SIZE_PX.default);
|
|
28447
28529
|
}
|
|
28448
|
-
function isRecord$
|
|
28530
|
+
function isRecord$31(value) {
|
|
28449
28531
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28450
28532
|
}
|
|
28451
28533
|
function toPlainTextFromTipTap(value) {
|
|
28452
|
-
if (!isRecord$
|
|
28534
|
+
if (!isRecord$31(value)) return "";
|
|
28453
28535
|
if (typeof value.text === "string") return value.text;
|
|
28454
28536
|
const content = value.content;
|
|
28455
28537
|
if (!Array.isArray(content)) return "";
|
|
@@ -28506,7 +28588,7 @@ function suggestSemanticIconForFeatureCard(card) {
|
|
|
28506
28588
|
|
|
28507
28589
|
//#endregion
|
|
28508
28590
|
//#region ../blocks/src/system/icons/generatedAssets.ts
|
|
28509
|
-
function isRecord$
|
|
28591
|
+
function isRecord$30(value) {
|
|
28510
28592
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28511
28593
|
}
|
|
28512
28594
|
function generatedIconAssetRefKey(ref) {
|
|
@@ -28516,11 +28598,11 @@ function collectGeneratedIconAssetRefs(page) {
|
|
|
28516
28598
|
const blocks = [];
|
|
28517
28599
|
for (const block of page.blocks) {
|
|
28518
28600
|
if (block.kind !== "block.feature-cards" || typeof block.id !== "string") continue;
|
|
28519
|
-
const content = isRecord$
|
|
28601
|
+
const content = isRecord$30(block.draftContent) ? block.draftContent : isRecord$30(block.content) ? block.content : null;
|
|
28520
28602
|
const cards = Array.isArray(content?.cards) ? content.cards : [];
|
|
28521
28603
|
const refs = new Map();
|
|
28522
28604
|
for (const card of cards) {
|
|
28523
|
-
if (!isRecord$
|
|
28605
|
+
if (!isRecord$30(card)) continue;
|
|
28524
28606
|
const icon$1 = parseBlockIconValue(card.icon);
|
|
28525
28607
|
if (icon$1.kind !== "generated") continue;
|
|
28526
28608
|
const ref = {
|
|
@@ -29623,18 +29705,43 @@ const publicAppointmentServiceSchema = z.object({
|
|
|
29623
29705
|
pricing: publicPricingSchema.optional(),
|
|
29624
29706
|
priceAmount: z.number().nullable(),
|
|
29625
29707
|
priceCurrency: z.string().nullable(),
|
|
29626
|
-
location: publicLocationSchema
|
|
29708
|
+
location: publicLocationSchema,
|
|
29709
|
+
categoryId: z.string().nullable().optional().transform((value) => value ?? null)
|
|
29710
|
+
});
|
|
29711
|
+
const publicServiceCategorySchema = z.object({
|
|
29712
|
+
id: z.string().min(1),
|
|
29713
|
+
name: z.string(),
|
|
29714
|
+
description: z.string().nullable().optional().transform((value) => value ?? null)
|
|
29627
29715
|
});
|
|
29628
|
-
|
|
29716
|
+
/**
|
|
29717
|
+
* The loader hands over the catalogue `{ services, categories }` (issue 1403).
|
|
29718
|
+
* A bare services array is still accepted and read as a site with no
|
|
29719
|
+
* categories, so callers from before categories keep the flat list.
|
|
29720
|
+
*/
|
|
29721
|
+
const publicAppointmentServicesSchema = z.union([z.array(publicAppointmentServiceSchema).transform((services) => ({
|
|
29722
|
+
services,
|
|
29723
|
+
categories: []
|
|
29724
|
+
})), z.object({
|
|
29725
|
+
services: z.array(publicAppointmentServiceSchema),
|
|
29726
|
+
categories: z.array(publicServiceCategorySchema)
|
|
29727
|
+
})]);
|
|
29629
29728
|
const EMPTY_MESSAGE = "No appointments are available right now.";
|
|
29630
29729
|
const ERROR_MESSAGE = "Appointments are temporarily unavailable. Please try again shortly.";
|
|
29730
|
+
const OTHER_GROUP_KEY = "other";
|
|
29731
|
+
const OTHER_GROUP_HEADING = "Other";
|
|
29631
29732
|
function parseServices(value) {
|
|
29632
29733
|
const result = publicAppointmentServicesSchema.safeParse(value);
|
|
29633
29734
|
return result.success ? {
|
|
29634
29735
|
kind: "valid",
|
|
29635
|
-
services: result.data
|
|
29736
|
+
services: result.data.services,
|
|
29737
|
+
categories: result.data.categories
|
|
29636
29738
|
} : { kind: "invalid" };
|
|
29637
29739
|
}
|
|
29740
|
+
function readCategoryFilter(value) {
|
|
29741
|
+
if (typeof value !== "string") return null;
|
|
29742
|
+
const trimmed = value.trim();
|
|
29743
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
29744
|
+
}
|
|
29638
29745
|
function formatAppointmentDuration(durationMinutes) {
|
|
29639
29746
|
return `${durationMinutes} min`;
|
|
29640
29747
|
}
|
|
@@ -29708,8 +29815,44 @@ function buildRows(services, pathname, servicePathPrefix) {
|
|
|
29708
29815
|
detailsHref: servicePathPrefix && service.slug ? `${servicePathPrefix.replace(/\/$/, "")}/${encodeURIComponent(service.slug)}` : null
|
|
29709
29816
|
}));
|
|
29710
29817
|
}
|
|
29818
|
+
const EMPTY_VIEW = {
|
|
29819
|
+
kind: "empty",
|
|
29820
|
+
message: EMPTY_MESSAGE
|
|
29821
|
+
};
|
|
29822
|
+
function categoryGroup(category, services, toRows) {
|
|
29823
|
+
return {
|
|
29824
|
+
key: category.id,
|
|
29825
|
+
heading: category.name,
|
|
29826
|
+
intro: category.description,
|
|
29827
|
+
rows: toRows(services)
|
|
29828
|
+
};
|
|
29829
|
+
}
|
|
29830
|
+
function viewFromLayout(layout, toRows) {
|
|
29831
|
+
switch (layout.kind) {
|
|
29832
|
+
case "uncategorized-site": return layout.services.length === 0 ? EMPTY_VIEW : {
|
|
29833
|
+
kind: "items",
|
|
29834
|
+
rows: toRows(layout.services)
|
|
29835
|
+
};
|
|
29836
|
+
case "categorized-site": {
|
|
29837
|
+
const groups = layout.groups.map((group) => categoryGroup(group.category, group.services, toRows));
|
|
29838
|
+
const other = layout.other.length === 0 ? [] : [{
|
|
29839
|
+
key: OTHER_GROUP_KEY,
|
|
29840
|
+
heading: OTHER_GROUP_HEADING,
|
|
29841
|
+
intro: null,
|
|
29842
|
+
rows: toRows(layout.other)
|
|
29843
|
+
}];
|
|
29844
|
+
const allGroups = [...groups, ...other];
|
|
29845
|
+
return allGroups.length === 0 ? EMPTY_VIEW : {
|
|
29846
|
+
kind: "groups",
|
|
29847
|
+
groups: allGroups
|
|
29848
|
+
};
|
|
29849
|
+
}
|
|
29850
|
+
default: return assertNever(layout);
|
|
29851
|
+
}
|
|
29852
|
+
}
|
|
29711
29853
|
function buildAppointmentServicesView(input) {
|
|
29712
|
-
|
|
29854
|
+
const pathname = input.pathname;
|
|
29855
|
+
if (!pathname) {
|
|
29713
29856
|
return {
|
|
29714
29857
|
kind: "error",
|
|
29715
29858
|
message: ERROR_MESSAGE
|
|
@@ -29722,27 +29865,101 @@ function buildAppointmentServicesView(input) {
|
|
|
29722
29865
|
message: ERROR_MESSAGE
|
|
29723
29866
|
};
|
|
29724
29867
|
}
|
|
29725
|
-
|
|
29726
|
-
|
|
29727
|
-
|
|
29728
|
-
|
|
29868
|
+
const toRows = (services) => buildRows(services, pathname, input.servicePathPrefix ?? null);
|
|
29869
|
+
const view = selectCategoryView(parsed.categories, parsed.services, readCategoryFilter(input.categoryId));
|
|
29870
|
+
switch (view.kind) {
|
|
29871
|
+
case "single": return view.group.services.length === 0 ? EMPTY_VIEW : {
|
|
29872
|
+
kind: "groups",
|
|
29873
|
+
groups: [categoryGroup(view.group.category, view.group.services, toRows)]
|
|
29729
29874
|
};
|
|
29875
|
+
case "all":
|
|
29876
|
+
case "fallback-all": return viewFromLayout(view.layout, toRows);
|
|
29877
|
+
default: return assertNever(view);
|
|
29730
29878
|
}
|
|
29731
|
-
return {
|
|
29732
|
-
kind: "items",
|
|
29733
|
-
rows: buildRows(parsed.services, input.pathname, input.servicePathPrefix ?? null)
|
|
29734
|
-
};
|
|
29735
29879
|
}
|
|
29736
|
-
function
|
|
29880
|
+
function AppointmentServiceRows({ rows, RowTitle }) {
|
|
29881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29882
|
+
className: "appointment-services-rows rb-flex rb-flex-col",
|
|
29883
|
+
children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", {
|
|
29884
|
+
className: "appointment-services-row rb-border-b rb-border-border rb-py-4",
|
|
29885
|
+
children: [
|
|
29886
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29887
|
+
className: "appointment-services-row-main rb-min-w-0",
|
|
29888
|
+
children: [
|
|
29889
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RowTitle, {
|
|
29890
|
+
className: "appointment-services-row-title rb-text-lg rb-font-medium rb-leading-tight",
|
|
29891
|
+
children: row.detailsHref ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
29892
|
+
href: row.detailsHref,
|
|
29893
|
+
children: row.title
|
|
29894
|
+
}) : row.title
|
|
29895
|
+
}),
|
|
29896
|
+
row.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
29897
|
+
className: "appointment-services-row-description rb-text-sm rb-leading-6 status-muted",
|
|
29898
|
+
children: row.description
|
|
29899
|
+
}) : null,
|
|
29900
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
29901
|
+
className: "appointment-services-row-meta rb-caption status-muted",
|
|
29902
|
+
children: [row.durationLabel, row.locationLabel ? ` · ${row.locationLabel}` : ""]
|
|
29903
|
+
})
|
|
29904
|
+
]
|
|
29905
|
+
}),
|
|
29906
|
+
row.priceLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29907
|
+
className: "appointment-services-row-price rb-text-lg",
|
|
29908
|
+
children: row.priceLabel
|
|
29909
|
+
}) : null,
|
|
29910
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
|
|
29911
|
+
variant: "secondary",
|
|
29912
|
+
size: "sm",
|
|
29913
|
+
extraClassName: "appointment-services-row-action",
|
|
29914
|
+
href: row.href,
|
|
29915
|
+
label: "Check times",
|
|
29916
|
+
screenReaderSuffix: ` for ${row.title}`
|
|
29917
|
+
})
|
|
29918
|
+
]
|
|
29919
|
+
}, row.id))
|
|
29920
|
+
});
|
|
29921
|
+
}
|
|
29922
|
+
function AppointmentServiceGroups({ groups, hasSectionHeading, idPrefix }) {
|
|
29923
|
+
const GroupHeading = hasSectionHeading ? "h3" : "h2";
|
|
29924
|
+
const RowTitle = hasSectionHeading ? "h4" : "h3";
|
|
29925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29926
|
+
className: "appointment-services-groups rb-flex rb-flex-col rb-gap-10",
|
|
29927
|
+
children: groups.map((group) => {
|
|
29928
|
+
const headingId = `${idPrefix}-group-${group.key}`;
|
|
29929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
29930
|
+
className: "appointment-services-group rb-flex rb-flex-col rb-gap-2",
|
|
29931
|
+
"aria-labelledby": headingId,
|
|
29932
|
+
"data-appointment-services-group": group.key,
|
|
29933
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29934
|
+
className: "appointment-services-group-heading",
|
|
29935
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GroupHeading, {
|
|
29936
|
+
id: headingId,
|
|
29937
|
+
className: "appointment-services-group-title rb-text-sm rb-font-semibold rb-uppercase rb-tracking-wide",
|
|
29938
|
+
children: group.heading
|
|
29939
|
+
}), group.intro ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
29940
|
+
className: "appointment-services-group-intro rb-text-sm rb-leading-6 rb-max-w-prose status-muted",
|
|
29941
|
+
children: group.intro
|
|
29942
|
+
}) : null]
|
|
29943
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppointmentServiceRows, {
|
|
29944
|
+
rows: group.rows,
|
|
29945
|
+
RowTitle
|
|
29946
|
+
})]
|
|
29947
|
+
}, group.key);
|
|
29948
|
+
})
|
|
29949
|
+
});
|
|
29950
|
+
}
|
|
29951
|
+
function AppointmentServicesNode({ sectionHeading, categoryId, services, pathname, servicePathPrefix, blockId, className }) {
|
|
29737
29952
|
const view = buildAppointmentServicesView({
|
|
29738
29953
|
services,
|
|
29954
|
+
categoryId,
|
|
29739
29955
|
pathname: typeof pathname === "string" ? pathname : undefined,
|
|
29740
29956
|
servicePathPrefix: typeof servicePathPrefix === "string" ? servicePathPrefix : null
|
|
29741
29957
|
});
|
|
29742
29958
|
const rootClassName = `appointment-services ${className ?? ""}`.trim();
|
|
29743
|
-
const
|
|
29744
|
-
|
|
29745
|
-
|
|
29959
|
+
const hasSectionHeading = Boolean(sectionHeading);
|
|
29960
|
+
switch (view.kind) {
|
|
29961
|
+
case "error":
|
|
29962
|
+
case "empty": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29746
29963
|
className: rootClassName,
|
|
29747
29964
|
"data-appointment-services-state": view.kind,
|
|
29748
29965
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
@@ -29751,51 +29968,25 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
|
|
|
29751
29968
|
children: view.message
|
|
29752
29969
|
})
|
|
29753
29970
|
});
|
|
29971
|
+
case "items": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29972
|
+
className: `${rootClassName} rb-flex rb-flex-col`,
|
|
29973
|
+
"data-appointment-services-state": "populated",
|
|
29974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppointmentServiceRows, {
|
|
29975
|
+
rows: view.rows,
|
|
29976
|
+
RowTitle: hasSectionHeading ? "h3" : "h2"
|
|
29977
|
+
})
|
|
29978
|
+
});
|
|
29979
|
+
case "groups": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29980
|
+
className: `${rootClassName} rb-flex rb-flex-col`,
|
|
29981
|
+
"data-appointment-services-state": "populated",
|
|
29982
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppointmentServiceGroups, {
|
|
29983
|
+
groups: view.groups,
|
|
29984
|
+
hasSectionHeading,
|
|
29985
|
+
idPrefix: `appointment-services-${blockId ?? "block"}`
|
|
29986
|
+
})
|
|
29987
|
+
});
|
|
29988
|
+
default: return assertNever(view);
|
|
29754
29989
|
}
|
|
29755
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29756
|
-
className: `${rootClassName} rb-flex rb-flex-col`,
|
|
29757
|
-
"data-appointment-services-state": "populated",
|
|
29758
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29759
|
-
className: "appointment-services-rows rb-flex rb-flex-col",
|
|
29760
|
-
children: view.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", {
|
|
29761
|
-
className: "appointment-services-row rb-border-b rb-border-border rb-py-4",
|
|
29762
|
-
children: [
|
|
29763
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29764
|
-
className: "appointment-services-row-main rb-min-w-0",
|
|
29765
|
-
children: [
|
|
29766
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RowTitle, {
|
|
29767
|
-
className: "appointment-services-row-title rb-text-lg rb-font-medium rb-leading-tight",
|
|
29768
|
-
children: row.detailsHref ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
29769
|
-
href: row.detailsHref,
|
|
29770
|
-
children: row.title
|
|
29771
|
-
}) : row.title
|
|
29772
|
-
}),
|
|
29773
|
-
row.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
29774
|
-
className: "appointment-services-row-description rb-text-sm rb-leading-6 status-muted",
|
|
29775
|
-
children: row.description
|
|
29776
|
-
}) : null,
|
|
29777
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
29778
|
-
className: "appointment-services-row-meta rb-caption status-muted",
|
|
29779
|
-
children: [row.durationLabel, row.locationLabel ? ` · ${row.locationLabel}` : ""]
|
|
29780
|
-
})
|
|
29781
|
-
]
|
|
29782
|
-
}),
|
|
29783
|
-
row.priceLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29784
|
-
className: "appointment-services-row-price rb-text-lg",
|
|
29785
|
-
children: row.priceLabel
|
|
29786
|
-
}) : null,
|
|
29787
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
|
|
29788
|
-
variant: "secondary",
|
|
29789
|
-
size: "sm",
|
|
29790
|
-
extraClassName: "appointment-services-row-action",
|
|
29791
|
-
href: row.href,
|
|
29792
|
-
label: "Check times",
|
|
29793
|
-
screenReaderSuffix: ` for ${row.title}`
|
|
29794
|
-
})
|
|
29795
|
-
]
|
|
29796
|
-
}, row.id))
|
|
29797
|
-
})
|
|
29798
|
-
});
|
|
29799
29990
|
}
|
|
29800
29991
|
var appointment_services_default = AppointmentServicesNode;
|
|
29801
29992
|
|
|
@@ -31360,8 +31551,8 @@ function createLoadableValueState(tag, key, value) {
|
|
|
31360
31551
|
};
|
|
31361
31552
|
}
|
|
31362
31553
|
function upsertRedirectRule(existing, next) {
|
|
31363
|
-
if (existing.findIndex((rule$
|
|
31364
|
-
return existing.map((rule$
|
|
31554
|
+
if (existing.findIndex((rule$2) => rule$2.id === next.id) < 0) return [next, ...existing];
|
|
31555
|
+
return existing.map((rule$2) => rule$2.id === next.id ? next : rule$2);
|
|
31365
31556
|
}
|
|
31366
31557
|
function createInitialRedirectsClientState(initialState) {
|
|
31367
31558
|
return {
|
|
@@ -31716,7 +31907,7 @@ function getWizardLocalStorage() {
|
|
|
31716
31907
|
}
|
|
31717
31908
|
}
|
|
31718
31909
|
function parseEnvelope(raw, config$1) {
|
|
31719
|
-
if (!isRecord$
|
|
31910
|
+
if (!isRecord$29(raw)) return {
|
|
31720
31911
|
kind: "removed_invalid",
|
|
31721
31912
|
reason: "invalid_envelope"
|
|
31722
31913
|
};
|
|
@@ -31805,7 +31996,7 @@ function createWizardDraftStorage(config$1) {
|
|
|
31805
31996
|
}
|
|
31806
31997
|
};
|
|
31807
31998
|
}
|
|
31808
|
-
function isRecord$
|
|
31999
|
+
function isRecord$29(value) {
|
|
31809
32000
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31810
32001
|
}
|
|
31811
32002
|
function deepEqualJsonValue(left, right) {
|
|
@@ -31815,8 +32006,8 @@ function deepEqualJsonValue(left, right) {
|
|
|
31815
32006
|
if (left.length !== right.length) return false;
|
|
31816
32007
|
return left.every((item, index) => deepEqualJsonValue(item, right[index]));
|
|
31817
32008
|
}
|
|
31818
|
-
if (isRecord$
|
|
31819
|
-
if (!isRecord$
|
|
32009
|
+
if (isRecord$29(left) || isRecord$29(right)) {
|
|
32010
|
+
if (!isRecord$29(left) || !isRecord$29(right)) return false;
|
|
31820
32011
|
const leftKeys = Object.keys(left).sort();
|
|
31821
32012
|
if (!deepEqualJsonValue(leftKeys, Object.keys(right).sort())) return false;
|
|
31822
32013
|
return leftKeys.every((key) => deepEqualJsonValue(left[key], right[key]));
|
|
@@ -32278,12 +32469,12 @@ function resolveBookingSiteId(siteId, form$1) {
|
|
|
32278
32469
|
return siteId || form$1?.siteId || "";
|
|
32279
32470
|
}
|
|
32280
32471
|
function normalizeBookingFormConfig(form$1) {
|
|
32281
|
-
if (!isRecord$
|
|
32472
|
+
if (!isRecord$28(form$1)) return null;
|
|
32282
32473
|
const id = readNonEmptyString(form$1.id);
|
|
32283
32474
|
const name = readNonEmptyString(form$1.name);
|
|
32284
32475
|
if (!id || !name) return null;
|
|
32285
|
-
const schemaSource = isRecord$
|
|
32286
|
-
const settingsSource = isRecord$
|
|
32476
|
+
const schemaSource = isRecord$28(form$1.schema) ? form$1.schema : isRecord$28(form$1.schemaJson) ? form$1.schemaJson : null;
|
|
32477
|
+
const settingsSource = isRecord$28(form$1.settings) ? form$1.settings : isRecord$28(form$1.settingsJson) ? form$1.settingsJson : null;
|
|
32287
32478
|
return {
|
|
32288
32479
|
id,
|
|
32289
32480
|
name,
|
|
@@ -32307,10 +32498,10 @@ function normalizeBookingServices(services) {
|
|
|
32307
32498
|
if (Array.isArray(services)) {
|
|
32308
32499
|
return services.filter(isBookingFormService).map(normalizeService);
|
|
32309
32500
|
}
|
|
32310
|
-
if (isRecord$
|
|
32501
|
+
if (isRecord$28(services) && "services" in services) {
|
|
32311
32502
|
return Array.isArray(services.services) ? services.services.filter(isBookingFormService).map(normalizeService) : [];
|
|
32312
32503
|
}
|
|
32313
|
-
return isRecord$
|
|
32504
|
+
return isRecord$28(services) ? Object.values(services).filter(isBookingFormService).map(normalizeService) : [];
|
|
32314
32505
|
}
|
|
32315
32506
|
function normalizeBookingSchema(value) {
|
|
32316
32507
|
if (!value) return undefined;
|
|
@@ -32322,7 +32513,7 @@ function normalizeBookingSchema(value) {
|
|
|
32322
32513
|
};
|
|
32323
32514
|
}
|
|
32324
32515
|
function readBookingFormField(value) {
|
|
32325
|
-
if (!isRecord$
|
|
32516
|
+
if (!isRecord$28(value)) return null;
|
|
32326
32517
|
const id = readNonEmptyString(value.id);
|
|
32327
32518
|
const label = readNonEmptyString(value.label);
|
|
32328
32519
|
const type = readBookingFieldType(value.type);
|
|
@@ -32365,7 +32556,7 @@ function readBookingFieldOptions(value) {
|
|
|
32365
32556
|
return options.length > 0 ? options : undefined;
|
|
32366
32557
|
}
|
|
32367
32558
|
function readBookingFieldOption(value) {
|
|
32368
|
-
if (!isRecord$
|
|
32559
|
+
if (!isRecord$28(value)) return null;
|
|
32369
32560
|
const optionValue = readNonEmptyString(value.value);
|
|
32370
32561
|
const label = readNonEmptyString(value.label);
|
|
32371
32562
|
return optionValue && label ? {
|
|
@@ -32385,7 +32576,7 @@ function normalizeBookingSettings(value) {
|
|
|
32385
32576
|
};
|
|
32386
32577
|
}
|
|
32387
32578
|
function isBookingFormService(value) {
|
|
32388
|
-
return isRecord$
|
|
32579
|
+
return isRecord$28(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string" && (value.consent === undefined || blockBookingConsentSchema.safeParse(value.consent).success);
|
|
32389
32580
|
}
|
|
32390
32581
|
function collectBookingCustomFields(data) {
|
|
32391
32582
|
const customFields = {};
|
|
@@ -32441,7 +32632,7 @@ function readStringArray(value) {
|
|
|
32441
32632
|
const strings = value.filter((item) => typeof item === "string");
|
|
32442
32633
|
return strings.length > 0 ? strings : undefined;
|
|
32443
32634
|
}
|
|
32444
|
-
function isRecord$
|
|
32635
|
+
function isRecord$28(value) {
|
|
32445
32636
|
return typeof value === "object" && value !== null;
|
|
32446
32637
|
}
|
|
32447
32638
|
function getBookingServicePaymentSelectionMode(service) {
|
|
@@ -32670,6 +32861,41 @@ function getBookingSuccessMessage(successMessage) {
|
|
|
32670
32861
|
return successMessage?.trim() || "Your appointment has been booked! Check your email for confirmation.";
|
|
32671
32862
|
}
|
|
32672
32863
|
|
|
32864
|
+
//#endregion
|
|
32865
|
+
//#region ../blocks/src/system/runtime/nodes/booking-form.service-categories.ts
|
|
32866
|
+
function isRecord$27(value) {
|
|
32867
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32868
|
+
}
|
|
32869
|
+
function readCategory(value) {
|
|
32870
|
+
if (!isRecord$27(value)) return [];
|
|
32871
|
+
const { id, name, description } = value;
|
|
32872
|
+
if (typeof id !== "string" || id.trim() === "" || typeof name !== "string") {
|
|
32873
|
+
return [];
|
|
32874
|
+
}
|
|
32875
|
+
return [{
|
|
32876
|
+
id,
|
|
32877
|
+
name,
|
|
32878
|
+
description: typeof description === "string" ? description : null
|
|
32879
|
+
}];
|
|
32880
|
+
}
|
|
32881
|
+
/**
|
|
32882
|
+
* The ordered service categories carried by a catalogue-shaped services
|
|
32883
|
+
* source (`{ services, categories }`). Every other shape has none, which
|
|
32884
|
+
* reads as a site without categories. Order is preserved: the database owns
|
|
32885
|
+
* it.
|
|
32886
|
+
*/
|
|
32887
|
+
function normalizeBookingServiceCategories(services) {
|
|
32888
|
+
if (!isRecord$27(services) || !Array.isArray(services.categories)) return [];
|
|
32889
|
+
return services.categories.flatMap(readCategory);
|
|
32890
|
+
}
|
|
32891
|
+
/**
|
|
32892
|
+
* The ordered service categories a headless booking override was given in
|
|
32893
|
+
* its loader data (`data.services`).
|
|
32894
|
+
*/
|
|
32895
|
+
function readOverrideServiceCategories(data) {
|
|
32896
|
+
return isRecord$27(data) ? normalizeBookingServiceCategories(data.services) : [];
|
|
32897
|
+
}
|
|
32898
|
+
|
|
32673
32899
|
//#endregion
|
|
32674
32900
|
//#region ../blocks/src/system/runtime/nodes/booking-runtime-sources.ts
|
|
32675
32901
|
const APPOINTMENT_BOOKING_RUNTIME_FORM_ID = "booking-form";
|
|
@@ -32796,7 +33022,8 @@ function normalizeAppointmentBookingServices(input) {
|
|
|
32796
33022
|
priceCurrency: service.priceCurrency,
|
|
32797
33023
|
paymentTerms: service.paymentTerms,
|
|
32798
33024
|
paymentTermsAvailability: service.paymentTermsAvailability,
|
|
32799
|
-
consent: service.consent
|
|
33025
|
+
consent: service.consent,
|
|
33026
|
+
categoryId: service.categoryId ?? null
|
|
32800
33027
|
}));
|
|
32801
33028
|
}
|
|
32802
33029
|
function buildAppointmentBookingSourceProps(input) {
|
|
@@ -32814,6 +33041,7 @@ function buildAppointmentBookingSourceProps(input) {
|
|
|
32814
33041
|
siteId: input.siteId,
|
|
32815
33042
|
services: input.services
|
|
32816
33043
|
}),
|
|
33044
|
+
serviceCategories: [...input.serviceCategories ?? []],
|
|
32817
33045
|
serviceId: input.serviceId,
|
|
32818
33046
|
resourceId: input.resourceId,
|
|
32819
33047
|
initialData: input.initialData,
|
|
@@ -32880,11 +33108,20 @@ const bookingServiceSchema = z.object({
|
|
|
32880
33108
|
priceCurrency: z.string().nullable().optional(),
|
|
32881
33109
|
paymentTerms: blockBookingPaymentTermsSchema.optional(),
|
|
32882
33110
|
paymentTermsAvailability: blockBookingPaymentTermsAvailabilitySchema.optional(),
|
|
32883
|
-
consent: blockBookingConsentSchema.optional()
|
|
33111
|
+
consent: blockBookingConsentSchema.optional(),
|
|
33112
|
+
categoryId: z.string().nullable().optional()
|
|
33113
|
+
});
|
|
33114
|
+
const bookingServiceCategorySchema = z.object({
|
|
33115
|
+
id: z.string(),
|
|
33116
|
+
name: z.string(),
|
|
33117
|
+
description: z.string().nullable()
|
|
32884
33118
|
});
|
|
32885
33119
|
const bookingServicesSourceSchema = z.union([
|
|
32886
33120
|
z.array(bookingServiceSchema),
|
|
32887
|
-
z.object({
|
|
33121
|
+
z.object({
|
|
33122
|
+
services: z.array(bookingServiceSchema).optional(),
|
|
33123
|
+
categories: z.array(bookingServiceCategorySchema).optional()
|
|
33124
|
+
}),
|
|
32888
33125
|
z.record(z.string(), bookingServiceSchema)
|
|
32889
33126
|
]);
|
|
32890
33127
|
const bookingConfigSchema = z.object({
|
|
@@ -32937,6 +33174,7 @@ const bookingHydrationSchema = z.object({
|
|
|
32937
33174
|
rebookContext: z.object({ kind: z.literal("portal_rebook") }).nullable().optional(),
|
|
32938
33175
|
form: bookingConfigSchema.nullable(),
|
|
32939
33176
|
services: z.array(bookingServiceSchema),
|
|
33177
|
+
serviceCategories: z.array(bookingServiceCategorySchema).optional(),
|
|
32940
33178
|
spamProtectionEnabled: z.boolean().optional()
|
|
32941
33179
|
});
|
|
32942
33180
|
const bookingRenderSchema = z.object({
|
|
@@ -32982,6 +33220,7 @@ const bookingFormBlockRuntime = defineClientOwnedBlockRuntime({
|
|
|
32982
33220
|
rebookContext: source.rebookContext ?? null,
|
|
32983
33221
|
form: form$1,
|
|
32984
33222
|
services,
|
|
33223
|
+
serviceCategories: normalizeBookingServiceCategories(source.services),
|
|
32985
33224
|
spamProtectionEnabled: source.spamProtectionEnabled
|
|
32986
33225
|
}
|
|
32987
33226
|
};
|
|
@@ -48792,6 +49031,125 @@ function generateFooterBottomTextLinkStyles(footer, themeId, tokens) {
|
|
|
48792
49031
|
return cssChunks.join("\n");
|
|
48793
49032
|
}
|
|
48794
49033
|
|
|
49034
|
+
//#endregion
|
|
49035
|
+
//#region ../theme-core/src/layout/boundaryCss.ts
|
|
49036
|
+
/**
|
|
49037
|
+
* Section-break CSS, generated from the transition catalogue (issue 1422).
|
|
49038
|
+
*
|
|
49039
|
+
* The renderer emits one element per shown join:
|
|
49040
|
+
*
|
|
49041
|
+
* <div data-block-boundary data-boundary-treatment="wave-edge-gentle"
|
|
49042
|
+
* data-boundary-placement="previous"
|
|
49043
|
+
* style="--boundary-shape-paint: …; --boundary-band-paint: …">
|
|
49044
|
+
*
|
|
49045
|
+
* Every selector matches an exact attribute value, so there is no reliance on
|
|
49046
|
+
* prefix ordering in the cascade and nothing reads colours out of a string.
|
|
49047
|
+
* The shape layer is `::after`; the band layer (paint → paint only) is
|
|
49048
|
+
* `::before`.
|
|
49049
|
+
*/
|
|
49050
|
+
const waveMaskSvgPaths = {
|
|
49051
|
+
classic: "M0 72V46C130 55 260 24 420 30C590 36 690 62 860 42C1035 21 1160 47 1305 36C1365 31 1415 33 1440 38V72H0Z",
|
|
49052
|
+
balanced: "M0 72V42C120 24 240 24 360 42C480 60 600 60 720 42C840 24 960 24 1080 42C1200 60 1320 60 1440 42V72H0Z",
|
|
49053
|
+
gentle: "M0 72V43C180 32 300 32 480 43C660 54 780 54 960 43C1140 32 1260 32 1440 43V72H0Z",
|
|
49054
|
+
bold: "M0 72V44C90 14 270 14 360 44C450 74 630 74 720 44C810 14 990 14 1080 44C1170 74 1350 74 1440 44V72H0Z",
|
|
49055
|
+
drift: "M0 72V39C115 31 205 54 340 48C505 41 610 16 760 33C920 51 1015 64 1160 44C1280 27 1375 35 1440 50V72H0Z"
|
|
49056
|
+
};
|
|
49057
|
+
function waveMaskDataUrl(mask) {
|
|
49058
|
+
return svgDataUrl(`<svg viewBox='0 0 1440 72' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><path d='${waveMaskSvgPaths[mask]}' fill='white'/></svg>`);
|
|
49059
|
+
}
|
|
49060
|
+
/**
|
|
49061
|
+
* How each placement anchors the layers against the zero-height boundary
|
|
49062
|
+
* element that sits exactly on the join.
|
|
49063
|
+
*
|
|
49064
|
+
* - `centred` straddles the join, band under shape.
|
|
49065
|
+
* - `previous` sits above the join, inside the previous section.
|
|
49066
|
+
* - `next` sits below the join, inside the next section, with the shape
|
|
49067
|
+
* flipped so it reads as the mirror of `previous`.
|
|
49068
|
+
*/
|
|
49069
|
+
const placementRules = {
|
|
49070
|
+
centred: {
|
|
49071
|
+
shape: ["top: 0;", "transform: translateY(-50%);"],
|
|
49072
|
+
band: ["top: 0;", "transform: translateY(-50%);"]
|
|
49073
|
+
},
|
|
49074
|
+
previous: {
|
|
49075
|
+
shape: ["bottom: 0;"],
|
|
49076
|
+
band: null
|
|
49077
|
+
},
|
|
49078
|
+
next: {
|
|
49079
|
+
shape: ["top: 0;", "transform: scaleY(-1);"],
|
|
49080
|
+
band: null
|
|
49081
|
+
}
|
|
49082
|
+
};
|
|
49083
|
+
function generateBoundaryCss(selector) {
|
|
49084
|
+
const boundary = `${selector} [data-block-boundary]`;
|
|
49085
|
+
return [
|
|
49086
|
+
rule$1(boundary, [
|
|
49087
|
+
"position: relative;",
|
|
49088
|
+
"z-index: 3;",
|
|
49089
|
+
"height: 0;",
|
|
49090
|
+
"pointer-events: none;"
|
|
49091
|
+
]),
|
|
49092
|
+
rule$1(`${selector} [data-block][data-site-style-boundary-before] > :where([data-slot='section'])`, ["padding-top: calc(var(--rb-section-pad-y, 0rem) + var(--site-style-boundary-before-reserve, 0rem));"]),
|
|
49093
|
+
rule$1(`${selector} [data-block][data-site-style-boundary-after] > :where([data-slot='section'])`, ["padding-bottom: calc(var(--rb-section-pad-y, 0rem) + var(--site-style-boundary-after-reserve, 0rem));"]),
|
|
49094
|
+
rule$1(`${boundary}::before,\n${boundary}::after`, [
|
|
49095
|
+
"content: '';",
|
|
49096
|
+
"position: absolute;",
|
|
49097
|
+
"left: 0;",
|
|
49098
|
+
"right: 0;",
|
|
49099
|
+
"height: var(--boundary-height);",
|
|
49100
|
+
"pointer-events: none;"
|
|
49101
|
+
]),
|
|
49102
|
+
rule$1(`${boundary}::before`, ["z-index: 0;", "background: var(--boundary-band-paint, transparent);"]),
|
|
49103
|
+
rule$1(`${boundary}::after`, ["z-index: 1;"]),
|
|
49104
|
+
...placementCss(boundary),
|
|
49105
|
+
...transitionCatalogueEntries.flatMap((entry) => treatmentCss(boundary, entry))
|
|
49106
|
+
].join("\n\n");
|
|
49107
|
+
}
|
|
49108
|
+
function placementCss(boundary) {
|
|
49109
|
+
return Object.keys(placementRules).flatMap((placement) => {
|
|
49110
|
+
const placed = `${boundary}[data-boundary-placement='${placement}']`;
|
|
49111
|
+
const rules = placementRules[placement];
|
|
49112
|
+
return [rule$1(`${placed}::after`, rules.shape), rules.band ? rule$1(`${placed}::before`, rules.band) : rule$1(`${placed}::before`, ["content: none;"])];
|
|
49113
|
+
});
|
|
49114
|
+
}
|
|
49115
|
+
function treatmentCss(boundary, entry) {
|
|
49116
|
+
const selected = `${boundary}[data-boundary-treatment='${entry.intent}']`;
|
|
49117
|
+
const metrics = boundaryRuntimeMetricsForDecorativeTransition(entry.intent);
|
|
49118
|
+
return [rule$1(selected, [`--boundary-height: ${metrics.heightCss};`]), rule$1(`${selected}::after`, shapeDeclarations(entry))];
|
|
49119
|
+
}
|
|
49120
|
+
function shapeDeclarations(entry) {
|
|
49121
|
+
switch (entry.shape.kind) {
|
|
49122
|
+
case "fade": return [
|
|
49123
|
+
"/* Fallback for browsers without color-mix(). */",
|
|
49124
|
+
"background: linear-gradient(to bottom, transparent 0%, var(--boundary-shape-paint) 100%);",
|
|
49125
|
+
"background: linear-gradient(to bottom, transparent 0%, color-mix(in srgb, var(--boundary-shape-paint) 16%, transparent) 34%, color-mix(in srgb, var(--boundary-shape-paint) 68%, transparent) 78%, var(--boundary-shape-paint) 100%);"
|
|
49126
|
+
];
|
|
49127
|
+
case "wave": {
|
|
49128
|
+
const mask = waveMaskDataUrl(entry.shape.mask);
|
|
49129
|
+
return [
|
|
49130
|
+
"background: var(--boundary-shape-paint);",
|
|
49131
|
+
`mask-image: url("${mask}");`,
|
|
49132
|
+
"mask-repeat: no-repeat;",
|
|
49133
|
+
"mask-size: 100% 100%;",
|
|
49134
|
+
`-webkit-mask-image: url("${mask}");`,
|
|
49135
|
+
"-webkit-mask-repeat: no-repeat;",
|
|
49136
|
+
"-webkit-mask-size: 100% 100%;"
|
|
49137
|
+
];
|
|
49138
|
+
}
|
|
49139
|
+
case "angle": return [
|
|
49140
|
+
"height: calc(var(--boundary-height) + 2px);",
|
|
49141
|
+
"background: var(--boundary-shape-paint);",
|
|
49142
|
+
`clip-path: ${anglePolygonCss(entry.shape.polygon)};`
|
|
49143
|
+
];
|
|
49144
|
+
}
|
|
49145
|
+
}
|
|
49146
|
+
function rule$1(selector, declarations) {
|
|
49147
|
+
return `${selector} {\n ${declarations.join("\n ")}\n}`;
|
|
49148
|
+
}
|
|
49149
|
+
function svgDataUrl(svg) {
|
|
49150
|
+
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
49151
|
+
}
|
|
49152
|
+
|
|
48795
49153
|
//#endregion
|
|
48796
49154
|
//#region ../theme-core/src/layout/generateLayoutCss.ts
|
|
48797
49155
|
/**
|
|
@@ -48827,7 +49185,7 @@ function generateLayoutCss(options) {
|
|
|
48827
49185
|
if (bodyTextTypographyCss) {
|
|
48828
49186
|
cssChunks.push(bodyTextTypographyCss);
|
|
48829
49187
|
}
|
|
48830
|
-
cssChunks.push(
|
|
49188
|
+
cssChunks.push(generateBoundaryCss(selector));
|
|
48831
49189
|
return cssChunks.join("\n\n");
|
|
48832
49190
|
}
|
|
48833
49191
|
function toPaddingValue(preset) {
|
|
@@ -48839,197 +49197,6 @@ function toPaddingValue(preset) {
|
|
|
48839
49197
|
};
|
|
48840
49198
|
return map[preset];
|
|
48841
49199
|
}
|
|
48842
|
-
const classicWaveTransitionMask = svgDataUrl("<svg viewBox='0 0 1440 72' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><path d='M0 72V46C130 55 260 24 420 30C590 36 690 62 860 42C1035 21 1160 47 1305 36C1365 31 1415 33 1440 38V72H0Z' fill='white'/></svg>");
|
|
48843
|
-
const balancedWaveTransitionMask = svgDataUrl("<svg viewBox='0 0 1440 72' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><path d='M0 72V42C120 24 240 24 360 42C480 60 600 60 720 42C840 24 960 24 1080 42C1200 60 1320 60 1440 42V72H0Z' fill='white'/></svg>");
|
|
48844
|
-
const gentleWaveTransitionMask = svgDataUrl("<svg viewBox='0 0 1440 72' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><path d='M0 72V43C180 32 300 32 480 43C660 54 780 54 960 43C1140 32 1260 32 1440 43V72H0Z' fill='white'/></svg>");
|
|
48845
|
-
const boldWaveTransitionMask = svgDataUrl("<svg viewBox='0 0 1440 72' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><path d='M0 72V44C90 14 270 14 360 44C450 74 630 74 720 44C810 14 990 14 1080 44C1170 74 1350 74 1440 44V72H0Z' fill='white'/></svg>");
|
|
48846
|
-
const driftWaveTransitionMask = svgDataUrl("<svg viewBox='0 0 1440 72' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><path d='M0 72V39C115 31 205 54 340 48C505 41 610 16 760 33C920 51 1015 64 1160 44C1280 27 1375 35 1440 50V72H0Z' fill='white'/></svg>");
|
|
48847
|
-
function generateSiteStyleTransitionCss(themeId) {
|
|
48848
|
-
const selector = `:where([data-theme-scope="${themeId}"])`;
|
|
48849
|
-
const compactBoundaryHeight = requiredBoundaryHeightCss("wave-edge-gentle");
|
|
48850
|
-
const mediumBoundaryHeight = requiredBoundaryHeightCss("wave-edge");
|
|
48851
|
-
const largeBoundaryHeight = requiredBoundaryHeightCss("wave-edge-bold");
|
|
48852
|
-
const spaciousBoundaryHeight = requiredBoundaryHeightCss("soft-fade-long");
|
|
48853
|
-
const expansiveBoundaryHeight = requiredBoundaryHeightCss("soft-fade-expansive");
|
|
48854
|
-
return `${selector} [data-style-group^='site-style-transition-'] {
|
|
48855
|
-
position: relative;
|
|
48856
|
-
z-index: 2;
|
|
48857
|
-
--site-style-transition-from: transparent;
|
|
48858
|
-
--site-style-transition-to: rgb(var(--tb-background));
|
|
48859
|
-
}
|
|
48860
|
-
|
|
48861
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-'] {
|
|
48862
|
-
position: relative;
|
|
48863
|
-
z-index: 3;
|
|
48864
|
-
height: 0;
|
|
48865
|
-
pointer-events: none;
|
|
48866
|
-
--site-style-boundary-height: ${mediumBoundaryHeight};
|
|
48867
|
-
}
|
|
48868
|
-
|
|
48869
|
-
${selector} [data-block][data-site-style-boundary-before] > :where([data-slot='section']) {
|
|
48870
|
-
padding-top: calc(var(--rb-section-pad-y, 0rem) + var(--site-style-boundary-before-reserve, 0rem));
|
|
48871
|
-
}
|
|
48872
|
-
|
|
48873
|
-
${selector} [data-block][data-site-style-boundary-after] > :where([data-slot='section']) {
|
|
48874
|
-
padding-bottom: calc(var(--rb-section-pad-y, 0rem) + var(--site-style-boundary-after-reserve, 0rem));
|
|
48875
|
-
}
|
|
48876
|
-
|
|
48877
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-']::before,
|
|
48878
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-']::before,
|
|
48879
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-soft-fade']::before {
|
|
48880
|
-
content: '';
|
|
48881
|
-
position: absolute;
|
|
48882
|
-
left: 0;
|
|
48883
|
-
right: 0;
|
|
48884
|
-
top: 0;
|
|
48885
|
-
transform: translateY(-50%);
|
|
48886
|
-
z-index: 0;
|
|
48887
|
-
height: var(--site-style-boundary-height);
|
|
48888
|
-
background: var(--site-style-transition-from);
|
|
48889
|
-
pointer-events: none;
|
|
48890
|
-
}
|
|
48891
|
-
|
|
48892
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-']::after,
|
|
48893
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-']::after,
|
|
48894
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-soft-fade']::after {
|
|
48895
|
-
content: '';
|
|
48896
|
-
position: absolute;
|
|
48897
|
-
left: 0;
|
|
48898
|
-
right: 0;
|
|
48899
|
-
top: 0;
|
|
48900
|
-
transform: translateY(-50%);
|
|
48901
|
-
z-index: 1;
|
|
48902
|
-
height: var(--site-style-boundary-height);
|
|
48903
|
-
pointer-events: none;
|
|
48904
|
-
}
|
|
48905
|
-
|
|
48906
|
-
${selector} [data-style-group*='-from-base-'] {
|
|
48907
|
-
--site-style-transition-from: rgb(var(--tb-background));
|
|
48908
|
-
}
|
|
48909
|
-
|
|
48910
|
-
${selector} [data-style-group*='-from-muted-band-'] {
|
|
48911
|
-
--site-style-transition-from: rgb(var(--tb-muted));
|
|
48912
|
-
}
|
|
48913
|
-
|
|
48914
|
-
${selector} [data-style-group*='-from-accent-band-'] {
|
|
48915
|
-
--site-style-transition-from: rgb(var(--tb-accent));
|
|
48916
|
-
}
|
|
48917
|
-
|
|
48918
|
-
${selector} [data-style-group*='-from-brand-depth-band-'] {
|
|
48919
|
-
--site-style-transition-from: rgb(var(--tb-primary-800));
|
|
48920
|
-
}
|
|
48921
|
-
|
|
48922
|
-
${selector} [data-style-group$='-to-base'],
|
|
48923
|
-
${selector} [data-style-group$='-to-hero-image'] {
|
|
48924
|
-
--site-style-transition-to: rgb(var(--tb-background));
|
|
48925
|
-
}
|
|
48926
|
-
|
|
48927
|
-
${selector} [data-style-group$='-to-muted-band'] {
|
|
48928
|
-
--site-style-transition-to: rgb(var(--tb-muted));
|
|
48929
|
-
}
|
|
48930
|
-
|
|
48931
|
-
${selector} [data-style-group$='-to-accent-band'] {
|
|
48932
|
-
--site-style-transition-to: rgb(var(--tb-accent));
|
|
48933
|
-
}
|
|
48934
|
-
|
|
48935
|
-
${selector} [data-style-group$='-to-brand-depth-band'] {
|
|
48936
|
-
--site-style-transition-to: rgb(var(--tb-primary-800));
|
|
48937
|
-
}
|
|
48938
|
-
|
|
48939
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-soft-fade']::after {
|
|
48940
|
-
/* Fallback for browsers without color-mix(). */
|
|
48941
|
-
background: linear-gradient(
|
|
48942
|
-
to bottom,
|
|
48943
|
-
transparent 0%,
|
|
48944
|
-
var(--site-style-transition-to) 100%
|
|
48945
|
-
);
|
|
48946
|
-
background: linear-gradient(
|
|
48947
|
-
to bottom,
|
|
48948
|
-
transparent 0%,
|
|
48949
|
-
color-mix(in srgb, var(--site-style-transition-to) 16%, transparent) 34%,
|
|
48950
|
-
color-mix(in srgb, var(--site-style-transition-to) 68%, transparent) 78%,
|
|
48951
|
-
var(--site-style-transition-to) 100%
|
|
48952
|
-
);
|
|
48953
|
-
}
|
|
48954
|
-
|
|
48955
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-soft-fade-long-'] {
|
|
48956
|
-
--site-style-boundary-height: ${spaciousBoundaryHeight};
|
|
48957
|
-
}
|
|
48958
|
-
|
|
48959
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-soft-fade-expansive-'] {
|
|
48960
|
-
--site-style-boundary-height: ${expansiveBoundaryHeight};
|
|
48961
|
-
}
|
|
48962
|
-
|
|
48963
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-']::after {
|
|
48964
|
-
height: calc(var(--site-style-boundary-height) + 2px);
|
|
48965
|
-
background: var(--site-style-transition-to);
|
|
48966
|
-
clip-path: polygon(0 42%, 100% 8%, 100% 100%, 0 100%);
|
|
48967
|
-
}
|
|
48968
|
-
|
|
48969
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-subtle-'] {
|
|
48970
|
-
--site-style-boundary-height: ${compactBoundaryHeight};
|
|
48971
|
-
}
|
|
48972
|
-
|
|
48973
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-subtle-']::after {
|
|
48974
|
-
clip-path: polygon(0 34%, 100% 18%, 100% 100%, 0 100%);
|
|
48975
|
-
}
|
|
48976
|
-
|
|
48977
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-steep-'] {
|
|
48978
|
-
--site-style-boundary-height: ${largeBoundaryHeight};
|
|
48979
|
-
}
|
|
48980
|
-
|
|
48981
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-angle-edge-steep-']::after {
|
|
48982
|
-
clip-path: polygon(0 54%, 100% 0%, 100% 100%, 0 100%);
|
|
48983
|
-
}
|
|
48984
|
-
|
|
48985
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-']::after {
|
|
48986
|
-
background: var(--site-style-transition-to);
|
|
48987
|
-
mask-image: url("${classicWaveTransitionMask}");
|
|
48988
|
-
mask-repeat: no-repeat;
|
|
48989
|
-
mask-size: 100% 100%;
|
|
48990
|
-
-webkit-mask-image: url("${classicWaveTransitionMask}");
|
|
48991
|
-
-webkit-mask-repeat: no-repeat;
|
|
48992
|
-
-webkit-mask-size: 100% 100%;
|
|
48993
|
-
}
|
|
48994
|
-
|
|
48995
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-balanced-']::after {
|
|
48996
|
-
mask-image: url("${balancedWaveTransitionMask}");
|
|
48997
|
-
-webkit-mask-image: url("${balancedWaveTransitionMask}");
|
|
48998
|
-
}
|
|
48999
|
-
|
|
49000
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-gentle-'] {
|
|
49001
|
-
--site-style-boundary-height: ${compactBoundaryHeight};
|
|
49002
|
-
}
|
|
49003
|
-
|
|
49004
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-gentle-']::after {
|
|
49005
|
-
mask-image: url("${gentleWaveTransitionMask}");
|
|
49006
|
-
-webkit-mask-image: url("${gentleWaveTransitionMask}");
|
|
49007
|
-
}
|
|
49008
|
-
|
|
49009
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-bold-'] {
|
|
49010
|
-
--site-style-boundary-height: ${largeBoundaryHeight};
|
|
49011
|
-
}
|
|
49012
|
-
|
|
49013
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-bold-']::after {
|
|
49014
|
-
mask-image: url("${boldWaveTransitionMask}");
|
|
49015
|
-
-webkit-mask-image: url("${boldWaveTransitionMask}");
|
|
49016
|
-
}
|
|
49017
|
-
|
|
49018
|
-
${selector} [data-block-boundary][data-style-group^='site-style-transition-wave-edge-drift-']::after {
|
|
49019
|
-
mask-image: url("${driftWaveTransitionMask}");
|
|
49020
|
-
-webkit-mask-image: url("${driftWaveTransitionMask}");
|
|
49021
|
-
}`;
|
|
49022
|
-
}
|
|
49023
|
-
function requiredBoundaryHeightCss(transition) {
|
|
49024
|
-
const metrics = boundaryRuntimeMetricsForTransition(transition);
|
|
49025
|
-
if (!metrics) {
|
|
49026
|
-
throw new Error(`Missing boundary runtime metrics for ${transition}`);
|
|
49027
|
-
}
|
|
49028
|
-
return metrics.heightCss;
|
|
49029
|
-
}
|
|
49030
|
-
function svgDataUrl(svg) {
|
|
49031
|
-
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
49032
|
-
}
|
|
49033
49200
|
function generateHeroTypographyCss(themeId, theme) {
|
|
49034
49201
|
const typography = theme.hero?.typography;
|
|
49035
49202
|
if (!typography) return "";
|
|
@@ -49056,36 +49223,29 @@ function generateHeroTypographyCss(themeId, theme) {
|
|
|
49056
49223
|
if (microSubheadlineRules.length > 0) {
|
|
49057
49224
|
chunks.push(`${microSubheadlineSelector} {\n ${microSubheadlineRules.join("\n ")}\n}`);
|
|
49058
49225
|
}
|
|
49059
|
-
|
|
49060
|
-
|
|
49061
|
-
|
|
49062
|
-
|
|
49063
|
-
|
|
49064
|
-
|
|
49065
|
-
|
|
49066
|
-
if (tabletSubheadlineRules.length > 0) {
|
|
49067
|
-
tabletChunks.push(`${subheadlineSelector} {\n ${tabletSubheadlineRules.join("\n ")}\n }`);
|
|
49068
|
-
}
|
|
49069
|
-
if (tabletChunks.length > 0) {
|
|
49070
|
-
chunks.push(`@media ${MQ_TABLET_ONLY} {\n ${tabletChunks.join("\n\n ")}\n}`);
|
|
49071
|
-
}
|
|
49072
|
-
}
|
|
49073
|
-
if (typography.responsive?.mobile) {
|
|
49074
|
-
const mobileHeadlineRules = buildTypographyRules("headline", typography.responsive.mobile.headlineSize, typography.responsive.mobile.headlineLineHeight);
|
|
49075
|
-
const mobileSubheadlineRules = buildTypographyRules("subheadline", typography.responsive.mobile.subheadlineSize, typography.responsive.mobile.subheadlineLineHeight);
|
|
49076
|
-
const mobileChunks = [];
|
|
49077
|
-
if (mobileHeadlineRules.length > 0) {
|
|
49078
|
-
mobileChunks.push(`${headlineSelector} {\n ${mobileHeadlineRules.join("\n ")}\n }`);
|
|
49079
|
-
}
|
|
49080
|
-
if (mobileSubheadlineRules.length > 0) {
|
|
49081
|
-
mobileChunks.push(`${subheadlineSelector} {\n ${mobileSubheadlineRules.join("\n ")}\n }`);
|
|
49082
|
-
}
|
|
49083
|
-
if (mobileChunks.length > 0) {
|
|
49084
|
-
chunks.push(`@media ${MQ_SM_DOWN} {\n ${mobileChunks.join("\n\n ")}\n}`);
|
|
49085
|
-
}
|
|
49226
|
+
const selectors = {
|
|
49227
|
+
headline: headlineSelector,
|
|
49228
|
+
subheadline: subheadlineSelector
|
|
49229
|
+
};
|
|
49230
|
+
const responsiveChunks = [responsiveHeroTypographyCss(MQ_TABLET_ONLY, selectors, typography.responsive?.tablet), responsiveHeroTypographyCss(MQ_SM_DOWN, selectors, typography.responsive?.mobile)];
|
|
49231
|
+
for (const chunk of responsiveChunks) {
|
|
49232
|
+
if (chunk) chunks.push(chunk);
|
|
49086
49233
|
}
|
|
49087
49234
|
return chunks.join("\n\n");
|
|
49088
49235
|
}
|
|
49236
|
+
function responsiveHeroTypographyCss(media$1, selectors, overrides) {
|
|
49237
|
+
if (!overrides) return null;
|
|
49238
|
+
const headlineRules = buildTypographyRules("headline", overrides.headlineSize, overrides.headlineLineHeight);
|
|
49239
|
+
const subheadlineRules = buildTypographyRules("subheadline", overrides.subheadlineSize, overrides.subheadlineLineHeight);
|
|
49240
|
+
const mediaChunks = [];
|
|
49241
|
+
if (headlineRules.length > 0) {
|
|
49242
|
+
mediaChunks.push(`${selectors.headline} {\n ${headlineRules.join("\n ")}\n }`);
|
|
49243
|
+
}
|
|
49244
|
+
if (subheadlineRules.length > 0) {
|
|
49245
|
+
mediaChunks.push(`${selectors.subheadline} {\n ${subheadlineRules.join("\n ")}\n }`);
|
|
49246
|
+
}
|
|
49247
|
+
return mediaChunks.length > 0 ? `@media ${media$1} {\n ${mediaChunks.join("\n\n ")}\n}` : null;
|
|
49248
|
+
}
|
|
49089
49249
|
function buildTypographyRules(role, size, lineHeight) {
|
|
49090
49250
|
const rules = [];
|
|
49091
49251
|
if (size) {
|
|
@@ -50302,7 +50462,7 @@ function escapeStyleContent(css) {
|
|
|
50302
50462
|
function compileCustomCssRules(rules, themeId) {
|
|
50303
50463
|
if (!rules || rules.length === 0) return "";
|
|
50304
50464
|
const scopePrefix = `:where([data-theme-scope="${themeId}"])`;
|
|
50305
|
-
return rules.map((rule$
|
|
50465
|
+
return rules.map((rule$2) => compileRule(rule$2.selector, rule$2.declarations, scopePrefix)).filter(Boolean).join("\n\n");
|
|
50306
50466
|
}
|
|
50307
50467
|
/**
|
|
50308
50468
|
* Compile an array of block-specific CSS rules to a scoped CSS string.
|
|
@@ -50315,15 +50475,15 @@ function compileCustomCssRules(rules, themeId) {
|
|
|
50315
50475
|
function compileBlockCustomCssRules(rules, themeId) {
|
|
50316
50476
|
if (!rules || rules.length === 0) return "";
|
|
50317
50477
|
const rulesByBlock = new Map();
|
|
50318
|
-
for (const rule$
|
|
50319
|
-
const existing = rulesByBlock.get(rule$
|
|
50320
|
-
existing.push(rule$
|
|
50321
|
-
rulesByBlock.set(rule$
|
|
50478
|
+
for (const rule$2 of rules) {
|
|
50479
|
+
const existing = rulesByBlock.get(rule$2.blockKind) || [];
|
|
50480
|
+
existing.push(rule$2);
|
|
50481
|
+
rulesByBlock.set(rule$2.blockKind, existing);
|
|
50322
50482
|
}
|
|
50323
50483
|
const cssChunks = [];
|
|
50324
50484
|
for (const [blockKind, blockRules] of rulesByBlock) {
|
|
50325
50485
|
const scopePrefix = `:where([data-theme-scope="${themeId}"]) :where([data-block="${blockKind}"])`;
|
|
50326
|
-
const blockCss = blockRules.map((rule$
|
|
50486
|
+
const blockCss = blockRules.map((rule$2) => compileRule(rule$2.selector, rule$2.declarations, scopePrefix)).filter(Boolean).join("\n");
|
|
50327
50487
|
if (blockCss) {
|
|
50328
50488
|
cssChunks.push(`/* Block: ${blockKind} */\n${blockCss}`);
|
|
50329
50489
|
}
|
|
@@ -50575,7 +50735,7 @@ function compileFontFace(atRule) {
|
|
|
50575
50735
|
* }
|
|
50576
50736
|
*/
|
|
50577
50737
|
function compileMedia(atRule, scopePrefix, options) {
|
|
50578
|
-
const rules = atRule.rules.map((rule$
|
|
50738
|
+
const rules = atRule.rules.map((rule$2) => compileNestedRule(rule$2.selector, rule$2.declarations, scopePrefix)).filter(Boolean).join("\n");
|
|
50579
50739
|
if (!rules) return "";
|
|
50580
50740
|
const containerQuery = options.responsiveMode === "container" ? convertMediaQueryToContainerQuery(atRule.query) : null;
|
|
50581
50741
|
if (containerQuery) {
|
|
@@ -50593,7 +50753,7 @@ function compileMedia(atRule, scopePrefix, options) {
|
|
|
50593
50753
|
* }
|
|
50594
50754
|
*/
|
|
50595
50755
|
function compileSupports(atRule, scopePrefix) {
|
|
50596
|
-
const rules = atRule.rules.map((rule$
|
|
50756
|
+
const rules = atRule.rules.map((rule$2) => compileNestedRule(rule$2.selector, rule$2.declarations, scopePrefix)).filter(Boolean).join("\n");
|
|
50597
50757
|
if (!rules) return "";
|
|
50598
50758
|
return `@supports ${atRule.condition} {\n${indent(rules, 2)}\n}`;
|
|
50599
50759
|
}
|
|
@@ -50679,20 +50839,20 @@ function diffCssRules(before, after) {
|
|
|
50679
50839
|
});
|
|
50680
50840
|
}
|
|
50681
50841
|
}
|
|
50682
|
-
for (const [id, rule$
|
|
50842
|
+
for (const [id, rule$2] of afterMap) {
|
|
50683
50843
|
const beforeRule = beforeMap.get(id);
|
|
50684
50844
|
if (!beforeRule) {
|
|
50685
50845
|
patches.push({
|
|
50686
50846
|
op: "add",
|
|
50687
|
-
rule: rule$
|
|
50847
|
+
rule: rule$2
|
|
50688
50848
|
});
|
|
50689
|
-
} else if (!rulesEqual(beforeRule, rule$
|
|
50849
|
+
} else if (!rulesEqual(beforeRule, rule$2)) {
|
|
50690
50850
|
const changes = {};
|
|
50691
|
-
if (beforeRule.selector !== rule$
|
|
50692
|
-
changes.selector = rule$
|
|
50851
|
+
if (beforeRule.selector !== rule$2.selector) {
|
|
50852
|
+
changes.selector = rule$2.selector;
|
|
50693
50853
|
}
|
|
50694
|
-
if (!declarationsEqual(beforeRule.declarations, rule$
|
|
50695
|
-
changes.declarations = rule$
|
|
50854
|
+
if (!declarationsEqual(beforeRule.declarations, rule$2.declarations)) {
|
|
50855
|
+
changes.declarations = rule$2.declarations;
|
|
50696
50856
|
}
|
|
50697
50857
|
if (Object.keys(changes).length > 0) {
|
|
50698
50858
|
patches.push({
|
|
@@ -51325,71 +51485,173 @@ function requireThemeResources(resources, blockKind) {
|
|
|
51325
51485
|
}
|
|
51326
51486
|
|
|
51327
51487
|
//#endregion
|
|
51328
|
-
//#region ../blocks/src/
|
|
51329
|
-
|
|
51330
|
-
|
|
51331
|
-
|
|
51488
|
+
//#region ../blocks/src/pageRenderJoins.ts
|
|
51489
|
+
/**
|
|
51490
|
+
* Re-points joins across omitted blocks. Pure over joins.
|
|
51491
|
+
*
|
|
51492
|
+
* Joins are keyed by adjacent block-id pairs, so dropping B from [A, B, C]
|
|
51493
|
+
* removes the A→C join as well as B's own, because no A→C join was ever
|
|
51494
|
+
* resolved. For each surviving pair the original join is kept when the pair
|
|
51495
|
+
* was already adjacent. Across a gap, the treatment comes from the join
|
|
51496
|
+
* entering the omitted run (A→first omitted), falling back to the one leaving
|
|
51497
|
+
* it (last omitted→C). Nothing visual is carried: the survivors are composed
|
|
51498
|
+
* from their own content afterwards.
|
|
51499
|
+
*
|
|
51500
|
+
* `survivors` are compared by identity against `originalBlocks`.
|
|
51501
|
+
*/
|
|
51502
|
+
function retargetJoinsAcrossOmissions(input) {
|
|
51503
|
+
const { joins, originalBlocks, survivingBlocks } = input;
|
|
51504
|
+
if (joins.length === 0) return joins;
|
|
51505
|
+
if (originalBlocks.every((block) => survivingBlocks.has(block))) return joins;
|
|
51506
|
+
const byPair = joinsByPair(joins);
|
|
51507
|
+
const retargeted = [];
|
|
51508
|
+
let previousSurvivor = null;
|
|
51509
|
+
let run = [];
|
|
51510
|
+
for (const block of originalBlocks) {
|
|
51511
|
+
if (!survivingBlocks.has(block)) {
|
|
51512
|
+
run.push(block);
|
|
51513
|
+
continue;
|
|
51514
|
+
}
|
|
51515
|
+
if (previousSurvivor?.id && block.id) {
|
|
51516
|
+
const join$1 = run.length === 0 ? byPair.get(pairKey(previousSurvivor.id, block.id)) : joinAcrossRun(byPair, previousSurvivor.id, block.id, run);
|
|
51517
|
+
if (join$1) retargeted.push(join$1);
|
|
51518
|
+
}
|
|
51519
|
+
previousSurvivor = block;
|
|
51520
|
+
run = [];
|
|
51521
|
+
}
|
|
51522
|
+
return retargeted;
|
|
51523
|
+
}
|
|
51524
|
+
function joinAcrossRun(byPair, previousBlockId, nextBlockId, run) {
|
|
51525
|
+
const firstOmittedId = run[0]?.id;
|
|
51526
|
+
const lastOmittedId = run[run.length - 1]?.id;
|
|
51527
|
+
const entering = firstOmittedId ? byPair.get(pairKey(previousBlockId, firstOmittedId)) : undefined;
|
|
51528
|
+
const exiting = lastOmittedId ? byPair.get(pairKey(lastOmittedId, nextBlockId)) : undefined;
|
|
51529
|
+
const donor = entering ?? exiting;
|
|
51530
|
+
return donor ? {
|
|
51531
|
+
previousBlockId,
|
|
51532
|
+
nextBlockId,
|
|
51533
|
+
treatment: donor.treatment
|
|
51534
|
+
} : undefined;
|
|
51332
51535
|
}
|
|
51333
|
-
|
|
51334
|
-
|
|
51536
|
+
/**
|
|
51537
|
+
* The single composition site. For every adjacent pair of survivors with ids,
|
|
51538
|
+
* finds its join and composes it from both survivors' final content: what
|
|
51539
|
+
* each paints with and the frame each draws.
|
|
51540
|
+
*/
|
|
51541
|
+
function composePageJoins(input) {
|
|
51542
|
+
const byPair = joinsByPair(input.joins);
|
|
51543
|
+
return input.survivors.flatMap((previous, index) => {
|
|
51544
|
+
const next = input.survivors[index + 1];
|
|
51545
|
+
if (!next || !previous.id || !next.id) return [];
|
|
51546
|
+
const join$1 = byPair.get(pairKey(previous.id, next.id));
|
|
51547
|
+
return [{
|
|
51548
|
+
previousBlockId: previous.id,
|
|
51549
|
+
nextBlockId: next.id,
|
|
51550
|
+
join: join$1 ? composeJoin(join$1, previous, next) : null
|
|
51551
|
+
}];
|
|
51552
|
+
});
|
|
51335
51553
|
}
|
|
51336
|
-
function
|
|
51337
|
-
|
|
51338
|
-
|
|
51339
|
-
|
|
51340
|
-
|
|
51554
|
+
function composeJoin(join$1, previous, next) {
|
|
51555
|
+
return {
|
|
51556
|
+
boundaryId: pairKey(join$1.previousBlockId, join$1.nextBlockId),
|
|
51557
|
+
previousBlockId: join$1.previousBlockId,
|
|
51558
|
+
nextBlockId: join$1.nextBlockId,
|
|
51559
|
+
treatment: join$1.treatment,
|
|
51560
|
+
outcome: composeBoundary(sectionFactsForContent(previous.content), sectionFactsForContent(next.content))
|
|
51561
|
+
};
|
|
51341
51562
|
}
|
|
51342
|
-
|
|
51343
|
-
|
|
51344
|
-
|
|
51563
|
+
/** Placement, reserves and paint for a join that draws; null otherwise. */
|
|
51564
|
+
function renderedJoinLayout(join$1) {
|
|
51565
|
+
if (!join$1 || join$1.outcome.kind !== "shown") return null;
|
|
51566
|
+
return boundaryLayout(join$1.treatment, join$1.outcome.composition);
|
|
51567
|
+
}
|
|
51568
|
+
/** Joins with a missing id on either side cannot sit between two blocks. */
|
|
51569
|
+
function joinsByPair(joins) {
|
|
51570
|
+
return new Map(joins.flatMap((join$1) => join$1.previousBlockId && join$1.nextBlockId ? [[pairKey(join$1.previousBlockId, join$1.nextBlockId), join$1]] : []));
|
|
51571
|
+
}
|
|
51572
|
+
/** Slot lookup key for an adjacent pair, in the one boundary-id scheme. */
|
|
51573
|
+
function joinSlotKey(previousBlockId, nextBlockId) {
|
|
51574
|
+
return pairKey(previousBlockId, nextBlockId);
|
|
51575
|
+
}
|
|
51576
|
+
function pairKey(previousBlockId, nextBlockId) {
|
|
51577
|
+
return makeBoundaryId(asDesignBlockId(previousBlockId), asDesignBlockId(nextBlockId));
|
|
51578
|
+
}
|
|
51579
|
+
|
|
51580
|
+
//#endregion
|
|
51581
|
+
//#region ../blocks/src/pageRendererBoundaries.tsx
|
|
51582
|
+
function joinSlotsByPair(slots) {
|
|
51583
|
+
return new Map(slots.map((slot) => [joinSlotKey(slot.previousBlockId, slot.nextBlockId), slot]));
|
|
51584
|
+
}
|
|
51585
|
+
function joinSlotBetween(previousBlockId, nextBlockId, slots) {
|
|
51345
51586
|
if (!previousBlockId || !nextBlockId) return null;
|
|
51346
|
-
|
|
51347
|
-
|
|
51348
|
-
|
|
51587
|
+
return slots.get(joinSlotKey(previousBlockId, nextBlockId)) ?? null;
|
|
51588
|
+
}
|
|
51589
|
+
/**
|
|
51590
|
+
* The markup at one join: the painted boundary element when the join draws,
|
|
51591
|
+
* then whatever `renderJoin` adds. Null when there is nothing to render.
|
|
51592
|
+
*/
|
|
51593
|
+
function renderJoinSlot(input) {
|
|
51594
|
+
const { slot } = input;
|
|
51595
|
+
if (!slot) return null;
|
|
51596
|
+
const layout = renderedJoinLayout(slot.join);
|
|
51597
|
+
const painted = slot.join && layout ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
51349
51598
|
"aria-hidden": "true",
|
|
51350
51599
|
"data-block-boundary": "",
|
|
51351
|
-
"data-boundary-id":
|
|
51352
|
-
"data-boundary-previous-block-id":
|
|
51353
|
-
"data-boundary-next-block-id":
|
|
51354
|
-
"data-
|
|
51355
|
-
|
|
51356
|
-
|
|
51357
|
-
|
|
51600
|
+
"data-boundary-id": slot.join.boundaryId,
|
|
51601
|
+
"data-boundary-previous-block-id": slot.previousBlockId,
|
|
51602
|
+
"data-boundary-next-block-id": slot.nextBlockId,
|
|
51603
|
+
"data-boundary-treatment": slot.join.treatment,
|
|
51604
|
+
"data-boundary-placement": layout.placement,
|
|
51605
|
+
style: boundaryPaintStyle(layout.paint)
|
|
51606
|
+
}, `${input.blockKey}:boundary`) : null;
|
|
51607
|
+
const extra = input.renderJoin?.({
|
|
51608
|
+
previousBlockId: slot.previousBlockId,
|
|
51609
|
+
nextBlockId: slot.nextBlockId,
|
|
51610
|
+
join: slot.join
|
|
51611
|
+
});
|
|
51612
|
+
if (!painted && (extra === null || extra === undefined)) return null;
|
|
51613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [painted, extra] }, `${input.blockKey}:join`);
|
|
51358
51614
|
}
|
|
51359
|
-
|
|
51360
|
-
|
|
51361
|
-
|
|
51362
|
-
|
|
51363
|
-
}
|
|
51615
|
+
/**
|
|
51616
|
+
* The one render-edge place a theme token becomes CSS.
|
|
51617
|
+
*/
|
|
51618
|
+
function themeTokenCss(token) {
|
|
51619
|
+
return `rgb(var(--tb-${token}))`;
|
|
51364
51620
|
}
|
|
51365
|
-
function
|
|
51366
|
-
const before = input.before?.metrics.reserveCss ?? null;
|
|
51367
|
-
const after = input.after?.metrics.reserveCss ?? null;
|
|
51368
|
-
if (!before && !after) return undefined;
|
|
51621
|
+
function boundaryPaintStyle(paint) {
|
|
51369
51622
|
return {
|
|
51370
|
-
|
|
51371
|
-
...
|
|
51623
|
+
"--boundary-shape-paint": themeTokenCss(paint.shape),
|
|
51624
|
+
...paint.band ? { "--boundary-band-paint": themeTokenCss(paint.band) } : {}
|
|
51372
51625
|
};
|
|
51373
51626
|
}
|
|
51374
|
-
|
|
51375
|
-
|
|
51376
|
-
|
|
51377
|
-
|
|
51378
|
-
|
|
51379
|
-
|
|
51380
|
-
|
|
51381
|
-
|
|
51382
|
-
|
|
51627
|
+
/**
|
|
51628
|
+
* Reserve attributes and variables for a block wrapper, from the joins on
|
|
51629
|
+
* either side. A join's `before` reserve sits inside its previous section, so
|
|
51630
|
+
* it pads the bottom of the block above the join; its `after` reserve pads the
|
|
51631
|
+
* top of the block below. Joins that do not draw reserve nothing.
|
|
51632
|
+
*/
|
|
51633
|
+
function blockBoundaryReserves(input) {
|
|
51634
|
+
const top = reserveOnSide(input.before, "after");
|
|
51635
|
+
const bottom = reserveOnSide(input.after, "before");
|
|
51636
|
+
const style = {
|
|
51637
|
+
...top ? { "--site-style-boundary-before-reserve": top.length } : {},
|
|
51638
|
+
...bottom ? { "--site-style-boundary-after-reserve": bottom.length } : {}
|
|
51383
51639
|
};
|
|
51384
|
-
}
|
|
51385
|
-
function mergeStyleObjects(left, right) {
|
|
51386
|
-
if (!left) return right;
|
|
51387
|
-
if (!right) return left;
|
|
51388
51640
|
return {
|
|
51389
|
-
|
|
51390
|
-
|
|
51641
|
+
topPlacement: top?.placement,
|
|
51642
|
+
bottomPlacement: bottom?.placement,
|
|
51643
|
+
style: top || bottom ? style : undefined
|
|
51391
51644
|
};
|
|
51392
51645
|
}
|
|
51646
|
+
/** The reserve one join needs on one side of itself, if it draws at all. */
|
|
51647
|
+
function reserveOnSide(slot, side) {
|
|
51648
|
+
const layout = renderedJoinLayout(slot?.join ?? null);
|
|
51649
|
+
const length = layout?.reserves[side] ?? null;
|
|
51650
|
+
return layout && length ? {
|
|
51651
|
+
length,
|
|
51652
|
+
placement: layout.placement
|
|
51653
|
+
} : null;
|
|
51654
|
+
}
|
|
51393
51655
|
function pageBlockPosition(index, blockCount) {
|
|
51394
51656
|
if (blockCount <= 1) return "only";
|
|
51395
51657
|
if (index === 0) return "first";
|
|
@@ -56735,6 +56997,15 @@ const appointmentServicesManifest = createBlockManifest({
|
|
|
56735
56997
|
required: false,
|
|
56736
56998
|
ui: { intent: "content" }
|
|
56737
56999
|
},
|
|
57000
|
+
createSiteOptionSelectField({
|
|
57001
|
+
id: "categoryId",
|
|
57002
|
+
label: "Category",
|
|
57003
|
+
description: "Show one category (with its heading and intro), or leave it on All categories to show everything grouped.",
|
|
57004
|
+
required: false,
|
|
57005
|
+
multiple: false,
|
|
57006
|
+
optionSource: "appointmentServiceCategories",
|
|
57007
|
+
ui: { intent: "content" }
|
|
57008
|
+
}),
|
|
56738
57009
|
sectionStylesField({
|
|
56739
57010
|
id: "_sectionStyles",
|
|
56740
57011
|
label: "Section styles",
|
|
@@ -56769,6 +57040,7 @@ const appointmentServicesManifest = createBlockManifest({
|
|
|
56769
57040
|
richText({ className: "rb-prose rb-max-w-none" }, bind("content.description"), when("content.description")),
|
|
56770
57041
|
el("appointment-services", {
|
|
56771
57042
|
sectionHeading: { $bind: { from: "content.heading" } },
|
|
57043
|
+
categoryId: { $bind: { from: "content.categoryId" } },
|
|
56772
57044
|
services: { $bind: { from: "data.services" } },
|
|
56773
57045
|
pathname: { $bind: { from: "$root.pathname" } },
|
|
56774
57046
|
servicePathPrefix: { $bind: { from: "$root.appointmentServicePathPrefix" } }
|
|
@@ -62382,11 +62654,10 @@ function buildPageRenderPlan(input) {
|
|
|
62382
62654
|
return {
|
|
62383
62655
|
entries,
|
|
62384
62656
|
omitted,
|
|
62385
|
-
|
|
62386
|
-
|
|
62657
|
+
runtimeJoins: retargetJoinsAcrossOmissions({
|
|
62658
|
+
joins: input.runtimeJoins ?? [],
|
|
62387
62659
|
originalBlocks: input.page.blocks,
|
|
62388
|
-
survivingBlocks: new Set(entries.map((entry) => entry.block))
|
|
62389
|
-
previewStage: input.previewStage
|
|
62660
|
+
survivingBlocks: new Set(entries.map((entry) => entry.block))
|
|
62390
62661
|
})
|
|
62391
62662
|
};
|
|
62392
62663
|
}
|
|
@@ -62495,88 +62766,15 @@ function getBlockOverride(blockKind, overrides) {
|
|
|
62495
62766
|
* For draft/preview: draftContent takes priority over content.
|
|
62496
62767
|
* For published: content is the source of truth.
|
|
62497
62768
|
*/
|
|
62769
|
+
/**
|
|
62770
|
+
* The content a block renders with. Every render path (public, preview,
|
|
62771
|
+
* templates, SDK) chooses content here, so this is also where a stale
|
|
62772
|
+
* `site-style-transition-*` styleGroup is dropped; authored values survive.
|
|
62773
|
+
*/
|
|
62498
62774
|
function getRenderableContent(block, previewStage = "published") {
|
|
62499
62775
|
const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
|
|
62500
|
-
return isObjectRecord(source) ? source : {};
|
|
62501
|
-
}
|
|
62502
|
-
/**
|
|
62503
|
-
* Re-points section boundaries across omitted blocks.
|
|
62504
|
-
*
|
|
62505
|
-
* Boundaries are keyed by adjacent block-id *pairs*, so dropping B from
|
|
62506
|
-
* [A, B, C] does not merely remove B's boundaries — it removes the boundary
|
|
62507
|
-
* between the survivors, because no `A→C` key was ever compiled.
|
|
62508
|
-
*
|
|
62509
|
-
* Per decision D2 the treatment for a merged gap comes from the boundary
|
|
62510
|
-
* entering the omitted run (`A→firstOmitted`), falling back to the one leaving
|
|
62511
|
-
* it (`lastOmitted→C`). The destination surface is a separate question: only
|
|
62512
|
-
* the exiting boundary knows what C looks like, so the merged boundary ends on
|
|
62513
|
-
* that endpoint rather than on the omitted block's. In the exiting-only
|
|
62514
|
-
* fallback the origin remains an approximation: `from` is the omitted block's
|
|
62515
|
-
* surface, because no compiled boundary carries A's. The hosted path no longer
|
|
62516
|
-
* needs this at all (site-renderer admits blocks before compiling boundaries);
|
|
62517
|
-
* it remains the safety net for an SDK whose compiled boundaries predate an
|
|
62518
|
-
* omission.
|
|
62519
|
-
*/
|
|
62520
|
-
function retargetBoundariesAcrossOmissions(input) {
|
|
62521
|
-
const { boundaries, originalBlocks, survivingBlocks, previewStage } = input;
|
|
62522
|
-
if (boundaries === undefined) return undefined;
|
|
62523
|
-
if (boundaries.length === 0) return boundaries;
|
|
62524
|
-
const anyOmitted = originalBlocks.some((block) => !survivingBlocks.has(block));
|
|
62525
|
-
if (!anyOmitted) return boundaries;
|
|
62526
|
-
const byPair = new Map(boundaries.map((boundary) => [pairKey(boundary.previousBlockId, boundary.nextBlockId), boundary]));
|
|
62527
|
-
const retargeted = [];
|
|
62528
|
-
let previousSurvivor = null;
|
|
62529
|
-
let run = [];
|
|
62530
|
-
for (const block of originalBlocks) {
|
|
62531
|
-
if (!survivingBlocks.has(block)) {
|
|
62532
|
-
run.push(block);
|
|
62533
|
-
continue;
|
|
62534
|
-
}
|
|
62535
|
-
if (previousSurvivor?.id && block.id) {
|
|
62536
|
-
const boundary = run.length === 0 ? byPair.get(pairKey(previousSurvivor.id, block.id)) : mergedBoundary({
|
|
62537
|
-
byPair,
|
|
62538
|
-
previousBlock: previousSurvivor,
|
|
62539
|
-
previousBlockId: previousSurvivor.id,
|
|
62540
|
-
nextBlock: block,
|
|
62541
|
-
nextBlockId: block.id,
|
|
62542
|
-
run,
|
|
62543
|
-
previewStage
|
|
62544
|
-
});
|
|
62545
|
-
if (boundary) retargeted.push(boundary);
|
|
62546
|
-
}
|
|
62547
|
-
previousSurvivor = block;
|
|
62548
|
-
run = [];
|
|
62549
|
-
}
|
|
62550
|
-
return retargeted;
|
|
62551
|
-
}
|
|
62552
|
-
function mergedBoundary(input) {
|
|
62553
|
-
const { byPair, previousBlock, previousBlockId, nextBlock, nextBlockId, run, previewStage } = input;
|
|
62554
|
-
const firstOmittedId = run[0]?.id;
|
|
62555
|
-
const lastOmittedId = run[run.length - 1]?.id;
|
|
62556
|
-
const entering = firstOmittedId ? byPair.get(pairKey(previousBlockId, firstOmittedId)) : undefined;
|
|
62557
|
-
const exiting = lastOmittedId ? byPair.get(pairKey(lastOmittedId, nextBlockId)) : undefined;
|
|
62558
|
-
const donor = entering ?? exiting;
|
|
62559
|
-
if (!donor) return undefined;
|
|
62560
|
-
const transition = compileTransitionRuntime({
|
|
62561
|
-
treatment: donor.treatment,
|
|
62562
|
-
from: donor.from,
|
|
62563
|
-
to: exiting?.to ?? donor.to
|
|
62564
|
-
});
|
|
62565
|
-
const rekeyed = {
|
|
62566
|
-
...donor,
|
|
62567
|
-
boundaryId: makeBoundaryId(asDesignBlockId(previousBlockId), asDesignBlockId(nextBlockId)),
|
|
62568
|
-
previousBlockId,
|
|
62569
|
-
nextBlockId,
|
|
62570
|
-
from: transition.from,
|
|
62571
|
-
to: transition.to,
|
|
62572
|
-
cssVars: transition.cssVars
|
|
62573
|
-
};
|
|
62574
|
-
return retargetCompiledBoundaryRuntimeForContentAdjacency(rekeyed, {
|
|
62575
|
-
currentContent: getRenderableContent(previousBlock, previewStage),
|
|
62576
|
-
nextContent: getRenderableContent(nextBlock, previewStage)
|
|
62577
|
-
});
|
|
62776
|
+
return isObjectRecord(source) ? stripStaleTransitionStyleGroup(source) : {};
|
|
62578
62777
|
}
|
|
62579
|
-
const pairKey = boundaryKey;
|
|
62580
62778
|
|
|
62581
62779
|
//#endregion
|
|
62582
62780
|
//#region ../blocks/src/system/manifest/hydrateLinks.ts
|
|
@@ -62774,25 +62972,47 @@ function preparePageRender(input) {
|
|
|
62774
62972
|
prepared
|
|
62775
62973
|
});
|
|
62776
62974
|
}
|
|
62777
|
-
|
|
62778
|
-
return {
|
|
62779
|
-
entries,
|
|
62780
|
-
constructionFailures,
|
|
62781
|
-
runtimeBoundaries: input.plan.runtimeBoundaries
|
|
62782
|
-
};
|
|
62783
|
-
}
|
|
62784
|
-
const survivors = entries.filter((candidate) => candidate.prepared.kind !== "render-threw");
|
|
62975
|
+
const survivors = input.audience === "authoring" ? entries : entries.filter((candidate) => candidate.prepared.kind !== "render-threw");
|
|
62785
62976
|
return {
|
|
62786
62977
|
entries: survivors,
|
|
62787
62978
|
constructionFailures,
|
|
62788
|
-
|
|
62789
|
-
boundaries: input.plan.runtimeBoundaries,
|
|
62790
|
-
originalBlocks: input.plan.entries.map((planned) => planned.block),
|
|
62791
|
-
survivingBlocks: new Set(survivors.map((survivor) => survivor.entry.block)),
|
|
62792
|
-
previewStage: input.previewStage
|
|
62793
|
-
})
|
|
62979
|
+
joins: composeSurvivorJoins(input.plan, survivors, input.themeResources)
|
|
62794
62980
|
};
|
|
62795
62981
|
}
|
|
62982
|
+
/**
|
|
62983
|
+
* The only place joins are composed. Plan-time omissions were already
|
|
62984
|
+
* re-pointed by the plan; construction failures are re-pointed here by the
|
|
62985
|
+
* same primitive, so `[A, B, C]` losing B still gets an A→C join. Each
|
|
62986
|
+
* survivor is then classified from its final content.
|
|
62987
|
+
*/
|
|
62988
|
+
function composeSurvivorJoins(plan, survivors, themeResources) {
|
|
62989
|
+
const joins = retargetJoinsAcrossOmissions({
|
|
62990
|
+
joins: plan.runtimeJoins,
|
|
62991
|
+
originalBlocks: plan.entries.map((planned) => planned.block),
|
|
62992
|
+
survivingBlocks: new Set(survivors.map((survivor) => survivor.entry.block))
|
|
62993
|
+
});
|
|
62994
|
+
return composePageJoins({
|
|
62995
|
+
joins,
|
|
62996
|
+
survivors: survivors.map(({ entry }) => ({
|
|
62997
|
+
id: entry.block.id,
|
|
62998
|
+
kind: entry.block.kind,
|
|
62999
|
+
content: boundaryClassificationContent(entry, themeResources)
|
|
63000
|
+
}))
|
|
63001
|
+
});
|
|
63002
|
+
}
|
|
63003
|
+
/**
|
|
63004
|
+
* The content a join is classified from must be the content that paints the
|
|
63005
|
+
* section. The default block renderer layers the theme's per-block style
|
|
63006
|
+
* defaults (`theme.blockOverrides[kind].styles`, background included) under
|
|
63007
|
+
* the block's own `_sectionStyles`, so classify that same projection. An
|
|
63008
|
+
* override component renders its own markup from the unmerged content.
|
|
63009
|
+
*/
|
|
63010
|
+
function boundaryClassificationContent(entry, themeResources) {
|
|
63011
|
+
if (entry.kind !== "renderable" || entry.override) {
|
|
63012
|
+
return entry.renderableContent;
|
|
63013
|
+
}
|
|
63014
|
+
return mergeContentWithBlockStyleOverrides(entry.renderableContent, themeResources.kind === "available" ? themeResources.config : undefined, entry.block.kind);
|
|
63015
|
+
}
|
|
62796
63016
|
function prepareEntry(entry, input) {
|
|
62797
63017
|
if (entry.kind !== "renderable") return { kind: "plan-decided" };
|
|
62798
63018
|
const draftContent = previewableEditorContent(entry);
|
|
@@ -63006,7 +63226,7 @@ function EditorPageRenderer(props$1) {
|
|
|
63006
63226
|
});
|
|
63007
63227
|
}
|
|
63008
63228
|
function PageRendererCore(props$1) {
|
|
63009
|
-
const { page, audience,
|
|
63229
|
+
const { page, audience, runtimeJoins, dataContext, routeMap, registry, sdkConfig, customBlocks, blockOverrides } = props$1;
|
|
63010
63230
|
const imageResolveContext = import_react.useMemo(() => resolvePageRendererImageResolveContext(dataContext), [
|
|
63011
63231
|
dataContext?.imageResolveContext,
|
|
63012
63232
|
dataContext?.mediaAssets,
|
|
@@ -63022,7 +63242,7 @@ function PageRendererCore(props$1) {
|
|
|
63022
63242
|
blocks: []
|
|
63023
63243
|
},
|
|
63024
63244
|
audience,
|
|
63025
|
-
|
|
63245
|
+
runtimeJoins,
|
|
63026
63246
|
previewStage,
|
|
63027
63247
|
sdkConfig,
|
|
63028
63248
|
customBlocks,
|
|
@@ -63030,7 +63250,7 @@ function PageRendererCore(props$1) {
|
|
|
63030
63250
|
}), [
|
|
63031
63251
|
page,
|
|
63032
63252
|
audience,
|
|
63033
|
-
|
|
63253
|
+
runtimeJoins,
|
|
63034
63254
|
previewStage,
|
|
63035
63255
|
sdkConfig,
|
|
63036
63256
|
customBlocks,
|
|
@@ -63047,19 +63267,16 @@ function PageRendererCore(props$1) {
|
|
|
63047
63267
|
dataContext,
|
|
63048
63268
|
routeMap,
|
|
63049
63269
|
themeResources,
|
|
63050
|
-
imageResolveContext
|
|
63051
|
-
previewStage
|
|
63270
|
+
imageResolveContext
|
|
63052
63271
|
}), [
|
|
63053
63272
|
plan,
|
|
63054
63273
|
audience,
|
|
63055
63274
|
dataContext,
|
|
63056
63275
|
routeMap,
|
|
63057
63276
|
themeResources,
|
|
63058
|
-
imageResolveContext
|
|
63059
|
-
previewStage
|
|
63277
|
+
imageResolveContext
|
|
63060
63278
|
]);
|
|
63061
|
-
const
|
|
63062
|
-
const usesRuntimeBoundaries = preparation.runtimeBoundaries !== undefined;
|
|
63279
|
+
const joinSlots = import_react.useMemo(() => joinSlotsByPair(preparation.joins), [preparation.joins]);
|
|
63063
63280
|
reportAndReplayOmissions({
|
|
63064
63281
|
plan,
|
|
63065
63282
|
preparation,
|
|
@@ -63079,10 +63296,9 @@ function PageRendererCore(props$1) {
|
|
|
63079
63296
|
themeResources,
|
|
63080
63297
|
imageResolveContext,
|
|
63081
63298
|
resolvedRegistry,
|
|
63082
|
-
|
|
63083
|
-
usesRuntimeBoundaries,
|
|
63299
|
+
joinSlots,
|
|
63084
63300
|
wrapBlock: props$1.wrapBlock,
|
|
63085
|
-
|
|
63301
|
+
renderJoin: props$1.renderJoin
|
|
63086
63302
|
})) });
|
|
63087
63303
|
}
|
|
63088
63304
|
/**
|
|
@@ -63177,27 +63393,25 @@ function requireEntryBlockOverride(entry, themeResources) {
|
|
|
63177
63393
|
}
|
|
63178
63394
|
/**
|
|
63179
63395
|
* Renders one planned block: its wrapper, style-group data attributes,
|
|
63180
|
-
* boundary reserve space and
|
|
63396
|
+
* boundary reserve space and the join markup that follows it.
|
|
63181
63397
|
*
|
|
63182
63398
|
* Extracted from PageRendererCore so the component stays about wiring the plan
|
|
63183
63399
|
* rather than also owning per-block markup.
|
|
63184
63400
|
*/
|
|
63185
63401
|
function renderPlanEntry(input) {
|
|
63186
|
-
const { index, entries, props: props$1, themeResources, imageResolveContext, resolvedRegistry,
|
|
63402
|
+
const { index, entries, props: props$1, themeResources, imageResolveContext, resolvedRegistry, joinSlots, wrapBlock, renderJoin } = input;
|
|
63187
63403
|
const entry = input.entry.entry;
|
|
63188
63404
|
const block = entry.block;
|
|
63189
63405
|
const blockPosition = pageBlockPosition(index, entries.length);
|
|
63190
63406
|
const blockKey = blockKeyFor(block, index);
|
|
63191
63407
|
const previousBlock = entries[index - 1]?.entry.block ?? null;
|
|
63192
63408
|
const nextBlock = entries[index + 1]?.entry.block ?? null;
|
|
63193
|
-
const
|
|
63194
|
-
const
|
|
63195
|
-
const boundaryElement =
|
|
63196
|
-
|
|
63197
|
-
nextBlock,
|
|
63409
|
+
const joinBefore = joinSlotBetween(previousBlock?.id, block.id, joinSlots);
|
|
63410
|
+
const joinAfter = joinSlotBetween(block.id, nextBlock?.id, joinSlots);
|
|
63411
|
+
const boundaryElement = renderJoinSlot({
|
|
63412
|
+
slot: joinAfter,
|
|
63198
63413
|
blockKey,
|
|
63199
|
-
|
|
63200
|
-
wrapBoundary
|
|
63414
|
+
renderJoin
|
|
63201
63415
|
});
|
|
63202
63416
|
const cleanKind = block.kind.replace(/^block\./, "");
|
|
63203
63417
|
const managesOwnWrapper = entry.kind === "renderable" && entry.managesOwnWrapper;
|
|
@@ -63220,12 +63434,10 @@ function renderPlanEntry(input) {
|
|
|
63220
63434
|
const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : undefined;
|
|
63221
63435
|
const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : undefined;
|
|
63222
63436
|
const blockComposition = readBlockComposition(renderableContent.blockComposition);
|
|
63223
|
-
const
|
|
63224
|
-
|
|
63225
|
-
|
|
63226
|
-
after: boundaryAfter
|
|
63437
|
+
const reserves = blockBoundaryReserves({
|
|
63438
|
+
before: joinBefore,
|
|
63439
|
+
after: joinAfter
|
|
63227
63440
|
});
|
|
63228
|
-
const blockStyle = mergeStyleObjects(transitionStyle, boundaryReserveStyle);
|
|
63229
63441
|
const blockElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
63230
63442
|
className: wrapperClassName,
|
|
63231
63443
|
"data-block": cleanKind,
|
|
@@ -63237,25 +63449,16 @@ function renderPlanEntry(input) {
|
|
|
63237
63449
|
"data-block-composition": blockComposition?.treatment,
|
|
63238
63450
|
"data-block-composition-kind": blockComposition?.kind,
|
|
63239
63451
|
"data-page-block-position": blockPosition,
|
|
63240
|
-
"data-site-style-boundary-before":
|
|
63241
|
-
"data-site-style-boundary-after":
|
|
63452
|
+
"data-site-style-boundary-before": reserves.topPlacement,
|
|
63453
|
+
"data-site-style-boundary-after": reserves.bottomPlacement,
|
|
63242
63454
|
"data-style-group": styleGroup,
|
|
63243
|
-
style:
|
|
63455
|
+
style: reserves.style,
|
|
63244
63456
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MemoBlockSection, { ...blockSectionProps })
|
|
63245
63457
|
}, blockKey);
|
|
63246
63458
|
if (boundaryElement) {
|
|
63247
63459
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [blockElement, boundaryElement] }, blockKey);
|
|
63248
63460
|
}
|
|
63249
|
-
|
|
63250
|
-
return blockElement;
|
|
63251
|
-
}
|
|
63252
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [blockElement, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
63253
|
-
"aria-hidden": "true",
|
|
63254
|
-
"data-block-transition": "",
|
|
63255
|
-
"data-block-transition-for": block.id ?? blockKey,
|
|
63256
|
-
"data-style-group": styleGroup,
|
|
63257
|
-
style: transitionStyle
|
|
63258
|
-
})] }, blockKey);
|
|
63461
|
+
return blockElement;
|
|
63259
63462
|
}
|
|
63260
63463
|
function resolvePageRendererImageResolveContext(dataContext) {
|
|
63261
63464
|
const input = dataContext?.imageResolveContext;
|
|
@@ -81223,6 +81426,17 @@ function coerceToString(value) {
|
|
|
81223
81426
|
return "";
|
|
81224
81427
|
}
|
|
81225
81428
|
/**
|
|
81429
|
+
* The appointment-services catalogue (issue 1403) pairs the services with the
|
|
81430
|
+
* site's ordered categories. Both are needed to group them, so that response
|
|
81431
|
+
* is passed through whole; any other `{ services }` wrapper is unwrapped.
|
|
81432
|
+
*/
|
|
81433
|
+
function coerceServicesPayload(record) {
|
|
81434
|
+
return Array.isArray(record.services) && Array.isArray(record.categories) ? {
|
|
81435
|
+
services: record.services,
|
|
81436
|
+
categories: record.categories
|
|
81437
|
+
} : record.services;
|
|
81438
|
+
}
|
|
81439
|
+
/**
|
|
81226
81440
|
* Extract data from API response.
|
|
81227
81441
|
* Unwraps common response wrappers: { data }, { form }, { entries }, { services }, { teamMembers }
|
|
81228
81442
|
*
|
|
@@ -81237,7 +81451,7 @@ function coercePayload(payload) {
|
|
|
81237
81451
|
if ("data" in record && typeof record.data !== "function") return record.data;
|
|
81238
81452
|
if ("form" in record && typeof record.form !== "function") return record.form;
|
|
81239
81453
|
if ("entries" in record && typeof record.entries !== "function") return record.entries;
|
|
81240
|
-
if ("services" in record && typeof record.services !== "function") return record
|
|
81454
|
+
if ("services" in record && typeof record.services !== "function") return coerceServicesPayload(record);
|
|
81241
81455
|
if ("teamMembers" in record && typeof record.teamMembers !== "function") return record.teamMembers;
|
|
81242
81456
|
}
|
|
81243
81457
|
return payload;
|
|
@@ -101805,7 +102019,7 @@ async function loadConfig(configPath, output) {
|
|
|
101805
102019
|
return { errorMessage: "No config path provided." };
|
|
101806
102020
|
}
|
|
101807
102021
|
try {
|
|
101808
|
-
const { loadConfigFile: loadConfigFile$1 } = await import("../load-config-
|
|
102022
|
+
const { loadConfigFile: loadConfigFile$1 } = await import("../load-config-BToL9PfS.mjs");
|
|
101809
102023
|
const rawConfig = await loadConfigFile$1(configPath);
|
|
101810
102024
|
const parsed = riverbankSiteConfigSchema.safeParse(rawConfig);
|
|
101811
102025
|
if (!parsed.success) {
|
|
@@ -113214,6 +113428,7 @@ const allowedPathPrefixes = [
|
|
|
113214
113428
|
"/sites/{siteId}/bookings/closures",
|
|
113215
113429
|
"/sites/{siteId}/bookings/resources",
|
|
113216
113430
|
"/sites/{siteId}/bookings/services",
|
|
113431
|
+
"/sites/{siteId}/bookings/service-categories",
|
|
113217
113432
|
"/sites/{siteId}/bookings/appointment-setup",
|
|
113218
113433
|
"/sites/{siteId}/bookings/appointments",
|
|
113219
113434
|
"/sites/{siteId}/bookings/appointment-reservations",
|
|
@@ -113347,13 +113562,13 @@ function classifyDemoDashboardMutationDescriptor(descriptor) {
|
|
|
113347
113562
|
publicMessage: descriptor.demoMutation.publicMessage
|
|
113348
113563
|
};
|
|
113349
113564
|
}
|
|
113350
|
-
for (const rule$
|
|
113351
|
-
if (!matchesClassificationRule(descriptor, rule$
|
|
113565
|
+
for (const rule$2 of demoMutationClassificationRules) {
|
|
113566
|
+
if (!matchesClassificationRule(descriptor, rule$2)) continue;
|
|
113352
113567
|
return {
|
|
113353
113568
|
kind: "classified",
|
|
113354
113569
|
capability,
|
|
113355
|
-
classification: rule$
|
|
113356
|
-
publicMessage: rule$
|
|
113570
|
+
classification: rule$2.classification,
|
|
113571
|
+
publicMessage: rule$2.publicMessage
|
|
113357
113572
|
};
|
|
113358
113573
|
}
|
|
113359
113574
|
return {
|
|
@@ -113362,12 +113577,12 @@ function classifyDemoDashboardMutationDescriptor(descriptor) {
|
|
|
113362
113577
|
publicMessage: "This demo action needs a safety classification before it can run."
|
|
113363
113578
|
};
|
|
113364
113579
|
}
|
|
113365
|
-
function matchesClassificationRule(descriptor, rule$
|
|
113366
|
-
switch (rule$
|
|
113367
|
-
case "path_starts_with": return rule$
|
|
113368
|
-
case "path_fragments": return pathContainsAnySegmentSequence(descriptor.path, rule$
|
|
113369
|
-
case "path_prefixes": return rule$
|
|
113370
|
-
default: return assertNever(rule$
|
|
113580
|
+
function matchesClassificationRule(descriptor, rule$2) {
|
|
113581
|
+
switch (rule$2.kind) {
|
|
113582
|
+
case "path_starts_with": return rule$2.prefixes.some((prefix) => descriptor.path.startsWith(prefix));
|
|
113583
|
+
case "path_fragments": return pathContainsAnySegmentSequence(descriptor.path, rule$2.fragments);
|
|
113584
|
+
case "path_prefixes": return rule$2.prefixes.some((prefix) => descriptor.path.startsWith(prefix));
|
|
113585
|
+
default: return assertNever(rule$2);
|
|
113371
113586
|
}
|
|
113372
113587
|
}
|
|
113373
113588
|
function isDashboardSiteMutation(descriptor) {
|
|
@@ -114125,25 +114340,10 @@ function deriveLaunchDomainRequirement(siteId, domainState) {
|
|
|
114125
114340
|
} : evidenceFromDerivedState(state)
|
|
114126
114341
|
});
|
|
114127
114342
|
}
|
|
114128
|
-
function
|
|
114129
|
-
|
|
114130
|
-
const overrides = input.overrides ?? [];
|
|
114131
|
-
const appointmentOverrideDefinition = LAUNCH_REQUIREMENT_OVERRIDE_DEFINITIONS.configure_appointments;
|
|
114343
|
+
function generatedSiteReviewRequirements(input) {
|
|
114344
|
+
if (input.publicExperience === "hosted_booking") return [];
|
|
114132
114345
|
const isGeneratedSiteReviewed = input.reviewGeneratedSite.kind === "reviewed";
|
|
114133
|
-
|
|
114134
|
-
const confirmEmailState = input.email.kind === "confirmed" ? "complete" : "pending";
|
|
114135
|
-
requirements.push(requirement({
|
|
114136
|
-
id: "confirm_email",
|
|
114137
|
-
packId: "core",
|
|
114138
|
-
priority: "required",
|
|
114139
|
-
state: confirmEmailState,
|
|
114140
|
-
owner: "either",
|
|
114141
|
-
title: "Confirm your email",
|
|
114142
|
-
description: confirmEmailState === "complete" ? "Email confirmed. Your dashboard and launch path are unlocked." : "Confirm your email before the site can go live.",
|
|
114143
|
-
action: informationalAction("Confirm your email"),
|
|
114144
|
-
evidence: evidenceFromDerivedState(confirmEmailState)
|
|
114145
|
-
}));
|
|
114146
|
-
requirements.push(requirement({
|
|
114346
|
+
return [requirement({
|
|
114147
114347
|
id: "review_generated_site",
|
|
114148
114348
|
packId: "core",
|
|
114149
114349
|
priority: "required",
|
|
@@ -114165,7 +114365,26 @@ function deriveLaunchReadiness(input) {
|
|
|
114165
114365
|
kind: "deferred",
|
|
114166
114366
|
reason: "pending_acknowledgement"
|
|
114167
114367
|
}
|
|
114368
|
+
})];
|
|
114369
|
+
}
|
|
114370
|
+
function deriveLaunchReadiness(input) {
|
|
114371
|
+
const siteId = input.siteId ?? null;
|
|
114372
|
+
const overrides = input.overrides ?? [];
|
|
114373
|
+
const appointmentOverrideDefinition = LAUNCH_REQUIREMENT_OVERRIDE_DEFINITIONS.configure_appointments;
|
|
114374
|
+
const requirements = [];
|
|
114375
|
+
const confirmEmailState = input.email.kind === "confirmed" ? "complete" : "pending";
|
|
114376
|
+
requirements.push(requirement({
|
|
114377
|
+
id: "confirm_email",
|
|
114378
|
+
packId: "core",
|
|
114379
|
+
priority: "required",
|
|
114380
|
+
state: confirmEmailState,
|
|
114381
|
+
owner: "either",
|
|
114382
|
+
title: "Confirm your email",
|
|
114383
|
+
description: confirmEmailState === "complete" ? "Email confirmed. Your dashboard and launch path are unlocked." : "Confirm your email before the site can go live.",
|
|
114384
|
+
action: informationalAction("Confirm your email"),
|
|
114385
|
+
evidence: evidenceFromDerivedState(confirmEmailState)
|
|
114168
114386
|
}));
|
|
114387
|
+
requirements.push(...generatedSiteReviewRequirements(input));
|
|
114169
114388
|
if (input.appointments.kind !== "disabled") {
|
|
114170
114389
|
const appointmentsOverride = input.appointments.kind === "pending_setup" ? findLaunchOverride(overrides, appointmentOverrideDefinition.requirementId) : null;
|
|
114171
114390
|
requirements.push(requirement({
|
|
@@ -114624,7 +114843,8 @@ const appointmentSetupServiceDraftSchema = z.object({
|
|
|
114624
114843
|
venue: appointmentSetupVenueChoiceSchema,
|
|
114625
114844
|
timezone: z.string().trim().min(1).nullable(),
|
|
114626
114845
|
payment: appointmentSetupPaymentDraftSchema,
|
|
114627
|
-
assignment: appointmentSetupServiceAssignmentDraftSchema
|
|
114846
|
+
assignment: appointmentSetupServiceAssignmentDraftSchema,
|
|
114847
|
+
categoryId: z.string().uuid().nullable().optional()
|
|
114628
114848
|
}).superRefine((service, ctx) => {
|
|
114629
114849
|
if (service.payment.kind !== "free" && (service.priceAmount === null || service.priceAmount <= 0)) {
|
|
114630
114850
|
ctx.addIssue({
|
|
@@ -118663,9 +118883,9 @@ function isNegationForEnvRule(line) {
|
|
|
118663
118883
|
function normalizePattern(pattern) {
|
|
118664
118884
|
return pattern.replace(/^\.\//u, "").replace(/\/$/u, "");
|
|
118665
118885
|
}
|
|
118666
|
-
function appendGitignoreRule(content, rule$
|
|
118667
|
-
if (content.length === 0) return `${rule$
|
|
118668
|
-
return `${content.endsWith("\n") ? content : `${content}\n`}${rule$
|
|
118886
|
+
function appendGitignoreRule(content, rule$2) {
|
|
118887
|
+
if (content.length === 0) return `${rule$2}\n`;
|
|
118888
|
+
return `${content.endsWith("\n") ? content : `${content}\n`}${rule$2}\n`;
|
|
118669
118889
|
}
|
|
118670
118890
|
/**
|
|
118671
118891
|
* Plan the one exact environment rule needed by local onboarding. Existing
|