riverbankcms 0.22.0 → 0.22.2

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $t as footerPreferencesSchema, C as stableStringify, Ct as themeSchema, D as evaluateSiteCommandBatchExposure, Fn as buildMediaIdentifierFromFilename, Gn as normalizeAmbiguousStoragePathForSite, Hn as getExtensionForMimeType, J as createContentEntryRef, Jn as MAX_MANAGEMENT_MEDIA_UPLOAD_BYTES, N as entryIdentifierForCommand, O as evaluateSiteCommandExposure, Qt as pageDesignIntentSchemaVersion, Rn as resolveMediaIdentifier, T as parseAndPlanCommandBatchForTypes, Un as getMimeType, Ut as buttonStyleSelectionSchema, Zt as pageDesignBoundaryTreatmentSchema, it as slugPart, k as getSiteCommandMetadata, lr as asPageFlowPresetId, m as isInternalResolvedLinkValue, n as sdkCourseBookingSettingsSchema, or as asAppearancePresetId, q as createCommandRef, qn as FILE_SIZE_LIMITS, r as sdkEventOccurrenceInputSchema, s as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, tt as createSiteCommandSiteRef, ur as asSiteStyleId, w as createDryRunReport, wn as getDirectImageUrlForSiteScopedPath, y as eventVisibilitySchema, z as eventBookingOfferIntentSchema, zn as slugifyMediaIdentifier } from "./sdk-event-upsert-BqjzK2zT.mjs";
3
- import { Bn as ok, Cn as unsafeAsOccurrenceId, M as parseFooterCompositionV1, Pn as unsafeAsStaffMemberId, S as parseManagementKey, Xt as assertNever, a as canonicalizeConfiguredBookingVerticalConfig, an as parsePageId, b as createSecret, bn as unsafeAsEventSeriesId, c as resolveSiteVerticalBookingConfig, i as areConfiguredBookingVerticalConfigsEqual, l as DEFAULT_EVENT_TYPE_PRESETS, m as publicReadFreshnessSeconds, o as parseVerticalId, s as parseVerticalPresetId, sn as parseSiteId, t as resolveEventCatalogue, u as EVENT_PRESET_VALUES, un as unsafeAsAppointmentResourceId, x as exposeSecret, yn as unsafeAsEventOfferingId, zn as err } from "./src-zzwJUef5.mjs";
4
- import { n as CliSdkPeerError, t as loadConfigFile } from "./load-config-j58KSqxl.mjs";
2
+ import { $t as pageDesignIntentSchemaVersion, A as getSiteCommandMetadata, B as eventBookingOfferIntentSchema, Dn as getDirectImageUrlForSiteScopedPath, E as parseAndPlanCommandBatchForTypes, Gn as getExtensionForMimeType, Hn as slugifyMediaIdentifier, J as createCommandRef, Jn as normalizeAmbiguousStoragePathForSite, Kn as getMimeType, O as evaluateSiteCommandBatchExposure, P as entryIdentifierForCommand, Qt as pageDesignBoundaryTreatmentSchema, Rn as buildMediaIdentifierFromFilename, T as createDryRunReport, Vn as resolveMediaIdentifier, Wt as buttonStyleSelectionSchema, Xn as FILE_SIZE_LIMITS, Y as createContentEntryRef, Zn as MAX_MANAGEMENT_MEDIA_UPLOAD_BYTES, at as slugPart, en as footerPreferencesSchema, fr as asPageFlowPresetId, k as evaluateSiteCommandExposure, lr as asAppearancePresetId, m as isInternalResolvedLinkValue, n as sdkCourseBookingSettingsSchema, nt as createSiteCommandSiteRef, pr as asSiteStyleId, r as sdkEventOccurrenceInputSchema, s as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, w as stableStringify, wt as themeSchema, x as resolvePageUpsertSeo, y as eventVisibilitySchema } from "./sdk-event-upsert-zWw5VolM.mjs";
3
+ import { $t as assertNever, Cn as unsafeAsEventSeriesId, En as unsafeAsOccurrenceId, Hn as err, K as formatDate, Ln as unsafeAsStaffMemberId, M as parseFooterCompositionV1, S as parseManagementKey, Sn as unsafeAsEventOfferingId, Un as ok, a as canonicalizeConfiguredBookingVerticalConfig, b as createSecret, c as resolveSiteVerticalBookingConfig, cn as parsePageId, ct as parseBookingLocalDate, ft as resolveBookingTimeZoneId, i as areConfiguredBookingVerticalConfigsEqual, l as DEFAULT_EVENT_TYPE_PRESETS, m as publicReadFreshnessSeconds, o as parseVerticalId, pn as unsafeAsAppointmentResourceId, s as parseVerticalPresetId, t as resolveEventCatalogue, u as EVENT_PRESET_VALUES, un as parseSiteId, x as exposeSecret } from "./src-ZACBG29u.mjs";
4
+ import { n as CliSdkPeerError, t as loadConfigFile } from "./load-config-BV9Ig2CH.mjs";
5
5
  import { Command } from "commander";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import * as fs$1 from "fs/promises";
@@ -414,6 +414,12 @@ const newsletterUsageLocationSchemas = [z.object({
414
414
  campaignName: z.string()
415
415
  })];
