riverbankcms 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2113,6 +2113,93 @@ function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
2113
2113
  return new Date(guess);
2114
2114
  }
2115
2115
 
2116
+ //#endregion
2117
+ //#region ../core/src/appointment-service-categories.ts
2118
+ /**
2119
+ * Groups services under their categories.
2120
+ *
2121
+ * A service whose `categoryId` names no category in `categories` lands in
2122
+ * Other. The composite foreign key keeps that from happening with stored data,
2123
+ * so this is only the total, safe answer for a caller holding a stale list.
2124
+ */
2125
+ function layoutServicesByCategory(categories, services, options) {
2126
+ if (categories.length === 0) {
2127
+ return {
2128
+ kind: "uncategorized-site",
2129
+ services: [...services]
2130
+ };
2131
+ }
2132
+ const buckets = new Map(categories.map((category) => [category.id, []]));
2133
+ const other = [];
2134
+ for (const service of services) {
2135
+ const bucket = service.categoryId === null ? undefined : buckets.get(service.categoryId);
2136
+ if (bucket !== undefined) {
2137
+ bucket.push(service);
2138
+ } else {
2139
+ other.push(service);
2140
+ }
2141
+ }
2142
+ const groups = [];
2143
+ for (const category of categories) {
2144
+ const groupServices = buckets.get(category.id) ?? [];
2145
+ if (groupServices.length === 0 && !options.keepEmptyGroups) continue;
2146
+ groups.push({
2147
+ category,
2148
+ services: groupServices
2149
+ });
2150
+ }
2151
+ if (groups.length === 0 && !options.keepEmptyGroups) {
2152
+ return {
2153
+ kind: "uncategorized-site",
2154
+ services: other
2155
+ };
2156
+ }
2157
+ return {
2158
+ kind: "categorized-site",
2159
+ groups,
2160
+ other
2161
+ };
2162
+ }
2163
+ /** The services in display order: each group in turn, then Other. */
2164
+ function flattenServiceCategoryLayout(layout) {
2165
+ switch (layout.kind) {
2166
+ case "uncategorized-site": return [...layout.services];
2167
+ case "categorized-site": return [...layout.groups.flatMap((group) => group.services), ...layout.other];
2168
+ }
2169
+ }
2170
+ /**
2171
+ * Selects the public view for an optional category filter.
2172
+ *
2173
+ * It takes the category and service lists rather than a prebuilt layout
2174
+ * because the public layout has already dropped empty categories, and then an
2175
+ * empty category (`single` with no services) could not be told apart from a
2176
+ * deleted one (`fallback-all`).
2177
+ */
2178
+ function selectCategoryView(categories, services, filterCategoryId) {
2179
+ const publicLayout = () => layoutServicesByCategory(categories, services, { keepEmptyGroups: false });
2180
+ if (filterCategoryId === null || filterCategoryId === undefined) {
2181
+ return {
2182
+ kind: "all",
2183
+ layout: publicLayout()
2184
+ };
2185
+ }
2186
+ const category = categories.find((candidate) => candidate.id === filterCategoryId);
2187
+ if (category === undefined) {
2188
+ return {
2189
+ kind: "fallback-all",
2190
+ missingCategoryId: filterCategoryId,
2191
+ layout: publicLayout()
2192
+ };
2193
+ }
2194
+ return {
2195
+ kind: "single",
2196
+ group: {
2197
+ category,
2198
+ services: services.filter((service) => service.categoryId === filterCategoryId)
2199
+ }
2200
+ };
2201
+ }
2202
+
2116
2203
  //#endregion
2117
2204
  //#region ../core/src/dated-offering-settlement.ts
