riverbankcms 0.9.0 → 0.11.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) {
@@ -3207,9 +3294,20 @@ const knownSocialPlatforms = [
3207
3294
  "instagram",
3208
3295
  "linkedin",
3209
3296
  "tiktok",
3297
+ "whatsapp",
3210
3298
  "x",
3211
3299
  "youtube"
3212
3300
  ];
3301
+ /** How each platform is named wherever people see it (settings, composer, footer link labels). */
3302
+ const knownSocialPlatformLabels = {
3303
+ facebook: "Facebook",
3304
+ instagram: "Instagram",
3305
+ linkedin: "LinkedIn",
3306
+ tiktok: "TikTok",
3307
+ whatsapp: "WhatsApp",
3308
+ x: "X",
3309
+ youtube: "YouTube"
3310
+ };
3213
3311
  function isRecord$8(value) {
3214
3312
  return typeof value === "object" && value !== null && !Array.isArray(value);
3215
3313
  }
@@ -3590,6 +3688,38 @@ function parsePremises(value) {
3590
3688
  function resolvePublicProfilePremises(profile, hasBusinessAddress) {
3591
3689
  return profile.premises ?? hasBusinessAddress;
3592
3690
  }
3691
+ /**
3692
+ * The contact details the site may publish: the stored contact with every
3693
+ * hidden method removed, or null when nothing is left to show.
3694
+ *
3695
+ * Every public reader goes through this. The privacy policy identity is the
3696
+ * one exception and reads the stored email directly, because a hidden email
3697
+ * can still be the policy's contact.
3698
+ */
3699
+ function publishedContactDetails(profile) {
3700
+ const { contact, contactVisibility } = profile;
3701
+ if (contact === null) return null;
3702
+ const phone = contactVisibility.phone === "shown" ? contact.phone : null;
3703
+ const email = contactVisibility.email === "shown" ? contact.email : null;
3704
+ if (phone !== null && email !== null) {
3705
+ return {
3706
+ kind: "phone-and-email",
3707
+ phone,
3708
+ email
3709
+ };
3710
+ }
3711
+ if (phone !== null) return {
3712
+ kind: "phone",
3713
+ phone,
3714
+ email: null
3715
+ };
3716
+ if (email !== null) return {
3717
+ kind: "email",
3718
+ phone: null,
3719
+ email
3720
+ };
3721
+ return null;
3722
+ }
3593
3723
  function parseAddressVisibility(value) {
3594
3724
  if (value === undefined || value === null) return ok("shown");
3595
3725
  if (value === "shown" || value === "hidden") return ok(value);
@@ -7083,4 +7213,4 @@ function eventCatalogueChoices(catalogue) {
7083
7213
  }
7084
7214
 
7085
7215
  //#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 };
7216
+ export { parseEventPageSurfaceSubject as $, footerNavigationLayouts as A, unsafeAsOriginalFilename as At, formatBookingDate as B, unsafeAsStoragePath as Bt, parseMailingListContentVersionId as C, unsafeAsDetectedMimeType as Ct, sameMailingListPlacementTargeting as D, unsafeAsFileChecksumSha256 as Dt, planMailingListChoicePresentation as E, unsafeAsEventSeriesId as Et, isPresent as F, unsafeAsSiteFontId as Ft, getBookingLocalDateKey as G, formatBookingTime as H, unsafeAsUserId as Ht, normalizeLocationAddressText as I, unsafeAsSiteId as It, parseUtcIsoDateTimeString as J, getLocalScheduleDate as K, toLocationCoordinates as L, unsafeAsSiteScopedStoragePath as Lt, parseMailingListPlacementTargeting as M, unsafeAsPositiveSeconds as Mt, isCanonicalRichTextDoc as N, unsafeAsProductId as Nt, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as O, unsafeAsMediaAssetId as Ot, assertAllowedPublicUrl as P, unsafeAsSafeDownloadFilename as Pt, parseBookingTimeZone as Q, selectCategoryView as R, unsafeAsStaffMemberId as Rt, parseMailingListBlockId as S, unsafeAsDemoCapability as St, parseMailingListRuntimeContext as T, unsafeAsEventOfferingId as Tt, formatLocalScheduleDate as U, err as Ut, formatBookingDateParts as V, unsafeAsUploadSessionId as Vt, formatLocalScheduleTime as W, ok as Wt, toScheduledBookingDateRange as X, toBookingTimeZone as Y, toScheduledBookingDateTime as Z, createSecret as _, parseUserId as _t, parseVerticalId as a, publicEventPricingType as at, stableJsonStringify as b, unsafeAsBookingSessionId as bt, DEFAULT_EVENT_TYPE_PRESETS as c, fromArray as ct, SURFACE_EVENT_PRESET_VALUES as d, assertNever as dt, formatBookingPriceDisplay as et, WHOLE_SERIES_EVENT_PRESET_VALUES as f, parseApiKeyId as ft, resolveWholeSeriesBookingPhase as g, parseSiteId as gt, orderedLiveRunSessions as h, parsePageId as ht, canonicalizeConfiguredBookingVerticalConfig as i, publicEventPricingDisplay as it, parseFooterCompositionV1 as j, unsafeAsPositiveByteCount as jt, parseMailingListProviderScope as k, unsafeAsOccurrenceId as kt, EVENT_PRESET_VALUES as l, mapNonEmptyArray as lt, CANCELLED_SESSION_STATUS as m, parseMediaAssetId as mt, NAVIGATION_LOCATIONS as n, isPublicEventPricingOptionDisplayable as nt, parseVerticalPresetId as o, resolveExactOrFreePriceDisplay as ot, publicReadFreshnessSeconds as p, parseEventSeriesId as pt, getLocalScheduleTime as q, areConfiguredBookingVerticalConfigsEqual as r, publicEventPricingCurrency as rt, resolveSiteVerticalBookingConfig as s, resolvePricingOptionsPriceDisplay as st, resolveEventCatalogue as t, formatEventPricing as tt, ORDINARY_EVENT_PRESET_VALUES as u, formatCurrencyAmount as ut, exposeSecret as v, unsafeAsAppointmentResourceId as vt, parseMailingListSignedSourceToken as w, unsafeAsEntitlementId as wt, buildMailingListSignupBlockSourceRef as x, unsafeAsDeclaredMimeType as xt, parseManagementKey as y, unsafeAsBookingRequirementId as yt, buildBookingUtcDateWindow as z, unsafeAsStorageBucketName 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-CRQseim3.mjs";
3
+ import "./src-CiZrHLCj.mjs";
4
+ import { n as syncLocalMediaForPush, r as syncLocalMediaForPull, y as writeMediaManifest } from "./local-sync-7ecbT9He.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.11.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 };