riverbankcms 0.19.0 → 0.20.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/README.md +23 -0
- package/dist/acceptance/matrix.mjs +3 -3
- package/dist/cli/index.mjs +2291 -105791
- package/dist/cli/init-docs/content/workflow-content-types.md +25 -0
- package/dist/entryCommands-8kDjOex0.mjs +111695 -0
- package/dist/{eventUpsertInputSchema-Bkafrrjw.mjs → eventUpsertInputSchema-VVBVGA6x.mjs} +333 -547
- package/dist/load-config-Cut7_6t_.mjs +4 -0
- package/dist/{load-config-CErro6mj.mjs → load-config-gqUEjIyB.mjs} +2 -2
- package/dist/{plan-DW5O751d.mjs → plan-HAEMHc5T.mjs} +1 -1
- package/dist/{sdk-event-upsert-BdvfnCyV.mjs → richTextSchema-DTvrDDF5.mjs} +1300 -165
- package/dist/scaffold/index.mjs +2 -2
- package/dist/{src-yL0DBH7S.mjs → src-Dixcv4PB.mjs} +109 -15
- package/dist/testing.mjs +5 -4
- package/package.json +1 -1
- package/dist/load-config-rPaisrdG.mjs +0 -4
- package/dist/local-sync-CWLEhMZ-.mjs +0 -4635
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { An as unsafeAsStoragePath, B as parsePublicContactDetails, C as stableJsonStringify, Cn as unsafeAsProductId, Dn as unsafeAsSiteScopedStoragePath, En as unsafeAsSiteId, H as isPresent, Mn as unsafeAsUserId, Mt as fromArray, N as parseFooterCompositionV1, Nn as err, Nt as mapNonEmptyArray, P as footerNavigationLayouts, Pn as ok, Pt as mapReadonlyNonEmptyArray, Tn as unsafeAsSiteFontId, Wt as assertNever, Zt as parseMediaAssetId, an as unsafeAsBookingRequirementId, bn as unsafeAsPositiveByteCount, c as resolveSiteVerticalBookingConfig, cn as unsafeAsDeclaredMimeType, ct as validateBookingPaymentOptionKinds, d as ORDINARY_EVENT_PRESET_VALUES, dn as unsafeAsEntitlementId, gn as unsafeAsMediaAssetId, hn as unsafeAsFileChecksumSha256, jn as unsafeAsUploadSessionId, kn as unsafeAsStorageBucketName, nt as localScheduleTimePattern, on as unsafeAsBookingSessionId, r as NAVIGATION_LOCATIONS, rt as parseUtcIsoDateTimeString, st as parseBookingTimeZone, tn as parseSiteId, u as EVENT_PRESET_VALUES, un as unsafeAsDetectedMimeType, vn as unsafeAsOriginalFilename, wn as unsafeAsSafeDownloadFilename, xn as unsafeAsPositiveSeconds, z as isCanonicalRichTextDoc } from "./src-Dixcv4PB.mjs";
|
|
3
3
|
import "node:module";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
@@ -4038,6 +4038,7 @@ function canonicalHoverToken(reference, palette) {
|
|
|
4038
4038
|
}
|
|
4039
4039
|
return canonicalToken(reference, palette);
|
|
4040
4040
|
}
|
|
4041
|
+
/** Keep a candidate only when it meets ordinary-text contrast on the ground. */
|
|
4041
4042
|
function safeTokenOr(candidate$1, fallback, backgroundHex, palette) {
|
|
4042
4043
|
return firstSafeToken([candidate$1], backgroundHex, palette) ?? fallback;
|
|
4043
4044
|
}
|
|
@@ -4459,7 +4460,11 @@ function resolveSurface(spec, context) {
|
|
|
4459
4460
|
token: spec.token
|
|
4460
4461
|
}, {
|
|
4461
4462
|
...context,
|
|
4462
|
-
buttonContext: spec.buttonContext ?? context.buttonContext
|
|
4463
|
+
buttonContext: spec.buttonContext ?? context.buttonContext,
|
|
4464
|
+
...spec.foreground ? { foreground: {
|
|
4465
|
+
...context.foreground,
|
|
4466
|
+
...spec.foreground
|
|
4467
|
+
} } : {}
|
|
4463
4468
|
});
|
|
4464
4469
|
case "tint": return resolveTintSurface(spec, context);
|
|
4465
4470
|
}
|
|
@@ -4928,8 +4933,12 @@ const cardListKnobs = [
|
|
|
4928
4933
|
const lookKnobBlocks = {
|
|
4929
4934
|
actionStyle: cardListKnobBlocks,
|
|
4930
4935
|
titleSize: "block.hero",
|
|
4931
|
-
imagePosition: [
|
|
4932
|
-
|
|
4936
|
+
imagePosition: [
|
|
4937
|
+
"block.hero",
|
|
4938
|
+
"block.intro",
|
|
4939
|
+
"block.media-text"
|
|
4940
|
+
],
|
|
4941
|
+
imageShape: ["block.intro", "block.media-text"],
|
|
4933
4942
|
aspectRatio: "block.media-text",
|
|
4934
4943
|
stickerLine: "block.hero",
|
|
4935
4944
|
smallCaption: "block.hero",
|
|
@@ -4992,6 +5001,7 @@ function cardListKnobDefaults(block, arrangement, knobs, defaults) {
|
|
|
4992
5001
|
}
|
|
4993
5002
|
const arrangementLookTargets = {
|
|
4994
5003
|
hero: "hero",
|
|
5004
|
+
intro: "intro",
|
|
4995
5005
|
"feature-cards": "feature-cards",
|
|
4996
5006
|
"event-calendar": "events",
|
|
4997
5007
|
testimonials: "testimonials",
|
|
@@ -5953,14 +5963,20 @@ const blockAppearancePresets = [
|
|
|
5953
5963
|
}
|
|
5954
5964
|
}),
|
|
5955
5965
|
defineArrangementLook("body-text-reading-column", "body-text", "Reading column", "prose", []),
|
|
5956
|
-
defineArrangementLook("form-beside-introduction-arched-panel", "form", "Introduction beside an arched form", "two-column", [], {
|
|
5957
|
-
|
|
5966
|
+
defineArrangementLook("form-beside-introduction-arched-panel", "form", "Introduction beside an arched form", "two-column", [], {
|
|
5967
|
+
slotRoles: { panel: "card" },
|
|
5968
|
+
styleFallback: [id$1("form-below-introduction")]
|
|
5969
|
+
}),
|
|
5970
|
+
defineArrangementLook("newsletter-signup-in-arch", "newsletter-signup", "Signup in an arch", "arch", [], { styleFallback: [id$1("newsletter-signup-text-beside")] }),
|
|
5958
5971
|
defineArrangementLook("image-gallery-square-tiles", "image-gallery", "Square tiles", "tiles", []),
|
|
5959
5972
|
defineArrangementLook("image-gallery-arched-captions", "image-gallery", "Arched photos with captions", "tiles", [], { styleFallback: [id$1("image-gallery-square-tiles")] }),
|
|
5960
|
-
defineArrangementLook("media-text-circle-beside-text", "media-text", "Circle beside the text", "circle-beside", ["imagePosition"], {
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5973
|
+
defineArrangementLook("media-text-circle-beside-text", "media-text", "Circle beside the text", "circle-beside", ["imagePosition"], {
|
|
5974
|
+
forcedKnobs: {
|
|
5975
|
+
imageShape: "circle",
|
|
5976
|
+
aspectRatio: "1/1"
|
|
5977
|
+
},
|
|
5978
|
+
styleFallback: [id$1("media-text-photo-beside-text")]
|
|
5979
|
+
}),
|
|
5964
5980
|
defineArrangementLook("hero-photo-beside-text", "hero", "Photo beside the text", "split", heroKnobs, { slotRoles: { sticker: "highlight" } }),
|
|
5965
5981
|
defineArrangementLook("hero-headline-row", "hero", "Big headline, then text and photo", "headline-row", heroKnobs, {
|
|
5966
5982
|
slotRoles: { sticker: "highlight" },
|
|
@@ -5981,6 +5997,15 @@ const blockAppearancePresets = [
|
|
|
5981
5997
|
"text",
|
|
5982
5998
|
"action"
|
|
5983
5999
|
], ["showPhotos", "cardMarker"], { itemRoles: { items: "card" } }),
|
|
6000
|
+
defineCardListLook("card-list-accent-edged-cards", "Accent-edged cards", "cards", [
|
|
6001
|
+
"media",
|
|
6002
|
+
"title",
|
|
6003
|
+
"text",
|
|
6004
|
+
"action"
|
|
6005
|
+
], ["showPhotos", "cardMarker"], {
|
|
6006
|
+
itemRoles: { items: "card" },
|
|
6007
|
+
styleFallback: [id$1("feature-cards-cards")]
|
|
6008
|
+
}),
|
|
5984
6009
|
defineCardListLook("feature-cards-open-columns", "Open columns", "cards", [
|
|
5985
6010
|
"media",
|
|
5986
6011
|
"title",
|
|
@@ -6091,6 +6116,52 @@ const blockAppearancePresets = [
|
|
|
6091
6116
|
defineArrangementLook("event-details-panel", "event-details", "Details panel", "details-panel", [], {
|
|
6092
6117
|
slotRoles: { panel: "card" },
|
|
6093
6118
|
styleFallback: [id$1("event-details-header")]
|
|
6119
|
+
}),
|
|
6120
|
+
defineArrangementLook("intro-statement-beside-text", "intro", "Big statement beside the text", "statement-copy", [], { styleFallback: [id$1("intro-photo-beside-text")] }),
|
|
6121
|
+
defineArrangementLook("intro-photo-beside-text", "intro", "Small photo beside the text", "media-copy", ["imagePosition", "imageShape"], { whenMissing: [{
|
|
6122
|
+
fact: "photo",
|
|
6123
|
+
look: id$1("intro-statement-beside-text")
|
|
6124
|
+
}] }),
|
|
6125
|
+
defineArrangementLook("media-text-photo-beside-text", "media-text", "Photo beside the text", "default", ["imagePosition", "imageShape"]),
|
|
6126
|
+
defineArrangementLook("newsletter-signup-one-row", "newsletter-signup", "Signup in one row", "inline", [], {
|
|
6127
|
+
slotRoles: { panel: "card" },
|
|
6128
|
+
styleFallback: [id$1("newsletter-signup-text-beside")]
|
|
6129
|
+
}),
|
|
6130
|
+
defineArrangementLook("newsletter-signup-text-beside", "newsletter-signup", "Text beside the signup", "editorial-split", [], {
|
|
6131
|
+
slotRoles: { panel: "card" },
|
|
6132
|
+
styleFallback: [id$1("newsletter-signup-in-arch")]
|
|
6133
|
+
}),
|
|
6134
|
+
defineArrangementLook("form-below-introduction", "form", "Form below its introduction", "default", [], {
|
|
6135
|
+
slotRoles: { panel: "card" },
|
|
6136
|
+
styleFallback: [id$1("form-beside-introduction-arched-panel")]
|
|
6137
|
+
}),
|
|
6138
|
+
defineCardListLook("card-list-wide-slides", "Wide cards, one at a time", "slides", [
|
|
6139
|
+
"media",
|
|
6140
|
+
"title",
|
|
6141
|
+
"text",
|
|
6142
|
+
"action"
|
|
6143
|
+
], ["showPhotos"], {
|
|
6144
|
+
itemRoles: { items: "card" },
|
|
6145
|
+
slotRoles: { date: "highlight" },
|
|
6146
|
+
knobDefaults: {
|
|
6147
|
+
actionStyle: "button",
|
|
6148
|
+
dates: "summary"
|
|
6149
|
+
},
|
|
6150
|
+
styleFallback: [id$1("card-list-plates"), id$1("feature-cards-cards")]
|
|
6151
|
+
}),
|
|
6152
|
+
defineCardListLook("card-list-scroll-row", "A row of cards you can scroll", "track", [
|
|
6153
|
+
"media",
|
|
6154
|
+
"title",
|
|
6155
|
+
"text",
|
|
6156
|
+
"action"
|
|
6157
|
+
], ["showPhotos"], {
|
|
6158
|
+
itemRoles: { items: "card" },
|
|
6159
|
+
slotRoles: { date: "highlight" },
|
|
6160
|
+
knobDefaults: {
|
|
6161
|
+
actionStyle: "button",
|
|
6162
|
+
dates: "summary"
|
|
6163
|
+
},
|
|
6164
|
+
styleFallback: [id$1("feature-cards-cards")]
|
|
6094
6165
|
})
|
|
6095
6166
|
];
|
|
6096
6167
|
|
|
@@ -8692,11 +8763,11 @@ function isVideoPosterFileAssetSource(source) {
|
|
|
8692
8763
|
|
|
8693
8764
|
//#endregion
|
|
8694
8765
|
//#region ../media-core/src/typeGuards.ts
|
|
8695
|
-
function isRecord$
|
|
8766
|
+
function isRecord$4(value) {
|
|
8696
8767
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8697
8768
|
}
|
|
8698
|
-
function asRecord(value) {
|
|
8699
|
-
return isRecord$
|
|
8769
|
+
function asRecord$1(value) {
|
|
8770
|
+
return isRecord$4(value) ? value : undefined;
|
|
8700
8771
|
}
|
|
8701
8772
|
|
|
8702
8773
|
//#endregion
|
|
@@ -9627,7 +9698,7 @@ function parseTaggedObject(value, allowed) {
|
|
|
9627
9698
|
return parseOneOf(record.value.tag, allowed);
|
|
9628
9699
|
}
|
|
9629
9700
|
function requireRecord(value) {
|
|
9630
|
-
if (!isRecord$
|
|
9701
|
+
if (!isRecord$4(value)) return err("expected-object");
|
|
9631
9702
|
return ok(value);
|
|
9632
9703
|
}
|
|
9633
9704
|
function requireString(value) {
|
|
@@ -9838,7 +9909,7 @@ function parseOptionalRowExif(value) {
|
|
|
9838
9909
|
if (value === null || value === undefined) {
|
|
9839
9910
|
return ok(undefined);
|
|
9840
9911
|
}
|
|
9841
|
-
if (!isRecord$
|
|
9912
|
+
if (!isRecord$4(value) || !isFileJsonObject(value)) {
|
|
9842
9913
|
return err({
|
|
9843
9914
|
tag: "invalid-exif",
|
|
9844
9915
|
error: "expected-object"
|
|
@@ -9912,7 +9983,7 @@ function isFileJsonValue(value) {
|
|
|
9912
9983
|
if (Array.isArray(value)) {
|
|
9913
9984
|
return value.every(isFileJsonValue);
|
|
9914
9985
|
}
|
|
9915
|
-
return isRecord$
|
|
9986
|
+
return isRecord$4(value) && isFileJsonObject(value);
|
|
9916
9987
|
}
|
|
9917
9988
|
function emptyStatePatch(patch) {
|
|
9918
9989
|
return {
|
|
@@ -12491,7 +12562,7 @@ function isCmsMediaObjectType(value) {
|
|
|
12491
12562
|
return mediaTypeDiscriminants.some((type) => type === value);
|
|
12492
12563
|
}
|
|
12493
12564
|
function isCmsMediaObject(value) {
|
|
12494
|
-
if (!isRecord$
|
|
12565
|
+
if (!isRecord$4(value)) return false;
|
|
12495
12566
|
if (value.tag === "media") return true;
|
|
12496
12567
|
const type = value.type;
|
|
12497
12568
|
if (!isCmsMediaObjectType(type)) return false;
|
|
@@ -12510,7 +12581,7 @@ function collectMediaObjects(value, out, location = "") {
|
|
|
12510
12581
|
value.forEach((item, index) => collectMediaObjects(item, out, `${location}[${index}]`));
|
|
12511
12582
|
return;
|
|
12512
12583
|
}
|
|
12513
|
-
if (!isRecord$
|
|
12584
|
+
if (!isRecord$4(value)) return;
|
|
12514
12585
|
if (isCmsMediaObject(value)) {
|
|
12515
12586
|
out.push({
|
|
12516
12587
|
obj: value,
|
|
@@ -12570,7 +12641,7 @@ function scanForMediaAssetUsage(value, tokens) {
|
|
|
12570
12641
|
for (const item of node) visit(item);
|
|
12571
12642
|
return;
|
|
12572
12643
|
}
|
|
12573
|
-
if (!isRecord$
|
|
12644
|
+
if (!isRecord$4(node)) return;
|
|
12574
12645
|
for (const [key, child] of Object.entries(node)) {
|
|
12575
12646
|
if (typeof child === "string") {
|
|
12576
12647
|
switch (key) {
|
|
@@ -12682,8 +12753,8 @@ function walkAndCollectImageAttrs(value, out, location = "") {
|
|
|
12682
12753
|
value.forEach((item, index) => walkAndCollectImageAttrs(item, out, `${location}[${index}]`));
|
|
12683
12754
|
return;
|
|
12684
12755
|
}
|
|
12685
|
-
if (!isRecord$
|
|
12686
|
-
if (value.type === "image" && isRecord$
|
|
12756
|
+
if (!isRecord$4(value)) return;
|
|
12757
|
+
if (value.type === "image" && isRecord$4(value.attrs)) {
|
|
12687
12758
|
out.push({
|
|
12688
12759
|
attrs: value.attrs,
|
|
12689
12760
|
location: location ? `${location}.attrs` : "attrs"
|
|
@@ -12880,7 +12951,7 @@ function resolvePortableMediaReferences(references, lookup) {
|
|
|
12880
12951
|
|
|
12881
12952
|
//#endregion
|
|
12882
12953
|
//#region ../media-core/src/contentMediaAudit.ts
|
|
12883
|
-
function isRecord$
|
|
12954
|
+
function isRecord$6(value) {
|
|
12884
12955
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12885
12956
|
}
|
|
12886
12957
|
function formatContentFieldPath(path) {
|
|
@@ -12894,11 +12965,11 @@ function summarizeContentMediaValue(value) {
|
|
|
12894
12965
|
}
|
|
12895
12966
|
if (value === null) return "null";
|
|
12896
12967
|
if (Array.isArray(value)) return `array(${value.length})`;
|
|
12897
|
-
if (isRecord$
|
|
12968
|
+
if (isRecord$6(value)) return `object(${Object.keys(value).sort().join(",")})`;
|
|
12898
12969
|
return typeof value;
|
|
12899
12970
|
}
|
|
12900
12971
|
function isPortableMediaValue(value, allowedMediaTypes$1) {
|
|
12901
|
-
if (!isRecord$
|
|
12972
|
+
if (!isRecord$6(value) || !parseCanonicalMediaIdentifier(value.identifier).ok) return false;
|
|
12902
12973
|
const type = value.type ?? allowedMediaTypes$1[0];
|
|
12903
12974
|
const validType = allowedMediaTypes$1.some((allowed) => allowed === type);
|
|
12904
12975
|
const hasEnvironmentFields = [
|
|
@@ -12949,7 +13020,7 @@ function auditMediaValue(context, path, allowedMediaTypes$1, value) {
|
|
|
12949
13020
|
}];
|
|
12950
13021
|
}
|
|
12951
13022
|
function auditFields(context, fields, value, parentPath) {
|
|
12952
|
-
if (!isRecord$
|
|
13023
|
+
if (!isRecord$6(value)) return [];
|
|
12953
13024
|
const findings = [];
|
|
12954
13025
|
for (const field of fields) {
|
|
12955
13026
|
if (!(field.id in value)) continue;
|
|
@@ -12966,7 +13037,7 @@ function auditFields(context, fields, value, parentPath) {
|
|
|
12966
13037
|
if (!Array.isArray(fieldValue)) break;
|
|
12967
13038
|
for (const [index, item] of fieldValue.entries()) {
|
|
12968
13039
|
const itemPath = [...fieldPath, index];
|
|
12969
|
-
if (!isRecord$
|
|
13040
|
+
if (!isRecord$6(item)) {
|
|
12970
13041
|
findings.push({
|
|
12971
13042
|
tag: "missing-schema",
|
|
12972
13043
|
context,
|
|
@@ -13068,7 +13139,7 @@ function resolveLegacyMediaFindings(findings, assets) {
|
|
|
13068
13139
|
//#endregion
|
|
13069
13140
|
//#region ../media-core/src/contentMediaAuditFieldAdapter.ts
|
|
13070
13141
|
const contentMediaTypes = new Set(mediaTypeDiscriminants);
|
|
13071
|
-
function isRecord$
|
|
13142
|
+
function isRecord$5(value) {
|
|
13072
13143
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13073
13144
|
}
|
|
13074
13145
|
function unknownArray(value) {
|
|
@@ -13077,7 +13148,7 @@ function unknownArray(value) {
|
|
|
13077
13148
|
function fieldsArray(value) {
|
|
13078
13149
|
const directFields = unknownArray(value);
|
|
13079
13150
|
if (directFields) return directFields;
|
|
13080
|
-
if (!isRecord$
|
|
13151
|
+
if (!isRecord$5(value)) return null;
|
|
13081
13152
|
return unknownArray(value.fields);
|
|
13082
13153
|
}
|
|
13083
13154
|
function nestedFields(field) {
|
|
@@ -13146,7 +13217,7 @@ function mergeFields(fields) {
|
|
|
13146
13217
|
}
|
|
13147
13218
|
function adaptFields(rawFields, flattenRepeaterGroups = false, defaultFileKinds = ["document"]) {
|
|
13148
13219
|
return mergeFields(rawFields.flatMap((rawField) => {
|
|
13149
|
-
if (!isRecord$
|
|
13220
|
+
if (!isRecord$5(rawField)) return [];
|
|
13150
13221
|
const { id: id$2, type } = rawField;
|
|
13151
13222
|
if (typeof id$2 !== "string" || !id$2 || typeof type !== "string") return [];
|
|
13152
13223
|
if (type === "media" || type === "file") {
|
|
@@ -13156,7 +13227,7 @@ function adaptFields(rawFields, flattenRepeaterGroups = false, defaultFileKinds
|
|
|
13156
13227
|
allowedMediaTypes: allowedMediaTypes(rawField, type, defaultFileKinds)
|
|
13157
13228
|
}];
|
|
13158
13229
|
}
|
|
13159
|
-
if (flattenRepeaterGroups && type === "group" && isRecord$
|
|
13230
|
+
if (flattenRepeaterGroups && type === "group" && isRecord$5(rawField.ui) && rawField.ui.flattenInRepeater === true) {
|
|
13160
13231
|
return adaptFields(nestedFields(rawField), false, defaultFileKinds);
|
|
13161
13232
|
}
|
|
13162
13233
|
if (type === "group" || type === "modal") {
|
|
@@ -13171,12 +13242,12 @@ function adaptFields(rawFields, flattenRepeaterGroups = false, defaultFileKinds
|
|
|
13171
13242
|
return [{
|
|
13172
13243
|
kind: "object",
|
|
13173
13244
|
id: id$2,
|
|
13174
|
-
fields: adaptFields(tabs.flatMap((tab) => isRecord$
|
|
13245
|
+
fields: adaptFields(tabs.flatMap((tab) => isRecord$5(tab) ? unknownArray(tab.fields) ?? [] : []), false, defaultFileKinds)
|
|
13175
13246
|
}];
|
|
13176
13247
|
}
|
|
13177
13248
|
if (type !== "repeater") return [];
|
|
13178
|
-
if (isRecord$
|
|
13179
|
-
const variants = Object.entries(rawField.itemTypes).flatMap(([typeId, itemType]) => isRecord$
|
|
13249
|
+
if (isRecord$5(rawField.itemTypes)) {
|
|
13250
|
+
const variants = Object.entries(rawField.itemTypes).flatMap(([typeId, itemType]) => isRecord$5(itemType) && Array.isArray(itemType.fields) ? [{
|
|
13180
13251
|
typeId,
|
|
13181
13252
|
fields: adaptFields(itemType.fields, true, defaultFileKinds)
|
|
13182
13253
|
}] : []);
|
|
@@ -13675,7 +13746,7 @@ const runtimeBoxBackgroundSchema = z.discriminatedUnion("type", [
|
|
|
13675
13746
|
]).nullable().optional() })
|
|
13676
13747
|
]);
|
|
13677
13748
|
function normalizeAuthoringOpacity(value) {
|
|
13678
|
-
if (!isRecord$
|
|
13749
|
+
if (!isRecord$3(value)) return value;
|
|
13679
13750
|
return {
|
|
13680
13751
|
...value,
|
|
13681
13752
|
opacity: normalizeOpacity(value.opacity)
|
|
@@ -13684,7 +13755,7 @@ function normalizeAuthoringOpacity(value) {
|
|
|
13684
13755
|
function normalizeOpacity(value) {
|
|
13685
13756
|
return typeof value === "number" && value > 1 && value <= 100 ? value / 100 : value;
|
|
13686
13757
|
}
|
|
13687
|
-
function isRecord$
|
|
13758
|
+
function isRecord$3(value) {
|
|
13688
13759
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13689
13760
|
}
|
|
13690
13761
|
|
|
@@ -13730,6 +13801,10 @@ function resolveSectionBackground(source, lookDefault, rhythm, arrangementHeroPh
|
|
|
13730
13801
|
}
|
|
13731
13802
|
return rhythmBackground(rhythm);
|
|
13732
13803
|
}
|
|
13804
|
+
function resolveSectionPhotoPlacement(background, heroPhoto) {
|
|
13805
|
+
if (heroPhoto?.paintsGround === false) return "none";
|
|
13806
|
+
return background.kind !== "base" && background.background.type === "image" && background.background.image !== undefined ? "behind-text" : "none";
|
|
13807
|
+
}
|
|
13733
13808
|
function resolveSectionForeground(background, palette) {
|
|
13734
13809
|
return resolveSurfaceForeground(background.kind === "base" ? null : background.background, palette, {}, { compositeBase: "background" });
|
|
13735
13810
|
}
|
|
@@ -14553,7 +14628,7 @@ function validateCompositionBudget(input) {
|
|
|
14553
14628
|
|
|
14554
14629
|
//#endregion
|
|
14555
14630
|
//#region ../theme-core/src/site-styles/records.ts
|
|
14556
|
-
function isRecord$
|
|
14631
|
+
function isRecord$2(value) {
|
|
14557
14632
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14558
14633
|
}
|
|
14559
14634
|
|
|
@@ -14755,15 +14830,15 @@ function parsePersistedFooterPreferences(value) {
|
|
|
14755
14830
|
}
|
|
14756
14831
|
/** One-time backfill rule, also exercised against the migration SQL. Not a runtime fallback. */
|
|
14757
14832
|
function readFooterPreferences(theme) {
|
|
14758
|
-
const footer = isRecord$
|
|
14759
|
-
const background = isRecord$
|
|
14833
|
+
const footer = isRecord$2(theme) && isRecord$2(theme.footer) ? theme.footer : {};
|
|
14834
|
+
const background = isRecord$2(footer.background) ? footer.background : {};
|
|
14760
14835
|
const token = background.type === "color" && background.contentOwner === siteChromeBackgroundOverrideOwner ? parseSiteChromeBackgroundColorToken(background.color) : null;
|
|
14761
14836
|
return {
|
|
14762
14837
|
background: token === null ? { kind: "default" } : {
|
|
14763
14838
|
kind: "color",
|
|
14764
14839
|
token
|
|
14765
14840
|
},
|
|
14766
|
-
navigationLayout: isRecord$
|
|
14841
|
+
navigationLayout: isRecord$2(footer.navLayout) && footer.navLayout.layout === "stack" ? "stack" : "inline-wrap"
|
|
14767
14842
|
};
|
|
14768
14843
|
}
|
|
14769
14844
|
function applyFooterPreferences(theme, footer, preferences) {
|
|
@@ -15642,6 +15717,9 @@ const arrangementSlotNames = [
|
|
|
15642
15717
|
"social",
|
|
15643
15718
|
"base",
|
|
15644
15719
|
"section",
|
|
15720
|
+
"background",
|
|
15721
|
+
"schedule-section",
|
|
15722
|
+
"shop-section",
|
|
15645
15723
|
"stack",
|
|
15646
15724
|
"inline",
|
|
15647
15725
|
"grid",
|
|
@@ -19297,7 +19375,11 @@ const BUTTON_STYLE_IDS = [
|
|
|
19297
19375
|
"hairline-tab",
|
|
19298
19376
|
"marquee"
|
|
19299
19377
|
];
|
|
19300
|
-
const quietArrowParametersSchema = z.object({
|
|
19378
|
+
const quietArrowParametersSchema = z.object({
|
|
19379
|
+
secondaryTreatment: z.enum(["outlined", "solid-accent"]),
|
|
19380
|
+
size: z.enum(["comfortable"]).optional(),
|
|
19381
|
+
hoverTreatment: z.enum(["deep-and-sheet"]).optional()
|
|
19382
|
+
}).strict();
|
|
19301
19383
|
const FLAT_INK_HOVER_TREATMENT_VALUES = [
|
|
19302
19384
|
"contextual",
|
|
19303
19385
|
"secondary",
|
|
@@ -19410,15 +19492,35 @@ function admitKnownStyleParameters(styleId, value) {
|
|
|
19410
19492
|
repairs
|
|
19411
19493
|
};
|
|
19412
19494
|
}
|
|
19495
|
+
/** Repair optional recipe choices independently so one bad field cannot discard another. */
|
|
19496
|
+
function admitQuietArrowOptionalParameters(parameters) {
|
|
19497
|
+
const size = quietArrowParametersSchema.shape.size.safeParse(parameters?.size);
|
|
19498
|
+
const hover = quietArrowParametersSchema.shape.hoverTreatment.safeParse(parameters?.hoverTreatment);
|
|
19499
|
+
return {
|
|
19500
|
+
values: {
|
|
19501
|
+
...size.success && size.data ? { size: size.data } : {},
|
|
19502
|
+
...hover.success && hover.data ? { hoverTreatment: hover.data } : {}
|
|
19503
|
+
},
|
|
19504
|
+
supportedKeys: [
|
|
19505
|
+
"secondaryTreatment",
|
|
19506
|
+
...size.success ? ["size"] : [],
|
|
19507
|
+
...hover.success ? ["hoverTreatment"] : []
|
|
19508
|
+
]
|
|
19509
|
+
};
|
|
19510
|
+
}
|
|
19413
19511
|
function admitQuietArrowParameters(value) {
|
|
19414
19512
|
const parameters = objectRecord(value);
|
|
19415
19513
|
const treatment = parameters?.secondaryTreatment;
|
|
19416
19514
|
const valid = treatment === "outlined" || treatment === "solid-accent";
|
|
19417
|
-
const
|
|
19515
|
+
const optional = admitQuietArrowOptionalParameters(parameters);
|
|
19516
|
+
const extraRepairs = Object.keys(parameters ?? {}).filter((key) => !optional.supportedKeys.includes(key)).map((key) => repair("quiet-arrow", key, null, "unsupported-option"));
|
|
19418
19517
|
return {
|
|
19419
19518
|
selection: buttonStyleSelectionSchema.parse({
|
|
19420
19519
|
styleId: "quiet-arrow",
|
|
19421
|
-
parameters: {
|
|
19520
|
+
parameters: {
|
|
19521
|
+
secondaryTreatment: valid ? treatment : "outlined",
|
|
19522
|
+
...optional.values
|
|
19523
|
+
}
|
|
19422
19524
|
}),
|
|
19423
19525
|
repairs: [...extraRepairs, ...valid ? [] : [repair("quiet-arrow", "secondaryTreatment", null, parameters ? "unsupported-option" : "invalid-option-shape")]]
|
|
19424
19526
|
};
|
|
@@ -19920,6 +20022,63 @@ const solidAccentSecondary = {
|
|
|
19920
20022
|
},
|
|
19921
20023
|
affordance: { iconId: "ArrowRight" }
|
|
19922
20024
|
};
|
|
20025
|
+
/** Selection-owned sizing leaves historical recipe output unchanged when absent. */
|
|
20026
|
+
function sizedQuietArrowRoles(roles, size) {
|
|
20027
|
+
if (size === undefined) return roles;
|
|
20028
|
+
return mapButtonRoleAppearances(roles, (appearance) => ({
|
|
20029
|
+
...appearance,
|
|
20030
|
+
states: mapButtonVisualAppearances(appearance.states, (state) => ({
|
|
20031
|
+
...state,
|
|
20032
|
+
sizes: {
|
|
20033
|
+
sm: {
|
|
20034
|
+
padding: "0.875rem 1.125rem",
|
|
20035
|
+
fontSize: "text-xs"
|
|
20036
|
+
},
|
|
20037
|
+
md: {
|
|
20038
|
+
padding: "0.75rem 1.375rem",
|
|
20039
|
+
fontSize: "text-sm"
|
|
20040
|
+
},
|
|
20041
|
+
lg: {
|
|
20042
|
+
padding: "0.875rem 1.75rem",
|
|
20043
|
+
fontSize: "text-sm"
|
|
20044
|
+
},
|
|
20045
|
+
xl: {
|
|
20046
|
+
padding: "1rem 2rem",
|
|
20047
|
+
fontSize: "text-base"
|
|
20048
|
+
}
|
|
20049
|
+
}
|
|
20050
|
+
}))
|
|
20051
|
+
}));
|
|
20052
|
+
}
|
|
20053
|
+
/** Forward sheet interaction is explicit selection data; absent preserves the captured recipe. */
|
|
20054
|
+
function quietArrowHoverRoles(roles, treatment) {
|
|
20055
|
+
if (treatment === undefined) return roles;
|
|
20056
|
+
const hover = (role, colour) => ({
|
|
20057
|
+
...roles[role],
|
|
20058
|
+
states: {
|
|
20059
|
+
...roles[role].states,
|
|
20060
|
+
hover: {
|
|
20061
|
+
...roles[role].states.hover,
|
|
20062
|
+
background: {
|
|
20063
|
+
type: "solid",
|
|
20064
|
+
colorToken: unsafeAsOpaqueButtonColourToken(colour)
|
|
20065
|
+
},
|
|
20066
|
+
text: "treatment",
|
|
20067
|
+
effects: [],
|
|
20068
|
+
...role === "secondary" ? { border: {
|
|
20069
|
+
widthClass: "border",
|
|
20070
|
+
marksBoundary: true,
|
|
20071
|
+
boundaryInk: unsafeAsOpaqueButtonColourToken("text")
|
|
20072
|
+
} } : {}
|
|
20073
|
+
}
|
|
20074
|
+
}
|
|
20075
|
+
});
|
|
20076
|
+
return {
|
|
20077
|
+
...roles,
|
|
20078
|
+
primary: hover("primary", "primary-800"),
|
|
20079
|
+
secondary: hover("secondary", "surface")
|
|
20080
|
+
};
|
|
20081
|
+
}
|
|
19923
20082
|
const quietArrowRecipe = defineButtonStyleRecipe({
|
|
19924
20083
|
id: "quiet-arrow",
|
|
19925
20084
|
accessibilityLabel: "Wide uppercase buttons with trailing arrows",
|
|
@@ -19943,10 +20102,10 @@ const quietArrowRecipe = defineButtonStyleRecipe({
|
|
|
19943
20102
|
label: "Solid accent"
|
|
19944
20103
|
}]
|
|
19945
20104
|
}],
|
|
19946
|
-
defineSystem: (parameters) => ({ roles: {
|
|
20105
|
+
defineSystem: (parameters) => ({ roles: quietArrowHoverRoles(sizedQuietArrowRoles({
|
|
19947
20106
|
...quietArrowSystem.roles,
|
|
19948
20107
|
secondary: parameters.secondaryTreatment === "solid-accent" ? solidAccentSecondary : quietArrowSystem.roles.secondary
|
|
19949
|
-
} })
|
|
20108
|
+
}, parameters.size), parameters.hoverTreatment) })
|
|
19950
20109
|
});
|
|
19951
20110
|
|
|
19952
20111
|
//#endregion
|
|
@@ -27505,10 +27664,11 @@ function recipeFrame(frame) {
|
|
|
27505
27664
|
case "container": return { container: {
|
|
27506
27665
|
rounded: frame.rounded,
|
|
27507
27666
|
border: true,
|
|
27508
|
-
shadow: true,
|
|
27667
|
+
shadow: frame.shadow ?? true,
|
|
27509
27668
|
padding: frame.padding,
|
|
27510
27669
|
tint: frame.tint,
|
|
27511
|
-
opacity: frame.opacity
|
|
27670
|
+
opacity: frame.opacity,
|
|
27671
|
+
...frame.mobileSheet ? { mobileSheet: frame.mobileSheet } : {}
|
|
27512
27672
|
} };
|
|
27513
27673
|
case "nav-container": return { navContainer: {
|
|
27514
27674
|
type: frame.type,
|
|
@@ -28015,6 +28175,36 @@ const groundedSerifTypography = {
|
|
|
28015
28175
|
},
|
|
28016
28176
|
scale: "balanced"
|
|
28017
28177
|
};
|
|
28178
|
+
/** Folio keeps the practitioner pairing, with a larger serif and working sans names. */
|
|
28179
|
+
const folioTypography = {
|
|
28180
|
+
...groundedSerifTypography,
|
|
28181
|
+
body: {
|
|
28182
|
+
...groundedSerifTypography.body,
|
|
28183
|
+
family: "Open Sans, system-ui, sans-serif",
|
|
28184
|
+
size: "lg"
|
|
28185
|
+
},
|
|
28186
|
+
smallHeading: {
|
|
28187
|
+
family: "Open Sans, system-ui, sans-serif",
|
|
28188
|
+
weight: "semibold"
|
|
28189
|
+
},
|
|
28190
|
+
headings: {
|
|
28191
|
+
...groundedSerifTypography.headings,
|
|
28192
|
+
h1: {
|
|
28193
|
+
...groundedSerifTypography.headings.h1,
|
|
28194
|
+
lineHeight: "tight",
|
|
28195
|
+
letterSpacing: "tight"
|
|
28196
|
+
},
|
|
28197
|
+
h2: {
|
|
28198
|
+
...groundedSerifTypography.headings.h2,
|
|
28199
|
+
lineHeight: "tight",
|
|
28200
|
+
letterSpacing: "tight"
|
|
28201
|
+
},
|
|
28202
|
+
h3: {
|
|
28203
|
+
...groundedSerifTypography.headings.h3,
|
|
28204
|
+
lineHeight: "tight"
|
|
28205
|
+
}
|
|
28206
|
+
}
|
|
28207
|
+
};
|
|
28018
28208
|
const kirtanOrnateTypography = {
|
|
28019
28209
|
body: {
|
|
28020
28210
|
family: "Jost, system-ui, sans-serif",
|
|
@@ -28669,6 +28859,15 @@ const eyebrowTypographyStyleSchema = z.object({
|
|
|
28669
28859
|
});
|
|
28670
28860
|
const typographySchema = z.object({
|
|
28671
28861
|
body: bodyTypographyStyleSchema,
|
|
28862
|
+
smallHeading: z.object({
|
|
28863
|
+
family: z.string().min(1),
|
|
28864
|
+
weight: z.enum([
|
|
28865
|
+
"regular",
|
|
28866
|
+
"medium",
|
|
28867
|
+
"semibold",
|
|
28868
|
+
"bold"
|
|
28869
|
+
])
|
|
28870
|
+
}).optional(),
|
|
28672
28871
|
headings: z.object({
|
|
28673
28872
|
default: headingTypographyStyleSchema,
|
|
28674
28873
|
h1: headingTypographyOverridesSchema,
|
|
@@ -30536,6 +30735,7 @@ const headerContainerSchema = z.object({
|
|
|
30536
30735
|
"lg"
|
|
30537
30736
|
]).default("md"),
|
|
30538
30737
|
tint: z.string().nullable().optional(),
|
|
30738
|
+
mobileSheet: z.literal("inset").optional(),
|
|
30539
30739
|
opacity: z.number().min(0).max(1).default(.12)
|
|
30540
30740
|
}).optional();
|
|
30541
30741
|
|
|
@@ -33032,15 +33232,17 @@ const curatedSiteStyleIdValues = [
|
|
|
33032
33232
|
"site-style:grounded-practice",
|
|
33033
33233
|
"site-style:poster",
|
|
33034
33234
|
"site-style:lantern",
|
|
33035
|
-
"site-style:measure"
|
|
33235
|
+
"site-style:measure",
|
|
33236
|
+
"site-style:folio"
|
|
33036
33237
|
];
|
|
33037
33238
|
/** The same eligibility decision governs offering and the apply write boundary. */
|
|
33038
33239
|
function siteStyleOfferingDecision(offering, target) {
|
|
33039
33240
|
if (target.audience === "lab") return { kind: "offered" };
|
|
33241
|
+
const localDemo = target.audience === "local-demo" && target.environment === "local-development";
|
|
33040
33242
|
switch (offering.kind) {
|
|
33041
33243
|
case "public": return { kind: "offered" };
|
|
33042
|
-
case "lab": return { kind: "lab" };
|
|
33043
|
-
case "client": return target.audience === "site-picker" && target.siteSlug != null && offering.siteSlugs.includes(target.siteSlug) ? { kind: "offered" } : { kind: "client-site-mismatch" };
|
|
33244
|
+
case "lab": return localDemo ? { kind: "offered" } : { kind: "lab" };
|
|
33245
|
+
case "client": return localDemo || (target.audience === "site-picker" || target.audience === "local-demo") && target.siteSlug != null && offering.siteSlugs.includes(target.siteSlug) ? { kind: "offered" } : { kind: "client-site-mismatch" };
|
|
33044
33246
|
}
|
|
33045
33247
|
}
|
|
33046
33248
|
function offeredSiteStyles(target, catalogue = curatedSiteStyles) {
|
|
@@ -33380,6 +33582,30 @@ const headerCurationBySiteStyle = {
|
|
|
33380
33582
|
"fine-line"
|
|
33381
33583
|
]
|
|
33382
33584
|
}]),
|
|
33585
|
+
"site-style:folio": defineHeaderCuration([
|
|
33586
|
+
{
|
|
33587
|
+
layoutId: "floating",
|
|
33588
|
+
styleIds: ["minimal-surface", "glass"]
|
|
33589
|
+
},
|
|
33590
|
+
{
|
|
33591
|
+
layoutId: "classic",
|
|
33592
|
+
styleIds: [
|
|
33593
|
+
"minimal",
|
|
33594
|
+
"serif-line",
|
|
33595
|
+
"fine-line",
|
|
33596
|
+
"soft-bar"
|
|
33597
|
+
]
|
|
33598
|
+
},
|
|
33599
|
+
{
|
|
33600
|
+
layoutId: "centered",
|
|
33601
|
+
styleIds: [
|
|
33602
|
+
"serif-line",
|
|
33603
|
+
"fine-line",
|
|
33604
|
+
"minimal",
|
|
33605
|
+
"soft-bar"
|
|
33606
|
+
]
|
|
33607
|
+
}
|
|
33608
|
+
]),
|
|
33383
33609
|
"site-style:measure": defineHeaderCuration([{
|
|
33384
33610
|
layoutId: "classic",
|
|
33385
33611
|
styleIds: ["fine-line", "minimal"]
|
|
@@ -33409,6 +33635,7 @@ function defineCuratedSiteStyle(input) {
|
|
|
33409
33635
|
recommendedAppearancePresetIds
|
|
33410
33636
|
},
|
|
33411
33637
|
headerCuration: headerCurationBySiteStyle[input.id],
|
|
33638
|
+
headerStyleRecipes: input.headerStyleRecipes,
|
|
33412
33639
|
footerLookRecipes: input.footerLookRecipes,
|
|
33413
33640
|
recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
|
|
33414
33641
|
buttonStyleChoices: input.buttonStyleChoices,
|
|
@@ -33478,6 +33705,233 @@ function paletteRecommendation(authoringKey, note) {
|
|
|
33478
33705
|
const id = asAppearancePresetId;
|
|
33479
33706
|
const quieterOrStandard = { titleSize: ["quiet", "auto"] };
|
|
33480
33707
|
/** Fulcrum: cards are white sheets, the statement is the brand band, stickers are sheets too. */
|
|
33708
|
+
const folioRoles = {
|
|
33709
|
+
card: "sheet",
|
|
33710
|
+
statement: {
|
|
33711
|
+
default: "band",
|
|
33712
|
+
band: "sheet"
|
|
33713
|
+
},
|
|
33714
|
+
highlight: "band"
|
|
33715
|
+
};
|
|
33716
|
+
const folioLinks = { link: "primary" };
|
|
33717
|
+
const folioLooks = {
|
|
33718
|
+
kind: "offers",
|
|
33719
|
+
skin: "folio",
|
|
33720
|
+
skinTokens: {
|
|
33721
|
+
radius: "10px",
|
|
33722
|
+
rule: "1px",
|
|
33723
|
+
"mark-length": "44px",
|
|
33724
|
+
"mark-weight": "2px",
|
|
33725
|
+
gutter: "32px",
|
|
33726
|
+
"copy-gap": "1.25rem",
|
|
33727
|
+
"stack-gap": "2.5rem"
|
|
33728
|
+
},
|
|
33729
|
+
fontLoading: {
|
|
33730
|
+
extraHeadingFontWeights: [600],
|
|
33731
|
+
italicHeadingFontWeights: [500]
|
|
33732
|
+
},
|
|
33733
|
+
surfaces: {
|
|
33734
|
+
base: {
|
|
33735
|
+
kind: "token",
|
|
33736
|
+
token: "background",
|
|
33737
|
+
foreground: folioLinks
|
|
33738
|
+
},
|
|
33739
|
+
sheet: {
|
|
33740
|
+
kind: "token",
|
|
33741
|
+
token: "surface",
|
|
33742
|
+
roleOnly: true,
|
|
33743
|
+
foreground: folioLinks
|
|
33744
|
+
},
|
|
33745
|
+
band: {
|
|
33746
|
+
kind: "token",
|
|
33747
|
+
token: "muted",
|
|
33748
|
+
foreground: folioLinks
|
|
33749
|
+
},
|
|
33750
|
+
brand: {
|
|
33751
|
+
kind: "token",
|
|
33752
|
+
token: "primary",
|
|
33753
|
+
foreground: folioLinks
|
|
33754
|
+
},
|
|
33755
|
+
deep: {
|
|
33756
|
+
kind: "token",
|
|
33757
|
+
token: "primary-800",
|
|
33758
|
+
foreground: folioLinks
|
|
33759
|
+
}
|
|
33760
|
+
},
|
|
33761
|
+
rhythm: {
|
|
33762
|
+
"flow:quiet": [
|
|
33763
|
+
"base",
|
|
33764
|
+
"base",
|
|
33765
|
+
"band",
|
|
33766
|
+
"base",
|
|
33767
|
+
"band",
|
|
33768
|
+
"base"
|
|
33769
|
+
],
|
|
33770
|
+
"flow:balanced": [
|
|
33771
|
+
"base",
|
|
33772
|
+
"band",
|
|
33773
|
+
"base",
|
|
33774
|
+
"deep",
|
|
33775
|
+
"base",
|
|
33776
|
+
"band"
|
|
33777
|
+
],
|
|
33778
|
+
"flow:expressive": [
|
|
33779
|
+
"base",
|
|
33780
|
+
"band",
|
|
33781
|
+
"deep",
|
|
33782
|
+
"base",
|
|
33783
|
+
"band",
|
|
33784
|
+
"brand"
|
|
33785
|
+
]
|
|
33786
|
+
},
|
|
33787
|
+
offers: [
|
|
33788
|
+
{
|
|
33789
|
+
id: id("hero-photo-beside-text"),
|
|
33790
|
+
treatment: "hero-framed",
|
|
33791
|
+
knobValues: quieterOrStandard,
|
|
33792
|
+
roleMap: folioRoles
|
|
33793
|
+
},
|
|
33794
|
+
{
|
|
33795
|
+
id: id("hero-photo-behind-text"),
|
|
33796
|
+
treatment: "hero-panel",
|
|
33797
|
+
knobValues: quieterOrStandard,
|
|
33798
|
+
roleMap: folioRoles
|
|
33799
|
+
},
|
|
33800
|
+
{
|
|
33801
|
+
id: id("hero-page-head"),
|
|
33802
|
+
treatment: "hero-ruled",
|
|
33803
|
+
knobValues: quieterOrStandard,
|
|
33804
|
+
roleMap: folioRoles
|
|
33805
|
+
},
|
|
33806
|
+
{
|
|
33807
|
+
id: id("intro-photo-beside-text"),
|
|
33808
|
+
treatment: "intro-keyline",
|
|
33809
|
+
roleMap: folioRoles
|
|
33810
|
+
},
|
|
33811
|
+
{
|
|
33812
|
+
id: id("intro-statement-beside-text"),
|
|
33813
|
+
treatment: "intro-ruled-split",
|
|
33814
|
+
roleMap: folioRoles
|
|
33815
|
+
},
|
|
33816
|
+
{
|
|
33817
|
+
id: id("media-text-photo-beside-text"),
|
|
33818
|
+
treatment: "media-mount",
|
|
33819
|
+
roleMap: folioRoles
|
|
33820
|
+
},
|
|
33821
|
+
{
|
|
33822
|
+
id: id("media-text-circle-beside-text"),
|
|
33823
|
+
treatment: "media-circle",
|
|
33824
|
+
roleMap: folioRoles
|
|
33825
|
+
},
|
|
33826
|
+
{
|
|
33827
|
+
id: id("feature-cards-cards"),
|
|
33828
|
+
treatment: "cards-sheet",
|
|
33829
|
+
roleMap: folioRoles
|
|
33830
|
+
},
|
|
33831
|
+
{
|
|
33832
|
+
id: id("feature-cards-open-columns"),
|
|
33833
|
+
treatment: "cards-open",
|
|
33834
|
+
roleMap: folioRoles
|
|
33835
|
+
},
|
|
33836
|
+
{
|
|
33837
|
+
id: id("feature-cards-index"),
|
|
33838
|
+
treatment: "cards-register",
|
|
33839
|
+
roleMap: folioRoles
|
|
33840
|
+
},
|
|
33841
|
+
{
|
|
33842
|
+
id: id("body-text-reading-column"),
|
|
33843
|
+
treatment: "body-reading",
|
|
33844
|
+
roleMap: folioRoles
|
|
33845
|
+
},
|
|
33846
|
+
{
|
|
33847
|
+
id: id("event-calendar-ruled-rows"),
|
|
33848
|
+
treatment: "calendar-card",
|
|
33849
|
+
itemRoles: { container: "card" },
|
|
33850
|
+
surfaceTints: { date: {
|
|
33851
|
+
source: "text",
|
|
33852
|
+
opacity: 8
|
|
33853
|
+
} },
|
|
33854
|
+
roleMap: folioRoles
|
|
33855
|
+
},
|
|
33856
|
+
{
|
|
33857
|
+
id: id("event-calendar-session-cards"),
|
|
33858
|
+
treatment: "calendar-sheets",
|
|
33859
|
+
roleMap: folioRoles
|
|
33860
|
+
},
|
|
33861
|
+
{
|
|
33862
|
+
id: id("event-calendar-next-three"),
|
|
33863
|
+
treatment: "calendar-compact",
|
|
33864
|
+
roleMap: folioRoles
|
|
33865
|
+
},
|
|
33866
|
+
{
|
|
33867
|
+
id: id("event-calendar-month-grid"),
|
|
33868
|
+
treatment: "calendar-month",
|
|
33869
|
+
roleMap: folioRoles
|
|
33870
|
+
},
|
|
33871
|
+
{
|
|
33872
|
+
id: id("event-details-panel"),
|
|
33873
|
+
treatment: "details-sheet",
|
|
33874
|
+
roleMap: {
|
|
33875
|
+
...folioRoles,
|
|
33876
|
+
card: "section"
|
|
33877
|
+
}
|
|
33878
|
+
},
|
|
33879
|
+
{
|
|
33880
|
+
id: id("event-details-header"),
|
|
33881
|
+
treatment: "details-ruled",
|
|
33882
|
+
roleMap: folioRoles
|
|
33883
|
+
},
|
|
33884
|
+
{
|
|
33885
|
+
id: id("newsletter-signup-text-beside"),
|
|
33886
|
+
treatment: "signup-sheet",
|
|
33887
|
+
roleMap: {
|
|
33888
|
+
...folioRoles,
|
|
33889
|
+
card: "section"
|
|
33890
|
+
}
|
|
33891
|
+
},
|
|
33892
|
+
{
|
|
33893
|
+
id: id("newsletter-signup-one-row"),
|
|
33894
|
+
treatment: "signup-row",
|
|
33895
|
+
roleMap: {
|
|
33896
|
+
...folioRoles,
|
|
33897
|
+
card: "section"
|
|
33898
|
+
}
|
|
33899
|
+
},
|
|
33900
|
+
{
|
|
33901
|
+
id: id("form-below-introduction"),
|
|
33902
|
+
treatment: "form-sheet-below",
|
|
33903
|
+
roleMap: {
|
|
33904
|
+
...folioRoles,
|
|
33905
|
+
card: "section"
|
|
33906
|
+
}
|
|
33907
|
+
},
|
|
33908
|
+
{
|
|
33909
|
+
id: id("testimonials-lead-quote"),
|
|
33910
|
+
treatment: "quote-lead",
|
|
33911
|
+
roleMap: folioRoles
|
|
33912
|
+
},
|
|
33913
|
+
{
|
|
33914
|
+
id: id("testimonials-quote-cards"),
|
|
33915
|
+
treatment: "quote-sheets",
|
|
33916
|
+
roleMap: folioRoles
|
|
33917
|
+
},
|
|
33918
|
+
{
|
|
33919
|
+
id: id("card-list-accent-edged-cards"),
|
|
33920
|
+
treatment: "cards-accent-edged",
|
|
33921
|
+
roleMap: folioRoles
|
|
33922
|
+
},
|
|
33923
|
+
{
|
|
33924
|
+
id: id("card-list-wide-slides"),
|
|
33925
|
+
treatment: "carousel-wide-sheet",
|
|
33926
|
+
roleMap: folioRoles
|
|
33927
|
+
},
|
|
33928
|
+
{
|
|
33929
|
+
id: id("card-list-scroll-row"),
|
|
33930
|
+
treatment: "carousel-row-sheet",
|
|
33931
|
+
roleMap: folioRoles
|
|
33932
|
+
}
|
|
33933
|
+
]
|
|
33934
|
+
};
|
|
33481
33935
|
const fulcrumRoles = {
|
|
33482
33936
|
card: "sheet",
|
|
33483
33937
|
statement: {
|
|
@@ -33614,6 +34068,55 @@ const fulcrumOffers = [
|
|
|
33614
34068
|
id: id("testimonials-scroll-row"),
|
|
33615
34069
|
treatment: "cards",
|
|
33616
34070
|
roleMap: fulcrumRoles
|
|
34071
|
+
},
|
|
34072
|
+
{
|
|
34073
|
+
id: id("intro-photo-beside-text"),
|
|
34074
|
+
treatment: "intro-plate",
|
|
34075
|
+
roleMap: fulcrumRoles
|
|
34076
|
+
},
|
|
34077
|
+
{
|
|
34078
|
+
id: id("intro-statement-beside-text"),
|
|
34079
|
+
treatment: "lintel",
|
|
34080
|
+
roleMap: fulcrumRoles
|
|
34081
|
+
},
|
|
34082
|
+
{
|
|
34083
|
+
id: id("media-text-photo-beside-text"),
|
|
34084
|
+
treatment: "beside-plate",
|
|
34085
|
+
roleMap: fulcrumRoles
|
|
34086
|
+
},
|
|
34087
|
+
{
|
|
34088
|
+
id: id("newsletter-signup-one-row"),
|
|
34089
|
+
treatment: "signup-strip",
|
|
34090
|
+
roleMap: {
|
|
34091
|
+
...fulcrumRoles,
|
|
34092
|
+
card: "section"
|
|
34093
|
+
}
|
|
34094
|
+
},
|
|
34095
|
+
{
|
|
34096
|
+
id: id("newsletter-signup-text-beside"),
|
|
34097
|
+
treatment: "signup-beside-panel",
|
|
34098
|
+
roleMap: fulcrumRoles
|
|
34099
|
+
},
|
|
34100
|
+
{
|
|
34101
|
+
id: id("form-below-introduction"),
|
|
34102
|
+
treatment: "form-sheet",
|
|
34103
|
+
roleMap: fulcrumRoles
|
|
34104
|
+
},
|
|
34105
|
+
{
|
|
34106
|
+
id: id("card-list-wide-slides"),
|
|
34107
|
+
treatment: "carousel-wide-plate",
|
|
34108
|
+
roleMap: fulcrumRoles,
|
|
34109
|
+
knobValues: { actionStyle: ["link"] }
|
|
34110
|
+
},
|
|
34111
|
+
{
|
|
34112
|
+
id: id("card-list-scroll-row"),
|
|
34113
|
+
treatment: "carousel-row-cards",
|
|
34114
|
+
roleMap: fulcrumRoles
|
|
34115
|
+
},
|
|
34116
|
+
{
|
|
34117
|
+
id: id("card-list-accent-edged-cards"),
|
|
34118
|
+
treatment: "cards-accent-edged",
|
|
34119
|
+
roleMap: fulcrumRoles
|
|
33617
34120
|
}
|
|
33618
34121
|
];
|
|
33619
34122
|
const fulcrumLooks = {
|
|
@@ -33816,6 +34319,49 @@ const posterOffers = [
|
|
|
33816
34319
|
id: id("testimonials-scroll-row"),
|
|
33817
34320
|
treatment: "punchy",
|
|
33818
34321
|
roleMap: posterRoles
|
|
34322
|
+
},
|
|
34323
|
+
{
|
|
34324
|
+
id: id("intro-photo-beside-text"),
|
|
34325
|
+
treatment: "ink-edge",
|
|
34326
|
+
roleMap: posterRoles
|
|
34327
|
+
},
|
|
34328
|
+
{
|
|
34329
|
+
id: id("intro-statement-beside-text"),
|
|
34330
|
+
treatment: "headline",
|
|
34331
|
+
roleMap: posterRoles
|
|
34332
|
+
},
|
|
34333
|
+
{
|
|
34334
|
+
id: id("media-text-photo-beside-text"),
|
|
34335
|
+
treatment: "beside-slab",
|
|
34336
|
+
roleMap: posterRoles
|
|
34337
|
+
},
|
|
34338
|
+
{
|
|
34339
|
+
id: id("newsletter-signup-one-row"),
|
|
34340
|
+
treatment: "signup-ticket",
|
|
34341
|
+
roleMap: posterRoles
|
|
34342
|
+
},
|
|
34343
|
+
{
|
|
34344
|
+
id: id("newsletter-signup-text-beside"),
|
|
34345
|
+
treatment: "signup-block",
|
|
34346
|
+
roleMap: {
|
|
34347
|
+
...posterRoles,
|
|
34348
|
+
card: "pop"
|
|
34349
|
+
}
|
|
34350
|
+
},
|
|
34351
|
+
{
|
|
34352
|
+
id: id("form-below-introduction"),
|
|
34353
|
+
treatment: "form-heavy",
|
|
34354
|
+
roleMap: posterRoles
|
|
34355
|
+
},
|
|
34356
|
+
{
|
|
34357
|
+
id: id("card-list-wide-slides"),
|
|
34358
|
+
treatment: "carousel-wide-stamp",
|
|
34359
|
+
roleMap: posterRoles
|
|
34360
|
+
},
|
|
34361
|
+
{
|
|
34362
|
+
id: id("card-list-scroll-row"),
|
|
34363
|
+
treatment: "carousel-row-punchy",
|
|
34364
|
+
roleMap: posterRoles
|
|
33819
34365
|
}
|
|
33820
34366
|
];
|
|
33821
34367
|
const posterLooks = {
|
|
@@ -34092,6 +34638,48 @@ const lanternOffers = [
|
|
|
34092
34638
|
treatment: "quote-arch",
|
|
34093
34639
|
addKnobs: ["archFrame"],
|
|
34094
34640
|
roleMap: lanternRoles
|
|
34641
|
+
},
|
|
34642
|
+
{
|
|
34643
|
+
id: id("testimonials-scroll-row"),
|
|
34644
|
+
treatment: "quote-row-cards",
|
|
34645
|
+
addKnobs: ["archFrame"],
|
|
34646
|
+
roleMap: lanternRoles
|
|
34647
|
+
},
|
|
34648
|
+
{
|
|
34649
|
+
id: id("intro-photo-beside-text"),
|
|
34650
|
+
treatment: "ringed",
|
|
34651
|
+
roleMap: lanternRoles
|
|
34652
|
+
},
|
|
34653
|
+
{
|
|
34654
|
+
id: id("intro-statement-beside-text"),
|
|
34655
|
+
treatment: "divided",
|
|
34656
|
+
roleMap: lanternRoles
|
|
34657
|
+
},
|
|
34658
|
+
{
|
|
34659
|
+
id: id("media-text-photo-beside-text"),
|
|
34660
|
+
treatment: "outlined",
|
|
34661
|
+
roleMap: lanternRoles
|
|
34662
|
+
},
|
|
34663
|
+
{
|
|
34664
|
+
id: id("newsletter-signup-text-beside"),
|
|
34665
|
+
treatment: "signup-beside-arch",
|
|
34666
|
+
addKnobs: ["archFrame"],
|
|
34667
|
+
roleMap: lanternRoles
|
|
34668
|
+
},
|
|
34669
|
+
{
|
|
34670
|
+
id: id("form-below-introduction"),
|
|
34671
|
+
treatment: "form-arch-below",
|
|
34672
|
+
roleMap: lanternRoles
|
|
34673
|
+
},
|
|
34674
|
+
{
|
|
34675
|
+
id: id("card-list-wide-slides"),
|
|
34676
|
+
treatment: "carousel-wide-arch",
|
|
34677
|
+
roleMap: lanternRoles
|
|
34678
|
+
},
|
|
34679
|
+
{
|
|
34680
|
+
id: id("card-list-scroll-row"),
|
|
34681
|
+
treatment: "carousel-row-cards",
|
|
34682
|
+
roleMap: lanternRoles
|
|
34095
34683
|
}
|
|
34096
34684
|
];
|
|
34097
34685
|
const lanternLooks = {
|
|
@@ -34286,6 +34874,51 @@ const measureOffers = [
|
|
|
34286
34874
|
id: id("testimonials-one-at-a-time"),
|
|
34287
34875
|
treatment: "counter",
|
|
34288
34876
|
roleMap: measureRoles
|
|
34877
|
+
},
|
|
34878
|
+
{
|
|
34879
|
+
id: id("testimonials-scroll-row"),
|
|
34880
|
+
treatment: "quote-row-hairline",
|
|
34881
|
+
roleMap: measureRuledPanelRoles
|
|
34882
|
+
},
|
|
34883
|
+
{
|
|
34884
|
+
id: id("intro-photo-beside-text"),
|
|
34885
|
+
treatment: "rail-photo",
|
|
34886
|
+
roleMap: measureRoles
|
|
34887
|
+
},
|
|
34888
|
+
{
|
|
34889
|
+
id: id("intro-statement-beside-text"),
|
|
34890
|
+
treatment: "rule-split",
|
|
34891
|
+
roleMap: measureRoles
|
|
34892
|
+
},
|
|
34893
|
+
{
|
|
34894
|
+
id: id("media-text-photo-beside-text"),
|
|
34895
|
+
treatment: "beside-grid",
|
|
34896
|
+
roleMap: measureRoles
|
|
34897
|
+
},
|
|
34898
|
+
{
|
|
34899
|
+
id: id("newsletter-signup-one-row"),
|
|
34900
|
+
treatment: "signup-rail-row",
|
|
34901
|
+
roleMap: measureRuledPanelRoles
|
|
34902
|
+
},
|
|
34903
|
+
{
|
|
34904
|
+
id: id("newsletter-signup-text-beside"),
|
|
34905
|
+
treatment: "signup-split",
|
|
34906
|
+
roleMap: measureRoles
|
|
34907
|
+
},
|
|
34908
|
+
{
|
|
34909
|
+
id: id("form-below-introduction"),
|
|
34910
|
+
treatment: "form-rail",
|
|
34911
|
+
roleMap: measureRuledPanelRoles
|
|
34912
|
+
},
|
|
34913
|
+
{
|
|
34914
|
+
id: id("card-list-wide-slides"),
|
|
34915
|
+
treatment: "carousel-wide-sheet",
|
|
34916
|
+
roleMap: measureRoles
|
|
34917
|
+
},
|
|
34918
|
+
{
|
|
34919
|
+
id: id("card-list-scroll-row"),
|
|
34920
|
+
treatment: "carousel-row-sheets",
|
|
34921
|
+
roleMap: measureRoles
|
|
34289
34922
|
}
|
|
34290
34923
|
];
|
|
34291
34924
|
const measureLooks = {
|
|
@@ -34813,7 +35446,10 @@ const curatedSiteStyles = [
|
|
|
34813
35446
|
headingDecoration: noHeadingDecoration,
|
|
34814
35447
|
description: "Calm and editorial: Newsreader over IBM Plex Sans, hairlines instead of boxes, flat ink actions, and photos mounted on an offset plate in the brand tone.",
|
|
34815
35448
|
generationBrief: "Use a calm, well-run voice: precise, reassuring and specific. Lead with what happens at a first visit, keep proof concrete (registrations, same-week appointments, outcomes), use sentence case throughout with no all-caps labels, and let photographs carry the boldness. Avoid spa or hard-sell wellness language and medical claims.",
|
|
34816
|
-
offering: {
|
|
35449
|
+
offering: {
|
|
35450
|
+
kind: "public",
|
|
35451
|
+
generation: { kind: "explicit_only" }
|
|
35452
|
+
},
|
|
34817
35453
|
tokenRecipes: {
|
|
34818
35454
|
palette: "brand-led",
|
|
34819
35455
|
contrast: "standard",
|
|
@@ -34948,7 +35584,10 @@ const curatedSiteStyles = [
|
|
|
34948
35584
|
headingDecoration: noHeadingDecoration,
|
|
34949
35585
|
description: "Loud but controlled: huge condensed type, flat colour blocks, hard offset shadows on anything you can press, and one sticker for the news.",
|
|
34950
35586
|
generationBrief: "Write like a gig poster: short, direct lines, one fact set big (a time, a price, an age range), sentence case throughout and no all-caps labels. Keep body copy plain and friendly, and save the sticker line for one piece of real news.",
|
|
34951
|
-
offering: {
|
|
35587
|
+
offering: {
|
|
35588
|
+
kind: "public",
|
|
35589
|
+
generation: { kind: "explicit_only" }
|
|
35590
|
+
},
|
|
34952
35591
|
tokenRecipes: {
|
|
34953
35592
|
palette: "brand-led",
|
|
34954
35593
|
contrast: "strong",
|
|
@@ -35000,8 +35639,8 @@ const curatedSiteStyles = [
|
|
|
35000
35639
|
description: "Dark, candlelit and symmetrical: Gloock display over Alegreya Sans, every photo seen through an arched window, one small lozenge rule above each heading, and a lit panel for the one thing you would pick.",
|
|
35001
35640
|
generationBrief: "Warm and ceremonial without being religious. Write plain invitations (\"Come along this Friday\") with real times and prices, sentence case throughout and no all-caps labels. Let the quiet, candlelit mood come from the photographs rather than from spiritual language.",
|
|
35002
35641
|
offering: {
|
|
35003
|
-
kind: "
|
|
35004
|
-
|
|
35642
|
+
kind: "public",
|
|
35643
|
+
generation: { kind: "explicit_only" }
|
|
35005
35644
|
},
|
|
35006
35645
|
tokenRecipes: {
|
|
35007
35646
|
palette: "brand-led",
|
|
@@ -35059,7 +35698,10 @@ const curatedSiteStyles = [
|
|
|
35059
35698
|
headingDecoration: noHeadingDecoration,
|
|
35060
35699
|
description: "Swiss and warm: one grotesque through weight and size, a visible twelve-column grid, a heavy rule and a small hanging title at the top of every section, square corners and no shadows. The accent is only ever a small square.",
|
|
35061
35700
|
generationBrief: "Calm and exact, for one-to-one practices. Number real sequences and nothing else, give times and fees as plain figures, keep sentence case throughout, and include a crisis line where a therapy site needs one. Avoid wellness cliches and promises of outcomes.",
|
|
35062
|
-
offering: {
|
|
35701
|
+
offering: {
|
|
35702
|
+
kind: "public",
|
|
35703
|
+
generation: { kind: "explicit_only" }
|
|
35704
|
+
},
|
|
35063
35705
|
tokenRecipes: {
|
|
35064
35706
|
palette: "brand-led",
|
|
35065
35707
|
contrast: "strong",
|
|
@@ -35088,6 +35730,104 @@ const curatedSiteStyles = [
|
|
|
35088
35730
|
paletteRecommendation("measure-plaster"),
|
|
35089
35731
|
paletteRecommendation("measure-night")
|
|
35090
35732
|
]
|
|
35733
|
+
}),
|
|
35734
|
+
defineCuratedSiteStyle({
|
|
35735
|
+
id: "site-style:folio",
|
|
35736
|
+
name: "Folio",
|
|
35737
|
+
offering: {
|
|
35738
|
+
kind: "public",
|
|
35739
|
+
generation: { kind: "explicit_only" }
|
|
35740
|
+
},
|
|
35741
|
+
description: "Calm and editorial: a classic serif over a plain sans, soft corners, thin rules and photos with room around them. For practitioners who teach classes, see clients and run workshops.",
|
|
35742
|
+
generationBrief: "Use restrained serif headings, clear sans-serif body copy, natural photography, practical calls to action and concrete class and workshop details.",
|
|
35743
|
+
headingDecoration: noHeadingDecoration,
|
|
35744
|
+
tokenRecipes: {
|
|
35745
|
+
palette: "warm-neutral",
|
|
35746
|
+
contrast: "standard",
|
|
35747
|
+
radius: "soft",
|
|
35748
|
+
shadow: "none",
|
|
35749
|
+
typography: "classic-serif",
|
|
35750
|
+
spacing: "airy",
|
|
35751
|
+
motion: "subtle"
|
|
35752
|
+
},
|
|
35753
|
+
compositionBudget: accentLedQuietBudget,
|
|
35754
|
+
typography: folioTypography,
|
|
35755
|
+
heroTypography: groundedSerifHeroTypography,
|
|
35756
|
+
looks: folioLooks,
|
|
35757
|
+
contentTemplateDefaults: { event: "event-header" },
|
|
35758
|
+
themeOverrides: {
|
|
35759
|
+
accordions: editorialDividedAccordionSystem,
|
|
35760
|
+
testimonialQuote: serifDisplayQuote
|
|
35761
|
+
},
|
|
35762
|
+
headerStyleRecipes: { "minimal-surface": {
|
|
35763
|
+
tone: "neutral",
|
|
35764
|
+
background: { kind: "transparent" },
|
|
35765
|
+
nav: {
|
|
35766
|
+
kind: "minimal",
|
|
35767
|
+
hoverColorToken: "primary"
|
|
35768
|
+
},
|
|
35769
|
+
navWeight: "medium",
|
|
35770
|
+
navLinkWeight: "medium",
|
|
35771
|
+
navTypography: "plain",
|
|
35772
|
+
border: "none",
|
|
35773
|
+
shadow: { kind: "absent" },
|
|
35774
|
+
frame: {
|
|
35775
|
+
kind: "container",
|
|
35776
|
+
rounded: "lg",
|
|
35777
|
+
padding: "sm",
|
|
35778
|
+
tint: "background",
|
|
35779
|
+
opacity: 1,
|
|
35780
|
+
shadow: false,
|
|
35781
|
+
mobileSheet: "inset"
|
|
35782
|
+
},
|
|
35783
|
+
cta: { treatment: "default" },
|
|
35784
|
+
openingPlacement: "photo-behind-text"
|
|
35785
|
+
} },
|
|
35786
|
+
footerLookRecipes: { "footer-links-row": {
|
|
35787
|
+
arrangement: "simple",
|
|
35788
|
+
ground: {
|
|
35789
|
+
kind: "token",
|
|
35790
|
+
token: "surface"
|
|
35791
|
+
},
|
|
35792
|
+
nav: {
|
|
35793
|
+
weight: "regular",
|
|
35794
|
+
colorToken: "text",
|
|
35795
|
+
hoverColorToken: "primary",
|
|
35796
|
+
typography: "body"
|
|
35797
|
+
},
|
|
35798
|
+
legal: {
|
|
35799
|
+
kind: "separate",
|
|
35800
|
+
bar: {
|
|
35801
|
+
fullBleed: false,
|
|
35802
|
+
background: {
|
|
35803
|
+
kind: "token",
|
|
35804
|
+
token: "surface"
|
|
35805
|
+
},
|
|
35806
|
+
textColor: "text",
|
|
35807
|
+
textAlign: "left",
|
|
35808
|
+
paddingY: "tight",
|
|
35809
|
+
paddingX: "none",
|
|
35810
|
+
borderTop: { width: "none" }
|
|
35811
|
+
}
|
|
35812
|
+
},
|
|
35813
|
+
brandAlign: "start",
|
|
35814
|
+
brandLogoSize: "md"
|
|
35815
|
+
} },
|
|
35816
|
+
recommendedFooterLookIds: ["footer-links-row"],
|
|
35817
|
+
buttonStyleChoices: [
|
|
35818
|
+
buttonChoice("quiet-arrow", undefined, {
|
|
35819
|
+
secondaryTreatment: "solid-accent",
|
|
35820
|
+
size: "comfortable",
|
|
35821
|
+
hoverTreatment: "deep-and-sheet"
|
|
35822
|
+
}),
|
|
35823
|
+
buttonChoice("flat-ink"),
|
|
35824
|
+
buttonChoice("editorial-link")
|
|
35825
|
+
],
|
|
35826
|
+
paletteRecommendations: [
|
|
35827
|
+
paletteRecommendation("warm-neutral-forest"),
|
|
35828
|
+
paletteRecommendation("soft-natural-sage"),
|
|
35829
|
+
paletteRecommendation("soft-natural-stone")
|
|
35830
|
+
]
|
|
35091
35831
|
})
|
|
35092
35832
|
];
|
|
35093
35833
|
const curatedSiteStylesById = new Map(curatedSiteStyles.map((style) => [style.id, style]));
|
|
@@ -37928,29 +38668,29 @@ function planGeneratedHeaderOpeningSection(input) {
|
|
|
37928
38668
|
}
|
|
37929
38669
|
function hasPersistedImageBackground(content) {
|
|
37930
38670
|
const sectionStyles = content._sectionStyles;
|
|
37931
|
-
if (!isRecord$
|
|
38671
|
+
if (!isRecord$2(sectionStyles)) return false;
|
|
37932
38672
|
const background = sectionStyles.background;
|
|
37933
|
-
return isRecord$
|
|
38673
|
+
return isRecord$2(background) && background.type === "image" && background.image !== undefined;
|
|
37934
38674
|
}
|
|
37935
38675
|
function openingBackground(content) {
|
|
37936
38676
|
const sectionStyles = content ? content._sectionStyles : null;
|
|
37937
|
-
if (!isRecord$
|
|
38677
|
+
if (!isRecord$2(sectionStyles)) return null;
|
|
37938
38678
|
const background = sectionStyles.background;
|
|
37939
|
-
return isRecord$
|
|
38679
|
+
return isRecord$2(background) ? background : null;
|
|
37940
38680
|
}
|
|
37941
38681
|
function contentHasContrastOverlay(content) {
|
|
37942
38682
|
if (!content) return false;
|
|
37943
38683
|
const imageSurfaceTreatment = content.imageSurfaceTreatment;
|
|
37944
|
-
const imageSurfaceTreatmentKind = isRecord$
|
|
38684
|
+
const imageSurfaceTreatmentKind = isRecord$2(imageSurfaceTreatment) ? imageSurfaceTreatment.kind : null;
|
|
37945
38685
|
const background = openingBackground(content);
|
|
37946
38686
|
const backgroundOverlay = background?.overlay;
|
|
37947
|
-
const hasBackgroundOverlay = isRecord$
|
|
38687
|
+
const hasBackgroundOverlay = isRecord$2(backgroundOverlay) && backgroundOverlay.type !== undefined && backgroundOverlay.type !== null && backgroundOverlay.type !== "none";
|
|
37948
38688
|
return content.heroLegibility === "scrim-gradient" || imageSurfaceTreatmentKind === "brand-scrim" || imageSurfaceTreatmentKind === "neutral-scrim" || hasBackgroundOverlay;
|
|
37949
38689
|
}
|
|
37950
38690
|
function contentHasOpeningTopSpacing(content) {
|
|
37951
38691
|
if (!content) return false;
|
|
37952
38692
|
const sectionStyles = content._sectionStyles;
|
|
37953
|
-
const minHeight = isRecord$
|
|
38693
|
+
const minHeight = isRecord$2(sectionStyles) ? sectionStyles.minHeight : null;
|
|
37954
38694
|
return content.sectionHeight === "hero" || content.sectionHeight === "immersive" || minHeight === "hero" || minHeight === "immersive";
|
|
37955
38695
|
}
|
|
37956
38696
|
function runtimeHasContrastOverlay(block) {
|
|
@@ -38855,10 +39595,28 @@ function planUnknownOpeningNavHover(theme, style, restingToken) {
|
|
|
38855
39595
|
});
|
|
38856
39596
|
}
|
|
38857
39597
|
function applyPageOpeningForegroundToTheme(theme, recipe, context) {
|
|
38858
|
-
if (!recipe
|
|
39598
|
+
if (!recipe || !headerReadsOpening(recipe)) return theme;
|
|
39599
|
+
const header = applyOpeningPlacement(theme.header, recipe, context);
|
|
38859
39600
|
return {
|
|
38860
39601
|
...theme,
|
|
38861
|
-
header: applyOpeningForeground(theme,
|
|
39602
|
+
header: applyOpeningForeground(theme, header, recipe, context)
|
|
39603
|
+
};
|
|
39604
|
+
}
|
|
39605
|
+
/** Whether the page's opening section changes how this header compiles. */
|
|
39606
|
+
function headerReadsOpening(recipe) {
|
|
39607
|
+
return Boolean(recipe.openingForeground || recipe.openingPlacement);
|
|
39608
|
+
}
|
|
39609
|
+
/**
|
|
39610
|
+
* A header that floats only over a photo becomes an in-flow bar elsewhere:
|
|
39611
|
+
* the classic variant without the floating frame, so content starts below it.
|
|
39612
|
+
*/
|
|
39613
|
+
function applyOpeningPlacement(header, recipe, context) {
|
|
39614
|
+
if (recipe.openingPlacement !== "photo-behind-text") return header;
|
|
39615
|
+
if (header.variant !== "floating" || context?.openingPhotoBehindText === true) return header;
|
|
39616
|
+
const { container: _floatingFrame, ...inFlow } = header;
|
|
39617
|
+
return {
|
|
39618
|
+
...inFlow,
|
|
39619
|
+
variant: "classic"
|
|
38862
39620
|
};
|
|
38863
39621
|
}
|
|
38864
39622
|
|
|
@@ -43305,6 +44063,7 @@ const courseBookingSettingsSchema = z.object({
|
|
|
43305
44063
|
visibility: z.enum(["public", "unlisted"]),
|
|
43306
44064
|
acceptsPasses: z.boolean(),
|
|
43307
44065
|
acceptsMemberships: z.boolean(),
|
|
44066
|
+
siteTermsMode: z.enum(["site", "off"]).optional(),
|
|
43308
44067
|
ticketingMode: z.enum([
|
|
43309
44068
|
"inherit",
|
|
43310
44069
|
"enabled",
|
|
@@ -43542,13 +44301,44 @@ const eventBookingOfferIntentSchema = z.discriminatedUnion("bookingRequirement",
|
|
|
43542
44301
|
pricing: eventPricingIntentSchema,
|
|
43543
44302
|
paymentTerms: eventPaymentTermsIntentSchema
|
|
43544
44303
|
}).strict()]);
|
|
44304
|
+
/** A booked pricing change carries its target beside the offer it selects from. */
|
|
44305
|
+
const eventRunBookingCommandFields = {
|
|
44306
|
+
bookingOffer: eventBookingOfferIntentSchema,
|
|
44307
|
+
attendeeMigration: z.object({ pricingOptionIdentifier: z.string().trim().min(1) }).strict().optional()
|
|
44308
|
+
};
|
|
43545
44309
|
|
|
43546
44310
|
//#endregion
|
|
43547
44311
|
//#region ../site-commands/src/eventSeriesCommandRules.ts
|
|
44312
|
+
/** The timezone belongs to the command; a schedule authors local wall time. */
|
|
44313
|
+
const eventCommandScheduleSchema = z.object({
|
|
44314
|
+
recurrenceRule: z.string().min(1),
|
|
44315
|
+
startDate: isoLocalDateSchema,
|
|
44316
|
+
defaultStartTime: z.string().regex(localScheduleTimePattern),
|
|
44317
|
+
durationMinutes: positiveIntegerSchema
|
|
44318
|
+
}).strict();
|
|
44319
|
+
function withEventSeriesTiming(fields, occurrence) {
|
|
44320
|
+
return z.union([withEventSeriesBookingScope({
|
|
44321
|
+
...fields,
|
|
44322
|
+
occurrences: z.tuple([occurrence]).rest(occurrence).readonly(),
|
|
44323
|
+
schedule: z.never().optional()
|
|
44324
|
+
}), withEventSeriesBookingScope({
|
|
44325
|
+
...fields,
|
|
44326
|
+
schedule: eventCommandScheduleSchema,
|
|
44327
|
+
occurrences: z.never().optional()
|
|
44328
|
+
})]);
|
|
44329
|
+
}
|
|
43548
44330
|
/**
|
|
43549
44331
|
* Cross-field rules for `upsertEventSeries`, kept together so the schema in
|
|
43550
44332
|
* `commands.ts` reads as a shape and these read as the rules about it.
|
|
43551
44333
|
*/
|
|
44334
|
+
/** Ordinary runs inherit the parent's name; whole-series runs may author their own. */
|
|
44335
|
+
function withEventSeriesBookingScope(fields) {
|
|
44336
|
+
const common = z.object(fields);
|
|
44337
|
+
return z.discriminatedUnion("bookingScope", [common.extend({ bookingScope: z.literal("single_occurrence") }).strict(), common.extend({
|
|
44338
|
+
bookingScope: z.literal("whole_series"),
|
|
44339
|
+
runName: z.string().nullable().optional()
|
|
44340
|
+
}).strict()]);
|
|
44341
|
+
}
|
|
43552
44342
|
function checkOccurrenceInterval(occurrence, ctx) {
|
|
43553
44343
|
validateChronologicalFields({
|
|
43554
44344
|
start: occurrence.startAt,
|
|
@@ -44321,12 +45111,11 @@ const eventOccurrenceSchema = z.object({
|
|
|
44321
45111
|
const upsertEventSeriesCommandSchema = z.object({
|
|
44322
45112
|
type: z.literal("upsertEventSeries"),
|
|
44323
45113
|
ref: eventSeriesRefSchema,
|
|
44324
|
-
input:
|
|
45114
|
+
input: withEventSeriesTiming({
|
|
44325
45115
|
slug: z.string().min(1),
|
|
44326
45116
|
path: z.string().startsWith("/").nullable().optional(),
|
|
44327
45117
|
title: z.string().min(1),
|
|
44328
45118
|
preset: z.enum(EVENT_PRESET_VALUES),
|
|
44329
|
-
bookingScope: z.enum(["single_occurrence", "whole_series"]),
|
|
44330
45119
|
status: z.enum([
|
|
44331
45120
|
"draft",
|
|
44332
45121
|
"active",
|
|
@@ -44336,19 +45125,18 @@ const upsertEventSeriesCommandSchema = z.object({
|
|
|
44336
45125
|
...offeringCommonInputFields,
|
|
44337
45126
|
courseBooking: courseBookingSettingsSchema.optional(),
|
|
44338
45127
|
waitlist: waitlistIntentSchema.optional(),
|
|
44339
|
-
|
|
45128
|
+
...eventRunBookingCommandFields,
|
|
44340
45129
|
deliveryMode: z.enum([
|
|
44341
45130
|
"in_person",
|
|
44342
45131
|
"online",
|
|
44343
45132
|
"hybrid"
|
|
44344
45133
|
]).optional(),
|
|
44345
|
-
occurrences: z.array(eventOccurrenceSchema).min(1).readonly(),
|
|
44346
45134
|
content: contentSummarySchema.optional(),
|
|
44347
45135
|
settings: unknownRecordSchema.optional(),
|
|
44348
45136
|
tags: z.array(z.string()).readonly().optional(),
|
|
44349
45137
|
blocks: entrySlotBlocksSchema.optional(),
|
|
44350
45138
|
staffRefs: z.array(staffRefSchema).readonly().optional()
|
|
44351
|
-
})
|
|
45139
|
+
}, eventOccurrenceSchema)
|
|
44352
45140
|
}).strict().superRefine(checkDraftListingMatchesStatus);
|
|
44353
45141
|
const deleteEventSeriesCommandSchema = z.object({
|
|
44354
45142
|
type: z.literal("deleteEventSeries"),
|
|
@@ -44589,6 +45377,17 @@ const unsafeAsSiteCommandResourceId = (value) => value;
|
|
|
44589
45377
|
|
|
44590
45378
|
//#endregion
|
|
44591
45379
|
//#region ../site-commands/src/datedOfferingMapping.ts
|
|
45380
|
+
/** One timing authority goes to the SDK: generated dates never override a schedule. */
|
|
45381
|
+
function eventManagementTiming(input) {
|
|
45382
|
+
return input.schedule !== undefined ? { schedule: {
|
|
45383
|
+
...input.schedule,
|
|
45384
|
+
timezone: input.timezone
|
|
45385
|
+
} } : { occurrences: mapReadonlyNonEmptyArray(input.occurrences, (item) => ({
|
|
45386
|
+
startsAt: item.startAt,
|
|
45387
|
+
endsAt: item.endAt,
|
|
45388
|
+
timeZone: input.timezone
|
|
45389
|
+
})) };
|
|
45390
|
+
}
|
|
44592
45391
|
function eventManagementContent(content, operations) {
|
|
44593
45392
|
if (content === undefined) return undefined;
|
|
44594
45393
|
if (content.body !== undefined && typeof content.body !== "string" && !operations.isCanonicalBody(content.body)) {
|
|
@@ -45342,7 +46141,7 @@ function planCommandOrderingDependencies(command, commands, providerByRef, requi
|
|
|
45342
46141
|
|
|
45343
46142
|
//#endregion
|
|
45344
46143
|
//#region ../site-commands/src/guards.ts
|
|
45345
|
-
function isRecord(value) {
|
|
46144
|
+
function isRecord$1(value) {
|
|
45346
46145
|
return typeof value === "object" && value !== null;
|
|
45347
46146
|
}
|
|
45348
46147
|
|
|
@@ -45689,7 +46488,7 @@ function collectVenueRefsFromIntervals(intervals, path) {
|
|
|
45689
46488
|
}
|
|
45690
46489
|
function collectNavigationRefs(items, path) {
|
|
45691
46490
|
return items.flatMap((item, index) => {
|
|
45692
|
-
if (!isRecord(item)) return [];
|
|
46491
|
+
if (!isRecord$1(item)) return [];
|
|
45693
46492
|
const itemPath = `${path}[${index}]`;
|
|
45694
46493
|
const refs = [];
|
|
45695
46494
|
if (typeof item.pageRef === "string") {
|
|
@@ -45712,7 +46511,7 @@ function collectNavigationRefs(items, path) {
|
|
|
45712
46511
|
}
|
|
45713
46512
|
function collectBlockRefs(blocks, path) {
|
|
45714
46513
|
return blocks.flatMap((block, index) => {
|
|
45715
|
-
if (!isRecord(block)) return [];
|
|
46514
|
+
if (!isRecord$1(block)) return [];
|
|
45716
46515
|
const blockPath = `${path}[${index}]`;
|
|
45717
46516
|
return [...collectNestedRefs(block.props, `${blockPath}.props`), ...collectNestedRefs(block.children, `${blockPath}.children`)];
|
|
45718
46517
|
});
|
|
@@ -45728,7 +46527,7 @@ function collectNestedRefs(value, path) {
|
|
|
45728
46527
|
if (Array.isArray(value)) {
|
|
45729
46528
|
return value.flatMap((item, index) => collectNestedRefs(item, `${path}[${index}]`));
|
|
45730
46529
|
}
|
|
45731
|
-
if (!isRecord(value)) return [];
|
|
46530
|
+
if (!isRecord$1(value)) return [];
|
|
45732
46531
|
return Object.entries(value).flatMap(([key, child]) => collectNestedRefs(child, `${path}.${key}`));
|
|
45733
46532
|
}
|
|
45734
46533
|
|
|
@@ -45750,7 +46549,7 @@ function nativeWholeSeriesStaticExecutionGaps(command) {
|
|
|
45750
46549
|
].filter(isPresent);
|
|
45751
46550
|
}
|
|
45752
46551
|
function wholeSeriesOccurrenceVenueGap(input) {
|
|
45753
|
-
return input.occurrences.some((occurrence) => occurrence.venueRef !== undefined) ? staticGap("event_occurrence_venue_mapping_unsupported", "Whole-series occurrence venue overrides need native session-level venue mapping before mutation.") : null;
|
|
46552
|
+
return (input.occurrences ?? []).some((occurrence) => occurrence.venueRef !== undefined) ? staticGap("event_occurrence_venue_mapping_unsupported", "Whole-series occurrence venue overrides need native session-level venue mapping before mutation.") : null;
|
|
45754
46553
|
}
|
|
45755
46554
|
function wholeSeriesPricingGap(input) {
|
|
45756
46555
|
switch (input.bookingOffer.pricing.kind) {
|
|
@@ -45803,7 +46602,7 @@ function occurrenceVenueMappingGap(command) {
|
|
|
45803
46602
|
}
|
|
45804
46603
|
function resolveEventSeriesVenueMapping(command) {
|
|
45805
46604
|
const seriesVenue = command.input.venueRef !== undefined ? refSlug(command.input.venueRef) : command.input.venueIdentifier ?? null;
|
|
45806
|
-
const effectiveVenues = command.input.occurrences.map((occurrence) => occurrence.venueRef !== undefined ? refSlug(occurrence.venueRef) : seriesVenue);
|
|
46605
|
+
const effectiveVenues = (command.input.occurrences ?? []).map((occurrence) => occurrence.venueRef !== undefined ? refSlug(occurrence.venueRef) : seriesVenue);
|
|
45807
46606
|
const uniqueEffectiveVenues = [...new Set(effectiveVenues)];
|
|
45808
46607
|
return uniqueEffectiveVenues.length <= 1 ? {
|
|
45809
46608
|
kind: "resolved",
|
|
@@ -45963,9 +46762,9 @@ function deriveIdempotencyKey(input) {
|
|
|
45963
46762
|
].join("|"));
|
|
45964
46763
|
}
|
|
45965
46764
|
function findUnknownCommandTypes(input) {
|
|
45966
|
-
if (!isRecord(input) || !Array.isArray(input.commands)) return [];
|
|
46765
|
+
if (!isRecord$1(input) || !Array.isArray(input.commands)) return [];
|
|
45967
46766
|
return input.commands.flatMap((command, commandIndex) => {
|
|
45968
|
-
if (!isRecord(command) || typeof command.type !== "string") return [];
|
|
46767
|
+
if (!isRecord$1(command) || typeof command.type !== "string") return [];
|
|
45969
46768
|
if (commandTypeSet.has(command.type)) return [];
|
|
45970
46769
|
return [{
|
|
45971
46770
|
code: "unknown_command_type",
|
|
@@ -45991,9 +46790,9 @@ function commandIndexForIssuePath(path) {
|
|
|
45991
46790
|
return path[0] === "commands" && typeof path[1] === "number" ? path[1] : -1;
|
|
45992
46791
|
}
|
|
45993
46792
|
function commandTypeForIssue(input, commandIndex) {
|
|
45994
|
-
if (!isRecord(input) || !isUnknownArray(input.commands)) return null;
|
|
46793
|
+
if (!isRecord$1(input) || !isUnknownArray(input.commands)) return null;
|
|
45995
46794
|
const command = input.commands[commandIndex];
|
|
45996
|
-
return isRecord(command) && typeof command.type === "string" ? command.type : null;
|
|
46795
|
+
return isRecord$1(command) && typeof command.type === "string" ? command.type : null;
|
|
45997
46796
|
}
|
|
45998
46797
|
function isUnknownArray(value) {
|
|
45999
46798
|
return Array.isArray(value);
|
|
@@ -46445,6 +47244,103 @@ function isEventVisibility(value) {
|
|
|
46445
47244
|
}
|
|
46446
47245
|
const eventVisibilitySchema = z.enum(EVENT_VISIBILITY_VALUES, { error: EVENT_VISIBILITY_ERROR_MESSAGE });
|
|
46447
47246
|
|
|
47247
|
+
//#endregion
|
|
47248
|
+
//#region ../blocks/src/system/types/link.ts
|
|
47249
|
+
const nullableString = z.union([z.string().min(1), z.null()]);
|
|
47250
|
+
const RESOLVED_INTERNAL_LINK_ENTITY_TYPES = [
|
|
47251
|
+
"page",
|
|
47252
|
+
"content",
|
|
47253
|
+
"pageSurface"
|
|
47254
|
+
];
|
|
47255
|
+
function isResolvedInternalLinkEntityType(value) {
|
|
47256
|
+
return typeof value === "string" && RESOLVED_INTERNAL_LINK_ENTITY_TYPES.includes(value);
|
|
47257
|
+
}
|
|
47258
|
+
const resolvedInternalLinkKeys = [
|
|
47259
|
+
"entityId",
|
|
47260
|
+
"entityType",
|
|
47261
|
+
"href",
|
|
47262
|
+
"title",
|
|
47263
|
+
"typeLabel"
|
|
47264
|
+
];
|
|
47265
|
+
const internalRouteOnlyLinkSchema = z.object({
|
|
47266
|
+
kind: z.literal("internal"),
|
|
47267
|
+
routeId: z.string().min(1)
|
|
47268
|
+
}).passthrough().superRefine((value, ctx) => {
|
|
47269
|
+
const hasResolvedMetadata = resolvedInternalLinkKeys.some((key) => value[key] != null);
|
|
47270
|
+
if (!hasResolvedMetadata) return;
|
|
47271
|
+
ctx.addIssue({
|
|
47272
|
+
code: "custom",
|
|
47273
|
+
message: "Internal links with resolved metadata must include entityId, entityType, href, title, and typeLabel"
|
|
47274
|
+
});
|
|
47275
|
+
});
|
|
47276
|
+
const internalResolvedLinkSchema = z.object({
|
|
47277
|
+
kind: z.literal("internal"),
|
|
47278
|
+
routeId: z.string().min(1),
|
|
47279
|
+
entityId: z.string().min(1),
|
|
47280
|
+
entityType: z.enum(RESOLVED_INTERNAL_LINK_ENTITY_TYPES),
|
|
47281
|
+
href: z.string().min(1),
|
|
47282
|
+
title: z.string().min(1),
|
|
47283
|
+
typeLabel: z.string().min(1),
|
|
47284
|
+
contentTypeKey: nullableString.optional(),
|
|
47285
|
+
contentTypeName: nullableString.optional(),
|
|
47286
|
+
updatedAt: nullableString.optional()
|
|
47287
|
+
}).passthrough();
|
|
47288
|
+
const internalLinkSchema = z.union([internalResolvedLinkSchema, internalRouteOnlyLinkSchema]);
|
|
47289
|
+
const externalLinkSchema = z.object({
|
|
47290
|
+
kind: z.literal("external"),
|
|
47291
|
+
href: z.string().min(1)
|
|
47292
|
+
}).passthrough();
|
|
47293
|
+
const customLinkSchema = z.object({
|
|
47294
|
+
kind: z.literal("url"),
|
|
47295
|
+
href: z.string().min(1)
|
|
47296
|
+
}).passthrough();
|
|
47297
|
+
const pageLinkSchema = z.object({
|
|
47298
|
+
kind: z.literal("page"),
|
|
47299
|
+
identifier: z.string().min(1)
|
|
47300
|
+
}).passthrough();
|
|
47301
|
+
const entryLinkSchema = z.object({
|
|
47302
|
+
kind: z.literal("entry"),
|
|
47303
|
+
contentType: z.string().min(1),
|
|
47304
|
+
identifier: z.string().min(1)
|
|
47305
|
+
}).passthrough();
|
|
47306
|
+
/** Convert legacy URL strings without inventing page or entry references. */
|
|
47307
|
+
function normalizeLinkValue(value) {
|
|
47308
|
+
return typeof value === "string" && value.trim().length > 0 ? {
|
|
47309
|
+
kind: "url",
|
|
47310
|
+
href: value.trim()
|
|
47311
|
+
} : value;
|
|
47312
|
+
}
|
|
47313
|
+
const linkSchema = z.union([
|
|
47314
|
+
internalLinkSchema,
|
|
47315
|
+
externalLinkSchema,
|
|
47316
|
+
customLinkSchema,
|
|
47317
|
+
pageLinkSchema,
|
|
47318
|
+
entryLinkSchema
|
|
47319
|
+
]);
|
|
47320
|
+
function visitLinkValueReferences(value, visitor) {
|
|
47321
|
+
const parsed = linkSchema.safeParse(value);
|
|
47322
|
+
if (!parsed.success) {
|
|
47323
|
+
return;
|
|
47324
|
+
}
|
|
47325
|
+
const link = parsed.data;
|
|
47326
|
+
switch (link.kind) {
|
|
47327
|
+
case "internal":
|
|
47328
|
+
visitor.routeIds.add(link.routeId);
|
|
47329
|
+
return;
|
|
47330
|
+
case "page":
|
|
47331
|
+
visitor.pageIdentifiers.add(link.identifier);
|
|
47332
|
+
return;
|
|
47333
|
+
case "entry":
|
|
47334
|
+
visitor.entryIdentifiers.add(link.contentType, link.identifier);
|
|
47335
|
+
return;
|
|
47336
|
+
case "external":
|
|
47337
|
+
case "url": return;
|
|
47338
|
+
}
|
|
47339
|
+
}
|
|
47340
|
+
function isInternalResolvedLinkValue(value) {
|
|
47341
|
+
return value?.kind === "internal" && "entityId" in value && "entityType" in value && "href" in value && "title" in value && "typeLabel" in value && typeof value.entityId === "string" && isResolvedInternalLinkEntityType(value.entityType) && typeof value.href === "string" && typeof value.title === "string" && typeof value.typeLabel === "string";
|
|
47342
|
+
}
|
|
47343
|
+
|
|
46448
47344
|
//#endregion
|
|
46449
47345
|
//#region ../api/src/sdk-event-booking-offer.ts
|
|
46450
47346
|
function classifySdkEventBookingOffer(input) {
|
|
@@ -46468,7 +47364,6 @@ function classifySdkEventBookingOffer(input) {
|
|
|
46468
47364
|
|
|
46469
47365
|
//#endregion
|
|
46470
47366
|
//#region ../api/src/sdk-event-schedule.ts
|
|
46471
|
-
const timeRegex = /^([01]\d|2[0-3]):([0-5]\d)(:([0-5]\d))?$/;
|
|
46472
47367
|
const explicitOffsetDateTimeRegex = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(\.\d{1,3})?(Z|[+-]([01]\d|2[0-3]):[0-5]\d)$/;
|
|
46473
47368
|
const localDateTimeRegex = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(\.\d{1,3})?$/;
|
|
46474
47369
|
function issue(path, message) {
|
|
@@ -46541,7 +47436,7 @@ function classifyCanonicalSchedule(input, options) {
|
|
|
46541
47436
|
if (options.requireCanonicalFields && input.recurrenceRule === undefined) {
|
|
46542
47437
|
issues.push(issue(["recurrenceRule"], "recurrenceRule is required"));
|
|
46543
47438
|
}
|
|
46544
|
-
if (input.defaultStartTime !== undefined && input.defaultStartTime !== null && !
|
|
47439
|
+
if (input.defaultStartTime !== undefined && input.defaultStartTime !== null && !localScheduleTimePattern.test(input.defaultStartTime)) {
|
|
46545
47440
|
issues.push(issue(["defaultStartTime"], "Invalid time format (HH:MM or HH:MM:SS)"));
|
|
46546
47441
|
}
|
|
46547
47442
|
if (options.requireCanonicalFields && !input.defaultStartTime) {
|
|
@@ -46699,7 +47594,8 @@ const sdkEventUpsertOptionalFieldSchemas = {
|
|
|
46699
47594
|
]).optional(),
|
|
46700
47595
|
bookingScope: z.enum(["single_occurrence", "whole_series"]).optional(),
|
|
46701
47596
|
occurrences: z.array(sdkEventOccurrenceWireSchema).optional(),
|
|
46702
|
-
capacity: z.number().int().positive().nullable().optional()
|
|
47597
|
+
capacity: z.number().int().positive().nullable().optional(),
|
|
47598
|
+
attendeeMigration: z.object({ pricingOptionIdentifier: z.string().trim().min(1) }).strict().optional()
|
|
46703
47599
|
};
|
|
46704
47600
|
function timingIssue(path, message) {
|
|
46705
47601
|
return {
|
|
@@ -46807,73 +47703,66 @@ function classifySdkEventTiming(input, options = {}) {
|
|
|
46807
47703
|
issues: schedule.issues.map((issue$1) => timingIssue(["schedule", ...issue$1.path], issue$1.message))
|
|
46808
47704
|
};
|
|
46809
47705
|
}
|
|
46810
|
-
function
|
|
47706
|
+
function invalidEventGraph(path, message) {
|
|
47707
|
+
return {
|
|
47708
|
+
ok: false,
|
|
47709
|
+
issues: [{
|
|
47710
|
+
source: "graph",
|
|
47711
|
+
path,
|
|
47712
|
+
message,
|
|
47713
|
+
issue: { kind: "incoherentParentRunGraph" }
|
|
47714
|
+
}]
|
|
47715
|
+
};
|
|
47716
|
+
}
|
|
47717
|
+
function orderSdkEventRuns(input) {
|
|
46811
47718
|
const runRefs = new Set(input.runRefs);
|
|
46812
47719
|
const runsByIdentifier = new Map(input.runs.map((run) => [run.identifier, run]));
|
|
46813
47720
|
if (input.runRefs.length !== runRefs.size || runsByIdentifier.size !== input.runs.length || input.runRefs.length !== input.runs.length || input.runRefs.some((ref) => !runsByIdentifier.has(ref)) || input.runs.some((run) => run.eventRef !== input.identifier)) {
|
|
46814
|
-
return
|
|
46815
|
-
ok: false,
|
|
46816
|
-
issues: [{
|
|
46817
|
-
source: "graph",
|
|
46818
|
-
path: ["runRefs"],
|
|
46819
|
-
message: "Event runRefs and runs must form one complete parent graph",
|
|
46820
|
-
issue: { kind: "incoherentParentRunGraph" }
|
|
46821
|
-
}]
|
|
46822
|
-
};
|
|
47721
|
+
return invalidEventGraph(["runRefs"], "Event runRefs and runs must form one complete parent graph");
|
|
46823
47722
|
}
|
|
46824
|
-
const
|
|
47723
|
+
const resolveRun = (ref) => {
|
|
46825
47724
|
const run = runsByIdentifier.get(ref);
|
|
46826
47725
|
if (!run) throw new Error("Unreachable missing Event run after graph validation");
|
|
46827
47726
|
return run;
|
|
46828
47727
|
};
|
|
46829
|
-
|
|
46830
|
-
|
|
46831
|
-
|
|
46832
|
-
return {
|
|
46833
|
-
ok: false,
|
|
46834
|
-
issues: [{
|
|
46835
|
-
source: "graph",
|
|
46836
|
-
path: ["runs"],
|
|
46837
|
-
message: "An Event must contain one ordinary run or one or more whole-series runs",
|
|
46838
|
-
issue: { kind: "incoherentParentRunGraph" }
|
|
46839
|
-
}]
|
|
46840
|
-
};
|
|
46841
|
-
}
|
|
46842
|
-
const firstResult = parseSdkEventRunUpsertInput(firstRun, 0, options);
|
|
46843
|
-
const remainingResults = remainingRuns.map((run, index) => parseSdkEventRunUpsertInput(run, index + 1, options));
|
|
46844
|
-
const issues = [firstResult, ...remainingResults].flatMap((result) => result.ok ? [] : result.issues);
|
|
46845
|
-
if (issues.length > 0) return {
|
|
46846
|
-
ok: false,
|
|
46847
|
-
issues
|
|
46848
|
-
};
|
|
46849
|
-
if (!firstResult.ok) return {
|
|
46850
|
-
ok: false,
|
|
46851
|
-
issues: firstResult.issues
|
|
47728
|
+
return {
|
|
47729
|
+
ok: true,
|
|
47730
|
+
runs: [resolveRun(input.runRefs[0]), ...input.runRefs.slice(1).map(resolveRun)]
|
|
46852
47731
|
};
|
|
46853
|
-
|
|
47732
|
+
}
|
|
47733
|
+
function admitSdkEventRunGraph(input, runs) {
|
|
47734
|
+
const [first, ...rest] = runs;
|
|
47735
|
+
if (first.bookingScope === "single_occurrence" && rest.length > 0 || rest.some((run) => run.bookingScope !== first.bookingScope)) {
|
|
47736
|
+
return invalidEventGraph(["runs"], "An Event must contain one ordinary run or one or more whole-series runs");
|
|
47737
|
+
}
|
|
47738
|
+
if (first.bookingScope === "single_occurrence" && first.identifier !== input.slug) {
|
|
47739
|
+
return invalidEventGraph([
|
|
47740
|
+
"runs",
|
|
47741
|
+
"0",
|
|
47742
|
+
"identifier"
|
|
47743
|
+
], "identifier must match slug");
|
|
47744
|
+
}
|
|
46854
47745
|
return {
|
|
46855
47746
|
ok: true,
|
|
46856
47747
|
value: {
|
|
46857
47748
|
...input,
|
|
46858
|
-
runs
|
|
47749
|
+
runs
|
|
46859
47750
|
}
|
|
46860
47751
|
};
|
|
46861
47752
|
}
|
|
46862
|
-
function
|
|
46863
|
-
const
|
|
46864
|
-
|
|
46865
|
-
|
|
46866
|
-
|
|
46867
|
-
|
|
46868
|
-
|
|
46869
|
-
|
|
46870
|
-
|
|
46871
|
-
|
|
46872
|
-
|
|
46873
|
-
|
|
46874
|
-
|
|
46875
|
-
default: return timingAuthority;
|
|
46876
|
-
}
|
|
47753
|
+
function parseSdkEventUpsertInput(input, options = {}) {
|
|
47754
|
+
const graph = orderSdkEventRuns(input);
|
|
47755
|
+
if (!graph.ok) return graph;
|
|
47756
|
+
const [firstRun, ...remainingRuns] = graph.runs;
|
|
47757
|
+
const first = parseSdkEventRunUpsertInput(firstRun, 0, options);
|
|
47758
|
+
const remaining = remainingRuns.map((run, index) => parseSdkEventRunUpsertInput(run, index + 1, options));
|
|
47759
|
+
const issues = [first, ...remaining].flatMap((result) => result.ok ? [] : result.issues);
|
|
47760
|
+
if (!first.ok || issues.length > 0) return {
|
|
47761
|
+
ok: false,
|
|
47762
|
+
issues
|
|
47763
|
+
};
|
|
47764
|
+
const parsedRemaining = remaining.flatMap((result) => result.ok ? [result.value] : []);
|
|
47765
|
+
return admitSdkEventRunGraph(input, [first.value, ...parsedRemaining]);
|
|
46877
47766
|
}
|
|
46878
47767
|
function toSdkEventUpsertBody(input) {
|
|
46879
47768
|
const [first, ...rest] = input.runs;
|
|
@@ -46886,50 +47775,296 @@ function toSdkEventUpsertBody(input) {
|
|
|
46886
47775
|
runs: [toBody(first), ...rest.map(toBody)]
|
|
46887
47776
|
};
|
|
46888
47777
|
}
|
|
47778
|
+
function toValidatedSdkEventRun(input, timingAuthority, bookingOffer, runIndex) {
|
|
47779
|
+
if (timingAuthority.bookingScope === "single_occurrence" && "name" in input) {
|
|
47780
|
+
return invalidEventGraph([
|
|
47781
|
+
"runs",
|
|
47782
|
+
String(runIndex),
|
|
47783
|
+
"name"
|
|
47784
|
+
], "Unrecognized key: \"name\"");
|
|
47785
|
+
}
|
|
47786
|
+
const { schedule: _schedule, occurrences: _occurrences, bookingScope: _bookingScope, name, bookingOffer: _bookingOffer, ...common } = input;
|
|
47787
|
+
const fields = {
|
|
47788
|
+
...common,
|
|
47789
|
+
bookingOffer,
|
|
47790
|
+
timingAuthority,
|
|
47791
|
+
...timingAuthority.kind === "authored_schedule" ? { schedule: timingAuthority.schedule } : { occurrences: timingAuthority.occurrences }
|
|
47792
|
+
};
|
|
47793
|
+
return {
|
|
47794
|
+
ok: true,
|
|
47795
|
+
value: timingAuthority.bookingScope === "whole_series" ? {
|
|
47796
|
+
...fields,
|
|
47797
|
+
bookingScope: "whole_series",
|
|
47798
|
+
...name === undefined ? {} : { name }
|
|
47799
|
+
} : {
|
|
47800
|
+
...fields,
|
|
47801
|
+
bookingScope: "single_occurrence"
|
|
47802
|
+
}
|
|
47803
|
+
};
|
|
47804
|
+
}
|
|
46889
47805
|
function parseSdkEventRunUpsertInput(input, runIndex, options) {
|
|
46890
|
-
|
|
46891
|
-
|
|
46892
|
-
const issues = [];
|
|
46893
|
-
if (timingResult.ok && bookingOfferResult.ok) {
|
|
46894
|
-
const { schedule: _schedule, occurrences: _occurrences, bookingScope: _bookingScope, bookingOffer: _bookingOffer, ...common } = input;
|
|
47806
|
+
if (input.bookingScope === undefined) {
|
|
47807
|
+
const issue$1 = timingIssue(["bookingScope"], "bookingScope is required");
|
|
46895
47808
|
return {
|
|
46896
|
-
ok:
|
|
46897
|
-
|
|
46898
|
-
|
|
46899
|
-
|
|
46900
|
-
|
|
46901
|
-
|
|
46902
|
-
|
|
46903
|
-
return {
|
|
46904
|
-
...toSdkEventRunUpsertBody(parsed),
|
|
46905
|
-
timingAuthority: parsed.timingAuthority
|
|
46906
|
-
};
|
|
46907
|
-
})()
|
|
47809
|
+
ok: false,
|
|
47810
|
+
issues: [{
|
|
47811
|
+
runIndex,
|
|
47812
|
+
source: "timing",
|
|
47813
|
+
...issue$1,
|
|
47814
|
+
issue: issue$1
|
|
47815
|
+
}]
|
|
46908
47816
|
};
|
|
46909
47817
|
}
|
|
46910
|
-
|
|
46911
|
-
|
|
47818
|
+
const timing = classifySdkEventTiming(input, options.schedule);
|
|
47819
|
+
const offer = classifySdkEventBookingOffer(input.bookingOffer);
|
|
47820
|
+
if (timing.ok && offer.ok) {
|
|
47821
|
+
return toValidatedSdkEventRun(input, {
|
|
47822
|
+
...timing.timingAuthority,
|
|
47823
|
+
bookingScope: input.bookingScope
|
|
47824
|
+
}, offer.bookingOffer, runIndex);
|
|
47825
|
+
}
|
|
47826
|
+
return {
|
|
47827
|
+
ok: false,
|
|
47828
|
+
issues: [...timing.ok ? [] : timing.issues.map((issue$1) => ({
|
|
46912
47829
|
runIndex,
|
|
46913
47830
|
source: "timing",
|
|
46914
|
-
path:
|
|
46915
|
-
message:
|
|
46916
|
-
issue:
|
|
46917
|
-
})))
|
|
46918
|
-
}
|
|
46919
|
-
if (!bookingOfferResult.ok) {
|
|
46920
|
-
issues.push(...bookingOfferResult.issues.map((bookingOfferIssue) => ({
|
|
47831
|
+
path: issue$1.path,
|
|
47832
|
+
message: issue$1.message,
|
|
47833
|
+
issue: issue$1
|
|
47834
|
+
})), ...offer.ok ? [] : offer.issues.map((issue$1) => ({
|
|
46921
47835
|
runIndex,
|
|
46922
47836
|
source: "bookingOffer",
|
|
46923
|
-
path:
|
|
46924
|
-
message:
|
|
46925
|
-
issue:
|
|
46926
|
-
}))
|
|
47837
|
+
path: issue$1.path,
|
|
47838
|
+
message: issue$1.message,
|
|
47839
|
+
issue: issue$1
|
|
47840
|
+
}))]
|
|
47841
|
+
};
|
|
47842
|
+
}
|
|
47843
|
+
|
|
47844
|
+
//#endregion
|
|
47845
|
+
//#region ../blocks/src/lib/typeGuards.ts
|
|
47846
|
+
/**
|
|
47847
|
+
* Strict record guard: excludes null, primitives, and arrays.
|
|
47848
|
+
*/
|
|
47849
|
+
function isRecord(value) {
|
|
47850
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
47851
|
+
}
|
|
47852
|
+
/**
|
|
47853
|
+
* Non-null object guard: includes arrays for behavior parity with legacy helpers.
|
|
47854
|
+
*
|
|
47855
|
+
* NOTE: This intentionally narrows to UnknownRecord for compatibility with existing
|
|
47856
|
+
* callsites even though arrays pass at runtime. Follow-up cleanup should replace
|
|
47857
|
+
* this API with a more precise predicate type and migrate consumers.
|
|
47858
|
+
*/
|
|
47859
|
+
function isObjectRecord(value) {
|
|
47860
|
+
return typeof value === "object" && value !== null;
|
|
47861
|
+
}
|
|
47862
|
+
/**
|
|
47863
|
+
* Coerces unknown input into a strict record, returning an empty object fallback.
|
|
47864
|
+
*/
|
|
47865
|
+
function asRecord(value) {
|
|
47866
|
+
return isRecord(value) ? value : {};
|
|
47867
|
+
}
|
|
47868
|
+
|
|
47869
|
+
//#endregion
|
|
47870
|
+
//#region ../blocks/src/system/manifest/richTextSchema.ts
|
|
47871
|
+
/**
|
|
47872
|
+
* Shared Rich Text Schema
|
|
47873
|
+
*
|
|
47874
|
+
* This module provides a single source of truth for TipTap rich text validation
|
|
47875
|
+
* across both the block-form editor and the block rendering system.
|
|
47876
|
+
*
|
|
47877
|
+
* Rich-text fields use one canonical root shape:
|
|
47878
|
+
* `{ type: 'doc', content: [...] }`.
|
|
47879
|
+
*/
|
|
47880
|
+
/**
|
|
47881
|
+
* TipTap document node schema (recursive structure)
|
|
47882
|
+
*
|
|
47883
|
+
* Supports the full TipTap document structure including:
|
|
47884
|
+
* - type: Node type (e.g., 'doc', 'paragraph', 'text')
|
|
47885
|
+
* - content: Nested array of child nodes
|
|
47886
|
+
* - text: Text content for text nodes
|
|
47887
|
+
* - attrs: Node attributes (e.g., alignment, color)
|
|
47888
|
+
* - marks: Text formatting marks (e.g., bold, italic)
|
|
47889
|
+
*/
|
|
47890
|
+
const TipTapMarkSchema = z.object({
|
|
47891
|
+
type: z.string().min(1),
|
|
47892
|
+
attrs: z.record(z.string(), z.unknown()).optional()
|
|
47893
|
+
}).strict();
|
|
47894
|
+
const TipTapNodeSchema = z.lazy(() => z.object({
|
|
47895
|
+
type: z.string().min(1),
|
|
47896
|
+
content: z.array(TipTapNodeSchema).optional(),
|
|
47897
|
+
text: z.string().optional(),
|
|
47898
|
+
attrs: z.record(z.string(), z.unknown()).optional(),
|
|
47899
|
+
marks: z.array(TipTapMarkSchema).optional()
|
|
47900
|
+
}).strict().superRefine((node, ctx) => {
|
|
47901
|
+
if (node.type === "doc") {
|
|
47902
|
+
ctx.addIssue({
|
|
47903
|
+
code: "custom",
|
|
47904
|
+
path: ["type"],
|
|
47905
|
+
message: "Document nodes are only valid at the rich-text root"
|
|
47906
|
+
});
|
|
47907
|
+
}
|
|
47908
|
+
if (node.type === "text") {
|
|
47909
|
+
if (node.text === undefined || node.text.length === 0) {
|
|
47910
|
+
ctx.addIssue({
|
|
47911
|
+
code: "custom",
|
|
47912
|
+
path: ["text"],
|
|
47913
|
+
message: "Text nodes require a non-empty text value"
|
|
47914
|
+
});
|
|
47915
|
+
}
|
|
47916
|
+
if (node.content !== undefined) {
|
|
47917
|
+
ctx.addIssue({
|
|
47918
|
+
code: "custom",
|
|
47919
|
+
path: ["content"],
|
|
47920
|
+
message: "Text nodes cannot contain child nodes"
|
|
47921
|
+
});
|
|
47922
|
+
}
|
|
47923
|
+
return;
|
|
47924
|
+
}
|
|
47925
|
+
if (node.text !== undefined) {
|
|
47926
|
+
ctx.addIssue({
|
|
47927
|
+
code: "custom",
|
|
47928
|
+
path: ["text"],
|
|
47929
|
+
message: "Only text nodes can contain a text value"
|
|
47930
|
+
});
|
|
47931
|
+
}
|
|
47932
|
+
}));
|
|
47933
|
+
/**
|
|
47934
|
+
* Canonical schema for a TipTap rich-text document root.
|
|
47935
|
+
*
|
|
47936
|
+
* Stricter than {@link TipTapNodeSchema}: `type` is literally `'doc'` and
|
|
47937
|
+
* `content` is required (possibly empty). This is the shape every producer
|
|
47938
|
+
* (dummy content, editor output, migrations) must emit, and the shape every
|
|
47939
|
+
* non-legacy consumer can rely on.
|
|
47940
|
+
*
|
|
47941
|
+
*/
|
|
47942
|
+
const RichTextDocSchema = z.object({
|
|
47943
|
+
type: z.literal("doc"),
|
|
47944
|
+
content: z.array(TipTapNodeSchema)
|
|
47945
|
+
}).strict();
|
|
47946
|
+
/**
|
|
47947
|
+
* Type guard for {@link RichTextDoc}.
|
|
47948
|
+
*
|
|
47949
|
+
* Returns `true` only for the canonical unwrapped form. The shared structural
|
|
47950
|
+
* contract lives in `@riverbankcms/core`; parity tests keep its dependency-free
|
|
47951
|
+
* guard aligned with this detailed Zod validator.
|
|
47952
|
+
*/
|
|
47953
|
+
function isRichTextDoc(value) {
|
|
47954
|
+
return RichTextDocSchema.safeParse(value).success;
|
|
47955
|
+
}
|
|
47956
|
+
/**
|
|
47957
|
+
* Build a canonical {@link RichTextDoc} from plain-text paragraphs.
|
|
47958
|
+
*
|
|
47959
|
+
* Single source of truth for constructing a TipTap doc from strings.
|
|
47960
|
+
* Used by:
|
|
47961
|
+
* - `@riverbankcms/dummy-content` (fixture body generators)
|
|
47962
|
+
* - `@riverbankcms/content-model` (default template `cta-full` content)
|
|
47963
|
+
*
|
|
47964
|
+
* Empty strings produce a paragraph with no `content` array — matching
|
|
47965
|
+
* the TipTap convention for empty paragraphs. The shape is exactly what
|
|
47966
|
+
* {@link RichTextDocSchema} validates, so the type and runtime check
|
|
47967
|
+
* never drift from the constructor.
|
|
47968
|
+
*/
|
|
47969
|
+
function createRichTextDoc(paragraphs) {
|
|
47970
|
+
return {
|
|
47971
|
+
type: "doc",
|
|
47972
|
+
content: paragraphs.map((text) => text ? {
|
|
47973
|
+
type: "paragraph",
|
|
47974
|
+
content: [{
|
|
47975
|
+
type: "text",
|
|
47976
|
+
text
|
|
47977
|
+
}]
|
|
47978
|
+
} : { type: "paragraph" })
|
|
47979
|
+
};
|
|
47980
|
+
}
|
|
47981
|
+
function createHardBreakNode() {
|
|
47982
|
+
return { type: "hardBreak" };
|
|
47983
|
+
}
|
|
47984
|
+
/**
|
|
47985
|
+
* Parse a small markdown subset into TipTap inline nodes.
|
|
47986
|
+
*
|
|
47987
|
+
* This intentionally supports only bold (`**text**`) because the SDK/content
|
|
47988
|
+
* import paths use it for lightweight default content, not full markdown.
|
|
47989
|
+
*/
|
|
47990
|
+
function parseRichTextInlineMarkdown(text) {
|
|
47991
|
+
const out = [];
|
|
47992
|
+
const pushText = (value, marks) => {
|
|
47993
|
+
if (!value) return;
|
|
47994
|
+
out.push(marks && marks.length > 0 ? {
|
|
47995
|
+
type: "text",
|
|
47996
|
+
text: value,
|
|
47997
|
+
marks
|
|
47998
|
+
} : {
|
|
47999
|
+
type: "text",
|
|
48000
|
+
text: value
|
|
48001
|
+
});
|
|
48002
|
+
};
|
|
48003
|
+
let rest = text;
|
|
48004
|
+
while (rest.length > 0) {
|
|
48005
|
+
const start = rest.indexOf("**");
|
|
48006
|
+
if (start === -1) {
|
|
48007
|
+
pushText(rest);
|
|
48008
|
+
break;
|
|
48009
|
+
}
|
|
48010
|
+
const end = rest.indexOf("**", start + 2);
|
|
48011
|
+
if (end === -1) {
|
|
48012
|
+
pushText(rest);
|
|
48013
|
+
break;
|
|
48014
|
+
}
|
|
48015
|
+
pushText(rest.slice(0, start));
|
|
48016
|
+
pushText(rest.slice(start + 2, end), [{ type: "bold" }]);
|
|
48017
|
+
rest = rest.slice(end + 2);
|
|
46927
48018
|
}
|
|
48019
|
+
return out;
|
|
48020
|
+
}
|
|
48021
|
+
function parseRichTextParagraphInlineMarkdown(text) {
|
|
48022
|
+
return text.split("\n").flatMap((line, index) => {
|
|
48023
|
+
const lineNodes = parseRichTextInlineMarkdown(line.trim());
|
|
48024
|
+
return index === 0 ? lineNodes : [createHardBreakNode(), ...lineNodes];
|
|
48025
|
+
});
|
|
48026
|
+
}
|
|
48027
|
+
/**
|
|
48028
|
+
* Convert a plain string with a tiny markdown subset to canonical TipTap JSON.
|
|
48029
|
+
*
|
|
48030
|
+
* Double newlines create semantic paragraphs. Single newlines remain inside the
|
|
48031
|
+
* current paragraph as TipTap `hardBreak` nodes for line-oriented content such
|
|
48032
|
+
* as addresses, opening hours, and contact details.
|
|
48033
|
+
*/
|
|
48034
|
+
function createRichTextDocFromMarkdown(markdown) {
|
|
48035
|
+
const normalized = markdown.replace(/\r\n/g, "\n").trim();
|
|
48036
|
+
if (!normalized) return {
|
|
48037
|
+
type: "doc",
|
|
48038
|
+
content: []
|
|
48039
|
+
};
|
|
48040
|
+
const paragraphs = normalized.split(/\n{2,}/).map((paragraph) => paragraph.trim()).filter(Boolean);
|
|
46928
48041
|
return {
|
|
46929
|
-
|
|
46930
|
-
|
|
48042
|
+
type: "doc",
|
|
48043
|
+
content: paragraphs.map((paragraph) => {
|
|
48044
|
+
const inline = parseRichTextParagraphInlineMarkdown(paragraph);
|
|
48045
|
+
return inline.length > 0 ? {
|
|
48046
|
+
type: "paragraph",
|
|
48047
|
+
content: inline
|
|
48048
|
+
} : { type: "paragraph" };
|
|
48049
|
+
})
|
|
46931
48050
|
};
|
|
46932
48051
|
}
|
|
48052
|
+
function buildRichTextSchema(options) {
|
|
48053
|
+
let schema = RichTextDocSchema;
|
|
48054
|
+
if (options?.required) {
|
|
48055
|
+
const label = options.label ?? "This field";
|
|
48056
|
+
schema = schema.refine((val) => {
|
|
48057
|
+
const content = val.content;
|
|
48058
|
+
if (!Array.isArray(content) || content.length === 0) return false;
|
|
48059
|
+
const first = content[0];
|
|
48060
|
+
if (content.length === 1 && isRecord(first) && first.type === "paragraph" && (!("content" in first) || first.content == null)) {
|
|
48061
|
+
return false;
|
|
48062
|
+
}
|
|
48063
|
+
return true;
|
|
48064
|
+
}, { message: `${label} is required` });
|
|
48065
|
+
}
|
|
48066
|
+
return schema;
|
|
48067
|
+
}
|
|
46933
48068
|
|
|
46934
48069
|
//#endregion
|
|
46935
|
-
export {
|
|
48070
|
+
export { createBlocksRef as $, isOnColorBackgroundCandidateToken as $i, looksLikeUuid as $n, asLayoutVariantKey as $r, ACCORDION_OPEN_ACCENT_THICKNESS as $t, parseAndPlanCommandBatchForTypes as A, opaqueSurfaceDeclarations as Ai, pageDesignIntentSchemaVersion as An, parseRelativeStoragePath as Ar, themeSchema as At, pageIdentifierForCommand as B, unsafeAsOpaqueButtonColourToken as Bi, parseCanonicalRuntimeBackground as Bn, generateShadowValue as Br, MQ_MD_DOWN as Bt, pageLinkSchema as C, borderColorStyle as Ci, buildTextContrastShadow as Cn, slugifyMediaIdentifier as Cr, resolvePublishedLook as Ct, sortRecord as D, textColorStyle as Di, resolveItemSurface as Dn, getMimeType as Dr, getGradientPreset as Dt, venueManagementFields as E, rgbColorValue as Ei, arrangementSlotNames as En, getExtensionForMimeType as Er, GRADIENT_PRESET_IDS as Et, eventManagementTiming as F, resolveThemeColorReferenceValue as Fi, sectionFactsForContent as Fn, parseSafeDownloadFilename as Fr, BREAKPOINT_LG as Ft, bookingPaymentCollectionOptionSchema as G, DEFAULT_SURFACE_TEXT_COLOR as Gi, runtimeBoxBackgroundSchema as Gn, backgroundAppearanceQuickColorTokenNames as Gr, getComponentBorderWidthPx as Gt, hasConfiguredBookingVertical as H, surfaceToneFromForegroundToken as Hi, resolveSectionPhotoPlacement as Hn, cardVariantRoleValues as Hr, MQ_SM_UP as Ht, blockIdentifierForCommand as I, resolveTokenOrCssColorValue as Ii, boundaryRuntimeMetricsForDecorativeTransition as In, generateCardCoreCss as Ir, BREAKPOINT_MD as It, require_react as J, surfaceForegroundInputFromResolved as Ji, stripStaleTransitionStyleGroup as Jn, resolveEffectiveKnobs as Jr, parseCustomCssRules as Jt, bookingPaymentTermsSchema as K, SURFACE_FOREGROUND_CSS_VARS as Ki, pageDesignEditorBackgroundOverrideOwner as Kn, parseBackgroundAppearanceColorToken as Kr, getComponentShadowVar as Kt, blockOrderIdentifiersForCommand as L, generateShadowValue$1 as Li, anglePolygonCss as Ln, getDefaultCardVariants as Lr, BREAKPOINT_SM as Lt, evaluateSiteCommandBatchExposure as M, formatButtonColourContractError as Mi, headerRootPaint as Mn, MAX_MANAGEMENT_MEDIA_UPLOAD_BYTES as Mr, generateMobileOverlayBackdropFilterFix as Mt, evaluateSiteCommandExposure as N, isCssColorLiteral as Ni, boundaryLayout as Nn, classifyKnownMimeType as Nr, getHeaderPaintTargets as Nt, stableStringify as O, textColorValue as Oi, resolveLookSlotSurfaces as On, asRecord$1 as Or, parseGradientPresetId as Ot, getSiteCommandMetadata as P, resolveOnColorForThemeToken as Pi, composeBoundary as Pn, managementMediaLibraryUploadLimitForMimeType as Pr, renderHeaderPaintTargetRules as Pt, createBlockRef as Q, expandPalette as Qi, deleteEnvSpecificKeys as Qn, asDesignBlockId as Qr, LABEL_FONT_SIZE_MAP as Qt, entryIdentifierForCommand as R, PUBLIC_BUTTON_ROLES as Ri, transitionCatalogueEntries as Rn, generateCardCss as Rr, BREAKPOINT_XL as Rt, normalizeLinkValue as S, backgroundColorStyle as Si, footerForegroundCandidates as Sn, resolveMediaIdentifier as Sr, resolveModeArrangement as St, isEventVisibility as T, mergeStyles as Ti, arrangementLookHooks as Tn, resolveVideoSelectionIntentForMediaField as Tr, gradientToCss as Tt, eventCommandScheduleSchema as U, buildThemeTokens as Ui, boxBackgroundOverlaySchema as Un, normalizeCardRole as Ur, MQ_TABLET_ONLY as Ut, pagePathForCommand as V, selectLogoVariant as Vi, resolveSectionBackground as Vn, cardRoleSchema as Vr, MQ_SM_DOWN as Vt, eventBookingOfferIntentSchema as W, defaultThemeTokens as Wi, boxBackgroundSchema as Wn, backgroundAppearanceColorTokenNames as Wr, headerVariantValues as Wt, generateCssVars as X, surfaceForegroundValue as Xi, summarizePortableMediaReferences as Xn, cardListKnobBlocks as Xr, INPUT_FONT_SIZE_MAP as Xt, pickShadeTowardBackground as Y, surfaceForegroundStyle as Yi, collectPortableMediaReferencesFromContent as Yn, cardListFamilyBlocks as Yr, FONT_WEIGHT_MAP as Yt, ianaTimezoneSchema as Z, surfaceForegroundValueWithOpacity as Zi, walkAndCollectImageAttrs as Zn, asAppearancePresetId as Zr, INPUT_SPACING_MAP as Zt, internalResolvedLinkSchema as _, resolveSurface as _i, buildGoogleFontFamilyQuery as _n, mediaTypeDiscriminants as _r, mergeHeaderNavTypographyPreference as _t, isRecord as a, parseThemeColorToken as aa, defineNoBlockDesignCapability as ai, generateButtonActionLayoutCss as an, getDirectImageUrlForRelativePath as ar, createFormRef as at, isResolvedInternalLinkEntityType as b, safeTokenOr as bi, buttonStyleSelectionSchema as bn, parseCanonicalMediaIdentifier as br, readStoredMode as bt, sdkEventOccurrenceInputSchema as c, featuresFromHex as ca, featureCardCompositionTreatmentValues as ci, resolvedButtonColourDeclarations as cn, isSiteScopedDirectImageStoragePath as cr, createSiteCommandSiteRef as ct, classifySdkEventBookingOffer as d, __commonJSMin as da, makeBoundaryId as di, parseThemeButtonVariantId as dn, mediaSchema as dr, slugPart as dt, onColorTokenName as ea, asPageFlowPresetId as ei, ACCORDION_SPACING_MAP as en, rotateNormalizedPoint as er, createCommandRef as et, RESOLVED_INTERNAL_LINK_ENTITY_TYPES as f, __toESM as fa, offeringsPreviewCompositionTreatmentValues as fi, themeButtonExtraClassesWithTrailingIcon as fn, persistableMediaSchema as fr, effectiveHeaderNavLinkStyle as ft, internalLinkSchema as g, visibleHeadingDecorationFamilyValues as gi, skinTokenCssVars as gn, resolveManagedMediaReference as gr, readOpeningForegroundProjection as gt, externalLinkSchema as h, toNonEmptyReadonlyArray as hi, parseThemeForPersistence as hn, indexRenderableMediaAssets as hr, transparentHeaderForegroundInput as ht, isObjectRecord as i, resolveOpaqueSurfaceHex as ia, defineFrameCapability as ii, ICON_SIZE_PX as in, resolveMediaTransformForAspect as ir, createFooterRef as it, mapEventCommandContent as j, compileButtonColourStates as ji, footerPreferencesSchema as jn, FILE_SIZE_LIMITS as jr, generateHeaderScrollTreatmentStyles as jt, createDryRunReport as k, opaqueSurfaceContextFromTheme as ki, pageDesignBoundaryTreatmentSchema as kn, normalizeAmbiguousStoragePathForSite as kr, deriveSiteStyleBlockPolicy as kt, sdkEventUpsertOptionalFieldSchemas as l, hexToRgb as la, headingDecorationColorTokenValues as li, resolvedButtonFocusDeclarations as ln, imageMediaSchema as lr, createVenueRef as lt, entryLinkSchema as m, tileTreatmentValues as mi, themeButtonVariantClassNames as mn, buildRenderableMediaAssetIndex as mr, headerLeafTextColor as mt, createRichTextDoc as n, ORDINARY_TEXT_MIN_CONTRAST_RATIO as na, assertNever$1 as ni, ACCORDION_TRIGGER_LETTER_SPACING as nn, isExplicitRectCrop as nr, createEventCategoryRef as nt, classifySdkEventTiming as o, parseBlockColorToken as oa, eventListTreatmentValues as oi, generateButtonCss as on, getDirectImageUrlForSiteScopedPath as or, createNavigationRef as ot, customLinkSchema as p, testimonialsCompositionTreatmentValues as pi, themeButtonSizeClassName as pn, runtimeMediaSchema as pr, headerForegroundCandidates as pt, require_jsx_runtime as q, surfaceForegroundDeclarations as qi, siteChromeBackgroundOverrideOwner as qn, defineBlockDesignMetadata as qr, parseBlockCustomCssRules as qt, isRichTextDoc as r, contrastRatio as ra, defineBlockDesignCapability as ri, ICON_CONFIG as rn, parseAspectRatioValue as rr, createEventSeriesRef as rt, sdkCourseBookingSettingsSchema as s, parseColorTokenParts as sa, eyebrowTreatmentValues as si, RESOLVED_BUTTON_DISABLED_DECLARATIONS as sn, getImageUrl as sr, createPageRef as st, RichTextDocSchema as t, getTextColorForBackground as ta, asSiteStyleId as ti, ACCORDION_TRIGGER_FONT_SCALE as tn, normalizeWidthCandidates as tr, createContentEntryRef as tt, classifySdkEventSchedule as u, oklchToHexGamut as ua, introCompositionTreatmentValues as ui, generateDefaultButtonSystem as un, mediaPosterSchema as ur, refSlug as ut, internalRouteOnlyLinkSchema as v, surfaceDecorationColors as vi, generateFontFaceCss as vn, mediaIdentifierSchema as vr, readHeaderNavFontSizePreference as vt, eventVisibilitySchema as w, cssVarValue as wi, generateNavLinkCSS as wn, deriveVideoSlotPolicy as wr, requireCuratedSiteStyle as wt, linkSchema as x, TokenResolver as xi, generateFooterCss as xn, parseMediaIdentifier as xr, resolveEffectiveArrangement as xt, isInternalResolvedLinkValue as y, resolveSurfaceForeground as yi, getFontWidthRange as yn, buildMediaIdentifierFromFilename as yr, arrangementManifestFromVariants as yt, pageIdentifierForBlockCommand as z, buttonVariantIdSchema as zi, deriveSectionGround as zn, renderCssDeclarations as zr, MQ_LG_UP as zt };
|