2118
2205
  function parseStripeReference(value) {
@@ -3590,6 +3677,38 @@ function parsePremises(value) {
3590
3677
  function resolvePublicProfilePremises(profile, hasBusinessAddress) {
3591
3678
  return profile.premises ?? hasBusinessAddress;
3592
3679
  }
3680
+ /**
3681
+ * The contact details the site may publish: the stored contact with every
3682
+ * hidden method removed, or null when nothing is left to show.
3683
+ *
3684
+ * Every public reader goes through this. The privacy policy identity is the
3685
+ * one exception and reads the stored email directly, because a hidden email
3686
+ * can still be the policy's contact.
3687
+ */
3688
+ function publishedContactDetails(profile) {
3689
+ const { contact, contactVisibility } = profile;
3690
+ if (contact === null) return null;
3691
+ const phone = contactVisibility.phone === "shown" ? contact.phone : null;
3692
+ const email = contactVisibility.email === "shown" ? contact.email : null;
3693
+ if (phone !== null && email !== null) {
3694
+ return {
3695
+ kind: "phone-and-email",
3696
+ phone,
3697
+ email
3698
+ };
3699
+ }
3700
+ if (phone !== null) return {
3701
+ kind: "phone",
3702
+ phone,
3703
+ email: null
3704
+ };
3705
+ if (email !== null) return {
3706
+ kind: "email",
3707
+ phone: null,
3708
+ email
3709
+ };
3710
+ return null;
3711
+ }
3593
3712
  function parseAddressVisibility(value) {
3594
3713
  if (value === undefined || value === null) return ok("shown");
3595
3714
  if (value === "shown" || value === "hidden") return ok(value);
@@ -7083,4 +7202,4 @@ function eventCatalogueChoices(catalogue) {
7083
7202
  }
7084
7203
 
7085
7204
  //#endregion
7086
- export { formatEventPricing as $, parseFooterCompositionV1 as A, unsafeAsPositiveSeconds as At, formatBookingTime as B, unsafeAsUserId as Bt, parseMailingListContentVersionId as C, unsafeAsEventOfferingId as Ct, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as D, unsafeAsOccurrenceId as Dt, planMailingListChoicePresentation as E, unsafeAsMediaAssetId as Et, normalizeLocationAddressText as F, unsafeAsSiteScopedStoragePath as Ft, getLocalScheduleTime as G, formatLocalScheduleTime as H, ok as Ht, toLocationCoordinates as I, unsafeAsStaffMemberId as It, toScheduledBookingDateRange as J, parseUtcIsoDateTimeString as K, buildBookingUtcDateWindow as L, unsafeAsStorageBucketName as Lt, isCanonicalRichTextDoc as M, unsafeAsSafeDownloadFilename as Mt, assertAllowedPublicUrl as N, unsafeAsSiteFontId as Nt, parseMailingListProviderScope as O, unsafeAsOriginalFilename as Ot, isPresent as P, unsafeAsSiteId as Pt, formatBookingPriceDisplay as Q, formatBookingDate as R, unsafeAsStoragePath as Rt, parseMailingListBlockId as S, unsafeAsEntitlementId as St, parseMailingListRuntimeContext as T, unsafeAsFileChecksumSha256 as Tt, getBookingLocalDateKey as U, formatLocalScheduleDate as V, err as Vt, getLocalScheduleDate as W, parseBookingTimeZone as X, toScheduledBookingDateTime as Y, parseEventPageSurfaceSubject as Z, createSecret as _, unsafeAsBookingRequirementId as _t, parseVerticalId as a, resolvePricingOptionsPriceDisplay as at, stableJsonStringify as b, unsafeAsDemoCapability as bt, DEFAULT_EVENT_TYPE_PRESETS as c, formatCurrencyAmount as ct, SURFACE_EVENT_PRESET_VALUES as d, parseEventSeriesId as dt, isPublicEventPricingOptionDisplayable as et, WHOLE_SERIES_EVENT_PRESET_VALUES as f, parseMediaAssetId as ft, resolveWholeSeriesBookingPhase as g, unsafeAsAppointmentResourceId as gt, orderedLiveRunSessions as h, parseUserId as ht, canonicalizeConfiguredBookingVerticalConfig as i, resolveExactOrFreePriceDisplay as it, parseMailingListPlacementTargeting as j, unsafeAsProductId as jt, footerNavigationLayouts as k, unsafeAsPositiveByteCount as kt, EVENT_PRESET_VALUES as l, assertNever as lt, CANCELLED_SESSION_STATUS as m, parseSiteId as mt, NAVIGATION_LOCATIONS as n, publicEventPricingDisplay as nt, parseVerticalPresetId as o, fromArray as ot, publicReadFreshnessSeconds as p, parsePageId as pt, toBookingTimeZone as q, areConfiguredBookingVerticalConfigsEqual as r, publicEventPricingType as rt, resolveSiteVerticalBookingConfig as s, mapNonEmptyArray as st, resolveEventCatalogue as t, publicEventPricingCurrency as tt, ORDINARY_EVENT_PRESET_VALUES as u, parseApiKeyId as ut, exposeSecret as v, unsafeAsBookingSessionId as vt, parseMailingListSignedSourceToken as w, unsafeAsEventSeriesId as wt, buildMailingListSignupBlockSourceRef as x, unsafeAsDetectedMimeType as xt, parseManagementKey as y, unsafeAsDeclaredMimeType as yt, formatBookingDateParts as z, unsafeAsUploadSessionId as zt };
7205
+ export { formatBookingPriceDisplay as $, parseFooterCompositionV1 as A, unsafeAsPositiveByteCount as At, formatBookingDateParts as B, unsafeAsUploadSessionId as Bt, parseMailingListContentVersionId as C, unsafeAsEntitlementId as Ct, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as D, unsafeAsMediaAssetId as Dt, planMailingListChoicePresentation as E, unsafeAsFileChecksumSha256 as Et, normalizeLocationAddressText as F, unsafeAsSiteId as Ft, getLocalScheduleDate as G, formatLocalScheduleDate as H, err as Ht, toLocationCoordinates as I, unsafeAsSiteScopedStoragePath as It, toBookingTimeZone as J, getLocalScheduleTime as K, selectCategoryView as L, unsafeAsStaffMemberId as Lt, isCanonicalRichTextDoc as M, unsafeAsProductId as Mt, assertAllowedPublicUrl as N, unsafeAsSafeDownloadFilename as Nt, parseMailingListProviderScope as O, unsafeAsOccurrenceId as Ot, isPresent as P, unsafeAsSiteFontId as Pt, parseEventPageSurfaceSubject as Q, buildBookingUtcDateWindow as R, unsafeAsStorageBucketName as Rt, parseMailingListBlockId as S, unsafeAsDetectedMimeType as St, parseMailingListRuntimeContext as T, unsafeAsEventSeriesId as Tt, formatLocalScheduleTime as U, ok as Ut, formatBookingTime as V, unsafeAsUserId as Vt, getBookingLocalDateKey as W, toScheduledBookingDateTime as X, toScheduledBookingDateRange as Y, parseBookingTimeZone as Z, createSecret as _, unsafeAsAppointmentResourceId as _t, parseVerticalId as a, resolveExactOrFreePriceDisplay as at, stableJsonStringify as b, unsafeAsDeclaredMimeType as bt, DEFAULT_EVENT_TYPE_PRESETS as c, mapNonEmptyArray as ct, SURFACE_EVENT_PRESET_VALUES as d, parseApiKeyId as dt, formatEventPricing as et, WHOLE_SERIES_EVENT_PRESET_VALUES as f, parseEventSeriesId as ft, resolveWholeSeriesBookingPhase as g, parseUserId as gt, orderedLiveRunSessions as h, parseSiteId as ht, canonicalizeConfiguredBookingVerticalConfig as i, publicEventPricingType as it, parseMailingListPlacementTargeting as j, unsafeAsPositiveSeconds as jt, footerNavigationLayouts as k, unsafeAsOriginalFilename as kt, EVENT_PRESET_VALUES as l, formatCurrencyAmount as lt, CANCELLED_SESSION_STATUS as m, parsePageId as mt, NAVIGATION_LOCATIONS as n, publicEventPricingCurrency as nt, parseVerticalPresetId as o, resolvePricingOptionsPriceDisplay as ot, publicReadFreshnessSeconds as p, parseMediaAssetId as pt, parseUtcIsoDateTimeString as q, areConfiguredBookingVerticalConfigsEqual as r, publicEventPricingDisplay as rt, resolveSiteVerticalBookingConfig as s, fromArray as st, resolveEventCatalogue as t, isPublicEventPricingOptionDisplayable as tt, ORDINARY_EVENT_PRESET_VALUES as u, assertNever as ut, exposeSecret as v, unsafeAsBookingRequirementId as vt, parseMailingListSignedSourceToken as w, unsafeAsEventOfferingId as wt, buildMailingListSignupBlockSourceRef as x, unsafeAsDemoCapability as xt, parseManagementKey as y, unsafeAsBookingSessionId as yt, formatBookingDate as z, unsafeAsStoragePath as zt };
package/dist/testing.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./sdk-event-upsert-BNxbxaA0.mjs";
3
- import "./src-DbmhanBI.mjs";
4
- import { n as syncLocalMediaForPush, r as syncLocalMediaForPull, y as writeMediaManifest } from "./local-sync-DF-2DL_D.mjs";
2
+ import "./sdk-event-upsert-DhdlT2ko.mjs";
3
+ import "./src-DIAVNRwo.mjs";
4
+ import { n as syncLocalMediaForPush, r as syncLocalMediaForPull, y as writeMediaManifest } from "./local-sync-3ZG1khGb.mjs";
5
5
 
6
6
  export { syncLocalMediaForPull, syncLocalMediaForPush, writeMediaManifest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "riverbankcms",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Riverbank CMS command-line tools for SDK site developers",
5
5
  "bin": {
6
6
  "riverbankcms": "dist/cli/index.mjs"
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
- import { t as loadConfigFile } from "./load-config-Cf5uPEAn.mjs";
3
-
4
- export { loadConfigFile };