416
416
  const mediaUsageLocationSchema = z.discriminatedUnion("kind", [
417
+ z.object({
418
+ kind: z.literal("appointmentService"),
419
+ siteId: identifierSchema,
420
+ serviceId: identifierSchema,
421
+ serviceTitle: z.string()
422
+ }),
417
423
  ...newsletterUsageLocationSchemas,
418
424
  z.object({
419
425
  kind: z.literal("pageBlock"),
@@ -661,6 +667,8 @@ const sdkPullTruncationSchema = z.union([
661
667
  })
662
668
  ]);
663
669
  const sdkPullPageSchema = z.object({
670
+ seoTitle: z.string().nullable().optional(),
671
+ seoDescription: z.string().nullable().optional(),
664
672
  id: sdkIdentifierSchema$1,
665
673
  identifier: sdkIdentifierSchema$1,
666
674
  title: z.string(),
@@ -1839,6 +1847,34 @@ function createHttpClient(config) {
1839
1847
  };
1840
1848
  }
1841
1849
 
1850
+ //#endregion
1851
+ //#region ../management-client/src/appointmentServices.ts
1852
+ function createAppointmentServiceOperations(http) {
1853
+ return {
1854
+ async list() {
1855
+ const result = await http.get("/appointment-services");
1856
+ return result.services;
1857
+ },
1858
+ async get(serviceId) {
1859
+ try {
1860
+ const result = await http.get(`/appointment-services/${encodeURIComponent(serviceId)}`);
1861
+ return result.service;
1862
+ } catch (error) {
1863
+ if (is404Error(error)) return null;
1864
+ throw error;
1865
+ }
1866
+ },
1867
+ async create(input) {
1868
+ const result = await http.post("/appointment-services", input, "write");
1869
+ return result.service;
1870
+ },
1871
+ async update(serviceId, input) {
1872
+ const result = await http.patch(`/appointment-services/${encodeURIComponent(serviceId)}`, input);
1873
+ return result.service;
1874
+ }
1875
+ };
1876
+ }
1877
+
1842
1878
  //#endregion
1843
1879
  //#region ../management-client/src/entries.ts
1844
1880
  /**
@@ -1907,6 +1943,8 @@ function mapPulledPage(page) {
1907
1943
  id: page.id,
1908
1944
  identifier: page.identifier,
1909
1945
  title: page.title,
1946
+ ...page.seoTitle !== undefined ? { seoTitle: page.seoTitle } : {},
1947
+ ...page.seoDescription !== undefined ? { seoDescription: page.seoDescription } : {},
1910
1948
  path: page.path,
1911
1949
  status: page.status,
1912
1950
  hasUnpublishedChanges: page.hasUnpublishedChanges,
@@ -2617,6 +2655,7 @@ function createManagementClient(config) {
2617
2655
  }
2618
2656
  const http = createHttpClient(config);
2619
2657
  return {
2658
+ appointmentServices: createAppointmentServiceOperations(http),
2620
2659
  entries: createEntryOperations(http),
2621
2660
  pages: createPageOperations(http),
2622
2661
  blocks: createBlockOperations(http),
@@ -3850,16 +3889,23 @@ function parsePaginationOptions(options) {
3850
3889
  };
3851
3890
  }
3852
3891
  /**
3853
- * Format an ISO date string to a short date (YYYY-MM-DD).
3892
+ * Format an ISO calendar day for human-readable metadata columns.
3893
+ * Keep the source's lexical day; these cross-site facts have no business zone.
3854
3894
  *
3855
3895
  * @param isoDate - ISO date string (e.g., "2024-01-15T10:30:00Z")
3856
- * @returns Short date string (e.g., "2024-01-15")
3896
+ * @returns Short date string (e.g., "15 Jan 2024")
3857
3897
  *
3858
3898
  * @example
3859
- * formatDateShort("2024-01-15T10:30:00Z") // "2024-01-15"
3899
+ * formatDateShort("2024-01-15T10:30:00Z") // "15 Jan 2024"
3860
3900
  */
3861
3901
  function formatDateShort(isoDate) {
3862
- return isoDate.split("T")[0] ?? "";
3902
+ return formatDate({
3903
+ kind: "civil",
3904
+ value: parseBookingLocalDate(isoDate.split("T")[0] ?? "")
3905
+ }, {
3906
+ locale: "en-GB",
3907
+ timeZone: resolveBookingTimeZoneId("UTC")
3908
+ }, { date: "short" });
3863
3909
  }
3864
3910
  /**
3865
3911
  * Parse JSON data from --data flag or --file flag.
@@ -6357,6 +6403,47 @@ const SDK_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
6357
6403
  }
6358
6404
  });
6359
6405
 
6406
+ //#endregion
6407
+ //#region ../api/src/sdkAppointmentServiceEndpointDefinitions.ts
6408
+ const SDK_APPOINTMENT_SERVICE_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
6409
+ sdkListAppointmentServices: {
6410
+ path: "/sdk/{siteId}/appointment-services",
6411
+ method: "GET",
6412
+ auth: "service",
6413
+ responseKind: "json",
6414
+ errors: ["server:internal_error"]
6415
+ },
6416
+ sdkCreateAppointmentService: {
6417
+ path: "/sdk/{siteId}/appointment-services",
6418
+ method: "POST",
6419
+ auth: "service",
6420
+ responseKind: "json",
6421
+ errors: [
6422
+ "validation:invalid_input",
6423
+ "resource:not_found",
6424
+ "server:internal_error"
6425
+ ]
6426
+ },
6427
+ sdkGetAppointmentService: {
6428
+ path: "/sdk/{siteId}/appointment-services/{serviceId}",
6429
+ method: "GET",
6430
+ auth: "service",
6431
+ responseKind: "json",
6432
+ errors: ["resource:not_found", "server:internal_error"]
6433
+ },
6434
+ sdkUpdateAppointmentService: {
6435
+ path: "/sdk/{siteId}/appointment-services/{serviceId}",
6436
+ method: "PATCH",
6437
+ auth: "service",
6438
+ responseKind: "json",
6439
+ errors: [
6440
+ "validation:invalid_input",
6441
+ "resource:not_found",
6442
+ "server:internal_error"
6443
+ ]
6444
+ }
6445
+ });
6446
+
6360
6447
  //#endregion
6361
6448
  //#region ../api/src/sdkPageDesignEndpointDefinitions.ts
6362
6449
  /**
@@ -12404,6 +12491,7 @@ const ENDPOINT_DEFINITIONS = {
12404
12491
  auth: "service",
12405
12492
  responseKind: "json"
12406
12493
  },
12494
+ ...SDK_APPOINTMENT_SERVICE_ENDPOINT_DEFINITIONS,
12407
12495
  sdkUpsertEventCategory: {
12408
12496
  path: "/sdk/{siteId}/event-categories",
12409
12497
  method: "POST",
@@ -17095,6 +17183,8 @@ function convertPulledPagesToLocal(remotePages) {
17095
17183
  return remotePages.map((page) => ({
17096
17184
  identifier: page.identifier,
17097
17185
  title: page.title,
17186
+ ...page.seoTitle != null ? { seoTitle: page.seoTitle } : {},
17187
+ ...page.seoDescription != null ? { seoDescription: page.seoDescription } : {},
17098
17188
  path: page.path,
17099
17189
  status: page.status,
17100
17190
  hasUnpublishedChanges: page.hasUnpublishedChanges,
@@ -20831,6 +20921,18 @@ function calculateEntryDiffs(localEntries, remoteEntries, options) {
20831
20921
  };
20832
20922
  }
20833
20923
 
20924
+ //#endregion
20925
+ //#region src/site-commands/pageMetadata.ts
20926
+ /** The supported metadata sent by a CLI page upsert; empty SEO is omitted. */
20927
+ function pageMetadataForUpsert(page) {
20928
+ return {
20929
+ title: page.title,
20930
+ path: page.path,
20931
+ ...page.seoTitle ? { seoTitle: page.seoTitle } : {},
20932
+ ...page.seoDescription ? { seoDescription: page.seoDescription } : {}
20933
+ };
20934
+ }
20935
+
20834
20936
  //#endregion
20835
20937
  //#region src/sync/pageDiff.ts
20836
20938
  function createPageSummary() {
@@ -20879,7 +20981,9 @@ function recordBlockDiff(summary, diff) {
20879
20981
  case "unchanged":
20880
20982
  summary.unchanged++;
20881
20983
  break;
20882
- case "reorder": break;
20984
+ case "reorder":
20985
+ summary.update++;
20986
+ break;
20883
20987
  }
20884
20988
  }
20885
20989
  function createBlockDiffs(blocks, pageIdentifier, summary) {
@@ -20922,64 +21026,47 @@ function classifyBlock(localBlock, remoteBlock, pageIdentifier) {
20922
21026
  };
20923
21027
  }
20924
21028
  function buildRemoteBlockLookup(remoteBlocks) {
20925
- const lookup = new Map();
20926
- for (const block of remoteBlocks) lookup.set(block.identifier, block);
20927
- return lookup;
21029
+ return new Map(remoteBlocks.map((block) => [block.identifier, block]));
20928
21030
  }
20929
- function appendLocalBlockDiffs(localBlocks, remoteLookup, pageIdentifier, summary) {
20930
- const diffs = [];
20931
- for (const localBlock of localBlocks) {
20932
- const diff = classifyBlock(localBlock, remoteLookup.get(localBlock.identifier), pageIdentifier);
20933
- diffs.push(diff);
20934
- recordBlockDiff(summary, diff);
20935
- }
20936
- return diffs;
21031
+ function localBlockDiffs(localBlocks, remoteLookup, pageIdentifier) {
21032
+ return localBlocks.map((block) => classifyBlock(block, remoteLookup.get(block.identifier), pageIdentifier));
20937
21033
  }
20938
- function appendDeletedBlockDiffs(remoteBlocks, localBlockIdentifiers, pageIdentifier, summary, diffs) {
20939
- for (const remoteBlock of remoteBlocks) {
20940
- if (localBlockIdentifiers.has(remoteBlock.identifier)) continue;
20941
- const diff = {
20942
- type: "delete",
20943
- identifier: remoteBlock.identifier,
20944
- pageIdentifier
20945
- };
20946
- diffs.push(diff);
20947
- recordBlockDiff(summary, diff);
20948
- }
21034
+ function deletedBlockDiffs(remoteBlocks, localBlockIdentifiers, pageIdentifier) {
21035
+ return remoteBlocks.filter((block) => !localBlockIdentifiers.has(block.identifier)).map((block) => ({
21036
+ type: "delete",
21037
+ identifier: block.identifier,
21038
+ pageIdentifier
21039
+ }));
20949
21040
  }
20950
- function appendReorderDiff(localBlocks, remoteBlocks, remoteLookup, localBlockIdentifiers, pageIdentifier, diffs) {
20951
- const hasCreates = diffs.some((diff) => diff.type === "create");
20952
- if (hasCreates && remoteBlocks.length > 0) {
20953
- diffs.push({
20954
- type: "reorder",
20955
- identifier: pageIdentifier,
20956
- pageIdentifier
20957
- });
20958
- return;
20959
- }
21041
+ function blockReorderDiff(localBlocks, remoteBlocks, remoteLookup, localBlockIdentifiers, pageIdentifier, diffs) {
21042
+ const reorder = {
21043
+ type: "reorder",
21044
+ identifier: pageIdentifier,
21045
+ pageIdentifier
21046
+ };
21047
+ if (diffs.some((diff) => diff.type === "create") && remoteBlocks.length > 0) return reorder;
20960
21048
  const localOrder = localBlocks.filter((block) => remoteLookup.has(block.identifier)).map((block) => block.identifier);
20961
21049
  const remoteOrder = remoteBlocks.filter((block) => localBlockIdentifiers.has(block.identifier)).sort((a, b) => a.position - b.position).map((block) => block.identifier);
20962
- if (localOrder.length > 1 && !equal(localOrder, remoteOrder)) {
20963
- diffs.push({
20964
- type: "reorder",
20965
- identifier: pageIdentifier,
20966
- pageIdentifier
20967
- });
20968
- }
21050
+ return localOrder.length > 1 && !equal(localOrder, remoteOrder) ? reorder : undefined;
20969
21051
  }
20970
21052
  function calculateBlockDiffs(localBlocks, remoteBlocks, pageIdentifier, summary) {
20971
21053
  const remoteLookup = buildRemoteBlockLookup(remoteBlocks);
20972
21054
  const localBlockIdentifiers = new Set(localBlocks.map((block) => block.identifier));
20973
- const diffs = appendLocalBlockDiffs(localBlocks, remoteLookup, pageIdentifier, summary);
20974
- appendDeletedBlockDiffs(remoteBlocks, localBlockIdentifiers, pageIdentifier, summary, diffs);
20975
- appendReorderDiff(localBlocks, remoteBlocks, remoteLookup, localBlockIdentifiers, pageIdentifier, diffs);
21055
+ const contentDiffs = [...localBlockDiffs(localBlocks, remoteLookup, pageIdentifier), ...deletedBlockDiffs(remoteBlocks, localBlockIdentifiers, pageIdentifier)];
21056
+ const reorder = blockReorderDiff(localBlocks, remoteBlocks, remoteLookup, localBlockIdentifiers, pageIdentifier, contentDiffs);
21057
+ const diffs = [...contentDiffs, ...reorder ? [reorder] : []];
21058
+ diffs.forEach((diff) => recordBlockDiff(summary, diff));
20976
21059
  return diffs;
20977
21060
  }
20978
21061
  function changedPageFields(localPage, remotePage) {
20979
- const changes = [];
20980
- if (localPage.title !== remotePage.title) changes.push("title");
20981
- if (localPage.path !== remotePage.path) changes.push("path");
20982
- return changes;
21062
+ const localSeo = resolvePageUpsertSeo(pageMetadataForUpsert(localPage));
21063
+ const remoteSeo = resolvePageUpsertSeo(remotePage);
21064
+ return [
21065
+ ...localPage.title !== remotePage.title ? ["title"] : [],
21066
+ ...localPage.path !== remotePage.path ? ["path"] : [],
21067
+ ...localSeo.seoTitle !== remoteSeo.seoTitle ? ["seoTitle"] : [],
21068
+ ...localSeo.seoDescription !== remoteSeo.seoDescription ? ["seoDescription"] : []
21069
+ ];
20983
21070
  }
20984
21071
  function classifyPage(localPage, remotePage, options, blockSummary) {
20985
21072
  if (!remotePage) {
@@ -21002,20 +21089,12 @@ function classifyPage(localPage, remotePage, options, blockSummary) {
21002
21089
  }
21003
21090
  const blockDiffs = calculateBlockDiffs(localPage.blocks ?? [], remotePage.blocks ?? [], localPage.identifier, blockSummary);
21004
21091
  const changes = changedPageFields(localPage, remotePage);
21005
- const hasBlockChanges = blockDiffs.some((diff) => diff.type !== "unchanged");
21006
- if (changes.length > 0 || hasBlockChanges) {
21007
- return {
21008
- type: "update",
21009
- identifier: localPage.identifier,
21010
- changes: changes.length > 0 ? changes : undefined,
21011
- blocks: blockDiffs,
21012
- remoteBlockIdentifiers: (remotePage.blocks ?? []).map((block) => block.identifier),
21013
- statusChange
21014
- };
21015
- }
21016
21092
  return {
21017
- type: "unchanged",
21093
+ type: changes.length > 0 ? "update" : "unchanged",
21018
21094
  identifier: localPage.identifier,
21095
+ changes: changes.length > 0 ? changes : undefined,
21096
+ blocks: blockDiffs,
21097
+ remoteBlockIdentifiers: (remotePage.blocks ?? []).map((block) => block.identifier),
21019
21098
  statusChange
21020
21099
  };
21021
21100
  }
@@ -21037,6 +21116,10 @@ function calculatePageDiffs(localPages, remotePages, options) {
21037
21116
  blockSummary
21038
21117
  };
21039
21118
  }
21119
+ /** A page may have block operations without changing its metadata. */
21120
+ function hasPageOperations(diff) {
21121
+ return diff.type !== "unchanged" || Boolean(diff.statusChange) || (diff.blocks ?? []).some((block) => block.type !== "unchanged");
21122
+ }
21040
21123
 
21041
21124
  //#endregion
21042
21125
  //#region src/sync/navigationDiffMatching.ts
@@ -21206,7 +21289,10 @@ function buildBlockChanges(pageDiff, localPages, remotePages, mode) {
21206
21289
  function buildPageChanges(diff, lookups, mode) {
21207
21290
  const changes = [];
21208
21291
  for (const pageDiff of diff.pages) {
21209
- if (pageDiff.type === "unchanged" && !pageDiff.statusChange) continue;
21292
+ if (pageDiff.type === "unchanged" && !pageDiff.statusChange) {
21293
+ changes.push(...buildBlockChanges(pageDiff, lookups.localPages, lookups.remotePages, mode));
21294
+ continue;
21295
+ }
21210
21296
  const change = {
21211
21297
  type: "page",
21212
21298
  identifier: pageDiff.identifier,
@@ -21436,11 +21522,13 @@ function calculatePullBlockDiffs(remoteBlocks, localBlocks, pageIdentifier, summ
21436
21522
  return diff;
21437
21523
  });
21438
21524
  }
21439
- function changedPullPageFields(remotePage, localPage) {
21440
- const changes = [];
21441
- if (remotePage.title !== localPage.title) changes.push("title");
21442
- if (remotePage.path !== localPage.path) changes.push("path");
21443
- return changes;
21525
+ function changedPullPageFields(localPage, remotePage) {
21526
+ return [
21527
+ ...localPage.title !== remotePage.title ? ["title"] : [],
21528
+ ...localPage.path !== remotePage.path ? ["path"] : [],
21529
+ ...localPage.seoTitle !== (remotePage.seoTitle ?? undefined) ? ["seoTitle"] : [],
21530
+ ...localPage.seoDescription !== (remotePage.seoDescription ?? undefined) ? ["seoDescription"] : []
21531
+ ];
21444
21532
  }
21445
21533
  function calculatePullPageDiffs(remotePages, local) {
21446
21534
  const diffs = [];
@@ -21460,7 +21548,7 @@ function calculatePullPageDiffs(remotePages, local) {
21460
21548
  continue;
21461
21549
  }
21462
21550
  const blockDiffs = calculatePullBlockDiffs(remotePage.blocks ?? [], localPage.blocks ?? [], remotePage.identifier, blockSummary);
21463
- const changes = changedPullPageFields(remotePage, localPage);
21551
+ const changes = changedPullPageFields(localPage, remotePage);
21464
21552
  const diff = changes.length > 0 || blockDiffs.some((block) => block.type !== "unchanged") ? {
21465
21553
  type: "update",
21466
21554
  identifier: remotePage.identifier,
@@ -21716,11 +21804,17 @@ function formatPageDetails(diff, localPages, remotePages) {
21716
21804
  const localPage = localPages.get(diff.identifier);
21717
21805
  const remotePage = remotePages.get(diff.identifier);
21718
21806
  if (!localPage || !remotePage) return [];
21719
- const localFlat = { ...localPage };
21720
- const remoteFlat = { ...remotePage };
21721
- delete localFlat.blocks;
21722
- delete remoteFlat.blocks;
21723
- return findChangedFieldsWithValues(localFlat, remoteFlat).map((change) => ` ${formatFieldChange(change)}`);
21807
+ const localFields = {
21808
+ title: localPage.title,
21809
+ path: localPage.path,
21810
+ ...resolvePageUpsertSeo(pageMetadataForUpsert(localPage))
21811
+ };
21812
+ const remoteFields = {
21813
+ title: remotePage.title,
21814
+ path: remotePage.path,
21815
+ ...resolvePageUpsertSeo(remotePage)
21816
+ };
21817
+ return findChangedFieldsWithValues(localFields, remoteFields).map((change) => ` ${formatFieldChange(change)}`);
21724
21818
  }
21725
21819
  function buildIdentifierLookup(items) {
21726
21820
  const lookup = new Map();
@@ -21737,6 +21831,11 @@ function formatHumanDiff(diff, local, remote) {
21737
21831
  const localPages = buildIdentifierLookup(local.pages);
21738
21832
  const remotePages = buildIdentifierLookup(remote.pages);
21739
21833
  appendOperationSections$1(lines, "Pages", diff.pages, CREATE_UPDATE_OPERATIONS, (page) => page.identifier, (page) => formatPageDetails(page, localPages, remotePages));
21834
+ appendOperationSections$1(lines, "Blocks", diff.pages.flatMap((page) => page.blocks ?? []), [...ENTRY_OPERATIONS, {
21835
+ type: "reorder",
21836
+ label: "reordered",
21837
+ marker: "~"
21838
+ }], (block) => `${block.pageIdentifier}/${block.identifier}`);
21740
21839
  appendOperationSections$1(lines, "Navigation", diff.navigation, CREATE_UPDATE_OPERATIONS, (navigation) => navigation.type === "update" && navigation.changes ? `${navigation.location} [${navigation.changes.join(", ")}]` : navigation.location);
21741
21840
  if (diff.settings) {
21742
21841
  lines.push("\nSettings (updated):");
@@ -21956,13 +22055,21 @@ function appendSingleUpdateSection(lines, title, detail) {
21956
22055
  lines.push(`\n${title}:`);
21957
22056
  lines.push(` ~ ${detail}`);
21958
22057
  }
22058
+ function appendPageDetailSections(lines, pages) {
22059
+ appendOperationSections(lines, "Pages", pages, CREATE_UPDATE_DETAIL_OPERATIONS, (page) => formatIdentifierDetail(page.identifier, page.changes));
22060
+ appendOperationSections(lines, "Blocks", pages.flatMap((page) => page.blocks ?? []), [...CREATE_UPDATE_DELETE_DETAIL_OPERATIONS, {
22061
+ type: "reorder",
22062
+ label: "reordered",
22063
+ marker: "~"
22064
+ }], (block) => formatIdentifierDetail(`${block.pageIdentifier}/${block.identifier}`, block.changes));
22065
+ }
21959
22066
  /** Format detailed diff for display. */
21960
22067
  function formatDiffDetail(diff) {
21961
22068
  const lines = [];
21962
22069
  for (const [contentType, entryDiffs] of diff.entries) {
21963
22070
  appendOperationSections(lines, contentType, entryDiffs, CREATE_UPDATE_DELETE_DETAIL_OPERATIONS, (entry) => formatIdentifierDetail(entry.identifier, entry.changes));
21964
22071
  }
21965
- appendOperationSections(lines, "Pages", diff.pages, CREATE_UPDATE_DETAIL_OPERATIONS, (page) => formatIdentifierDetail(page.identifier, page.changes));
22072
+ appendPageDetailSections(lines, diff.pages);
21966
22073
  appendOperationSections(lines, "Navigation", diff.navigation, CREATE_UPDATE_DETAIL_OPERATIONS, (navigation) => navigation.location);
21967
22074
  if (diff.settings) {
21968
22075
  appendSingleUpdateSection(lines, "Settings (updated)", `[${diff.settings.changes.join(", ")}]`);
@@ -23202,4 +23309,4 @@ function optionalTitle(data) {
23202
23309
  }
23203
23310
 
23204
23311
  //#endregion
23205
- export { buildStorageUrl as $, createClientForEnv as $t, formatDiffDetail as A, createOutput as An, convertPulledFooterToLocal as At, formatFieldPath as B, linkPayloadSchema as Bn, extractApiErrorMessage as Bt, reportFromOutcomes as C, planEnvironmentWriteAuthorization as Cn, readJsonFile as Ct, normalizeRemoteHomepageReference as D, formatError as Dn, duplicateNavigationIdentityMessage as Dt, createEmptySyncResult as E, ErrorCodes as En, isMediaValue as Et, calculatePullDiff as F, loadSdkEnvironment as Fn, applyPushConfigPlan as Ft, prepareLocalMediaForPush as G, createBearerAPIClient as Gt, syncLocalMediaForPush as H, sdkConfiguredBookingVerticalConfigSchema as Hn, isRecord$5 as Ht, buildJsonDiff as I, createManagementClient as In, createPushConfigCommand as It, writeBinaryFileAtomic as J, deriveCmsApiUrlFromDashboardUrl as Jt, admitBinaryWriteDestination as K, ApiEnvelopeError as Kt, calculateEntryDiffs as L, ManagementApiError as Ln, loadPushConfigTarget as Lt, hasPendingChanges as M, getEnvironmentDebugInfo as Mn, convertPulledPagesToLocal as Mt, findChangedFieldsWithValues as N, isLocalConfigured as Nn, navigationCommandItemToManagementInput as Nt, calculateDiff as O, transportSuggestion as On, navigationIdentity as Ot, formatHumanDiff as P, isRemoteConfigured as Pn, normalizeNavigationConfigItemForCommand as Pt, walkLocalContentMedia as Q, confirmAction as Qt, buildFieldChanges as R, sdkEventScheduleSchema as Rn, preparePushConfigTarget as Rt, planCliCommandBatchForBindings as S, planEnvironmentExecution as Sn, listFiles as St, executeResidualSettingsSyncPlan as T, withRiverbankEnv as Tn, writeJsonFileAtomic as Tt, syncLocalMediaForPull as U, APPOINTMENT_SERVICE_VISIBILITY_VALUES as Ut, revalidateLocalMediaPushPlan as V, portablePageDesignSchema as Vn, normalizeApiError as Vt, applyLocalMediaPush as W, ApiRequestError as Wt, normalizeMediaIdentifierInput as X, mapEnvironmentExecutionOutcomesJson as Xt, sha256 as Y, API_ENDPOINTS as Yt, normalizeMediaValueToIdentifierOnly as Z, bindRequestTimeout as Zt, commandExecutionToReport as _, withConfirmation as _n, readMetadataFile as _t, executeEntryCommandPlanAsReport as a, formatDateShort as an, readEventCategoriesMeta as at, executeCompiledCliCommandPlanAsReport as b, executeEnvironmentPlan as bn, ensureDir$1 as bt, titleFromEntryData as c, handleCommandError as cn, readFormsMeta as ct, unsafeAsCliEntryIdentifier as d, parseJsonArray as dn, readSettingsMeta as dt, createCommandContext as en, downloadMedia as et, unsafeAsCliFormSlug as f, parseJsonData as fn, readVenuesMeta as ft, commandCompileFailureToReport as g, withCommandContext as gn, metadataTargetFromEnvironment as gt, mutationCounterForEffect as h, runWithInvocation as hn, metadataFilePath as ht, entrySiteCommandTypes as i, currentInvocationEnvelope as in, readAllMeta as it, formatDiffSummary as j, getEnvPrefix as jn, convertPulledNavigationToLocal as jt, calculateFooterDiff as k, CliExit as kn, navigationIdentityMap as kt, unsafeAsCliBlockIdentifier as l, managementClientConfigFor as ln, readNavigationMeta as lt, commandReportToSyncResult as m, resolveCommandPath as mn, ensureMetadataDir as mt, entryCommandCompileErrorToReport as n, createListCommand as nn, findLegacyEntryFiles as nt, executeEntryCommandPlanAsSyncResult as o, getOutputContext as on, readEventsMeta as ot, unsafeAsCliPageIdentifier as p, parsePaginationOptions as pn, writeMediaManifest as pt, readStableBinaryFile as q, unwrapResponse as qt, entryCommandReportToSyncResult as r, createOutputForCommand as rn, readEntries as rt, syncResultForEntryCommandCompileError as s, getOutputOnlyContext as sn, readFooterMeta as st, compileEntryPushCommands as t, createGetCommand as tn, extractMediaIdentifiers as tt, unsafeAsCliContentTypeKey as u, mapEntryForOutput as un, readPagesMeta as ut, commandReportHasFailures as v, withErrorHandling as vn, writeMetadataFile as vt, mergeManySyncResults as w, requireEnvironmentWriteAuthorization as wn, writeJsonFile$1 as wt, formatManagementError as x, parseEnvironmentSelection as xn, fileExists$1 as xt, executeCliCommandPlan as y, withOutputOnlyErrorHandling as yn, writeMetadataRecordMap as yt, formatFieldChange as z, sdkSettingsUpdateSchema as zn, revalidatePushConfigPlan as zt };
23312
+ export { normalizeMediaValueToIdentifierOnly as $, bindRequestTimeout as $t, formatDiffDetail as A, transportSuggestion as An, navigationIdentity as At, buildFieldChanges as B, sdkEventScheduleSchema as Bn, preparePushConfigTarget as Bt, reportFromOutcomes as C, parseEnvironmentSelection as Cn, fileExists$1 as Ct, normalizeRemoteHomepageReference as D, withRiverbankEnv as Dn, writeJsonFileAtomic as Dt, createEmptySyncResult as E, requireEnvironmentWriteAuthorization as En, writeJsonFile$1 as Et, calculatePullDiff as F, isLocalConfigured as Fn, navigationCommandItemToManagementInput as Ft, syncLocalMediaForPull as G, APPOINTMENT_SERVICE_VISIBILITY_VALUES as Gt, formatFieldPath as H, linkPayloadSchema as Hn, extractApiErrorMessage as Ht, buildJsonDiff as I, isRemoteConfigured as In, normalizeNavigationConfigItemForCommand as It, admitBinaryWriteDestination as J, ApiEnvelopeError as Jt, applyLocalMediaPush as K, ApiRequestError as Kt, hasPageOperations as L, loadSdkEnvironment as Ln, applyPushConfigPlan as Lt, hasPendingChanges as M, createOutput as Mn, convertPulledFooterToLocal as Mt, findChangedFieldsWithValues as N, getEnvPrefix as Nn, convertPulledNavigationToLocal as Nt, calculateDiff as O, ErrorCodes as On, isMediaValue as Ot, formatHumanDiff as P, getEnvironmentDebugInfo as Pn, convertPulledPagesToLocal as Pt, normalizeMediaIdentifierInput as Q, mapEnvironmentExecutionOutcomesJson as Qt, pageMetadataForUpsert as R, createManagementClient as Rn, createPushConfigCommand as Rt, planCliCommandBatchForBindings as S, executeEnvironmentPlan as Sn, ensureDir$1 as St, executeResidualSettingsSyncPlan as T, planEnvironmentWriteAuthorization as Tn, readJsonFile as Tt, revalidateLocalMediaPushPlan as U, portablePageDesignSchema as Un, normalizeApiError as Ut, formatFieldChange as V, sdkSettingsUpdateSchema as Vn, revalidatePushConfigPlan as Vt, syncLocalMediaForPush as W, sdkConfiguredBookingVerticalConfigSchema as Wn, isRecord$5 as Wt, writeBinaryFileAtomic as X, deriveCmsApiUrlFromDashboardUrl as Xt, readStableBinaryFile as Y, unwrapResponse as Yt, sha256 as Z, API_ENDPOINTS as Zt, commandExecutionToReport as _, runWithInvocation as _n, metadataFilePath as _t, executeEntryCommandPlanAsReport as a, createOutputForCommand as an, readEntries as at, executeCompiledCliCommandPlanAsReport as b, withErrorHandling as bn, writeMetadataFile as bt, titleFromEntryData as c, getOutputContext as cn, readEventsMeta as ct, unsafeAsCliEntryIdentifier as d, managementClientConfigFor as dn, readNavigationMeta as dt, confirmAction as en, walkLocalContentMedia as et, unsafeAsCliFormSlug as f, mapEntryForOutput as fn, readPagesMeta as ft, commandCompileFailureToReport as g, resolveCommandPath as gn, ensureMetadataDir as gt, mutationCounterForEffect as h, parsePaginationOptions as hn, writeMediaManifest as ht, entrySiteCommandTypes as i, createListCommand as in, findLegacyEntryFiles as it, formatDiffSummary as j, CliExit as jn, navigationIdentityMap as jt, calculateFooterDiff as k, formatError as kn, duplicateNavigationIdentityMessage as kt, unsafeAsCliBlockIdentifier as l, getOutputOnlyContext as ln, readFooterMeta as lt, commandReportToSyncResult as m, parseJsonData as mn, readVenuesMeta as mt, entryCommandCompileErrorToReport as n, createCommandContext as nn, downloadMedia as nt, executeEntryCommandPlanAsSyncResult as o, currentInvocationEnvelope as on, readAllMeta as ot, unsafeAsCliPageIdentifier as p, parseJsonArray as pn, readSettingsMeta as pt, prepareLocalMediaForPush as q, createBearerAPIClient as qt, entryCommandReportToSyncResult as r, createGetCommand as rn, extractMediaIdentifiers as rt, syncResultForEntryCommandCompileError as s, formatDateShort as sn, readEventCategoriesMeta as st, compileEntryPushCommands as t, createClientForEnv as tn, buildStorageUrl as tt, unsafeAsCliContentTypeKey as u, handleCommandError as un, readFormsMeta as ut, commandReportHasFailures as v, withCommandContext as vn, metadataTargetFromEnvironment as vt, mergeManySyncResults as w, planEnvironmentExecution as wn, listFiles as wt, formatManagementError as x, withOutputOnlyErrorHandling as xn, writeMetadataRecordMap as xt, executeCliCommandPlan as y, withConfirmation as yn, readMetadataFile as yt, calculateEntryDiffs as z, ManagementApiError as zn, loadPushConfigTarget as zt };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { _ as normalizeLinkValue, a as classifySdkEventSchedule, g as linkSchema, i as sdkEventUpsertOptionalFieldSchemas, n as sdkCourseBookingSettingsSchema, o as classifySdkEventBookingOffer } from "./sdk-event-upsert-BqjzK2zT.mjs";
3
- import { u as EVENT_PRESET_VALUES } from "./src-zzwJUef5.mjs";
2
+ import { _ as normalizeLinkValue, a as classifySdkEventSchedule, g as linkSchema, i as sdkEventUpsertOptionalFieldSchemas, n as sdkCourseBookingSettingsSchema, o as classifySdkEventBookingOffer } from "./sdk-event-upsert-zWw5VolM.mjs";
3
+ import { u as EVENT_PRESET_VALUES } from "./src-ZACBG29u.mjs";
4
4
  import { z } from "zod";
5
5
 
6
6
  //#region ../blocks/src/lib/typeGuards.ts
@@ -7,7 +7,7 @@ import { existsSync as existsSync$1 } from "fs";
7
7
  import { fileURLToPath } from "url";
8
8
 
9
9
  //#region package.json
10
- var version = "0.22.0";
10
+ var version = "0.22.2";
11
11
  var peerDependencies = { "@riverbankcms/sdk": ">=0.157.0 <1.0.0" };
12
12
  var package_default = {
13
13
  name: "riverbankcms",
@@ -83,7 +83,7 @@ var package_default = {
83
83
  //#endregion
84
84
  //#region src/version.ts
85
85
  /** The package manifest is the source-run fallback; builds inject this value. */
86
- const CLI_VERSION = typeof "0.22.0" === "string" ? "0.22.0" : version;
86
+ const CLI_VERSION = typeof "0.22.2" === "string" ? "0.22.2" : version;
87
87
  /**
88
88
  * The CLI's SDK peer range is bundled from the CLI manifest alongside its
89
89
  * version. Runtime config loading uses this value as the single compatibility
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { t as loadConfigFile } from "./load-config-BV9Ig2CH.mjs";
3
+
4
+ export { loadConfigFile };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Bn as ok, sn as parseSiteId, zn as err } from "./src-zzwJUef5.mjs";
2
+ import { Hn as err, Un as ok, un as parseSiteId } from "./src-ZACBG29u.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import "../src-zzwJUef5.mjs";
3
- import { a as prepareScaffoldExecution, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, l as deriveGeneratedPackageRanges, o as writeScaffoldFiles, r as preflightScaffoldPlan, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan, u as findPackageManifestPath } from "../plan-C4IphkPc.mjs";
2
+ import "../src-ZACBG29u.mjs";
3
+ import { a as prepareScaffoldExecution, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, l as deriveGeneratedPackageRanges, o as writeScaffoldFiles, r as preflightScaffoldPlan, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan, u as findPackageManifestPath } from "../plan-CFMj_Hee.mjs";
4
4
 
5
5
  export { deriveGeneratedPackageRanges, deriveScaffoldLocalManifest, deriveScaffoldPlan, findPackageManifestPath, loadGeneratedPackageRanges, preflightScaffoldPlan, preflightScaffoldTargets, prepareScaffoldExecution, writeScaffoldFiles };