@riverbankcms/sdk 0.84.0 → 0.84.1
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/{PreviewEditorSidebar-HML67UDA.mjs → PreviewEditorSidebar-X7RLMEI6.mjs} +2 -2
- package/dist/{PreviewEditorUI-I4BQUU6K.mjs → PreviewEditorUI-CT67N4O3.mjs} +2 -2
- package/dist/SdkPreviewModeRuntime-EIMQ3S2V.mjs +8 -0
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -4
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +6 -6
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +3 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizard.d.ts +0 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/constants.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +275 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.d.ts +10 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +22 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.state.d.ts +3 -303
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +9 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +8 -6
- package/dist/_dts/editor-blocks/src/BlockForm.d.ts +6 -4
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/{chunk-MSHZO4SL.mjs → chunk-O62NDCTI.mjs} +268 -186
- package/dist/{chunk-HFMGVJCE.mjs → chunk-QRKJDWT7.mjs} +5 -5
- package/dist/{chunk-6X2OVO3S.mjs → chunk-RCTJAZSK.mjs} +1 -1
- package/dist/{chunk-5E33VO6J.mjs → chunk-X5ZCSU6F.mjs} +1 -1
- package/dist/cli/index.mjs +323 -35
- package/dist/cli/init-docs/content/agents-section.md +5 -0
- package/dist/cli/init-docs/content/cli-reference.md +13 -0
- package/dist/cli/init-docs/content/content-management.md +31 -0
- package/dist/cli/init-docs/content/getting-started.md +12 -0
- package/dist/cli/init-docs/content/workflow-add-block.md +3 -1
- package/dist/cli/init-docs/content/workflow-agent-safe-sync.md +81 -0
- package/dist/cli/init-docs/content/workflow-create-page.md +13 -3
- package/dist/cli/init-docs/content/workflow-custom-block.md +9 -0
- package/dist/cli/init-docs/content/workflow-templates.md +14 -0
- package/dist/client/{accordion-ESY65T56.mjs → accordion-2UZPBMYM.mjs} +1 -1
- package/dist/client/{bookingForm-JRFNZUHD.mjs → bookingForm-DYXT6YB6.mjs} +3 -3
- package/dist/client/bookings.mjs +155 -134
- package/dist/client/{carousel-CPR5VWIP.mjs → carousel-QH77HR6X.mjs} +2 -2
- package/dist/client/{cart-ZUX5BA7O.mjs → cart-X4YK4FTW.mjs} +5 -5
- package/dist/client/{checkout-RULGBADZ.mjs → checkout-OM2BEPWD.mjs} +5 -5
- package/dist/client/{chunk-BT6AEIKN.mjs → chunk-3DTWLTXM.mjs} +1 -1
- package/dist/client/{chunk-JWEYB4V6.mjs → chunk-4OXKTA3D.mjs} +1 -1
- package/dist/client/{chunk-URQCZD5W.mjs → chunk-52CGCQ7B.mjs} +4 -4
- package/dist/client/{chunk-52I7BGEK.mjs → chunk-7UCLJ5SP.mjs} +1 -1
- package/dist/client/{chunk-Z5OBQ5I4.mjs → chunk-F5VRX5Y6.mjs} +1 -1
- package/dist/client/{chunk-RDJFCPY3.mjs → chunk-UHDWIXVR.mjs} +31 -115
- package/dist/client/{chunk-HXPWP5EN.mjs → chunk-VGDBVNOO.mjs} +175 -14
- package/dist/client/{chunk-5ZEAZ33K.mjs → chunk-ZKUO52W3.mjs} +1 -1
- package/dist/client/client.mjs +337 -217
- package/dist/client/{courseRegistration-QTUDC35T.mjs → courseRegistration-YBOGURTA.mjs} +3 -3
- package/dist/client/{eventCalendar-Q7NS4XLD.mjs → eventCalendar-K4QJVCMD.mjs} +5 -5
- package/dist/client/{eventCombined-QAO7VUO5.mjs → eventCombined-MTXGMTCZ.mjs} +5 -5
- package/dist/client/{eventDetails-WTNNU6Q3.mjs → eventDetails-3PC4NL3U.mjs} +5 -5
- package/dist/client/{eventListing-5TA2ELDT.mjs → eventListing-TFJET6DN.mjs} +5 -5
- package/dist/client/{eventRegistration-M6USZGRF.mjs → eventRegistration-QGPBGJTW.mjs} +5 -5
- package/dist/client/{form-DGVGXLMH.mjs → form-MDKR4FNB.mjs} +1 -1
- package/dist/client/{headerSection-O2AGMPCU.mjs → headerSection-Y5TMR3TW.mjs} +2 -2
- package/dist/client/hooks.mjs +315 -35
- package/dist/client/{locationMap-EJRNRIKJ.mjs → locationMap-RH2LG7FZ.mjs} +1 -1
- package/dist/client/{newsletterForm-7NTC2DTR.mjs → newsletterForm-ZR5UDGBT.mjs} +1 -1
- package/dist/client/{productDetail-HH4LP53D.mjs → productDetail-OIGDR4YE.mjs} +5 -5
- package/dist/client/{productList-YVHYM2AF.mjs → productList-4MA5S2CX.mjs} +5 -5
- package/dist/client/rendering/client.mjs +310 -190
- package/dist/client/rendering/islands.mjs +18 -18
- package/dist/client/rendering.mjs +310 -190
- package/dist/client/{shop-UIFX7XRK.mjs → shop-WXSYV5QO.mjs} +5 -5
- package/dist/preview-next/client/runtime.mjs +3 -3
- package/dist/{sdk-runtime-ZENAOYMN.mjs → sdk-runtime-7HJYPRWQ.mjs} +4 -4
- package/dist/server/components.mjs +188 -61
- package/dist/server/config-validation.mjs +313 -33
- package/dist/server/config.mjs +313 -33
- package/dist/server/data.mjs +315 -35
- package/dist/server/index.mjs +1 -1
- package/dist/server/next.mjs +189 -62
- package/dist/server/page-converter.mjs +315 -35
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +188 -61
- package/dist/server/rendering.mjs +188 -61
- package/dist/server/routing.mjs +334 -34
- package/dist/server/server.mjs +322 -42
- package/package.json +1 -1
- package/dist/SdkPreviewModeRuntime-MCKMVDTK.mjs +0 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { KeyboardCode, getBlockDefinition, CSS, useSdkConfig, unwrapResponse, parseSiteIconStyleGuideVersionId, parseBlockIconValue, listBlockDescriptors, useSensor, PointerSensor, useSensors, createEditorRemoveBlockCommand, unsafeAsEditorBlockId, DndContext, closestCenter, Button, Plus, useDroppable, useDraggable, useCombinedRefs, isKeyboardEvent, createCustomBlockRegistry, Card, cn, Collapsible, CollapsibleContent, listContentTypes, mergeBlockDescriptorsWithRegistry, createEditorReorderBlocksCommand, mutateBlockContent, deleteEntrySlotBlock, deleteBlock, useDndContext, useUniqueId, useIsomorphicLayoutEffect, EmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Search, getClientRect, resolveBlockTitle, CardHeader, GripVertical, ChevronRight, CardTitle, ArrowUp, ArrowDown, DropdownMenu, DropdownMenuTrigger, EllipsisVertical, DropdownMenuContent, DropdownMenuSeparator, DropdownMenuItem, Copy, Trash2, DialogFooter, DialogClose, CardContent, createEntrySlotBlock, createBlock, createEditorInsertBlockCommand, reorderEntrySlotBlocks, reorderBlocks, LoaderCircle, ChevronDown, getFeatureCardIconCompletion, toFeatureCardIconSuggestionInputs, getBlockIconSemanticFallbackId, suggestSemanticIconForFeatureCard, getGeneratedBlockIconStyleState, assertNever, createManifestFormAdapter, getModalConfig, createStoreBackend, validateBlockManifestIssues, isNonEmptyValue, Settings, ScrollableDialogContent, FormRenderer, Tabs, TabsList, TabsTrigger, TabsContent, RotateCcw, ImagePlus, Sparkles, Textarea, Callout, CalloutDescription, normalEditorCuratedPromotedFieldPaths, resolveVisiblePromotedFieldPathsForEditorBlock, CalloutTitle, unfinishedBlockCopy, recoveryConflictCopy, ManifestForm, unsafeAsEditorBlockValues, Box, mergeManifestWithSdkOptions, augmentManifestWithStyleGroups, suggestFeatureCardSemanticIcons, applyFeatureCardIconSuggestions, createFeatureCardIconKey, lucide_react_exports, isThemeV2NormalEditorRawStylePath, getFieldIntent, isHeaderField, isThemeV2NormalEditorRawStyleFieldName, BackgroundGradientField, BackgroundColorField, useField, FieldFrame, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, useMediaEditorOptional, useRichTextEditor, RichTextEditorSurface, ThemeScope, isObjectRecord, EMPTY_DOC, useAsyncPickerOptions, resolvePickerSelectionLabel, shouldShowPickerSearch, normalizePickerSearchThreshold, Combobox, Badge, useBlockContext, resolveMediaSlotContract, asRecord, parseAspectRatioValue, MediaEditor, PUBLIC_FILE_FIELD_KINDS, useBackendWatch, resolveIconPickerPreset, isIconPickerPreset, getIconPickerOptionsForPreset, isKnownIconName, getIconComponent, isOfferingsPreviewSourceKey, EyeOff, CommandMultiSelect, expectParsedBrandedId, parseSiteId, buildThemeRuntime, SdkConfigProvider, PaletteProvider, MediaEditorProvider, useEditorUiStoreInstance, useUISelector, getRichTextImagePositionFromTarget, insertOrReplaceRichTextImage, emitMediaCropDebug, Pencil, resolveVideoSelectionIntentForMediaField, resolveOfferingsPreviewGroupOrderEntries, normalizeOfferingsPreviewGroupOrder, inferLegacyOfferingsPreviewGroupOrder, siteOptionSources, evaluateVisibility, Root2, List, Trigger, Content, Input, Check, Label, isInternalResolvedLinkValue, resolveImageUrlWithContext, useMediaEditor, MediaPickerMini, MediaPickerDialog, toRoutableLinkPayload, classifyKnownMimeType, getDirectImageUrlForMediaAsset, isSvgMimeType } from './chunk-
|
|
2
|
+
import { KeyboardCode, getBlockDefinition, CSS, useSdkConfig, unwrapResponse, parseSiteIconStyleGuideVersionId, parseBlockIconValue, listBlockDescriptors, useSensor, PointerSensor, useSensors, createEditorRemoveBlockCommand, unsafeAsEditorBlockId, DndContext, closestCenter, Button, Plus, useDroppable, useDraggable, useCombinedRefs, isKeyboardEvent, createCustomBlockRegistry, Card, cn, Collapsible, CollapsibleContent, listContentTypes, mergeBlockDescriptorsWithRegistry, createEditorReorderBlocksCommand, mutateBlockContent, deleteEntrySlotBlock, deleteBlock, useDndContext, useUniqueId, useIsomorphicLayoutEffect, EmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Search, getClientRect, resolveBlockTitle, CardHeader, GripVertical, ChevronRight, CardTitle, ArrowUp, ArrowDown, DropdownMenu, DropdownMenuTrigger, EllipsisVertical, DropdownMenuContent, DropdownMenuSeparator, DropdownMenuItem, Copy, Trash2, DialogFooter, DialogClose, CardContent, createEntrySlotBlock, createBlock, createEditorInsertBlockCommand, reorderEntrySlotBlocks, reorderBlocks, LoaderCircle, ChevronDown, getFeatureCardIconCompletion, toFeatureCardIconSuggestionInputs, getBlockIconSemanticFallbackId, suggestSemanticIconForFeatureCard, getGeneratedBlockIconStyleState, assertNever, createManifestFormAdapter, getModalConfig, createStoreBackend, validateBlockManifestIssues, isNonEmptyValue, Settings, ScrollableDialogContent, FormRenderer, Tabs, TabsList, TabsTrigger, TabsContent, RotateCcw, ImagePlus, Sparkles, Textarea, Callout, CalloutDescription, normalEditorCuratedPromotedFieldPaths, resolveVisiblePromotedFieldPathsForEditorBlock, CalloutTitle, unfinishedBlockCopy, recoveryConflictCopy, ManifestForm, unsafeAsEditorBlockValues, Box, mergeManifestWithSdkOptions, augmentManifestWithStyleGroups, suggestFeatureCardSemanticIcons, applyFeatureCardIconSuggestions, createFeatureCardIconKey, lucide_react_exports, isThemeV2NormalEditorRawStylePath, getFieldIntent, isHeaderField, isThemeV2NormalEditorRawStyleFieldName, BackgroundGradientField, BackgroundColorField, useField, FieldFrame, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, useMediaEditorOptional, useRichTextEditor, RichTextEditorSurface, ThemeScope, isObjectRecord, EMPTY_DOC, useAsyncPickerOptions, resolvePickerSelectionLabel, shouldShowPickerSearch, normalizePickerSearchThreshold, Combobox, Badge, useBlockContext, resolveMediaSlotContract, asRecord, parseAspectRatioValue, MediaEditor, PUBLIC_FILE_FIELD_KINDS, useBackendWatch, resolveIconPickerPreset, isIconPickerPreset, getIconPickerOptionsForPreset, isKnownIconName, getIconComponent, isOfferingsPreviewSourceKey, EyeOff, CommandMultiSelect, expectParsedBrandedId, parseSiteId, buildThemeRuntime, SdkConfigProvider, PaletteProvider, MediaEditorProvider, useEditorUiStoreInstance, useUISelector, getRichTextImagePositionFromTarget, insertOrReplaceRichTextImage, emitMediaCropDebug, Pencil, resolveVideoSelectionIntentForMediaField, resolveOfferingsPreviewGroupOrderEntries, normalizeOfferingsPreviewGroupOrder, inferLegacyOfferingsPreviewGroupOrder, siteOptionSources, evaluateVisibility, Root2, List, Trigger, Content, Input, Check, Label, isInternalResolvedLinkValue, resolveImageUrlWithContext, useMediaEditor, MediaPickerMini, MediaPickerDialog, toRoutableLinkPayload, classifyKnownMimeType, getDirectImageUrlForMediaAsset, isSvgMimeType } from './chunk-O62NDCTI.mjs';
|
|
3
3
|
import React, { createContext, memo, useMemo, useState, useRef, useEffect, forwardRef, useCallback, useImperativeHandle, useContext, useSyncExternalStore, useLayoutEffect, Fragment as Fragment$1, useReducer } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
package/dist/cli/index.mjs
CHANGED
|
@@ -110,6 +110,30 @@ var init_collections = __esm({
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
// ../core/src/event-pricing.ts
|
|
113
|
+
function publicEventPricingType(pricing) {
|
|
114
|
+
switch (pricing.kind) {
|
|
115
|
+
case "drop_in":
|
|
116
|
+
case "free_registration":
|
|
117
|
+
return "free";
|
|
118
|
+
case "single_paid":
|
|
119
|
+
case "ticket_types":
|
|
120
|
+
case "course":
|
|
121
|
+
return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function isFreePublicEventPriceDisplay(display) {
|
|
125
|
+
switch (display.kind) {
|
|
126
|
+
case "free":
|
|
127
|
+
return true;
|
|
128
|
+
case "course":
|
|
129
|
+
return display.display.kind === "free";
|
|
130
|
+
case "exact":
|
|
131
|
+
case "from":
|
|
132
|
+
case "mixed":
|
|
133
|
+
case "unavailable":
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
113
137
|
var init_event_pricing = __esm({
|
|
114
138
|
"../core/src/event-pricing.ts"() {
|
|
115
139
|
}
|
|
@@ -140,8 +164,139 @@ var init_booking_instalments = __esm({
|
|
|
140
164
|
});
|
|
141
165
|
|
|
142
166
|
// ../core/src/booking-date-time.ts
|
|
167
|
+
function isValidTimeZone(timeZone) {
|
|
168
|
+
try {
|
|
169
|
+
new Intl.DateTimeFormat(DEFAULT_LOCALE, { timeZone }).format(/* @__PURE__ */ new Date());
|
|
170
|
+
return true;
|
|
171
|
+
} catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function getSafeTimeZone(timeZone) {
|
|
176
|
+
const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
|
|
177
|
+
return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
|
|
178
|
+
}
|
|
179
|
+
function parseStrictBookingTimeZone(timeZone) {
|
|
180
|
+
const normalized = timeZone.trim();
|
|
181
|
+
if (!normalized || !isValidTimeZone(normalized)) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
return normalized;
|
|
185
|
+
}
|
|
186
|
+
function formatParseError(error) {
|
|
187
|
+
switch (error.reason) {
|
|
188
|
+
case "invalid_starts_at":
|
|
189
|
+
return `Expected a valid UTC/offset-aware ISO datetime in startsAt, received "${error.value}"`;
|
|
190
|
+
case "invalid_ends_at":
|
|
191
|
+
return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
|
|
192
|
+
case "invalid_time_zone":
|
|
193
|
+
return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function formatToPartsLookup(date, locale, timeZone, format) {
|
|
197
|
+
return new Map(
|
|
198
|
+
new Intl.DateTimeFormat(locale, {
|
|
199
|
+
...format,
|
|
200
|
+
timeZone
|
|
201
|
+
}).formatToParts(date).map((part) => [part.type, part.value])
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
function getZonedDateTimeParts(date, timeZone) {
|
|
205
|
+
const parts = formatToPartsLookup(date, "en-GB", timeZone, {
|
|
206
|
+
year: "numeric",
|
|
207
|
+
month: "2-digit",
|
|
208
|
+
day: "2-digit",
|
|
209
|
+
hour: "2-digit",
|
|
210
|
+
minute: "2-digit",
|
|
211
|
+
second: "2-digit",
|
|
212
|
+
hour12: false
|
|
213
|
+
});
|
|
214
|
+
const read = (type) => Number(parts.get(type) ?? "");
|
|
215
|
+
return {
|
|
216
|
+
year: read("year"),
|
|
217
|
+
month: read("month"),
|
|
218
|
+
day: read("day"),
|
|
219
|
+
hour: read("hour"),
|
|
220
|
+
minute: read("minute"),
|
|
221
|
+
second: read("second")
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function formatDateKey(date) {
|
|
225
|
+
const year = String(date.year).padStart(4, "0");
|
|
226
|
+
const month = String(date.month).padStart(2, "0");
|
|
227
|
+
const day = String(date.day).padStart(2, "0");
|
|
228
|
+
return `${year}-${month}-${day}`;
|
|
229
|
+
}
|
|
230
|
+
function parseUtcIsoDateTimeString(value) {
|
|
231
|
+
const normalized = value.trim();
|
|
232
|
+
const hasUtcSuffix = normalized.endsWith("Z");
|
|
233
|
+
const hasExplicitOffset = /[+-]\d{2}:\d{2}$/u.test(normalized);
|
|
234
|
+
if (!hasUtcSuffix && !hasExplicitOffset) {
|
|
235
|
+
return err("missing-timezone-offset");
|
|
236
|
+
}
|
|
237
|
+
const date = new Date(normalized);
|
|
238
|
+
if (Number.isNaN(date.getTime())) {
|
|
239
|
+
return err("invalid-date-time");
|
|
240
|
+
}
|
|
241
|
+
return ok(date.toISOString());
|
|
242
|
+
}
|
|
243
|
+
function toUtcIsoDateTimeString(value) {
|
|
244
|
+
const parsed = parseUtcIsoDateTimeString(value);
|
|
245
|
+
if (!parsed.ok) {
|
|
246
|
+
const message = parsed.error === "missing-timezone-offset" ? `Expected an offset-aware ISO datetime, received "${value}"` : `Expected a valid ISO datetime, received "${value}"`;
|
|
247
|
+
throw new Error(message);
|
|
248
|
+
}
|
|
249
|
+
return parsed.value;
|
|
250
|
+
}
|
|
251
|
+
function parseScheduledBookingDateTime(input) {
|
|
252
|
+
try {
|
|
253
|
+
const startsAt = toUtcIsoDateTimeString(input.startsAt);
|
|
254
|
+
const timeZone = parseStrictBookingTimeZone(input.timeZone);
|
|
255
|
+
if (!timeZone) {
|
|
256
|
+
return {
|
|
257
|
+
ok: false,
|
|
258
|
+
field: "timeZone",
|
|
259
|
+
reason: "invalid_time_zone",
|
|
260
|
+
value: input.timeZone
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
ok: true,
|
|
265
|
+
value: {
|
|
266
|
+
startsAt,
|
|
267
|
+
timeZone,
|
|
268
|
+
locale: input.locale
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
} catch {
|
|
272
|
+
return {
|
|
273
|
+
ok: false,
|
|
274
|
+
field: "startsAt",
|
|
275
|
+
reason: "invalid_starts_at",
|
|
276
|
+
value: input.startsAt
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function toScheduledBookingDateTime(input) {
|
|
281
|
+
const result = parseScheduledBookingDateTime(input);
|
|
282
|
+
if (result.ok) {
|
|
283
|
+
return result.value;
|
|
284
|
+
}
|
|
285
|
+
throw new Error(formatParseError(result));
|
|
286
|
+
}
|
|
287
|
+
function getBookingLocalDateKey(input) {
|
|
288
|
+
return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
|
|
289
|
+
}
|
|
290
|
+
function getLocalScheduleDate(date, timeZone) {
|
|
291
|
+
const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
|
|
292
|
+
return { year: parts.year, month: parts.month, day: parts.day };
|
|
293
|
+
}
|
|
294
|
+
var DEFAULT_LOCALE, FALLBACK_TIMEZONE;
|
|
143
295
|
var init_booking_date_time = __esm({
|
|
144
296
|
"../core/src/booking-date-time.ts"() {
|
|
297
|
+
init_result();
|
|
298
|
+
DEFAULT_LOCALE = "en-US";
|
|
299
|
+
FALLBACK_TIMEZONE = "UTC";
|
|
145
300
|
}
|
|
146
301
|
});
|
|
147
302
|
|
|
@@ -18912,6 +19067,31 @@ var init_event_registration_shared = __esm({
|
|
|
18912
19067
|
}
|
|
18913
19068
|
});
|
|
18914
19069
|
|
|
19070
|
+
// ../blocks/src/system/constants/events.ts
|
|
19071
|
+
function isEventCalendarDisplayMode(value) {
|
|
19072
|
+
return typeof value === "string" && eventCalendarDisplayModeValues.includes(value);
|
|
19073
|
+
}
|
|
19074
|
+
function isEventCalendarListLayout(value) {
|
|
19075
|
+
return typeof value === "string" && eventCalendarListLayoutValues.includes(value);
|
|
19076
|
+
}
|
|
19077
|
+
function isEventContentType(slug) {
|
|
19078
|
+
if (!slug) return false;
|
|
19079
|
+
return EVENT_CONTENT_TYPE_SLUGS.includes(slug);
|
|
19080
|
+
}
|
|
19081
|
+
var EVENT_CONTENT_TYPE_SLUGS, eventCalendarDisplayModeValues, eventCalendarListLayoutValues, eventCalendarListLayoutOptions;
|
|
19082
|
+
var init_events = __esm({
|
|
19083
|
+
"../blocks/src/system/constants/events.ts"() {
|
|
19084
|
+
EVENT_CONTENT_TYPE_SLUGS = ["event", "events"];
|
|
19085
|
+
eventCalendarDisplayModeValues = ["combined", "month", "week", "list", "timetable"];
|
|
19086
|
+
eventCalendarListLayoutValues = ["stack", "grid", "compact"];
|
|
19087
|
+
eventCalendarListLayoutOptions = [
|
|
19088
|
+
{ id: "stack", label: "Stack" },
|
|
19089
|
+
{ id: "grid", label: "Grid" },
|
|
19090
|
+
{ id: "compact", label: "Compact" }
|
|
19091
|
+
];
|
|
19092
|
+
}
|
|
19093
|
+
});
|
|
19094
|
+
|
|
18915
19095
|
// ../blocks/src/system/runtime/nodes/events/shared/pricing.ts
|
|
18916
19096
|
function resolveRuntimeEventPricing(event) {
|
|
18917
19097
|
if (isPublicEventPricing(event.pricing)) {
|
|
@@ -19036,26 +19216,6 @@ var init_pricing = __esm({
|
|
|
19036
19216
|
DEFAULT_EVENT_CURRENCY = "USD";
|
|
19037
19217
|
}
|
|
19038
19218
|
});
|
|
19039
|
-
|
|
19040
|
-
// ../blocks/src/system/constants/events.ts
|
|
19041
|
-
function isEventCalendarDisplayMode(value) {
|
|
19042
|
-
return typeof value === "string" && eventCalendarDisplayModeValues.includes(value);
|
|
19043
|
-
}
|
|
19044
|
-
function isEventCalendarListLayout(value) {
|
|
19045
|
-
return typeof value === "string" && eventCalendarListLayoutValues.includes(value);
|
|
19046
|
-
}
|
|
19047
|
-
var eventCalendarDisplayModeValues, eventCalendarListLayoutValues, eventCalendarListLayoutOptions;
|
|
19048
|
-
var init_events = __esm({
|
|
19049
|
-
"../blocks/src/system/constants/events.ts"() {
|
|
19050
|
-
eventCalendarDisplayModeValues = ["combined", "month", "week", "list", "timetable"];
|
|
19051
|
-
eventCalendarListLayoutValues = ["stack", "grid", "compact"];
|
|
19052
|
-
eventCalendarListLayoutOptions = [
|
|
19053
|
-
{ id: "stack", label: "Stack" },
|
|
19054
|
-
{ id: "grid", label: "Grid" },
|
|
19055
|
-
{ id: "compact", label: "Compact" }
|
|
19056
|
-
];
|
|
19057
|
-
}
|
|
19058
|
-
});
|
|
19059
19219
|
var previewStageSchema, registrationButtonVariantSchema, eventButtonVariantSchema, eventLayoutSchema, eventCalendarDisplayModeSchema, columnOptionSchema, weekStartSchema, filterAutoShowSchema, calendarTabViewsSchema;
|
|
19060
19220
|
var init_contract_schemas = __esm({
|
|
19061
19221
|
"../blocks/src/system/runtime/nodes/shared/contract-schemas.ts"() {
|
|
@@ -19071,17 +19231,148 @@ var init_contract_schemas = __esm({
|
|
|
19071
19231
|
calendarTabViewsSchema = z.enum(["both", "month", "week"]);
|
|
19072
19232
|
}
|
|
19073
19233
|
});
|
|
19234
|
+
|
|
19235
|
+
// ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
|
|
19236
|
+
function getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep) {
|
|
19237
|
+
const baseSteps = hasPreSelectedContext ? ["select-tickets", "enter-details"] : ["select-event", "select-tickets", "enter-details"];
|
|
19238
|
+
if (!needsPaymentStep) {
|
|
19239
|
+
return baseSteps;
|
|
19240
|
+
}
|
|
19241
|
+
return [...baseSteps, "select-payment"];
|
|
19242
|
+
}
|
|
19243
|
+
var init_wizardSteps = __esm({
|
|
19244
|
+
"../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts"() {
|
|
19245
|
+
}
|
|
19246
|
+
});
|
|
19247
|
+
|
|
19248
|
+
// ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
|
|
19249
|
+
function eventMatchesOccurrenceId(event, occurrenceId) {
|
|
19250
|
+
return event.registrationOccurrenceId === occurrenceId || event.publicEventId === occurrenceId;
|
|
19251
|
+
}
|
|
19252
|
+
function findPreSelectedEvent(input) {
|
|
19253
|
+
const occurrenceContext = input.occurrenceContext;
|
|
19254
|
+
if (!occurrenceContext) {
|
|
19255
|
+
return null;
|
|
19256
|
+
}
|
|
19257
|
+
const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
|
|
19258
|
+
startsAt: occurrenceContext.startsAt,
|
|
19259
|
+
timeZone: occurrenceContext.timeZone
|
|
19260
|
+
}));
|
|
19261
|
+
return input.scopedEvents.find(
|
|
19262
|
+
(event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
|
|
19263
|
+
startsAt: event.startsAt,
|
|
19264
|
+
timeZone: event.timeZone
|
|
19265
|
+
})) === contextDate
|
|
19266
|
+
) ?? null;
|
|
19267
|
+
}
|
|
19268
|
+
function resolveEventRequiresPayment(input) {
|
|
19269
|
+
if (input.eligibility) {
|
|
19270
|
+
return input.eligibility.requiresPayment;
|
|
19271
|
+
}
|
|
19272
|
+
if (!input.event) {
|
|
19273
|
+
return false;
|
|
19274
|
+
}
|
|
19275
|
+
return publicEventPricingType(resolveRuntimeEventPricing(input.event)) !== "free";
|
|
19276
|
+
}
|
|
19277
|
+
var init_registrationDerivations = __esm({
|
|
19278
|
+
"../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts"() {
|
|
19279
|
+
init_src();
|
|
19280
|
+
init_pricing();
|
|
19281
|
+
}
|
|
19282
|
+
});
|
|
19283
|
+
|
|
19284
|
+
// ../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts
|
|
19285
|
+
function toRegistrationEvent(event) {
|
|
19286
|
+
return {
|
|
19287
|
+
...event,
|
|
19288
|
+
pricing: resolveRuntimeEventPricing(event),
|
|
19289
|
+
publicEventId: event.id,
|
|
19290
|
+
registrationOccurrenceId: event.occurrenceId
|
|
19291
|
+
};
|
|
19292
|
+
}
|
|
19293
|
+
function toRegistrationEvents(events) {
|
|
19294
|
+
return events.map(toRegistrationEvent);
|
|
19295
|
+
}
|
|
19296
|
+
var init_registrationEventAdapter = __esm({
|
|
19297
|
+
"../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts"() {
|
|
19298
|
+
init_pricing();
|
|
19299
|
+
}
|
|
19300
|
+
});
|
|
19074
19301
|
function buildEventRegistrationDisplay(source) {
|
|
19302
|
+
const stepLabels = buildEventRegistrationShellStepLabels(source);
|
|
19075
19303
|
return {
|
|
19076
19304
|
kind: "event-registration",
|
|
19077
19305
|
state: "generic-shell",
|
|
19078
19306
|
className: source.className ?? null,
|
|
19079
19307
|
titleText: "Event registration",
|
|
19080
|
-
bodyText:
|
|
19081
|
-
stepLabels
|
|
19308
|
+
bodyText: buildEventRegistrationShellBodyText(stepLabels),
|
|
19309
|
+
stepLabels,
|
|
19082
19310
|
summaryButtonText: source.buttonText?.trim() || "Register"
|
|
19083
19311
|
};
|
|
19084
19312
|
}
|
|
19313
|
+
function buildEventRegistrationShellStepLabels(source) {
|
|
19314
|
+
const scopedEvents = scopeEventRegistrationEvents(source);
|
|
19315
|
+
if (scopedEvents.length === 0) {
|
|
19316
|
+
return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
|
|
19317
|
+
}
|
|
19318
|
+
const preSelectedEvent = findPreSelectedEvent({
|
|
19319
|
+
scopedEvents,
|
|
19320
|
+
occurrenceContext: source.occurrenceContext
|
|
19321
|
+
});
|
|
19322
|
+
const hasPreSelectedContext = Boolean(source.occurrenceContext || preSelectedEvent);
|
|
19323
|
+
const needsPaymentStep = hasPreSelectedContext && preSelectedEvent ? resolveEventRequiresPayment({
|
|
19324
|
+
eligibility: null,
|
|
19325
|
+
event: preSelectedEvent
|
|
19326
|
+
}) : false;
|
|
19327
|
+
return getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep).map((step) => shellLabelForRegistrationStep(step, scopedEvents));
|
|
19328
|
+
}
|
|
19329
|
+
function scopeEventRegistrationEvents(source) {
|
|
19330
|
+
const events = toRegistrationEvents(source.events ?? []);
|
|
19331
|
+
if (source.occurrenceContext?.seriesId) {
|
|
19332
|
+
return events.filter((event) => event.seriesId === source.occurrenceContext?.seriesId);
|
|
19333
|
+
}
|
|
19334
|
+
const entrySlug = source.contentEntry?.slug;
|
|
19335
|
+
const entryContentType = source.contentEntry?.contentTypeSlug;
|
|
19336
|
+
if (entrySlug && entryContentType && isEventContentType(entryContentType)) {
|
|
19337
|
+
return events.filter((event) => event.slug === entrySlug);
|
|
19338
|
+
}
|
|
19339
|
+
return events;
|
|
19340
|
+
}
|
|
19341
|
+
function shellLabelForRegistrationStep(step, events) {
|
|
19342
|
+
switch (step) {
|
|
19343
|
+
case "select-event":
|
|
19344
|
+
return isDateSelection(events) ? "Date" : "Event";
|
|
19345
|
+
case "select-tickets":
|
|
19346
|
+
return "Tickets";
|
|
19347
|
+
case "enter-details":
|
|
19348
|
+
return "Details";
|
|
19349
|
+
case "select-payment":
|
|
19350
|
+
return "Payment";
|
|
19351
|
+
case "error":
|
|
19352
|
+
case "success":
|
|
19353
|
+
case "submitting":
|
|
19354
|
+
case "redirecting":
|
|
19355
|
+
case "verifying-payment":
|
|
19356
|
+
case "verifying-timeout":
|
|
19357
|
+
case "payment-failed":
|
|
19358
|
+
return "Details";
|
|
19359
|
+
}
|
|
19360
|
+
}
|
|
19361
|
+
function isDateSelection(events) {
|
|
19362
|
+
const firstSeriesId = events[0]?.seriesId;
|
|
19363
|
+
return Boolean(
|
|
19364
|
+
events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId)
|
|
19365
|
+
);
|
|
19366
|
+
}
|
|
19367
|
+
function buildEventRegistrationShellBodyText(stepLabels) {
|
|
19368
|
+
if (stepLabels.includes("Payment")) {
|
|
19369
|
+
return "Preparing tickets, details, and payment options.";
|
|
19370
|
+
}
|
|
19371
|
+
if (stepLabels[0] === "Tickets") {
|
|
19372
|
+
return "Preparing tickets and booking details.";
|
|
19373
|
+
}
|
|
19374
|
+
return "Preparing dates, tickets, and booking details.";
|
|
19375
|
+
}
|
|
19085
19376
|
function normalizeEventRegistrationEventInput(value) {
|
|
19086
19377
|
if (!isRecord5(value)) {
|
|
19087
19378
|
return value;
|
|
@@ -19094,21 +19385,21 @@ function normalizeEventRegistrationEventInput(value) {
|
|
|
19094
19385
|
function isRecord5(value) {
|
|
19095
19386
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19096
19387
|
}
|
|
19097
|
-
var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS,
|
|
19388
|
+
var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, EVENT_REGISTRATION_SHELL_STEP_LABELS, contentEntrySchema, eventRegistrationPublicEventSchema, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationBlockRuntime;
|
|
19098
19389
|
var init_event_registration_interactive = __esm({
|
|
19099
19390
|
"../blocks/src/system/runtime/nodes/event-registration.interactive.ts"() {
|
|
19100
19391
|
init_schemas2();
|
|
19101
19392
|
init_event_registration_shared();
|
|
19393
|
+
init_events();
|
|
19102
19394
|
init_pricing();
|
|
19103
19395
|
init_islands();
|
|
19104
19396
|
init_runtime();
|
|
19105
19397
|
init_contract_schemas();
|
|
19398
|
+
init_wizardSteps();
|
|
19399
|
+
init_registrationDerivations();
|
|
19400
|
+
init_registrationEventAdapter();
|
|
19106
19401
|
EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = ["Date", "Tickets", "Details"];
|
|
19107
|
-
[
|
|
19108
|
-
eventRegistrationGenericDateStepLabel,
|
|
19109
|
-
eventRegistrationGenericTicketsStepLabel,
|
|
19110
|
-
eventRegistrationGenericDetailsStepLabel
|
|
19111
|
-
] = EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
|
|
19402
|
+
EVENT_REGISTRATION_SHELL_STEP_LABELS = ["Event", "Date", "Tickets", "Details", "Payment"];
|
|
19112
19403
|
contentEntrySchema = z.object({
|
|
19113
19404
|
id: z.string(),
|
|
19114
19405
|
slug: z.string(),
|
|
@@ -19144,11 +19435,7 @@ var init_event_registration_interactive = __esm({
|
|
|
19144
19435
|
className: z.string().nullable(),
|
|
19145
19436
|
titleText: z.string(),
|
|
19146
19437
|
bodyText: z.string(),
|
|
19147
|
-
stepLabels: z.
|
|
19148
|
-
z.literal(eventRegistrationGenericDateStepLabel),
|
|
19149
|
-
z.literal(eventRegistrationGenericTicketsStepLabel),
|
|
19150
|
-
z.literal(eventRegistrationGenericDetailsStepLabel)
|
|
19151
|
-
]),
|
|
19438
|
+
stepLabels: z.array(z.enum(EVENT_REGISTRATION_SHELL_STEP_LABELS)).min(1),
|
|
19152
19439
|
summaryButtonText: z.string()
|
|
19153
19440
|
});
|
|
19154
19441
|
eventRegistrationHydrationSchema = z.object({
|
|
@@ -63780,7 +64067,8 @@ async function initDocs(options) {
|
|
|
63780
64067
|
{ filename: "cmsify-page.md", template: "workflow-cmsify-page" },
|
|
63781
64068
|
{ filename: "editor-workflows.md", template: "workflow-editor-workflows" },
|
|
63782
64069
|
{ filename: "preview-mode.md", template: "workflow-preview-mode" },
|
|
63783
|
-
{ filename: "isr-revalidation.md", template: "workflow-isr-revalidation" }
|
|
64070
|
+
{ filename: "isr-revalidation.md", template: "workflow-isr-revalidation" },
|
|
64071
|
+
{ filename: "agent-safe-sync.md", template: "workflow-agent-safe-sync" }
|
|
63784
64072
|
];
|
|
63785
64073
|
await Promise.all(
|
|
63786
64074
|
coreWorkflows.map(
|
|
@@ -64108,7 +64396,7 @@ var SimpleCache = class {
|
|
|
64108
64396
|
};
|
|
64109
64397
|
|
|
64110
64398
|
// src/version.ts
|
|
64111
|
-
var SDK_VERSION = "0.84.
|
|
64399
|
+
var SDK_VERSION = "0.84.1";
|
|
64112
64400
|
|
|
64113
64401
|
// src/client/error.ts
|
|
64114
64402
|
var RiverbankApiError = class _RiverbankApiError extends Error {
|
|
@@ -25,6 +25,7 @@ Detailed documentation is available in `.riverbank/docs/`:
|
|
|
25
25
|
- `block-types.md` - Available block types (auto-generated)
|
|
26
26
|
- `theme-schema.md` - Theme schema reference (auto-generated from Zod)
|
|
27
27
|
- `workflows/` - Step-by-step guides for common tasks, including editor workflows
|
|
28
|
+
- `workflows/agent-safe-sync.md` - Agent-safe dry-run, scoped push, and `--env` guidance
|
|
28
29
|
- `site-workflows/` - Site-specific workflows and customizations
|
|
29
30
|
|
|
30
31
|
### Quick Commands
|
|
@@ -36,6 +37,8 @@ riverbankcms push # Push local changes to CMS
|
|
|
36
37
|
riverbankcms push-config # Sync riverbank.config.ts schema/config to CMS
|
|
37
38
|
```
|
|
38
39
|
|
|
40
|
+
Use CLI `--env=remote` / `--env=local` for CMS commands rather than relying on `RIVERBANK_ENV=...` shell prefixes. Site `.env.local` files may set `RIVERBANK_ENV`, and the CLI flag is the explicit source of truth for sync operations.
|
|
41
|
+
|
|
39
42
|
### Working with Content
|
|
40
43
|
|
|
41
44
|
1. **Pull latest**: `riverbankcms pull` downloads content to `content/` directory
|
|
@@ -43,6 +46,8 @@ riverbankcms push-config # Sync riverbank.config.ts schema/config to CMS
|
|
|
43
46
|
3. **Preview**: `riverbankcms push --dry-run` shows what would change
|
|
44
47
|
4. **Push**: `riverbankcms push` applies changes to CMS
|
|
45
48
|
|
|
49
|
+
For narrow edits, push the narrowest scope possible, for example `riverbankcms push pages privacy-policy --env=remote --dry-run`. If broad local content is stale or contains unrelated differences, see `.riverbank/docs/workflows/agent-safe-sync.md`.
|
|
50
|
+
|
|
46
51
|
### Editing Page Content Directly
|
|
47
52
|
|
|
48
53
|
Page content lives in `content/pages/[identifier].json`. Each page has a `blocks` array containing the actual content. To edit copy:
|
|
@@ -25,6 +25,8 @@ All commands support these options:
|
|
|
25
25
|
- Remote operations default to dry-run and require `--yes` to execute
|
|
26
26
|
- When using `--env=both`, local runs first, then remote with the same safety rules
|
|
27
27
|
|
|
28
|
+
Prefer the CLI `--env` flag over shell prefixes such as `RIVERBANK_ENV=remote riverbankcms ...`. Site `.env.local` files may define `RIVERBANK_ENV`, and command-specific `--env` is the reliable way to target local or remote CMS sync.
|
|
29
|
+
|
|
28
30
|
## Environment Variables
|
|
29
31
|
|
|
30
32
|
### Local Environment (default)
|
|
@@ -148,6 +150,15 @@ riverbankcms push --dry-run --json-diff=summary
|
|
|
148
150
|
riverbankcms push --dry-run --json-diff=full
|
|
149
151
|
```
|
|
150
152
|
|
|
153
|
+
**Agent-safe scoped push example:**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
riverbankcms push pages privacy-policy --env=remote --dry-run
|
|
157
|
+
riverbankcms push pages privacy-policy --env=remote --yes
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
If unrelated local files would be included by a broad scope, stage a temporary content directory containing only the intended file(s) and use `--content-dir`; see `workflows/agent-safe-sync.md`.
|
|
161
|
+
|
|
151
162
|
**Options:**
|
|
152
163
|
|
|
153
164
|
| Option | Description |
|
|
@@ -284,6 +295,8 @@ riverbankcms push-config --config ./src/riverbank.config.ts
|
|
|
284
295
|
|
|
285
296
|
Syncs SDK schema/config surfaces such as custom blocks, block field options/extensions, content type definitions/templates, SDK-managed site settings, and footer blocks. Pages, entries, and navigation menus are synced with explicit `riverbankcms push` scopes.
|
|
286
297
|
|
|
298
|
+
If `push-config` returns template binding validation errors, treat them as schema feedback. For example, a content type `reference` field should bind to a custom block `reference` field with the same `referenceKind`, not to a plain `text` field.
|
|
299
|
+
|
|
287
300
|
This syncs:
|
|
288
301
|
|
|
289
302
|
- Custom blocks
|
|
@@ -314,6 +314,35 @@ riverbankcms push --dry-run
|
|
|
314
314
|
riverbankcms push
|
|
315
315
|
```
|
|
316
316
|
|
|
317
|
+
For agent work, prefer scoped pushes over broad pushes:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# One page
|
|
321
|
+
riverbankcms push pages privacy-policy --env=remote --dry-run
|
|
322
|
+
riverbankcms push pages privacy-policy --env=remote --yes
|
|
323
|
+
|
|
324
|
+
# One content type or entry
|
|
325
|
+
riverbankcms push entries blog-post --env=remote --dry-run
|
|
326
|
+
riverbankcms push entries blog-post welcome --env=remote --dry-run
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Use CLI `--env=local` / `--env=remote` rather than `RIVERBANK_ENV=...` shell prefixes for sync commands. Site `.env.local` files may set `RIVERBANK_ENV`, while the CLI flag explicitly selects the sync target.
|
|
330
|
+
|
|
331
|
+
If local files include unrelated page or entry differences, isolate the changed files with `--content-dir`:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
tmpdir=$(mktemp -d)
|
|
335
|
+
mkdir -p "$tmpdir/pages"
|
|
336
|
+
cp content/pages/privacy-policy.json "$tmpdir/pages/privacy-policy.json"
|
|
337
|
+
|
|
338
|
+
riverbankcms push pages --content-dir "$tmpdir" --env=remote --dry-run
|
|
339
|
+
riverbankcms push pages --content-dir "$tmpdir" --env=remote --yes
|
|
340
|
+
|
|
341
|
+
rm -rf "$tmpdir"
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
See `workflows/agent-safe-sync.md` for the full safe-push checklist.
|
|
345
|
+
|
|
317
346
|
### Sync Configuration
|
|
318
347
|
|
|
319
348
|
Configure sync behavior in `riverbank.config.ts`:
|
|
@@ -328,6 +357,8 @@ export default defineConfig({
|
|
|
328
357
|
});
|
|
329
358
|
```
|
|
330
359
|
|
|
360
|
+
`push-config` syncs schema/config surfaces such as custom blocks, block extensions/options, content type schemas/templates, SDK-managed settings, and footer blocks. It does not replace `push pages`, `push entries`, or `push navigation` for file-backed content.
|
|
361
|
+
|
|
331
362
|
| Option | Values | Description |
|
|
332
363
|
| ----------------- | ---------------- | -------------------------------------------- |
|
|
333
364
|
| `existingEntries` | `skip`, `update` | Whether to update entries that already exist |
|
|
@@ -92,6 +92,7 @@ Event registration blocks need both the SDK base stylesheet and a runtime theme
|
|
|
92
92
|
| `block-types.md` | Available block types (auto-generated) |
|
|
93
93
|
| `theme-schema.md` | Theme schema reference (auto-generated from Zod) |
|
|
94
94
|
| `workflows/` | Step-by-step guides for common tasks, including editor workflows |
|
|
95
|
+
| `workflows/agent-safe-sync.md` | Agent-safe dry-run, scoped push, and stale-content handling |
|
|
95
96
|
|
|
96
97
|
## Common Tasks
|
|
97
98
|
|
|
@@ -138,6 +139,17 @@ riverbankcms push --env=remote --yes
|
|
|
138
139
|
|
|
139
140
|
**Safety note:** Remote push requires `--yes` flag to prevent accidental production changes.
|
|
140
141
|
|
|
142
|
+
Prefer the CLI `--env` flag over shell prefixes such as `RIVERBANK_ENV=remote riverbankcms ...`. Site `.env.local` files often contain their own `RIVERBANK_ENV` value, while `--env=remote` is explicit and reliable for CLI sync commands.
|
|
143
|
+
|
|
144
|
+
For narrow production edits, dry-run and apply the smallest scope:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
riverbankcms push pages privacy-policy --env=remote --dry-run
|
|
148
|
+
riverbankcms push pages privacy-policy --env=remote --yes
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
If local content includes unrelated differences, see `workflows/agent-safe-sync.md` for the temporary `--content-dir` pattern.
|
|
152
|
+
|
|
141
153
|
## Media Safety (Avoid Broken Images)
|
|
142
154
|
|
|
143
155
|
- Portable content JSON should store media as **identifier-only** (no `assetId` / storage paths / `src`).
|
|
@@ -25,6 +25,8 @@ View built-in blocks in `block-types.md`. Common block kinds:
|
|
|
25
25
|
|
|
26
26
|
Check `schema.md` for custom blocks specific to this site.
|
|
27
27
|
|
|
28
|
+
Prefer built-in blocks before creating a custom block. For a simple policy/terms/about page, use `block.body-text` and put the page title, intro, and section headings in the rich text body. Only create a custom block when the needed structure or behavior cannot be represented by built-in blocks plus styling.
|
|
29
|
+
|
|
28
30
|
### 2. List Existing Blocks
|
|
29
31
|
|
|
30
32
|
See what blocks are already on the page:
|
|
@@ -62,7 +64,7 @@ Add a body text block:
|
|
|
62
64
|
```bash
|
|
63
65
|
riverbankcms block upsert home intro-content \
|
|
64
66
|
--kind block.body-text \
|
|
65
|
-
--data '{"content": "
|
|
67
|
+
--data '{"body": {"type": "doc", "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Welcome to our site. We offer..."}]}]}}'
|
|
66
68
|
```
|
|
67
69
|
|
|
68
70
|
Add an image block:
|