@riverbankcms/sdk 0.70.3 → 0.70.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_dts/api/src/contentTypes.d.ts +2 -1
- package/dist/_dts/block-form/src/client/index.d.ts +1 -1
- package/dist/_dts/block-form/src/fields/types.d.ts +14 -2
- package/dist/_dts/block-form/src/registry/schemas.d.ts +2 -0
- package/dist/_dts/block-form/src/widgets/MediaField/mediaFieldDefaults.d.ts +2 -2
- package/dist/_dts/block-form/src/widgets/MediaField/mediaFieldSchema.d.ts +2 -2
- package/dist/_dts/blocks/src/lib/media.d.ts +1 -1
- package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/cart.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/collection.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/cta-full.d.ts +1 -30727
- package/dist/_dts/blocks/src/system/blocks/events/event-spotlight.d.ts +11 -30827
- package/dist/_dts/blocks/src/system/blocks/faq.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/file-download.d.ts +3 -3
- package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +106 -1
- package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/blocks/shop.d.ts +1829 -149
- package/dist/_dts/blocks/src/system/defineBlock.d.ts +3 -3
- package/dist/_dts/blocks/src/system/fragments/library/card.d.ts +2 -30793
- package/dist/_dts/blocks/src/system/fragments/library/ctaRow.d.ts +2 -30727
- package/dist/_dts/blocks/src/system/fragments/library/feedbackCallout.d.ts +2 -30779
- package/dist/_dts/blocks/src/system/fragments/library/heroCtaRow.d.ts +33 -30743
- package/dist/_dts/blocks/src/system/fragments/library/sectionState.d.ts +2 -30770
- package/dist/_dts/blocks/src/system/fragments/types.d.ts +8 -7
- package/dist/_dts/blocks/src/system/manifest/derivedContent.d.ts +7 -5
- package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/manifest/schema.d.ts +192 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/file-download.d.ts +1 -1
- package/dist/_dts/content-model/src/content-types/schema.d.ts +7 -0
- package/dist/_dts/content-model/src/contentManifest.d.ts +4 -1
- package/dist/_dts/content-model/src/templates/bindingTypeCompatibility.d.ts +1 -1
- package/dist/_dts/core/src/index.d.ts +1 -1
- package/dist/_dts/core/src/planner.d.ts +4 -0
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +53 -20
- package/dist/_dts/editor-blocks/src/index.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/media/MediaField.d.ts +6 -5
- package/dist/_dts/media-core/src/videoSlotPolicy.d.ts +0 -1
- package/dist/_dts/media-editor/src/context.d.ts +4 -1
- package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +8 -1
- package/dist/_dts/media-react/src/index.d.ts +1 -5
- package/dist/_dts/preview-next/src/client/widgets/PreviewMediaField.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +1 -0
- package/dist/_dts/sdk/src/config/field-definitions.d.ts +6 -2
- package/dist/_dts/sdk/src/config/typed-entries.d.ts +4 -2
- package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +2 -1
- package/dist/_dts/sdk/src/manifest/prompt/examples/cta.d.ts +5 -5
- package/dist/_dts/sdk/src/manifest/prompt/examples/features-grid.d.ts +2 -2
- package/dist/_dts/sdk/src/manifest/prompt/examples/hero.d.ts +2 -2
- package/dist/_dts/sdk/src/manifest/prompt/examples/pricing.d.ts +10 -10
- package/dist/_dts/sdk/src/manifest/prompt/examples/testimonials.d.ts +4 -4
- package/dist/_dts/sdk/src/manifest/validation/output-schema.d.ts +11 -1
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +2 -1
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/cli/index.mjs +395 -190
- package/dist/cli/init-docs/content/workflow-preview-mode.md +167 -0
- package/dist/client/client.mjs +243 -203
- package/dist/client/hooks.mjs +172 -121
- package/dist/client/rendering/client.mjs +148 -112
- package/dist/client/rendering/islands.mjs +80 -31
- package/dist/client/rendering.mjs +242 -202
- package/dist/preview-next/client/runtime.mjs +386 -1135
- package/dist/server/components.mjs +219 -171
- package/dist/server/config-template-validation.mjs +31 -1
- package/dist/server/config-validation.mjs +172 -121
- package/dist/server/config.mjs +172 -121
- package/dist/server/data.mjs +172 -121
- package/dist/server/index.mjs +1 -1
- package/dist/server/next.mjs +220 -172
- package/dist/server/page-converter.mjs +379 -185
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +219 -171
- package/dist/server/rendering.mjs +219 -171
- package/dist/server/routing.mjs +175 -124
- package/dist/server/server.mjs +173 -122
- package/package.json +2 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -916,6 +916,9 @@ var init_repeaterGrid = __esm({
|
|
|
916
916
|
DEFAULT_REPEATER_GRID_COLUMN_FIELD_ID = "gridColumn";
|
|
917
917
|
}
|
|
918
918
|
});
|
|
919
|
+
function isDisplayMediaKind(kind) {
|
|
920
|
+
return DISPLAY_MEDIA_KINDS.includes(kind);
|
|
921
|
+
}
|
|
919
922
|
function assertNeverSelectSource(value) {
|
|
920
923
|
throw new Error(`Unhandled select source: ${JSON.stringify(value)}`);
|
|
921
924
|
}
|
|
@@ -927,6 +930,7 @@ function getFieldSchemaInternal() {
|
|
|
927
930
|
textFieldSchema,
|
|
928
931
|
richTextFieldSchema,
|
|
929
932
|
mediaFieldSchema,
|
|
933
|
+
fileFieldSchema,
|
|
930
934
|
booleanFieldSchema,
|
|
931
935
|
numberFieldSchema,
|
|
932
936
|
dateFieldSchema,
|
|
@@ -993,13 +997,32 @@ function createSdkSelectField(input) {
|
|
|
993
997
|
})
|
|
994
998
|
);
|
|
995
999
|
}
|
|
996
|
-
var visibilityLevels, siteOptionSources, mediaDeliverySchema, selectOptionSchema, selectSourceSchema, uiSchema, baseFieldSchema, textFieldSchema, richTextFieldSchema, mediaFieldSchema, booleanFieldSchema, dateFieldSchema, timeFieldSchema, dateTimeFieldSchema, slugFieldSchema, urlFieldSchema, linkFieldSchema, selectFieldSchema, referenceFieldSchema, itemTypeSchema, repeaterFieldSchema, groupFieldSchema, modalFieldSchema, numberFieldSchema, tabDefinitionSchema, tabGroupFieldSchema, presetOptionSchema, presetOrCustomFieldSchema, contentTypeSelectFieldSchema, entryPickerFieldSchema, _fieldSchemaInternal, fieldSchema, slotSchema, typographyTokens, colorTokens, spacingTokens, radiusTokens, styleTokenSchema, behaviourSchema, blockCategoryEnum;
|
|
1000
|
+
var visibilityLevels, MEDIA_KINDS, DISPLAY_MEDIA_KINDS, PUBLIC_FILE_FIELD_KINDS, siteOptionSources, mediaDeliverySchema, selectOptionSchema, selectSourceSchema, uiSchema, baseFieldSchema, textFieldSchema, richTextFieldSchema, mediaFieldSchema, fileFieldSchema, booleanFieldSchema, dateFieldSchema, timeFieldSchema, dateTimeFieldSchema, slugFieldSchema, urlFieldSchema, linkFieldSchema, selectFieldSchema, referenceFieldSchema, itemTypeSchema, repeaterFieldSchema, groupFieldSchema, modalFieldSchema, numberFieldSchema, tabDefinitionSchema, tabGroupFieldSchema, presetOptionSchema, presetOrCustomFieldSchema, contentTypeSelectFieldSchema, entryPickerFieldSchema, _fieldSchemaInternal, fieldSchema, slotSchema, typographyTokens, colorTokens, spacingTokens, radiusTokens, styleTokenSchema, behaviourSchema, blockCategoryEnum;
|
|
997
1001
|
var init_schema2 = __esm({
|
|
998
1002
|
"../blocks/src/system/manifest/schema.ts"() {
|
|
999
1003
|
init_src2();
|
|
1000
1004
|
init_node();
|
|
1001
1005
|
init_repeaterGrid();
|
|
1002
1006
|
visibilityLevels = ["admin", "designer", "author"];
|
|
1007
|
+
MEDIA_KINDS = [
|
|
1008
|
+
"image",
|
|
1009
|
+
"video",
|
|
1010
|
+
"audio",
|
|
1011
|
+
"document",
|
|
1012
|
+
"spreadsheet",
|
|
1013
|
+
"archive"
|
|
1014
|
+
];
|
|
1015
|
+
DISPLAY_MEDIA_KINDS = [
|
|
1016
|
+
"image",
|
|
1017
|
+
"video",
|
|
1018
|
+
"audio"
|
|
1019
|
+
];
|
|
1020
|
+
PUBLIC_FILE_FIELD_KINDS = [
|
|
1021
|
+
"document",
|
|
1022
|
+
"spreadsheet",
|
|
1023
|
+
"archive",
|
|
1024
|
+
"audio"
|
|
1025
|
+
];
|
|
1003
1026
|
siteOptionSources = [
|
|
1004
1027
|
"eventCategories",
|
|
1005
1028
|
"venues",
|
|
@@ -1160,11 +1183,19 @@ var init_schema2 = __esm({
|
|
|
1160
1183
|
});
|
|
1161
1184
|
mediaFieldSchema = baseFieldSchema.extend({
|
|
1162
1185
|
type: z.literal("media"),
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1186
|
+
// Keep full MEDIA_KINDS parse compatibility for pre-file-field manifests.
|
|
1187
|
+
// New authoring surfaces should use `file.fileKinds` for document/archive
|
|
1188
|
+
// style assets, but old saved schemas must not fail to open.
|
|
1189
|
+
mediaKinds: z.array(z.enum(MEDIA_KINDS)).default(["image"]).transform((kinds) => {
|
|
1190
|
+
const displayKinds = kinds.filter(isDisplayMediaKind);
|
|
1191
|
+
return displayKinds.length > 0 ? displayKinds : ["image"];
|
|
1192
|
+
}),
|
|
1166
1193
|
aspectRatio: z.string().optional()
|
|
1167
1194
|
});
|
|
1195
|
+
fileFieldSchema = baseFieldSchema.extend({
|
|
1196
|
+
type: z.literal("file"),
|
|
1197
|
+
fileKinds: z.array(z.enum(PUBLIC_FILE_FIELD_KINDS)).default([...PUBLIC_FILE_FIELD_KINDS])
|
|
1198
|
+
});
|
|
1168
1199
|
booleanFieldSchema = baseFieldSchema.extend({
|
|
1169
1200
|
type: z.literal("boolean")
|
|
1170
1201
|
});
|
|
@@ -9269,13 +9300,19 @@ function defineFragment(config2) {
|
|
|
9269
9300
|
function scopeFragmentFields(fragment, scope) {
|
|
9270
9301
|
const normalizedScope = scope.trim();
|
|
9271
9302
|
if (!normalizedScope) {
|
|
9272
|
-
return fragment.fields.map(
|
|
9303
|
+
return fragment.fields.map(
|
|
9304
|
+
(field) => cloneFieldDefinition2(field)
|
|
9305
|
+
);
|
|
9273
9306
|
}
|
|
9274
|
-
return fragment.fields.map(
|
|
9307
|
+
return fragment.fields.map(
|
|
9308
|
+
(field) => prefixFieldId(field, normalizedScope)
|
|
9309
|
+
);
|
|
9275
9310
|
}
|
|
9276
9311
|
function scopeFragmentLayout(fragment, scope) {
|
|
9277
9312
|
const normalizedScope = scope.trim();
|
|
9278
|
-
return fragment.layout.map(
|
|
9313
|
+
return fragment.layout.map(
|
|
9314
|
+
(node) => cloneAndScopeNode(node, normalizedScope)
|
|
9315
|
+
);
|
|
9279
9316
|
}
|
|
9280
9317
|
function validateFieldDefinitions(fields3, fragmentId) {
|
|
9281
9318
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -9357,7 +9394,9 @@ function cloneAndScopeNode(node, scope) {
|
|
|
9357
9394
|
...node
|
|
9358
9395
|
};
|
|
9359
9396
|
if (node.children) {
|
|
9360
|
-
cloned.children = node.children.map(
|
|
9397
|
+
cloned.children = node.children.map(
|
|
9398
|
+
(child) => cloneAndScopeNode(child, scope)
|
|
9399
|
+
);
|
|
9361
9400
|
}
|
|
9362
9401
|
if (node.props) {
|
|
9363
9402
|
cloned.props = scopePropBindings(node.props, scope);
|
|
@@ -9383,7 +9422,9 @@ function scopeBinding(binding, scope) {
|
|
|
9383
9422
|
const cloned = {
|
|
9384
9423
|
...binding,
|
|
9385
9424
|
transforms: binding.transforms?.map(
|
|
9386
|
-
(step) => ({
|
|
9425
|
+
(step) => ({
|
|
9426
|
+
...step
|
|
9427
|
+
})
|
|
9387
9428
|
) ?? []
|
|
9388
9429
|
};
|
|
9389
9430
|
cloned.from = scopeContentPath(binding.from, scope);
|
|
@@ -9427,7 +9468,9 @@ function scopePropValue(value, scope) {
|
|
|
9427
9468
|
};
|
|
9428
9469
|
}
|
|
9429
9470
|
const result = {};
|
|
9430
|
-
for (const [key, entry] of Object.entries(
|
|
9471
|
+
for (const [key, entry] of Object.entries(
|
|
9472
|
+
value
|
|
9473
|
+
)) {
|
|
9431
9474
|
result[key] = scopePropValue(entry, scope);
|
|
9432
9475
|
}
|
|
9433
9476
|
return result;
|
|
@@ -9473,13 +9516,18 @@ var init_types13 = __esm({
|
|
|
9473
9516
|
loader: dataLoaderSchema.optional()
|
|
9474
9517
|
});
|
|
9475
9518
|
fragmentConfigSchema = z.object({
|
|
9476
|
-
id: z.string().min(1, "Fragment id is required").regex(
|
|
9519
|
+
id: z.string().min(1, "Fragment id is required").regex(
|
|
9520
|
+
FRAGMENT_ID_PATTERN,
|
|
9521
|
+
"Fragment id must be alphanumeric with optional . _ - separators"
|
|
9522
|
+
),
|
|
9477
9523
|
title: z.string().optional(),
|
|
9478
9524
|
description: z.string().optional(),
|
|
9479
9525
|
category: z.enum(["content", "media", "interactive", "layout"]).optional(),
|
|
9480
9526
|
icon: z.string().optional(),
|
|
9481
9527
|
fields: fieldSchema.array().default([]),
|
|
9482
|
-
layout: z.union([NodeSchema, NodeSchema.array()]).transform(
|
|
9528
|
+
layout: z.union([NodeSchema, NodeSchema.array()]).transform(
|
|
9529
|
+
(value) => Array.isArray(value) ? value : [value]
|
|
9530
|
+
),
|
|
9483
9531
|
data: fragmentDataSchema.optional()
|
|
9484
9532
|
});
|
|
9485
9533
|
FragmentConfigError = class extends Error {
|
|
@@ -9949,34 +9997,35 @@ var init_ctaRow2 = __esm({
|
|
|
9949
9997
|
});
|
|
9950
9998
|
|
|
9951
9999
|
// ../blocks/src/system/fragments/library/heroCtaRow.ts
|
|
9952
|
-
var heroCtaRowFragment;
|
|
10000
|
+
var heroCtaFields, heroCtaRowFragment;
|
|
9953
10001
|
var init_heroCtaRow = __esm({
|
|
9954
10002
|
"../blocks/src/system/fragments/library/heroCtaRow.ts"() {
|
|
9955
10003
|
init_types13();
|
|
9956
10004
|
init_fragments();
|
|
9957
10005
|
init_ctas();
|
|
10006
|
+
heroCtaFields = [
|
|
10007
|
+
createCtasRepeater({
|
|
10008
|
+
label: "Calls to action",
|
|
10009
|
+
itemLabel: "CTA",
|
|
10010
|
+
maxItems: 3,
|
|
10011
|
+
button: {
|
|
10012
|
+
variants: [
|
|
10013
|
+
{ value: "default", label: "Default" },
|
|
10014
|
+
{ value: "primary", label: "Primary" },
|
|
10015
|
+
{ value: "secondary", label: "Secondary" },
|
|
10016
|
+
{ value: "outline", label: "Outline" }
|
|
10017
|
+
],
|
|
10018
|
+
defaultVariant: "default",
|
|
10019
|
+
includeSize: true,
|
|
10020
|
+
defaultSize: "lg"
|
|
10021
|
+
}
|
|
10022
|
+
})
|
|
10023
|
+
];
|
|
9958
10024
|
heroCtaRowFragment = defineFragment({
|
|
9959
10025
|
id: "heroCtaRow",
|
|
9960
10026
|
title: "Hero CTAs",
|
|
9961
10027
|
description: "Repeatable hero calls to action rendered inline.",
|
|
9962
|
-
fields:
|
|
9963
|
-
createCtasRepeater({
|
|
9964
|
-
label: "Calls to action",
|
|
9965
|
-
itemLabel: "CTA",
|
|
9966
|
-
maxItems: 3,
|
|
9967
|
-
button: {
|
|
9968
|
-
variants: [
|
|
9969
|
-
{ value: "default", label: "Default" },
|
|
9970
|
-
{ value: "primary", label: "Primary" },
|
|
9971
|
-
{ value: "secondary", label: "Secondary" },
|
|
9972
|
-
{ value: "outline", label: "Outline" }
|
|
9973
|
-
],
|
|
9974
|
-
defaultVariant: "default",
|
|
9975
|
-
includeSize: true,
|
|
9976
|
-
defaultSize: "lg"
|
|
9977
|
-
}
|
|
9978
|
-
})
|
|
9979
|
-
],
|
|
10028
|
+
fields: heroCtaFields,
|
|
9980
10029
|
layout: [
|
|
9981
10030
|
ctaRow({
|
|
9982
10031
|
collectionPath: "content.ctas",
|
|
@@ -12569,8 +12618,7 @@ var init_media2 = __esm({
|
|
|
12569
12618
|
"document",
|
|
12570
12619
|
"spreadsheet",
|
|
12571
12620
|
"archive",
|
|
12572
|
-
"audio"
|
|
12573
|
-
"video"
|
|
12621
|
+
"audio"
|
|
12574
12622
|
];
|
|
12575
12623
|
hotspotSchema2 = z41.object({
|
|
12576
12624
|
x: z41.number().min(0).max(1),
|
|
@@ -24623,6 +24671,7 @@ function deriveFieldValidationPlan(field, path24 = [field.id]) {
|
|
|
24623
24671
|
case "richText":
|
|
24624
24672
|
return makePlan("richText", "object", field, path24, required, commonConstraints(required, { kind: "richTextDoc" }));
|
|
24625
24673
|
case "media":
|
|
24674
|
+
case "file":
|
|
24626
24675
|
return makePlan("media", "object", field, path24, required, commonConstraints(required, { kind: "mediaObject" }));
|
|
24627
24676
|
case "link":
|
|
24628
24677
|
return makePlan("link", "object", field, path24, required, commonConstraints(required, { kind: "linkObject" }));
|
|
@@ -29319,104 +29368,107 @@ init_fragments();
|
|
|
29319
29368
|
init_boxStyles();
|
|
29320
29369
|
init_defineBlock();
|
|
29321
29370
|
init_shared3();
|
|
29322
|
-
var
|
|
29371
|
+
var eventSpotlightFields = [
|
|
29372
|
+
...sectionHeaderFields("Upcoming Events"),
|
|
29373
|
+
{
|
|
29374
|
+
id: "maxEvents",
|
|
29375
|
+
type: "select",
|
|
29376
|
+
label: "Events to display",
|
|
29377
|
+
description: "Number of events to show",
|
|
29378
|
+
required: false,
|
|
29379
|
+
multiple: false,
|
|
29380
|
+
defaultValue: "3",
|
|
29381
|
+
options: [
|
|
29382
|
+
{ value: "1", label: "1 event" },
|
|
29383
|
+
{ value: "2", label: "2 events" },
|
|
29384
|
+
{ value: "3", label: "3 events" },
|
|
29385
|
+
{ value: "4", label: "4 events" },
|
|
29386
|
+
{ value: "5", label: "5 events" },
|
|
29387
|
+
{ value: "6", label: "6 events" }
|
|
29388
|
+
],
|
|
29389
|
+
ui: { intent: "display" }
|
|
29390
|
+
},
|
|
29391
|
+
{
|
|
29392
|
+
id: "ctaLabel",
|
|
29393
|
+
type: "text",
|
|
29394
|
+
label: "Section button text",
|
|
29395
|
+
description: "Optional button shown below the spotlight cards",
|
|
29396
|
+
required: false,
|
|
29397
|
+
multiline: false,
|
|
29398
|
+
maxLength: 40,
|
|
29399
|
+
ui: { intent: "content" }
|
|
29400
|
+
},
|
|
29401
|
+
{
|
|
29402
|
+
id: "ctaUrl",
|
|
29403
|
+
type: "link",
|
|
29404
|
+
label: "Section button destination",
|
|
29405
|
+
required: false,
|
|
29406
|
+
ui: { intent: "display" }
|
|
29407
|
+
},
|
|
29408
|
+
layoutField,
|
|
29409
|
+
columnsField(["2", "3"]),
|
|
29410
|
+
...cardStylingFields,
|
|
29411
|
+
...eventDisplayFields,
|
|
29412
|
+
emptyStateField,
|
|
29413
|
+
sectionStylesField({
|
|
29414
|
+
id: "_sectionStyles",
|
|
29415
|
+
label: "Section styles"
|
|
29416
|
+
})
|
|
29417
|
+
];
|
|
29418
|
+
var eventSpotlightLayout = [
|
|
29419
|
+
styledSection({
|
|
29420
|
+
children: sectionContainer([
|
|
29421
|
+
// Optional heading
|
|
29422
|
+
text(
|
|
29423
|
+
{ as: "h2" },
|
|
29424
|
+
bind("content.heading"),
|
|
29425
|
+
when("content.heading")
|
|
29426
|
+
),
|
|
29427
|
+
// Optional description
|
|
29428
|
+
richText(
|
|
29429
|
+
{ className: "rb-prose rb-max-w-none" },
|
|
29430
|
+
bind("content.description"),
|
|
29431
|
+
when("content.description")
|
|
29432
|
+
),
|
|
29433
|
+
// Event spotlight component
|
|
29434
|
+
el("event-spotlight", {
|
|
29435
|
+
events: { $bind: { from: "data.events" } },
|
|
29436
|
+
layout: { $bind: { from: "content.layout", fallback: "grid" } },
|
|
29437
|
+
columns: { $bind: { from: "content.columns", fallback: "3" } },
|
|
29438
|
+
cardVariant: { $bind: { from: "content.cardVariant", fallback: "default" } },
|
|
29439
|
+
buttonVariant: { $bind: { from: "content.buttonVariant", fallback: "primary" } },
|
|
29440
|
+
buttonText: { $bind: { from: "content.buttonText", fallback: "View event" } },
|
|
29441
|
+
ctaLabel: { $bind: { from: "content.ctaLabel" } },
|
|
29442
|
+
ctaUrl: { $bind: { from: "content.ctaUrl", transforms: [{ id: "links.resolve" }] } },
|
|
29443
|
+
showVenue: { $bind: { from: "content.showVenue" } },
|
|
29444
|
+
showMap: { $bind: { from: "content.showMap" } },
|
|
29445
|
+
showCapacity: { $bind: { from: "content.showCapacity" } },
|
|
29446
|
+
emptyMessage: { $bind: { from: "content.emptyMessage" } }
|
|
29447
|
+
})
|
|
29448
|
+
], {
|
|
29449
|
+
gap: "lg"
|
|
29450
|
+
}),
|
|
29451
|
+
// sectionContainer (rb-container) already provides horizontal padding
|
|
29452
|
+
baseClass: "",
|
|
29453
|
+
spacing: "comfortable"
|
|
29454
|
+
})
|
|
29455
|
+
];
|
|
29456
|
+
var eventSpotlightConfig = {
|
|
29323
29457
|
id: "block.event-spotlight",
|
|
29324
29458
|
version: "1.1.0",
|
|
29325
29459
|
title: "Event Spotlight",
|
|
29326
29460
|
titleSource: "heading",
|
|
29327
29461
|
description: "Feature a few upcoming events on your homepage",
|
|
29328
29462
|
skipSectionStyles: true,
|
|
29329
|
-
additionalFields:
|
|
29330
|
-
...sectionHeaderFields("Upcoming Events"),
|
|
29331
|
-
{
|
|
29332
|
-
id: "maxEvents",
|
|
29333
|
-
type: "select",
|
|
29334
|
-
label: "Events to display",
|
|
29335
|
-
description: "Number of events to show",
|
|
29336
|
-
required: false,
|
|
29337
|
-
multiple: false,
|
|
29338
|
-
defaultValue: "3",
|
|
29339
|
-
options: [
|
|
29340
|
-
{ value: "1", label: "1 event" },
|
|
29341
|
-
{ value: "2", label: "2 events" },
|
|
29342
|
-
{ value: "3", label: "3 events" },
|
|
29343
|
-
{ value: "4", label: "4 events" },
|
|
29344
|
-
{ value: "5", label: "5 events" },
|
|
29345
|
-
{ value: "6", label: "6 events" }
|
|
29346
|
-
],
|
|
29347
|
-
ui: { intent: "display" }
|
|
29348
|
-
},
|
|
29349
|
-
{
|
|
29350
|
-
id: "ctaLabel",
|
|
29351
|
-
type: "text",
|
|
29352
|
-
label: "Section button text",
|
|
29353
|
-
description: "Optional button shown below the spotlight cards",
|
|
29354
|
-
required: false,
|
|
29355
|
-
multiline: false,
|
|
29356
|
-
maxLength: 40,
|
|
29357
|
-
ui: { intent: "content" }
|
|
29358
|
-
},
|
|
29359
|
-
{
|
|
29360
|
-
id: "ctaUrl",
|
|
29361
|
-
type: "link",
|
|
29362
|
-
label: "Section button destination",
|
|
29363
|
-
required: false,
|
|
29364
|
-
ui: { intent: "display" }
|
|
29365
|
-
},
|
|
29366
|
-
layoutField,
|
|
29367
|
-
columnsField(["2", "3"]),
|
|
29368
|
-
...cardStylingFields,
|
|
29369
|
-
...eventDisplayFields,
|
|
29370
|
-
emptyStateField,
|
|
29371
|
-
sectionStylesField({
|
|
29372
|
-
id: "_sectionStyles",
|
|
29373
|
-
label: "Section styles"
|
|
29374
|
-
})
|
|
29375
|
-
],
|
|
29463
|
+
additionalFields: eventSpotlightFields,
|
|
29376
29464
|
styleTokens: { background: "surface", typography: "body", spacing: "md" },
|
|
29377
29465
|
behaviours: { supportsThemeSwitching: true, inlineEditing: false, animation: false, paletteHidden: false },
|
|
29378
29466
|
category: "content",
|
|
29379
29467
|
tags: ["events", "featured", "homepage", "spotlight", "upcoming"],
|
|
29380
29468
|
icon: "Star",
|
|
29381
|
-
layout:
|
|
29382
|
-
|
|
29383
|
-
|
|
29384
|
-
// Optional heading
|
|
29385
|
-
text(
|
|
29386
|
-
{ as: "h2" },
|
|
29387
|
-
bind("content.heading"),
|
|
29388
|
-
when("content.heading")
|
|
29389
|
-
),
|
|
29390
|
-
// Optional description
|
|
29391
|
-
richText(
|
|
29392
|
-
{ className: "rb-prose rb-max-w-none" },
|
|
29393
|
-
bind("content.description"),
|
|
29394
|
-
when("content.description")
|
|
29395
|
-
),
|
|
29396
|
-
// Event spotlight component
|
|
29397
|
-
el("event-spotlight", {
|
|
29398
|
-
events: { $bind: { from: "data.events" } },
|
|
29399
|
-
layout: { $bind: { from: "content.layout", fallback: "grid" } },
|
|
29400
|
-
columns: { $bind: { from: "content.columns", fallback: "3" } },
|
|
29401
|
-
cardVariant: { $bind: { from: "content.cardVariant", fallback: "default" } },
|
|
29402
|
-
buttonVariant: { $bind: { from: "content.buttonVariant", fallback: "primary" } },
|
|
29403
|
-
buttonText: { $bind: { from: "content.buttonText", fallback: "View event" } },
|
|
29404
|
-
ctaLabel: { $bind: { from: "content.ctaLabel" } },
|
|
29405
|
-
ctaUrl: { $bind: { from: "content.ctaUrl", transforms: [{ id: "links.resolve" }] } },
|
|
29406
|
-
showVenue: { $bind: { from: "content.showVenue" } },
|
|
29407
|
-
showMap: { $bind: { from: "content.showMap" } },
|
|
29408
|
-
showCapacity: { $bind: { from: "content.showCapacity" } },
|
|
29409
|
-
emptyMessage: { $bind: { from: "content.emptyMessage" } }
|
|
29410
|
-
})
|
|
29411
|
-
], {
|
|
29412
|
-
gap: "lg"
|
|
29413
|
-
}),
|
|
29414
|
-
// sectionContainer (rb-container) already provides horizontal padding
|
|
29415
|
-
baseClass: "",
|
|
29416
|
-
spacing: "comfortable"
|
|
29417
|
-
})
|
|
29418
|
-
]
|
|
29419
|
-
});
|
|
29469
|
+
layout: eventSpotlightLayout
|
|
29470
|
+
};
|
|
29471
|
+
var eventSpotlightManifest = createBlockManifest(eventSpotlightConfig);
|
|
29420
29472
|
var eventSpotlightBlockDefinition = {
|
|
29421
29473
|
manifest: eventSpotlightManifest,
|
|
29422
29474
|
dataSchemas: {
|
|
@@ -30830,18 +30882,18 @@ var fileDownloadManifest = createBlockManifest({
|
|
|
30830
30882
|
title: "File Download",
|
|
30831
30883
|
titleSource: ["title", "file.filename"],
|
|
30832
30884
|
category: "media",
|
|
30833
|
-
description: "Add a simple public download link for a document, ZIP,
|
|
30885
|
+
description: "Add a simple public download link for a document, ZIP, or audio file.",
|
|
30834
30886
|
tags: ["file", "download", "document", "zip", "media"],
|
|
30835
30887
|
icon: "Download",
|
|
30836
30888
|
includeContainerStyles: true,
|
|
30837
30889
|
additionalFields: [
|
|
30838
30890
|
{
|
|
30839
30891
|
id: "file",
|
|
30840
|
-
type: "
|
|
30892
|
+
type: "file",
|
|
30841
30893
|
label: "Download file",
|
|
30842
30894
|
description: "Choose the file visitors can download.",
|
|
30843
30895
|
required: false,
|
|
30844
|
-
|
|
30896
|
+
fileKinds: [...PUBLIC_DOWNLOAD_MEDIA_TYPES],
|
|
30845
30897
|
ui: { intent: "content" }
|
|
30846
30898
|
},
|
|
30847
30899
|
{
|
|
@@ -37701,6 +37753,7 @@ function createListCommand(config2) {
|
|
|
37701
37753
|
}
|
|
37702
37754
|
|
|
37703
37755
|
// src/cli/push-config.ts
|
|
37756
|
+
var DEFAULT_CONFIG_PATH = "./riverbank.config.ts";
|
|
37704
37757
|
function isRecord5(value) {
|
|
37705
37758
|
return typeof value === "object" && value !== null;
|
|
37706
37759
|
}
|
|
@@ -37836,6 +37889,13 @@ async function pushConfigAction(output, options) {
|
|
|
37836
37889
|
let siteIdForErrorContext;
|
|
37837
37890
|
try {
|
|
37838
37891
|
process.env.RIVERBANK_ENV = options.isRemote ? "remote" : "local";
|
|
37892
|
+
if (!isJsonOutput) {
|
|
37893
|
+
output.info("push-config target", {
|
|
37894
|
+
env: process.env.RIVERBANK_ENV,
|
|
37895
|
+
dashboardUrl: options.dashboard,
|
|
37896
|
+
configPath: options.config ?? DEFAULT_CONFIG_PATH
|
|
37897
|
+
});
|
|
37898
|
+
}
|
|
37839
37899
|
const rawConfig = await loadConfigFile(options.config);
|
|
37840
37900
|
if (!isJsonOutput) output.info("Validating config...");
|
|
37841
37901
|
const parseResult = riverbankSiteConfigSchema.safeParse(rawConfig);
|
|
@@ -37948,7 +38008,7 @@ function resolveManagementApiKey(output, cliOption, isRemote) {
|
|
|
37948
38008
|
}
|
|
37949
38009
|
return apiKey;
|
|
37950
38010
|
}
|
|
37951
|
-
var pushConfigCommand = new Command("push-config").description("Push SDK config to dashboard").option("--api-key <key>", "Management API key (or set RIVERBANK_*_MGMT_API_KEY)").option("--dashboard <url>", "Dashboard URL (or set RIVERBANK_*_DASHBOARD_URL env var)").option("--config <path>",
|
|
38011
|
+
var pushConfigCommand = new Command("push-config").description("Push SDK config to dashboard").option("--api-key <key>", "Management API key (or set RIVERBANK_*_MGMT_API_KEY)").option("--dashboard <url>", "Dashboard URL (or set RIVERBANK_*_DASHBOARD_URL env var)").option("--config <path>", `Path to config file (default: ${DEFAULT_CONFIG_PATH})`).option(
|
|
37952
38012
|
"--force-content-types",
|
|
37953
38013
|
"Force overwrite content type schema even if modified in dashboard after last SDK sync"
|
|
37954
38014
|
).addHelpText("after", `
|
|
@@ -37966,6 +38026,7 @@ Description:
|
|
|
37966
38026
|
|
|
37967
38027
|
Examples:
|
|
37968
38028
|
$ npx riverbankcms push-config
|
|
38029
|
+
$ npx riverbankcms push-config --env=remote
|
|
37969
38030
|
$ npx riverbankcms push-config --api-key bld_mgmt_sk_... --dashboard https://www.riverbankcms.com
|
|
37970
38031
|
$ npx riverbankcms push-config --config ./src/riverbank.config.ts
|
|
37971
38032
|
`).action(async (options, command) => {
|
|
@@ -54444,7 +54505,8 @@ async function initDocs(options) {
|
|
|
54444
54505
|
{ filename: "content-types.md", template: "workflow-content-types" },
|
|
54445
54506
|
{ filename: "templates.md", template: "workflow-templates" },
|
|
54446
54507
|
{ filename: "cmsify-page.md", template: "workflow-cmsify-page" },
|
|
54447
|
-
{ filename: "editor-workflows.md", template: "workflow-editor-workflows" }
|
|
54508
|
+
{ filename: "editor-workflows.md", template: "workflow-editor-workflows" },
|
|
54509
|
+
{ filename: "preview-mode.md", template: "workflow-preview-mode" }
|
|
54448
54510
|
];
|
|
54449
54511
|
await Promise.all(
|
|
54450
54512
|
coreWorkflows.map(
|
|
@@ -54774,7 +54836,7 @@ var SimpleCache = class {
|
|
|
54774
54836
|
};
|
|
54775
54837
|
|
|
54776
54838
|
// src/version.ts
|
|
54777
|
-
var SDK_VERSION = "0.70.
|
|
54839
|
+
var SDK_VERSION = "0.70.4";
|
|
54778
54840
|
|
|
54779
54841
|
// src/client/error.ts
|
|
54780
54842
|
var RiverbankApiError = class _RiverbankApiError extends Error {
|
|
@@ -57827,7 +57889,14 @@ function collectLayoutClassNames(node, out = /* @__PURE__ */ new Set()) {
|
|
|
57827
57889
|
}
|
|
57828
57890
|
|
|
57829
57891
|
// src/manifest/validation/output-schema.ts
|
|
57830
|
-
var blockCategoryEnum2 = z.enum([
|
|
57892
|
+
var blockCategoryEnum2 = z.enum([
|
|
57893
|
+
"marketing",
|
|
57894
|
+
"content",
|
|
57895
|
+
"blog",
|
|
57896
|
+
"media",
|
|
57897
|
+
"layout",
|
|
57898
|
+
"interactive"
|
|
57899
|
+
]);
|
|
57831
57900
|
var llmColorValue = z.object({
|
|
57832
57901
|
name: z.string(),
|
|
57833
57902
|
hex: z.string()
|
|
@@ -57845,8 +57914,16 @@ var llmThemePatchValue = z.union([
|
|
|
57845
57914
|
z.array(llmThemePrimitive)
|
|
57846
57915
|
]);
|
|
57847
57916
|
var llmThemePatchOpSchema = z.discriminatedUnion("op", [
|
|
57848
|
-
z.object({
|
|
57849
|
-
|
|
57917
|
+
z.object({
|
|
57918
|
+
op: z.literal("add"),
|
|
57919
|
+
path: z.string().min(1),
|
|
57920
|
+
value: llmThemePatchValue
|
|
57921
|
+
}),
|
|
57922
|
+
z.object({
|
|
57923
|
+
op: z.literal("replace"),
|
|
57924
|
+
path: z.string().min(1),
|
|
57925
|
+
value: llmThemePatchValue
|
|
57926
|
+
}),
|
|
57850
57927
|
z.object({ op: z.literal("remove"), path: z.string().min(1) })
|
|
57851
57928
|
]);
|
|
57852
57929
|
var llmCssDeclaration = z.object({
|
|
@@ -57923,7 +58000,11 @@ var llmRichTextFieldSchema = llmBaseFieldSchema.extend({
|
|
|
57923
58000
|
});
|
|
57924
58001
|
var llmMediaFieldSchema = llmBaseFieldSchema.extend({
|
|
57925
58002
|
type: z.literal("media"),
|
|
57926
|
-
mediaKinds: z.array(z.enum(["image", "video", "audio"
|
|
58003
|
+
mediaKinds: z.array(z.enum(["image", "video", "audio"])).nullable()
|
|
58004
|
+
});
|
|
58005
|
+
var llmFileFieldSchema = llmBaseFieldSchema.extend({
|
|
58006
|
+
type: z.literal("file"),
|
|
58007
|
+
fileKinds: z.array(z.enum(["document", "spreadsheet", "archive", "audio"])).nullable()
|
|
57927
58008
|
});
|
|
57928
58009
|
var llmBooleanFieldSchema = llmBaseFieldSchema.extend({
|
|
57929
58010
|
type: z.literal("boolean")
|
|
@@ -57933,10 +58014,12 @@ var llmLinkFieldSchema = llmBaseFieldSchema.extend({
|
|
|
57933
58014
|
});
|
|
57934
58015
|
var llmSelectFieldSchema = llmBaseFieldSchema.extend({
|
|
57935
58016
|
type: z.literal("select"),
|
|
57936
|
-
options: z.array(
|
|
57937
|
-
|
|
57938
|
-
|
|
57939
|
-
|
|
58017
|
+
options: z.array(
|
|
58018
|
+
z.object({
|
|
58019
|
+
value: z.string(),
|
|
58020
|
+
label: z.string()
|
|
58021
|
+
})
|
|
58022
|
+
),
|
|
57940
58023
|
multiple: z.boolean().nullable()
|
|
57941
58024
|
});
|
|
57942
58025
|
var llmNumberFieldSchema = llmBaseFieldSchema.extend({
|
|
@@ -57972,6 +58055,7 @@ var llmFieldSchema = z.union([
|
|
|
57972
58055
|
llmTextFieldSchema,
|
|
57973
58056
|
llmRichTextFieldSchema,
|
|
57974
58057
|
llmMediaFieldSchema,
|
|
58058
|
+
llmFileFieldSchema,
|
|
57975
58059
|
llmBooleanFieldSchema,
|
|
57976
58060
|
llmLinkFieldSchema,
|
|
57977
58061
|
llmSelectFieldSchema,
|
|
@@ -57982,9 +58066,11 @@ var llmFieldSchema = z.union([
|
|
|
57982
58066
|
var llmBindingSchema = z.object({
|
|
57983
58067
|
from: z.string(),
|
|
57984
58068
|
fallback: z.string().nullable(),
|
|
57985
|
-
transforms: z.array(
|
|
57986
|
-
|
|
57987
|
-
|
|
58069
|
+
transforms: z.array(
|
|
58070
|
+
z.object({
|
|
58071
|
+
id: z.string()
|
|
58072
|
+
})
|
|
58073
|
+
).nullable()
|
|
57988
58074
|
});
|
|
57989
58075
|
var llmRepeatSchema = z.object({
|
|
57990
58076
|
collection: z.object({ from: z.string() }),
|
|
@@ -58043,11 +58129,17 @@ function collectValidationErrors(output) {
|
|
|
58043
58129
|
const blockIds = output.blocks.map((b) => b.id);
|
|
58044
58130
|
const singleBlockId = blockIds.length === 1 ? blockIds[0] ?? null : null;
|
|
58045
58131
|
for (const block of output.blocks) {
|
|
58046
|
-
const layoutErrors = validateLayoutDeep(
|
|
58132
|
+
const layoutErrors = validateLayoutDeep(
|
|
58133
|
+
block.layout,
|
|
58134
|
+
block.id,
|
|
58135
|
+
block.fields
|
|
58136
|
+
);
|
|
58047
58137
|
errors.push(...layoutErrors);
|
|
58048
58138
|
const fieldInfo = collectFieldInfo(block.fields);
|
|
58049
58139
|
const used = collectUsedFieldRefs(block.layout);
|
|
58050
|
-
const unusedTopLevelFields = Array.from(fieldInfo.topLevelFieldIds).filter(
|
|
58140
|
+
const unusedTopLevelFields = Array.from(fieldInfo.topLevelFieldIds).filter(
|
|
58141
|
+
(id) => !used.topLevel.has(id)
|
|
58142
|
+
);
|
|
58051
58143
|
if (unusedTopLevelFields.length > 0) {
|
|
58052
58144
|
errors.push({
|
|
58053
58145
|
path: `blocks["${block.id}"].fields`,
|
|
@@ -58055,10 +58147,15 @@ function collectValidationErrors(output) {
|
|
|
58055
58147
|
suggestion: `Every field should be bound to a layout node. Add $bind: { from: "content.${unusedTopLevelFields[0]}" } to an appropriate node, or remove unused fields.`
|
|
58056
58148
|
});
|
|
58057
58149
|
}
|
|
58058
|
-
for (const [
|
|
58150
|
+
for (const [
|
|
58151
|
+
repeaterFieldId,
|
|
58152
|
+
nestedFieldIds
|
|
58153
|
+
] of fieldInfo.repeaterNestedFieldIds.entries()) {
|
|
58059
58154
|
if (!used.topLevel.has(repeaterFieldId)) continue;
|
|
58060
58155
|
const usedNested = used.nestedByRepeater.get(repeaterFieldId) ?? /* @__PURE__ */ new Set();
|
|
58061
|
-
const missingNested = Array.from(nestedFieldIds).filter(
|
|
58156
|
+
const missingNested = Array.from(nestedFieldIds).filter(
|
|
58157
|
+
(id) => !usedNested.has(id)
|
|
58158
|
+
);
|
|
58062
58159
|
if (missingNested.length === 0) continue;
|
|
58063
58160
|
const itemName = used.itemNameByRepeater.get(repeaterFieldId) ?? "item";
|
|
58064
58161
|
errors.push({
|
|
@@ -58071,10 +58168,18 @@ function collectValidationErrors(output) {
|
|
|
58071
58168
|
errors.push(...missingBindings);
|
|
58072
58169
|
errors.push(...validateLinkFieldDefaultValues(block));
|
|
58073
58170
|
errors.push(...findMissingLinkHrefs(block.layout, block.id, block.fields));
|
|
58074
|
-
errors.push(
|
|
58171
|
+
errors.push(
|
|
58172
|
+
...detectRedundantLinkLabels(block.layout, block.id, block.fields)
|
|
58173
|
+
);
|
|
58075
58174
|
}
|
|
58076
58175
|
if (output.customCssRules && output.customCssRules.length > 0) {
|
|
58077
|
-
errors.push(
|
|
58176
|
+
errors.push(
|
|
58177
|
+
...validateCustomCssRules(
|
|
58178
|
+
output.customCssRules,
|
|
58179
|
+
singleBlockId,
|
|
58180
|
+
output.blocks
|
|
58181
|
+
)
|
|
58182
|
+
);
|
|
58078
58183
|
}
|
|
58079
58184
|
return errors;
|
|
58080
58185
|
}
|
|
@@ -58150,7 +58255,9 @@ function resolveFieldTypeForFrom(allFields, from, repeatStack) {
|
|
|
58150
58255
|
const segments = from.slice(prefix.length).split(".").filter(Boolean);
|
|
58151
58256
|
const [nestedId, ...rest] = segments;
|
|
58152
58257
|
if (!nestedId) return null;
|
|
58153
|
-
let current = ctx.fields.find(
|
|
58258
|
+
let current = ctx.fields.find(
|
|
58259
|
+
(f) => f.id === nestedId
|
|
58260
|
+
);
|
|
58154
58261
|
if (!current) return null;
|
|
58155
58262
|
for (const seg of rest) {
|
|
58156
58263
|
const nested = getNestedFields(current);
|
|
@@ -58166,7 +58273,9 @@ function bindingHasTransform(bind2, id) {
|
|
|
58166
58273
|
if (!bind2) return false;
|
|
58167
58274
|
const transforms = bind2.transforms;
|
|
58168
58275
|
if (!Array.isArray(transforms)) return false;
|
|
58169
|
-
return transforms.some(
|
|
58276
|
+
return transforms.some(
|
|
58277
|
+
(t) => t && typeof t === "object" && t.id === id
|
|
58278
|
+
);
|
|
58170
58279
|
}
|
|
58171
58280
|
function extractNestedHrefBindFromProps(props2) {
|
|
58172
58281
|
if (!props2 || typeof props2 !== "object") return null;
|
|
@@ -58227,7 +58336,15 @@ function findMissingLinkHrefs(node, blockId, fields3, path24 = "layout", repeatS
|
|
|
58227
58336
|
}
|
|
58228
58337
|
if ("children" in n && Array.isArray(n.children)) {
|
|
58229
58338
|
for (let i = 0; i < n.children.length; i++) {
|
|
58230
|
-
errors.push(
|
|
58339
|
+
errors.push(
|
|
58340
|
+
...findMissingLinkHrefs(
|
|
58341
|
+
n.children[i],
|
|
58342
|
+
blockId,
|
|
58343
|
+
fields3,
|
|
58344
|
+
`${path24}.children[${i}]`,
|
|
58345
|
+
nextRepeatStack
|
|
58346
|
+
)
|
|
58347
|
+
);
|
|
58231
58348
|
}
|
|
58232
58349
|
}
|
|
58233
58350
|
return errors;
|
|
@@ -58251,22 +58368,30 @@ function detectRedundantLinkLabels(node, blockId, fields3, path24 = "layout", re
|
|
|
58251
58368
|
}
|
|
58252
58369
|
if (Array.isArray(n.children) && n.children.length > 1) {
|
|
58253
58370
|
const children = n.children;
|
|
58254
|
-
const redundancies = findRedundantLinkTextSiblings(
|
|
58255
|
-
|
|
58256
|
-
|
|
58257
|
-
|
|
58258
|
-
|
|
58259
|
-
|
|
58371
|
+
const redundancies = findRedundantLinkTextSiblings(
|
|
58372
|
+
children,
|
|
58373
|
+
nextRepeatStack,
|
|
58374
|
+
path24
|
|
58375
|
+
);
|
|
58376
|
+
errors.push(
|
|
58377
|
+
...redundancies.map((r) => ({
|
|
58378
|
+
path: r.path,
|
|
58379
|
+
message: `Block "${blockId}": ${r.message}`,
|
|
58380
|
+
suggestion: r.suggestion
|
|
58381
|
+
}))
|
|
58382
|
+
);
|
|
58260
58383
|
}
|
|
58261
58384
|
if (Array.isArray(n.children)) {
|
|
58262
58385
|
for (let i = 0; i < n.children.length; i++) {
|
|
58263
|
-
errors.push(
|
|
58264
|
-
|
|
58265
|
-
|
|
58266
|
-
|
|
58267
|
-
|
|
58268
|
-
|
|
58269
|
-
|
|
58386
|
+
errors.push(
|
|
58387
|
+
...detectRedundantLinkLabels(
|
|
58388
|
+
n.children[i],
|
|
58389
|
+
blockId,
|
|
58390
|
+
fields3,
|
|
58391
|
+
`${path24}.children[${i}]`,
|
|
58392
|
+
nextRepeatStack
|
|
58393
|
+
)
|
|
58394
|
+
);
|
|
58270
58395
|
}
|
|
58271
58396
|
}
|
|
58272
58397
|
return errors;
|
|
@@ -58320,7 +58445,8 @@ function checkRedundantLabelBinding(linkBindFrom, textBindFrom, repeatStack) {
|
|
|
58320
58445
|
const ctx = repeatStack[i];
|
|
58321
58446
|
if (!ctx) continue;
|
|
58322
58447
|
const prefix = `${ctx.itemName}.`;
|
|
58323
|
-
if (!linkBindFrom.startsWith(prefix) || !textBindFrom.startsWith(prefix))
|
|
58448
|
+
if (!linkBindFrom.startsWith(prefix) || !textBindFrom.startsWith(prefix))
|
|
58449
|
+
continue;
|
|
58324
58450
|
const linkFieldId = linkBindFrom.slice(prefix.length).split(".")[0] ?? "";
|
|
58325
58451
|
const textFieldId = textBindFrom.slice(prefix.length).split(".")[0] ?? "";
|
|
58326
58452
|
const linkField = ctx.fields.find((f) => f.id === linkFieldId);
|
|
@@ -58345,7 +58471,10 @@ function validateCustomCssRules(rules, singleBlockId, blocks) {
|
|
|
58345
58471
|
const layoutClassNamesByBlockId = /* @__PURE__ */ new Map();
|
|
58346
58472
|
const layoutNodeInfosByBlockId = /* @__PURE__ */ new Map();
|
|
58347
58473
|
for (const block of blocks) {
|
|
58348
|
-
layoutClassNamesByBlockId.set(
|
|
58474
|
+
layoutClassNamesByBlockId.set(
|
|
58475
|
+
block.id,
|
|
58476
|
+
collectLayoutClassNames(block.layout)
|
|
58477
|
+
);
|
|
58349
58478
|
layoutNodeInfosByBlockId.set(block.id, collectLayoutNodeInfos(block.layout));
|
|
58350
58479
|
}
|
|
58351
58480
|
const missingLayoutHooksByBlockId = /* @__PURE__ */ new Map();
|
|
@@ -58414,11 +58543,18 @@ function validateCustomCssRules(rules, singleBlockId, blocks) {
|
|
|
58414
58543
|
}
|
|
58415
58544
|
}
|
|
58416
58545
|
}
|
|
58417
|
-
for (const [
|
|
58546
|
+
for (const [
|
|
58547
|
+
blockId,
|
|
58548
|
+
missingClassNames
|
|
58549
|
+
] of missingLayoutHooksByBlockId.entries()) {
|
|
58418
58550
|
const missing = Array.from(missingClassNames).sort();
|
|
58419
58551
|
if (missing.length === 0) continue;
|
|
58420
58552
|
const layoutNodeInfos = layoutNodeInfosByBlockId.get(blockId) ?? [];
|
|
58421
|
-
const attachSuggestions = buildClassHookAttachSuggestions(
|
|
58553
|
+
const attachSuggestions = buildClassHookAttachSuggestions(
|
|
58554
|
+
blockId,
|
|
58555
|
+
missing,
|
|
58556
|
+
layoutNodeInfos
|
|
58557
|
+
);
|
|
58422
58558
|
const attachSuggestionsLine = attachSuggestions ? `
|
|
58423
58559
|
|
|
58424
58560
|
Suggested attachments:
|
|
@@ -58452,7 +58588,9 @@ function buildClassHookAttachSuggestions(blockId, missingClassNames, nodes) {
|
|
|
58452
58588
|
continue;
|
|
58453
58589
|
}
|
|
58454
58590
|
if ((lower.includes("headline") || lower.includes("title")) && (headlineNode ?? firstStack)) {
|
|
58455
|
-
lines.push(
|
|
58591
|
+
lines.push(
|
|
58592
|
+
`- ${className} \u2192 add to ${headlineNode ?? firstStack}.props.className`
|
|
58593
|
+
);
|
|
58456
58594
|
continue;
|
|
58457
58595
|
}
|
|
58458
58596
|
if (lower.includes("highlight") && highlightNode) {
|
|
@@ -58460,7 +58598,9 @@ function buildClassHookAttachSuggestions(blockId, missingClassNames, nodes) {
|
|
|
58460
58598
|
continue;
|
|
58461
58599
|
}
|
|
58462
58600
|
if ((lower.includes("body") || lower.includes("copy") || lower.includes("paragraph")) && (paragraphNode ?? firstStack)) {
|
|
58463
|
-
lines.push(
|
|
58601
|
+
lines.push(
|
|
58602
|
+
`- ${className} \u2192 add to ${paragraphNode ?? firstStack}.props.className`
|
|
58603
|
+
);
|
|
58464
58604
|
continue;
|
|
58465
58605
|
}
|
|
58466
58606
|
lines.push(`- ${className} \u2192 add to ${rootPath}.props.className (fallback)`);
|
|
@@ -58468,7 +58608,10 @@ function buildClassHookAttachSuggestions(blockId, missingClassNames, nodes) {
|
|
|
58468
58608
|
return lines.slice(0, 8).join("\n");
|
|
58469
58609
|
}
|
|
58470
58610
|
function extractSelectorClasses(selector) {
|
|
58471
|
-
const withoutDataBlockAttrs = selector.replace(
|
|
58611
|
+
const withoutDataBlockAttrs = selector.replace(
|
|
58612
|
+
/\[data-block=(["']).*?\1\]/g,
|
|
58613
|
+
""
|
|
58614
|
+
);
|
|
58472
58615
|
const classes = /* @__PURE__ */ new Set();
|
|
58473
58616
|
const re = /\.([_a-zA-Z][-_a-zA-Z0-9]*)/g;
|
|
58474
58617
|
let match;
|
|
@@ -58485,7 +58628,9 @@ function extractBlockIdFromSelector(selector) {
|
|
|
58485
58628
|
return match?.[2] ?? null;
|
|
58486
58629
|
}
|
|
58487
58630
|
function validateNodeType(nodeType, path24, ctx) {
|
|
58488
|
-
if (!ALLOWED_NODE_TYPES.includes(
|
|
58631
|
+
if (!ALLOWED_NODE_TYPES.includes(
|
|
58632
|
+
nodeType
|
|
58633
|
+
)) {
|
|
58489
58634
|
return {
|
|
58490
58635
|
path: `${path24}.type`,
|
|
58491
58636
|
message: `Block "${ctx.blockId}": Unknown node type "${nodeType}" at ${path24}`,
|
|
@@ -58499,7 +58644,9 @@ function validateTransforms(transforms, path24, ctx) {
|
|
|
58499
58644
|
for (let i = 0; i < transforms.length; i++) {
|
|
58500
58645
|
const transform = transforms[i];
|
|
58501
58646
|
if (transform.id && typeof transform.id === "string") {
|
|
58502
|
-
if (!ALLOWED_TRANSFORM_IDS.includes(
|
|
58647
|
+
if (!ALLOWED_TRANSFORM_IDS.includes(
|
|
58648
|
+
transform.id
|
|
58649
|
+
)) {
|
|
58503
58650
|
errors.push({
|
|
58504
58651
|
path: `${path24}.transforms[${i}].id`,
|
|
58505
58652
|
message: `Block "${ctx.blockId}": Unknown transform "${transform.id}"`,
|
|
@@ -58548,16 +58695,28 @@ function validateLayoutNode(node, path24, ctx) {
|
|
|
58548
58695
|
if (typeError) errors.push(typeError);
|
|
58549
58696
|
}
|
|
58550
58697
|
if ("$bind" in n && n.$bind && typeof n.$bind === "object") {
|
|
58551
|
-
const bindErrors = validateBinding(
|
|
58698
|
+
const bindErrors = validateBinding(
|
|
58699
|
+
n.$bind,
|
|
58700
|
+
`${path24}.$bind`,
|
|
58701
|
+
ctx
|
|
58702
|
+
);
|
|
58552
58703
|
errors.push(...bindErrors);
|
|
58553
58704
|
}
|
|
58554
58705
|
if ("props" in n && n.props && typeof n.props === "object") {
|
|
58555
|
-
const propsErrors = validatePropsBindings(
|
|
58706
|
+
const propsErrors = validatePropsBindings(
|
|
58707
|
+
n.props,
|
|
58708
|
+
`${path24}.props`,
|
|
58709
|
+
ctx
|
|
58710
|
+
);
|
|
58556
58711
|
errors.push(...propsErrors);
|
|
58557
58712
|
}
|
|
58558
58713
|
if ("children" in n && Array.isArray(n.children)) {
|
|
58559
58714
|
for (let i = 0; i < n.children.length; i++) {
|
|
58560
|
-
const childErrors = validateLayoutNode(
|
|
58715
|
+
const childErrors = validateLayoutNode(
|
|
58716
|
+
n.children[i],
|
|
58717
|
+
`${path24}.children[${i}]`,
|
|
58718
|
+
ctx
|
|
58719
|
+
);
|
|
58561
58720
|
errors.push(...childErrors);
|
|
58562
58721
|
}
|
|
58563
58722
|
}
|
|
@@ -58571,7 +58730,11 @@ function validatePropsBindings(props2, path24, ctx) {
|
|
|
58571
58730
|
const bindErrors = validateBinding(bind2, `${path24}.${key}.$bind`, ctx);
|
|
58572
58731
|
errors.push(...bindErrors);
|
|
58573
58732
|
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
58574
|
-
const nestedErrors = validatePropsBindings(
|
|
58733
|
+
const nestedErrors = validatePropsBindings(
|
|
58734
|
+
value,
|
|
58735
|
+
`${path24}.${key}`,
|
|
58736
|
+
ctx
|
|
58737
|
+
);
|
|
58575
58738
|
errors.push(...nestedErrors);
|
|
58576
58739
|
}
|
|
58577
58740
|
}
|
|
@@ -58612,7 +58775,10 @@ function collectFieldInfo(fields3) {
|
|
|
58612
58775
|
topLevelFieldIds.add(field.id);
|
|
58613
58776
|
if (field.type === "repeater" && field.schema && typeof field.schema === "object" && "fields" in field.schema) {
|
|
58614
58777
|
const nestedFields = field.schema.fields ?? [];
|
|
58615
|
-
repeaterNestedFieldIds.set(
|
|
58778
|
+
repeaterNestedFieldIds.set(
|
|
58779
|
+
field.id,
|
|
58780
|
+
new Set(nestedFields.map((f) => f.id))
|
|
58781
|
+
);
|
|
58616
58782
|
}
|
|
58617
58783
|
}
|
|
58618
58784
|
return { topLevelFieldIds, repeaterNestedFieldIds };
|
|
@@ -58732,7 +58898,11 @@ function findMissingBindings(node, blockId, path24 = "layout") {
|
|
|
58732
58898
|
}
|
|
58733
58899
|
if ("children" in n && Array.isArray(n.children)) {
|
|
58734
58900
|
for (let i = 0; i < n.children.length; i++) {
|
|
58735
|
-
const childErrors = findMissingBindings(
|
|
58901
|
+
const childErrors = findMissingBindings(
|
|
58902
|
+
n.children[i],
|
|
58903
|
+
blockId,
|
|
58904
|
+
`${path24}.children[${i}]`
|
|
58905
|
+
);
|
|
58736
58906
|
errors.push(...childErrors);
|
|
58737
58907
|
}
|
|
58738
58908
|
}
|
|
@@ -58743,7 +58913,9 @@ function getMaxDepth(node, currentDepth = 0) {
|
|
|
58743
58913
|
const n = node;
|
|
58744
58914
|
if (!n.children || !Array.isArray(n.children)) return currentDepth;
|
|
58745
58915
|
if (n.children.length === 0) return currentDepth;
|
|
58746
|
-
return Math.max(
|
|
58916
|
+
return Math.max(
|
|
58917
|
+
...n.children.map((child) => getMaxDepth(child, currentDepth + 1))
|
|
58918
|
+
);
|
|
58747
58919
|
}
|
|
58748
58920
|
var CONTAINER_NODE_TYPES = ["section", "stack", "grid", "div", "inline"];
|
|
58749
58921
|
function detectPotentialTruncation(node, maxAllowedDepth, currentDepth = 0, path24 = "layout") {
|
|
@@ -58758,7 +58930,12 @@ function detectPotentialTruncation(node, maxAllowedDepth, currentDepth = 0, path
|
|
|
58758
58930
|
if (n.children && Array.isArray(n.children)) {
|
|
58759
58931
|
n.children.forEach((child, i) => {
|
|
58760
58932
|
truncatedPaths.push(
|
|
58761
|
-
...detectPotentialTruncation(
|
|
58933
|
+
...detectPotentialTruncation(
|
|
58934
|
+
child,
|
|
58935
|
+
maxAllowedDepth,
|
|
58936
|
+
currentDepth + 1,
|
|
58937
|
+
`${path24}.children[${i}]`
|
|
58938
|
+
)
|
|
58762
58939
|
);
|
|
58763
58940
|
});
|
|
58764
58941
|
}
|
|
@@ -58773,14 +58950,20 @@ function formatValidationFeedback(errors, output) {
|
|
|
58773
58950
|
if (truncatedPaths.length > 0) {
|
|
58774
58951
|
lines.push("### DEPTH LIMIT WARNING");
|
|
58775
58952
|
lines.push("");
|
|
58776
|
-
lines.push(
|
|
58953
|
+
lines.push(
|
|
58954
|
+
`The layout reached the maximum depth of ${MAX_LAYOUT_DEPTH} levels.`
|
|
58955
|
+
);
|
|
58777
58956
|
lines.push("These container nodes at the depth limit have no children:");
|
|
58778
58957
|
for (const path24 of truncatedPaths) {
|
|
58779
58958
|
lines.push(` \u26A0\uFE0F ${path24}`);
|
|
58780
58959
|
}
|
|
58781
58960
|
lines.push("");
|
|
58782
|
-
lines.push(
|
|
58783
|
-
|
|
58961
|
+
lines.push(
|
|
58962
|
+
"**FIX**: Flatten your layout structure or use $repeat for lists."
|
|
58963
|
+
);
|
|
58964
|
+
lines.push(
|
|
58965
|
+
"- Combine wrapper nodes where possible (e.g., section > stack > div \u2192 section > stack)"
|
|
58966
|
+
);
|
|
58784
58967
|
lines.push("- Use $repeat instead of manual nesting for repeated items");
|
|
58785
58968
|
lines.push(`- Current max depth: ${maxDepth}, limit: ${MAX_LAYOUT_DEPTH}`);
|
|
58786
58969
|
lines.push("");
|
|
@@ -58789,13 +58972,19 @@ function formatValidationFeedback(errors, output) {
|
|
|
58789
58972
|
if (errors.length === 0) {
|
|
58790
58973
|
return lines.length > 0 ? lines.join("\n") : "";
|
|
58791
58974
|
}
|
|
58792
|
-
lines.push(
|
|
58975
|
+
lines.push(
|
|
58976
|
+
"## CRITICAL: Your output failed validation. You MUST fix these errors."
|
|
58977
|
+
);
|
|
58793
58978
|
lines.push("");
|
|
58794
58979
|
lines.push("Your previous output had the following problems:");
|
|
58795
58980
|
lines.push("");
|
|
58796
58981
|
const missingBindErrors = errors.filter((e) => e.message.includes("no $bind"));
|
|
58797
|
-
const unusedFieldErrors = errors.filter(
|
|
58798
|
-
|
|
58982
|
+
const unusedFieldErrors = errors.filter(
|
|
58983
|
+
(e) => e.message.includes("never used")
|
|
58984
|
+
);
|
|
58985
|
+
const otherErrors = errors.filter(
|
|
58986
|
+
(e) => !e.message.includes("no $bind") && !e.message.includes("never used")
|
|
58987
|
+
);
|
|
58799
58988
|
if (missingBindErrors.length > 0) {
|
|
58800
58989
|
lines.push("### MISSING $bind ERRORS (nodes that display nothing)");
|
|
58801
58990
|
lines.push("");
|
|
@@ -58803,16 +58992,22 @@ function formatValidationFeedback(errors, output) {
|
|
|
58803
58992
|
lines.push(`\u274C ${error.message}`);
|
|
58804
58993
|
}
|
|
58805
58994
|
lines.push("");
|
|
58806
|
-
lines.push(
|
|
58995
|
+
lines.push(
|
|
58996
|
+
"**FIX**: Every text, richText, media, button, and link node MUST have $bind."
|
|
58997
|
+
);
|
|
58807
58998
|
lines.push("");
|
|
58808
58999
|
lines.push("WRONG (displays nothing):");
|
|
58809
59000
|
lines.push("```json");
|
|
58810
|
-
lines.push(
|
|
59001
|
+
lines.push(
|
|
59002
|
+
'{ "type": "text", "props": { "as": "h1" }, "children": null, "$bind": null }'
|
|
59003
|
+
);
|
|
58811
59004
|
lines.push("```");
|
|
58812
59005
|
lines.push("");
|
|
58813
59006
|
lines.push("CORRECT (bound to field):");
|
|
58814
59007
|
lines.push("```json");
|
|
58815
|
-
lines.push(
|
|
59008
|
+
lines.push(
|
|
59009
|
+
'{ "type": "text", "props": { "as": "h1" }, "children": null, "$bind": { "from": "content.headline", "fallback": null, "transforms": null } }'
|
|
59010
|
+
);
|
|
58816
59011
|
lines.push("```");
|
|
58817
59012
|
lines.push("");
|
|
58818
59013
|
}
|
|
@@ -58831,11 +59026,15 @@ function formatValidationFeedback(errors, output) {
|
|
|
58831
59026
|
if (fieldNames.length > 0) {
|
|
58832
59027
|
lines.push("**CHECKLIST - Add a binding for EACH of these fields:**");
|
|
58833
59028
|
for (const field of fieldNames) {
|
|
58834
|
-
lines.push(
|
|
59029
|
+
lines.push(
|
|
59030
|
+
`- [ ] ${field} \u2192 text node with $bind: { from: "content.${field}" }`
|
|
59031
|
+
);
|
|
58835
59032
|
}
|
|
58836
59033
|
lines.push("");
|
|
58837
59034
|
}
|
|
58838
|
-
lines.push(
|
|
59035
|
+
lines.push(
|
|
59036
|
+
"**COMMON MISTAKE**: Creating container nodes with `children: null` instead of actual bindings."
|
|
59037
|
+
);
|
|
58839
59038
|
lines.push("");
|
|
58840
59039
|
lines.push("This is WRONG (container with no content inside):");
|
|
58841
59040
|
lines.push("```json");
|
|
@@ -58845,12 +59044,18 @@ function formatValidationFeedback(errors, output) {
|
|
|
58845
59044
|
lines.push("This is CORRECT (container with bound text node):");
|
|
58846
59045
|
lines.push("```json");
|
|
58847
59046
|
lines.push('{ "type": "inline", "children": [');
|
|
58848
|
-
lines.push(
|
|
59047
|
+
lines.push(
|
|
59048
|
+
' { "type": "text", "$bind": { "from": "content.fieldName", "fallback": null, "transforms": null }, "props": null, "$repeat": null, "$when": null, "children": null }'
|
|
59049
|
+
);
|
|
58849
59050
|
lines.push("] }");
|
|
58850
59051
|
lines.push("```");
|
|
58851
59052
|
lines.push("");
|
|
58852
|
-
lines.push(
|
|
58853
|
-
|
|
59053
|
+
lines.push(
|
|
59054
|
+
"**FIX**: Every field you define MUST be used in a $bind somewhere in the layout."
|
|
59055
|
+
);
|
|
59056
|
+
lines.push(
|
|
59057
|
+
'If you have a field "highlight", you MUST have a node with $bind: { from: "content.highlight" }'
|
|
59058
|
+
);
|
|
58854
59059
|
lines.push("");
|
|
58855
59060
|
}
|
|
58856
59061
|
if (otherErrors.length > 0) {
|