riverbankcms 0.16.0 → 0.17.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.
@@ -141,7 +141,6 @@ const unsafeAsDemoLifecycleAuditEventId = (id) => id;
141
141
  const unsafeAsDemoRuntimeId = (id) => id;
142
142
  const unsafeAsDemoCapability = (value) => value;
143
143
  const unsafeAsDemoPaymentFlowId = (id) => id;
144
- const unsafeAsDemoClaimTtlHours = (value) => value;
145
144
  const unsafeAsGiftingOfferId = (id) => id;
146
145
  const unsafeAsGiftingInstrumentId = (id) => id;
147
146
  const unsafeAsBookingRequirementId = (id) => id;
@@ -392,6 +391,7 @@ const demoInstanceStatusValues = [
392
391
  "failed"
393
392
  ];
394
393
  const demoClaimStatusValues = [
394
+ "preparing",
395
395
  "active",
396
396
  "expired",
397
397
  "released"
@@ -418,7 +418,7 @@ function narrowDemoBlueprintArtifactKind(value) {
418
418
 
419
419
  //#endregion
420
420
  //#region ../core/src/demo-warm-pool-target.ts
421
- const DEFAULT_DEMO_WARM_POOL_TARGET = 0;
421
+ const DEFAULT_DEMO_WARM_POOL_TARGET = 1;
422
422
  const MAX_DEMO_WARM_POOL_TARGET = 20;
423
423
  function parseDemoWarmPoolTarget(value) {
424
424
  if (value === undefined || value === null || value.trim() === "") {
@@ -1441,6 +1441,25 @@ function isRecord$9(value) {
1441
1441
  return typeof value === "object" && value !== null && !Array.isArray(value);
1442
1442
  }
1443
1443
 
1444
+ //#endregion
1445
+ //#region ../core/src/ticket-quantity.ts
1446
+ function toPositiveTicketQuantity(value) {
1447
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {
1448
+ return err("invalid_quantity");
1449
+ }
1450
+ return ok(value);
1451
+ }
1452
+ /**
1453
+ * The places a booking holds: the sum of its ticket lines' quantities. The one
1454
+ * derivation for selections, persisted lines and a booking outcome's lines;
1455
+ * null when the total is not a positive whole number.
1456
+ */
1457
+ function deriveTotalTicketQuantity(lines) {
1458
+ const total = lines.reduce((sum, line) => sum + line.quantity, 0);
1459
+ const parsed = toPositiveTicketQuantity(total);
1460
+ return parsed.ok ? parsed.value : null;
1461
+ }
1462
+
1444
1463
  //#endregion
1445
1464
  //#region ../core/src/booking-flexible-balance.ts
1446
1465
  const DEFAULT_FLEXIBLE_BALANCE_STRIPE_MINIMUM_CHARGE_CENTS = 50;
@@ -1778,10 +1797,21 @@ function isSettleableOrderInstalmentPlanStatus(status) {
1778
1797
  function isSettleableFlexibleBalanceContractStatus(status) {
1779
1798
  return isLiveFlexibleBalanceContractStatus(status) && !CONTRACT_COLLECTION_IN_FLIGHT[status];
1780
1799
  }
1781
- function decideContractClosureForFailedOrder(status) {
1800
+ /** Shared reason for closing either form of booking payment terms. */
1801
+ const PAYMENT_TERMS_CLOSURE_REASONS = ["cancelled", "refunded"];
1802
+ /** Refund closure records its outcome even when collection has already ended. */
1803
+ function decideContractClosure(status, reason) {
1804
+ if (reason === "refunded") {
1805
+ return status === "refunded" ? { kind: "keep" } : {
1806
+ kind: "close",
1807
+ from: status,
1808
+ to: "refunded"
1809
+ };
1810
+ }
1782
1811
  return isLiveFlexibleBalanceContractStatus(status) ? {
1783
1812
  kind: "close",
1784
- from: status
1813
+ from: status,
1814
+ to: "closed_order_failed"
1785
1815
  } : { kind: "keep" };
1786
1816
  }
1787
1817
 
@@ -3930,9 +3960,190 @@ function parseBrevoConfirmationTemplateId(value) {
3930
3960
  return parsePositiveInteger(value);
3931
3961
  }
3932
3962
 
3963
+ //#endregion
3964
+ //#region ../core/src/mailing-list-targeting.ts
3965
+ const DEFAULT_MAILING_LIST_TARGETING = { mode: "default" };
3966
+ function sameMailingListPlacementTargeting(left, right) {
3967
+ if (left.mode !== right.mode) return false;
3968
+ if (left.mode === "default" || right.mode === "default") return true;
3969
+ if (left.provider !== right.provider || left.selection.tag !== right.selection.tag) return false;
3970
+ if (left.provider === "mailchimp" && (right.provider !== "mailchimp" || left.audienceId !== right.audienceId)) return false;
3971
+ return sameIds(mailingListTargetingChoiceIds(left), mailingListTargetingChoiceIds(right));
3972
+ }
3973
+ function mailingListTargetingChoiceIds(targeting) {
3974
+ switch (targeting.provider) {
3975
+ case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
3976
+ case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
3977
+ case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
3978
+ }
3979
+ }
3980
+ function sameIds(left, right) {
3981
+ const leftIds = new Set(left);
3982
+ const rightIds = new Set(right);
3983
+ return leftIds.size === left.length && rightIds.size === right.length && leftIds.size === rightIds.size && [...leftIds].every((id) => rightIds.has(id));
3984
+ }
3985
+ function resolveMailingListTarget(input) {
3986
+ if (input.targeting.mode === "default") {
3987
+ if (input.visitorSelection !== undefined) {
3988
+ return err({ tag: "visitor_selection_not_allowed" });
3989
+ }
3990
+ return ok(resolveDefaultTarget(input.setup));
3991
+ }
3992
+ if (input.targeting.provider !== input.setup.provider) {
3993
+ return err({
3994
+ tag: "targeting_provider_mismatch",
3995
+ setupProvider: input.setup.provider,
3996
+ targetingProvider: input.targeting.provider
3997
+ });
3998
+ }
3999
+ return resolveCustomTarget(input.targeting, input.visitorSelection);
4000
+ }
4001
+ function resolveDefaultTarget(setup) {
4002
+ switch (setup.provider) {
4003
+ case "native": return {
4004
+ provider: "native",
4005
+ topicIds: [setup.defaultTopicId]
4006
+ };
4007
+ case "brevo": return {
4008
+ provider: "brevo",
4009
+ listIds: [setup.defaultListId]
4010
+ };
4011
+ case "mailchimp": return {
4012
+ provider: "mailchimp",
4013
+ audienceId: setup.defaultAudienceId,
4014
+ interestIds: []
4015
+ };
4016
+ }
4017
+ }
4018
+ function resolveCustomTarget(targeting, visitorSelection) {
4019
+ switch (targeting.provider) {
4020
+ case "native": return resolveNativeTarget(targeting, visitorSelection);
4021
+ case "brevo": return resolveBrevoTarget(targeting, visitorSelection);
4022
+ case "mailchimp": return resolveMailchimpTarget(targeting, visitorSelection);
4023
+ }
4024
+ }
4025
+ function resolveNativeTarget(targeting, selection) {
4026
+ if (targeting.selection.tag === "fixed") {
4027
+ return selection === undefined ? ok({
4028
+ provider: "native",
4029
+ topicIds: targeting.selection.topicIds
4030
+ }) : err({ tag: "visitor_selection_not_allowed" });
4031
+ }
4032
+ if (selection === undefined) {
4033
+ return targeting.selection.offeredTopicIds.length === 1 ? ok({
4034
+ provider: "native",
4035
+ topicIds: targeting.selection.offeredTopicIds
4036
+ }) : err({ tag: "visitor_selection_required" });
4037
+ }
4038
+ if (selection.provider !== "native") {
4039
+ return err({ tag: "visitor_selection_provider_mismatch" });
4040
+ }
4041
+ const selected = selectedNonEmptySubset(selection.topicIds, targeting.selection.offeredTopicIds);
4042
+ return selected.ok ? ok({
4043
+ provider: "native",
4044
+ topicIds: selected.value
4045
+ }) : err({ tag: "visitor_selection_outside_offer" });
4046
+ }
4047
+ function resolveBrevoTarget(targeting, selection) {
4048
+ if (targeting.selection.tag === "fixed") {
4049
+ return selection === undefined ? ok({
4050
+ provider: "brevo",
4051
+ listIds: targeting.selection.listIds
4052
+ }) : err({ tag: "visitor_selection_not_allowed" });
4053
+ }
4054
+ if (selection === undefined) {
4055
+ return targeting.selection.offeredListIds.length === 1 ? ok({
4056
+ provider: "brevo",
4057
+ listIds: targeting.selection.offeredListIds
4058
+ }) : err({ tag: "visitor_selection_required" });
4059
+ }
4060
+ if (selection.provider !== "brevo") {
4061
+ return err({ tag: "visitor_selection_provider_mismatch" });
4062
+ }
4063
+ const selected = selectedNonEmptySubset(selection.listIds, targeting.selection.offeredListIds);
4064
+ return selected.ok ? ok({
4065
+ provider: "brevo",
4066
+ listIds: selected.value
4067
+ }) : err({ tag: "visitor_selection_outside_offer" });
4068
+ }
4069
+ function resolveMailchimpTarget(targeting, selection) {
4070
+ if (targeting.selection.tag === "fixed") {
4071
+ return selection === undefined ? ok({
4072
+ provider: "mailchimp",
4073
+ audienceId: targeting.audienceId,
4074
+ interestIds: targeting.selection.interestIds
4075
+ }) : err({ tag: "visitor_selection_not_allowed" });
4076
+ }
4077
+ if (selection === undefined) {
4078
+ return targeting.selection.offeredInterestIds.length === 1 ? ok({
4079
+ provider: "mailchimp",
4080
+ audienceId: targeting.audienceId,
4081
+ interestIds: targeting.selection.offeredInterestIds
4082
+ }) : err({ tag: "visitor_selection_required" });
4083
+ }
4084
+ if (selection.provider !== "mailchimp") {
4085
+ return err({ tag: "visitor_selection_provider_mismatch" });
4086
+ }
4087
+ const subset = selectedNonEmptySubset(selection.interestIds, targeting.selection.offeredInterestIds);
4088
+ return subset.ok ? ok({
4089
+ provider: "mailchimp",
4090
+ audienceId: targeting.audienceId,
4091
+ interestIds: subset.value
4092
+ }) : err({ tag: "visitor_selection_outside_offer" });
4093
+ }
4094
+ function selectedNonEmptySubset(selected, offered) {
4095
+ const normalized = [...new Set(selected)];
4096
+ const [first, ...rest] = normalized;
4097
+ if (first === undefined || normalized.some((item) => !offered.includes(item))) {
4098
+ return err("invalid_selection");
4099
+ }
4100
+ return ok([first, ...rest]);
4101
+ }
4102
+ function planMailingListChoicePresentation(targeting) {
4103
+ if (targeting.mode === "default" || targeting.selection.tag === "fixed") {
4104
+ return { tag: "hidden" };
4105
+ }
4106
+ switch (targeting.provider) {
4107
+ case "native": return targeting.selection.offeredTopicIds.length === 1 ? {
4108
+ tag: "automatic",
4109
+ selection: {
4110
+ provider: "native",
4111
+ topicIds: targeting.selection.offeredTopicIds
4112
+ }
4113
+ } : {
4114
+ tag: "visitor_choice",
4115
+ provider: "native",
4116
+ optionCount: targeting.selection.offeredTopicIds.length
4117
+ };
4118
+ case "brevo": return targeting.selection.offeredListIds.length === 1 ? {
4119
+ tag: "automatic",
4120
+ selection: {
4121
+ provider: "brevo",
4122
+ listIds: targeting.selection.offeredListIds
4123
+ }
4124
+ } : {
4125
+ tag: "visitor_choice",
4126
+ provider: "brevo",
4127
+ optionCount: targeting.selection.offeredListIds.length
4128
+ };
4129
+ case "mailchimp": return targeting.selection.offeredInterestIds.length === 1 ? {
4130
+ tag: "automatic",
4131
+ selection: {
4132
+ provider: "mailchimp",
4133
+ interestIds: targeting.selection.offeredInterestIds
4134
+ }
4135
+ } : {
4136
+ tag: "visitor_choice",
4137
+ provider: "mailchimp",
4138
+ optionCount: targeting.selection.offeredInterestIds.length
4139
+ };
4140
+ }
4141
+ }
4142
+
3933
4143
  //#endregion
3934
4144
  //#region ../core/src/mailing-list-targeting-parser.ts
3935
4145
  function parseMailingListPlacementTargeting(value) {
4146
+ if (value == null) return ok(DEFAULT_MAILING_LIST_TARGETING);
3936
4147
  if (!isRecord$6(value)) return targetingError("shape");
3937
4148
  if (value.mode === "default") return ok({ mode: "default" });
3938
4149
  if (value.mode !== "custom") return targetingError("mode");
@@ -4058,25 +4269,15 @@ function parseNonEmptyUniqueIds(value, parseId) {
4058
4269
  }
4059
4270
  function parseUniqueIds(value, parseId) {
4060
4271
  if (!Array.isArray(value)) return targetingError("targets");
4061
- const parsed = [];
4062
- for (const item of value) {
4272
+ return Array.from(value).reduce((parsed, item) => {
4273
+ if (!parsed.ok) return parsed;
4063
4274
  const id = parseId(item);
4064
- if (id === null) return targetingError("targets");
4065
- if (parsed.includes(id)) return targetingError("duplicate_target");
4066
- parsed.push(id);
4067
- }
4068
- return ok(parsed);
4275
+ return id === null ? targetingError("targets") : parsed.value.includes(id) ? targetingError("duplicate_target") : ok([...parsed.value, id]);
4276
+ }, ok([]));
4069
4277
  }
4070
4278
  function parseVisitorIds(value, parseId) {
4071
- if (!Array.isArray(value) || value.length === 0) return null;
4072
- const parsed = [];
4073
- for (const item of value) {
4074
- const id = parseId(item);
4075
- if (id === null) return null;
4076
- if (parsed.includes(id)) return null;
4077
- parsed.push(id);
4078
- }
4079
- return parsed;
4279
+ const parsed = parseNonEmptyUniqueIds(value, parseId);
4280
+ return parsed.ok ? parsed.value : null;
4080
4281
  }
4081
4282
  function isRecord$6(value) {
4082
4283
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -5077,183 +5278,102 @@ function setupError(field) {
5077
5278
  }
5078
5279
 
5079
5280
  //#endregion
5080
- //#region ../core/src/mailing-list-targeting.ts
5081
- function sameMailingListPlacementTargeting(left, right) {
5082
- if (left.mode !== right.mode) return false;
5083
- if (left.mode === "default" || right.mode === "default") return true;
5084
- if (left.provider !== right.provider || left.selection.tag !== right.selection.tag) return false;
5085
- if (left.provider === "mailchimp" && (right.provider !== "mailchimp" || left.audienceId !== right.audienceId)) return false;
5086
- return sameIds(targetingSelectionIds(left), targetingSelectionIds(right));
5087
- }
5088
- function targetingSelectionIds(targeting) {
5089
- switch (targeting.provider) {
5090
- case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
5091
- case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
5092
- case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
5281
+ //#region ../core/src/mailing-list-targeting-availability.ts
5282
+ function resolveMailingListDefaultDestination(provider) {
5283
+ switch (provider.provider) {
5284
+ case "native": return provider.topics.find((item) => item.id === provider.defaultTopicId) ?? null;
5285
+ case "brevo": return provider.lists.find((item) => item.id === provider.defaultListId) ?? null;
5286
+ case "mailchimp": return provider.audiences.find((item) => item.id === provider.defaultAudienceId) ?? null;
5093
5287
  }
5094
5288
  }
5095
- function sameIds(left, right) {
5096
- const leftIds = new Set(left);
5097
- const rightIds = new Set(right);
5098
- return leftIds.size === left.length && rightIds.size === right.length && leftIds.size === rightIds.size && [...leftIds].every((id) => rightIds.has(id));
5099
- }
5100
- function resolveMailingListTarget(input) {
5101
- if (input.targeting.mode === "default") {
5102
- if (input.visitorSelection !== undefined) {
5103
- return err({ tag: "visitor_selection_not_allowed" });
5289
+ function assessMailingListTargeting(context, targeting) {
5290
+ if (context?.tag !== "configured") return {
5291
+ tag: "unavailable",
5292
+ reason: "setup_missing",
5293
+ targeting
5294
+ };
5295
+ const catalog = context.provider;
5296
+ if (targeting.mode === "custom") return assessCustomTargeting(catalog, targeting);
5297
+ const destination = resolveMailingListDefaultDestination(catalog);
5298
+ return destination === null ? {
5299
+ tag: "unavailable",
5300
+ reason: "default_missing",
5301
+ targeting
5302
+ } : {
5303
+ tag: "available",
5304
+ value: {
5305
+ mode: "default",
5306
+ targeting,
5307
+ provider: catalog.provider,
5308
+ destination
5104
5309
  }
5105
- return ok(resolveDefaultTarget(input.setup));
5106
- }
5107
- if (input.targeting.provider !== input.setup.provider) {
5108
- return err({
5109
- tag: "targeting_provider_mismatch",
5110
- setupProvider: input.setup.provider,
5111
- targetingProvider: input.targeting.provider
5112
- });
5113
- }
5114
- return resolveCustomTarget(input.targeting, input.visitorSelection);
5115
- }
5116
- function resolveDefaultTarget(setup) {
5117
- switch (setup.provider) {
5118
- case "native": return {
5119
- provider: "native",
5120
- topicIds: [setup.defaultTopicId]
5121
- };
5122
- case "brevo": return {
5123
- provider: "brevo",
5124
- listIds: [setup.defaultListId]
5125
- };
5126
- case "mailchimp": return {
5127
- provider: "mailchimp",
5128
- audienceId: setup.defaultAudienceId,
5129
- interestIds: []
5130
- };
5131
- }
5132
- }
5133
- function resolveCustomTarget(targeting, visitorSelection) {
5134
- switch (targeting.provider) {
5135
- case "native": return resolveNativeTarget(targeting, visitorSelection);
5136
- case "brevo": return resolveBrevoTarget(targeting, visitorSelection);
5137
- case "mailchimp": return resolveMailchimpTarget(targeting, visitorSelection);
5138
- }
5139
- }
5140
- function resolveNativeTarget(targeting, selection) {
5141
- if (targeting.selection.tag === "fixed") {
5142
- return selection === undefined ? ok({
5143
- provider: "native",
5144
- topicIds: targeting.selection.topicIds
5145
- }) : err({ tag: "visitor_selection_not_allowed" });
5146
- }
5147
- if (selection === undefined) {
5148
- return targeting.selection.offeredTopicIds.length === 1 ? ok({
5149
- provider: "native",
5150
- topicIds: targeting.selection.offeredTopicIds
5151
- }) : err({ tag: "visitor_selection_required" });
5152
- }
5153
- if (selection.provider !== "native") {
5154
- return err({ tag: "visitor_selection_provider_mismatch" });
5155
- }
5156
- const selected = selectedNonEmptySubset(selection.topicIds, targeting.selection.offeredTopicIds);
5157
- return selected.ok ? ok({
5158
- provider: "native",
5159
- topicIds: selected.value
5160
- }) : err({ tag: "visitor_selection_outside_offer" });
5161
- }
5162
- function resolveBrevoTarget(targeting, selection) {
5163
- if (targeting.selection.tag === "fixed") {
5164
- return selection === undefined ? ok({
5165
- provider: "brevo",
5166
- listIds: targeting.selection.listIds
5167
- }) : err({ tag: "visitor_selection_not_allowed" });
5168
- }
5169
- if (selection === undefined) {
5170
- return targeting.selection.offeredListIds.length === 1 ? ok({
5171
- provider: "brevo",
5172
- listIds: targeting.selection.offeredListIds
5173
- }) : err({ tag: "visitor_selection_required" });
5174
- }
5175
- if (selection.provider !== "brevo") {
5176
- return err({ tag: "visitor_selection_provider_mismatch" });
5177
- }
5178
- const selected = selectedNonEmptySubset(selection.listIds, targeting.selection.offeredListIds);
5179
- return selected.ok ? ok({
5180
- provider: "brevo",
5181
- listIds: selected.value
5182
- }) : err({ tag: "visitor_selection_outside_offer" });
5183
- }
5184
- function resolveMailchimpTarget(targeting, selection) {
5185
- if (targeting.selection.tag === "fixed") {
5186
- return selection === undefined ? ok({
5187
- provider: "mailchimp",
5188
- audienceId: targeting.audienceId,
5189
- interestIds: targeting.selection.interestIds
5190
- }) : err({ tag: "visitor_selection_not_allowed" });
5191
- }
5192
- if (selection === undefined) {
5193
- return targeting.selection.offeredInterestIds.length === 1 ? ok({
5194
- provider: "mailchimp",
5195
- audienceId: targeting.audienceId,
5196
- interestIds: targeting.selection.offeredInterestIds
5197
- }) : err({ tag: "visitor_selection_required" });
5198
- }
5199
- if (selection.provider !== "mailchimp") {
5200
- return err({ tag: "visitor_selection_provider_mismatch" });
5201
- }
5202
- const subset = selectedNonEmptySubset(selection.interestIds, targeting.selection.offeredInterestIds);
5203
- return subset.ok ? ok({
5204
- provider: "mailchimp",
5205
- audienceId: targeting.audienceId,
5206
- interestIds: subset.value
5207
- }) : err({ tag: "visitor_selection_outside_offer" });
5208
- }
5209
- function selectedNonEmptySubset(selected, offered) {
5210
- const normalized = [...new Set(selected)];
5211
- const [first, ...rest] = normalized;
5212
- if (first === undefined || normalized.some((item) => !offered.includes(item))) {
5213
- return err("invalid_selection");
5214
- }
5215
- return ok([first, ...rest]);
5310
+ };
5216
5311
  }
5217
- function planMailingListChoicePresentation(targeting) {
5218
- if (targeting.mode === "default" || targeting.selection.tag === "fixed") {
5219
- return { tag: "hidden" };
5220
- }
5312
+ function assessCustomTargeting(catalog, targeting) {
5221
5313
  switch (targeting.provider) {
5222
- case "native": return targeting.selection.offeredTopicIds.length === 1 ? {
5223
- tag: "automatic",
5224
- selection: {
5225
- provider: "native",
5226
- topicIds: targeting.selection.offeredTopicIds
5227
- }
5228
- } : {
5229
- tag: "visitor_choice",
5314
+ case "native": return catalog.provider === "native" ? assessMatchedChoices({
5230
5315
  provider: "native",
5231
- optionCount: targeting.selection.offeredTopicIds.length
5316
+ catalog,
5317
+ targeting
5318
+ }, catalog.topics) : {
5319
+ tag: "unavailable",
5320
+ reason: "provider_mismatch",
5321
+ targeting
5232
5322
  };
5233
- case "brevo": return targeting.selection.offeredListIds.length === 1 ? {
5234
- tag: "automatic",
5235
- selection: {
5236
- provider: "brevo",
5237
- listIds: targeting.selection.offeredListIds
5238
- }
5239
- } : {
5240
- tag: "visitor_choice",
5323
+ case "brevo": return catalog.provider === "brevo" ? assessMatchedChoices({
5241
5324
  provider: "brevo",
5242
- optionCount: targeting.selection.offeredListIds.length
5325
+ catalog,
5326
+ targeting
5327
+ }, catalog.lists) : {
5328
+ tag: "unavailable",
5329
+ reason: "provider_mismatch",
5330
+ targeting
5243
5331
  };
5244
- case "mailchimp": return targeting.selection.offeredInterestIds.length === 1 ? {
5245
- tag: "automatic",
5246
- selection: {
5332
+ case "mailchimp": {
5333
+ if (catalog.provider !== "mailchimp") return {
5334
+ tag: "unavailable",
5335
+ reason: "provider_mismatch",
5336
+ targeting
5337
+ };
5338
+ const audience = catalog.audiences.find((item) => item.id === targeting.audienceId);
5339
+ return audience === undefined ? {
5340
+ tag: "unavailable",
5341
+ reason: "audience_missing",
5342
+ value: {
5343
+ mode: "custom",
5344
+ provider: "mailchimp",
5345
+ catalog,
5346
+ targeting
5347
+ }
5348
+ } : assessMatchedChoices({
5247
5349
  provider: "mailchimp",
5248
- interestIds: targeting.selection.offeredInterestIds
5249
- }
5250
- } : {
5251
- tag: "visitor_choice",
5252
- provider: "mailchimp",
5253
- optionCount: targeting.selection.offeredInterestIds.length
5254
- };
5350
+ catalog,
5351
+ targeting,
5352
+ audience
5353
+ }, audience.interests);
5354
+ }
5255
5355
  }
5256
5356
  }
5357
+ function assessMatchedChoices(matched, choices) {
5358
+ const selected = new Set(mailingListTargetingChoiceIds(matched.targeting));
5359
+ const available = new Set(choices.map((item) => item.id));
5360
+ const missingIds = [...selected].filter((id) => !available.has(id));
5361
+ const value = {
5362
+ mode: "custom",
5363
+ ...matched,
5364
+ choices,
5365
+ selectedChoices: choices.filter((item) => selected.has(item.id))
5366
+ };
5367
+ return missingIds.length > 0 ? {
5368
+ tag: "unavailable",
5369
+ reason: "choices_missing",
5370
+ missingIds,
5371
+ value
5372
+ } : {
5373
+ tag: "available",
5374
+ value
5375
+ };
5376
+ }
5257
5377
 
5258
5378
  //#endregion
5259
5379
  //#region ../core/src/mailing-list-runtime.ts
@@ -5346,59 +5466,47 @@ function parseBrevoRuntimeProvider(value) {
5346
5466
  function parseMailchimpRuntimeProvider(value) {
5347
5467
  if (!Array.isArray(value.audiences)) return null;
5348
5468
  const defaultAudienceId = parseMailchimpAudienceId(value.defaultAudienceId);
5349
- if (defaultAudienceId === null) return null;
5350
- const audiences = [];
5351
- for (const audience of value.audiences) {
5352
- if (!isRecord$1(audience)) return null;
5353
- const id = parseMailchimpAudienceId(audience.id);
5354
- const name = parseName(audience.name);
5355
- if (id === null || name === null || !Array.isArray(audience.interests)) {
5356
- return null;
5357
- }
5358
- const interests = parseMailchimpInterests(audience.interests);
5359
- if (interests === null) return null;
5360
- audiences.push({
5361
- id,
5362
- name,
5363
- interests
5364
- });
5365
- }
5366
- return {
5469
+ const audiences = Array.from(value.audiences, parseMailchimpAudience);
5470
+ return defaultAudienceId !== null && audiences.every((audience) => audience !== null) ? {
5367
5471
  provider: "mailchimp",
5368
5472
  defaultAudienceId,
5369
5473
  audiences
5370
- };
5474
+ } : null;
5371
5475
  }
5372
- function parseMailchimpInterests(value) {
5373
- const interests = [];
5374
- for (const interest of value) {
5375
- if (!isRecord$1(interest)) return null;
5376
- const id = parseMailchimpInterestId(interest.id);
5377
- const name = parseName(interest.name);
5378
- const categoryName = parseName(interest.categoryName);
5379
- if (id === null || name === null || categoryName === null) return null;
5380
- interests.push({
5381
- id,
5382
- name,
5383
- categoryName
5384
- });
5385
- }
5386
- return interests;
5476
+ function parseMailchimpAudience(value) {
5477
+ if (!isRecord$1(value) || !Array.isArray(value.interests)) return null;
5478
+ const id = parseMailchimpAudienceId(value.id);
5479
+ const name = parseName(value.name);
5480
+ const interests = Array.from(value.interests, parseMailchimpInterest);
5481
+ return id !== null && name !== null && interests.every((interest) => interest !== null) ? {
5482
+ id,
5483
+ name,
5484
+ interests
5485
+ } : null;
5486
+ }
5487
+ function parseMailchimpInterest(value) {
5488
+ if (!isRecord$1(value)) return null;
5489
+ const id = parseMailchimpInterestId(value.id);
5490
+ const name = parseName(value.name);
5491
+ const categoryName = parseName(value.categoryName);
5492
+ return id !== null && name !== null && categoryName !== null ? {
5493
+ id,
5494
+ name,
5495
+ categoryName
5496
+ } : null;
5387
5497
  }
5388
5498
  function parseNamedItems(value, parseId) {
5389
5499
  if (!Array.isArray(value)) return null;
5390
- const items = [];
5391
- for (const item of value) {
5500
+ const items = Array.from(value, (item) => {
5392
5501
  if (!isRecord$1(item)) return null;
5393
5502
  const id = parseId(item.id);
5394
5503
  const name = parseName(item.name);
5395
- if (id === null || name === null) return null;
5396
- items.push({
5504
+ return id !== null && name !== null ? {
5397
5505
  id,
5398
5506
  name
5399
- });
5400
- }
5401
- return items;
5507
+ } : null;
5508
+ });
5509
+ return items.every((item) => item !== null) ? items : null;
5402
5510
  }
5403
5511
  function parseName(value) {
5404
5512
  if (typeof value !== "string") return null;
@@ -6254,7 +6362,6 @@ const SECRET_KINDS = [
6254
6362
  "webhook-secret",
6255
6363
  "oauth-access-token",
6256
6364
  "oauth-refresh-token",
6257
- "preview-session-refresh-token",
6258
6365
  "oauth-authorization-code",
6259
6366
  "oauth-pkce-verifier",
6260
6367
  "registrar-epp-code"
@@ -7418,4 +7525,4 @@ function mergeBag(stored, patch, options) {
7418
7525
  }
7419
7526
 
7420
7527
  //#endregion
7421
- export { parseBookingTimeZone as $, unsafeAsEventSeriesId as $t, footerNavigationLayouts as A, parseCurrencyCode as At, buildBookingUtcDateWindow as B, parseRetiredCourseId as Bt, parseMailingListContentVersionId as C, isNonNegativeWholeCents as Ct, sameMailingListPlacementTargeting as D, unsafeAsNonNegativeCents as Dt, planMailingListChoicePresentation as E, toNonNegativeCents as Et, assertAllowedPublicUrl as F, parseDatedOfferingCapacityHoldId as Ft, formatLocalScheduleTime as G, unsafeAsBookingSessionId as Gt, formatBookingDateParts as H, parseUserId as Ht, isPresent as I, parseEventSeriesId as It, getLocalScheduleTime as J, unsafeAsDemoCapability as Jt, getBookingLocalDateKey as K, unsafeAsCheckoutLineId as Kt, normalizeLocationAddressText as L, parseMediaAssetId as Lt, parseMailingListPlacementTargeting as M, parseApiKeyId as Mt, isCanonicalRichTextDoc as N, parseCustomerId as Nt, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as O, unsafeAsPositiveCents as Ot, parsePublicContactDetails as P, parseDatedOfferingCapacityHoldAuditRef as Pt, toScheduledBookingDateTime as Q, unsafeAsEventOfferingId as Qt, toLocationCoordinates as R, parseMembershipId as Rt, parseMailingListBlockId as S, mapNonEmptyArray as St, parseMailingListRuntimeContext as T, toCents as Tt, formatBookingTime as U, unsafeAsAppointmentResourceId as Ut, formatBookingDate as V, parseSiteId as Vt, formatLocalScheduleDate as W, unsafeAsBookingRequirementId as Wt, toBookingTimeZone as X, unsafeAsEntitlementId as Xt, parseUtcIsoDateTimeString as Y, unsafeAsDetectedMimeType as Yt, toScheduledBookingDateRange as Z, unsafeAsEventInstanceId as Zt, createSecret as _, unsafeAsUserId as _n, publicEventPricingDisplay as _t, parseVerticalId as a, unsafeAsPositiveByteCount as an, clampConfiguredAmount as at, stableJsonStringify as b, resolvePricingOptionsPriceDisplay as bt, DEFAULT_EVENT_TYPE_PRESETS as c, unsafeAsProductId as cn, omitZeroAmountFutureRows as ct, SURFACE_EVENT_PRESET_VALUES as d, unsafeAsSiteId as dn, resolveFlexibleBalanceInitialPaymentCents as dt, unsafeAsFileChecksumSha256 as en, validateBookingPaymentOptionKinds as et, WHOLE_SERIES_EVENT_PRESET_VALUES as f, unsafeAsSiteScopedStoragePath as fn, parseEventPageSurfaceSubject as ft, resolveWholeSeriesBookingPhase as g, unsafeAsUploadSessionId as gn, publicEventPricingCurrency as gt, orderedLiveRunSessions as h, unsafeAsStoragePath as hn, isPublicEventPricingOptionDisplayable as ht, canonicalizeConfiguredBookingVerticalConfig as i, unsafeAsPassId as in, addIntervalPreservingMonthAnchor as it, parseFooterCompositionV1 as j, assertNever as jt, parseMailingListProviderScope as k, formatCurrencyAmount as kt, EVENT_PRESET_VALUES as l, unsafeAsSafeDownloadFilename as ln, splitAmountWithRemainderInFirst as lt, CANCELLED_SESSION_STATUS as m, unsafeAsStorageBucketName as mn, formatEventPricing as mt, NAVIGATION_LOCATIONS as n, unsafeAsOccurrenceId as nn, isSettleableFlexibleBalanceContractStatus as nt, parseVerticalPresetId as o, unsafeAsPositiveSeconds as on, getBookingInstalmentDepositRefundability as ot, publicReadFreshnessSeconds as p, unsafeAsStaffMemberId as pn, formatBookingPriceDisplay as pt, getLocalScheduleDate as q, unsafeAsDeclaredMimeType as qt, areConfiguredBookingVerticalConfigsEqual as r, unsafeAsOriginalFilename as rn, isSettleableOrderInstalmentPlanStatus as rt, resolveSiteVerticalBookingConfig as s, unsafeAsPricingOptionId as sn, getBookingInstalmentProtectedDepositAmountCents as st, resolveEventCatalogue as t, unsafeAsMediaAssetId as tn, isLiveOrderInstalmentPlanStatus as tt, ORDINARY_EVENT_PRESET_VALUES as u, unsafeAsSiteFontId as un, resolveFlexibleBalanceDueAt as ut, exposeSecret as v, err as vn, publicEventPricingType as vt, parseMailingListSignedSourceToken as w, parseNonNegativeCents as wt, buildMailingListSignupBlockSourceRef as x, fromArray as xt, parseManagementKey as y, ok as yn, resolveExactOrFreePriceDisplay as yt, selectCategoryView as z, parsePageId as zt };
7528
+ export { toBookingTimeZone as $, unsafeAsCheckoutLineId as $t, footerNavigationLayouts as A, parsePositiveCents as At, normalizeLocationAddressText as B, parseCustomerId as Bt, parseMailingListBlockId as C, unsafeAsUploadSessionId as Cn, publicEventPricingType as Ct, assessMailingListTargeting as D, mapNonEmptyArray as Dt, parseMailingListRuntimeContext as E, ok as En, fromArray as Et, sameMailingListPlacementTargeting as F, formatCurrencyAmount as Ft, formatBookingDateParts as G, parseMembershipId as Gt, selectCategoryView as H, parseDatedOfferingCapacityHoldId as Ht, isCanonicalRichTextDoc as I, parseCurrencyCode as It, formatLocalScheduleTime as J, parseSiteId as Jt, formatBookingTime as K, parsePageId as Kt, parsePublicContactDetails as L, assertNever as Lt, parseMailingListPlacementTargeting as M, toNonNegativeCents as Mt, DEFAULT_MAILING_LIST_TARGETING as N, unsafeAsNonNegativeCents as Nt, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as O, isNonNegativeWholeCents as Ot, planMailingListChoicePresentation as P, unsafeAsPositiveCents as Pt, parseUtcIsoDateTimeString as Q, unsafeAsBookingSessionId as Qt, assertAllowedPublicUrl as R, formatDurationUnitLabel as Rt, buildMailingListSignupBlockSourceRef as S, unsafeAsStoragePath as Sn, publicEventPricingOptions as St, parseMailingListSignedSourceToken as T, err as Tn, resolvePricingOptionsPriceDisplay as Tt, buildBookingUtcDateWindow as U, parseEventSeriesId as Ut, toLocationCoordinates as V, parseDatedOfferingCapacityHoldAuditRef as Vt, formatBookingDate as W, parseMediaAssetId as Wt, getLocalScheduleDate as X, unsafeAsAppointmentResourceId as Xt, getBookingLocalDateKey as Y, parseUserId as Yt, getLocalScheduleTime as Z, unsafeAsBookingRequirementId as Zt, resolveWholeSeriesBookingPhase as _, unsafeAsSiteFontId as _n, formatBookingPriceDisplay as _t, canonicalizeConfiguredBookingVerticalConfig as a, unsafeAsEventOfferingId as an, isSettleableFlexibleBalanceContractStatus as at, parseManagementKey as b, unsafeAsStaffMemberId as bn, publicEventPricingCurrency as bt, resolveSiteVerticalBookingConfig as c, unsafeAsMediaAssetId as cn, clampConfiguredAmount as ct, ORDINARY_EVENT_PRESET_VALUES as d, unsafeAsPassId as dn, getBookingInstalmentProtectedDepositAmountCents as dt, unsafeAsDeclaredMimeType as en, toScheduledBookingDateRange as et, SURFACE_EVENT_PRESET_VALUES as f, unsafeAsPositiveByteCount as fn, omitZeroAmountFutureRows as ft, orderedLiveRunSessions as g, unsafeAsSafeDownloadFilename as gn, parseEventPageSurfaceSubject as gt, CANCELLED_SESSION_STATUS as h, unsafeAsProductId as hn, resolveFlexibleBalanceInitialPaymentCents as ht, areConfiguredBookingVerticalConfigsEqual as i, unsafeAsEventInstanceId as in, isLiveOrderInstalmentPlanStatus as it, parseFooterCompositionV1 as j, toCents as jt, parseMailingListProviderScope as k, parseNonNegativeCents as kt, DEFAULT_EVENT_TYPE_PRESETS as l, unsafeAsOccurrenceId as ln, getBookingInstalmentDepositRefundability as lt, publicReadFreshnessSeconds as m, unsafeAsPricingOptionId as mn, resolveFlexibleBalanceDueAt as mt, EVENT_PRESET_VOCABULARY as n, unsafeAsDetectedMimeType as nn, parseBookingTimeZone as nt, parseVerticalId as o, unsafeAsEventSeriesId as on, isSettleableOrderInstalmentPlanStatus as ot, WHOLE_SERIES_EVENT_PRESET_VALUES as p, unsafeAsPositiveSeconds as pn, splitAmountWithRemainderInFirst as pt, formatLocalScheduleDate as q, parseRetiredCourseId as qt, NAVIGATION_LOCATIONS as r, unsafeAsEntitlementId as rn, validateBookingPaymentOptionKinds as rt, parseVerticalPresetId as s, unsafeAsFileChecksumSha256 as sn, addIntervalPreservingMonthAnchor as st, resolveEventCatalogue as t, unsafeAsDemoCapability as tn, toScheduledBookingDateTime as tt, EVENT_PRESET_VALUES as u, unsafeAsOriginalFilename as un, getBookingInstalmentPlanIntervalCount as ut, createSecret as v, unsafeAsSiteId as vn, formatEventPricing as vt, parseMailingListContentVersionId as w, unsafeAsUserId as wn, resolveExactOrFreePriceDisplay as wt, stableJsonStringify as x, unsafeAsStorageBucketName as xn, publicEventPricingDisplay as xt, exposeSecret as y, unsafeAsSiteScopedStoragePath as yn, isPublicEventPricingOptionDisplayable as yt, isPresent as z, parseApiKeyId as zt };