riverbankcms 0.27.0 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acceptance/matrix.mjs +3 -3
- package/dist/cli/index.mjs +3040 -5001
- package/dist/{entryCommands-Dg5IT7Uv.mjs → entryCommands-CrfobcW7.mjs} +2938 -363
- package/dist/{eventUpsertInputSchema-D4xpVjUT.mjs → eventUpsertInputSchema-R2GbOsj2.mjs} +372 -45
- package/dist/load-config-BB5L2u1y.mjs +4 -0
- package/dist/{load-config-DsPKn5yN.mjs → load-config-DTbiJyCf.mjs} +16 -6
- package/dist/{plan-oltx4aO0.mjs → plan-DJfyedxU.mjs} +1 -1
- package/dist/scaffold/index.mjs +2 -2
- package/dist/{sdk-event-upsert-CnvVuQJy.mjs → sdk-event-upsert-4Dn75Ui9.mjs} +5667 -2259
- package/dist/{src-DqoU7zKs.mjs → src-nzVzuMR1.mjs} +591 -352
- package/dist/testing.mjs +4 -4
- package/package.json +1 -1
- package/dist/load-config-BcATOVmw.mjs +0 -4
|
@@ -22,7 +22,7 @@ function err(error) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
//#endregion
|
|
25
|
-
//#region ../core/src/branded.ts
|
|
25
|
+
//#region ../core/src/branded/uuid.ts
|
|
26
26
|
const UUID_PATTERN$1 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
27
27
|
function parseUuidBrand(value, unsafeConstructor) {
|
|
28
28
|
if (typeof value !== "string") {
|
|
@@ -43,22 +43,10 @@ function expectParsedBrandedId(result) {
|
|
|
43
43
|
}
|
|
44
44
|
return result.value;
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* function can't verify the input string is actually shaped as a preview
|
|
50
|
-
* id — the predicate `isPreviewEntryId` is the recommended narrowing path.
|
|
51
|
-
*/
|
|
52
|
-
const unsafeAsPreviewEntryId = (id) => id;
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region ../core/src/branded/events.ts
|
|
53
49
|
const unsafeAsEventInstanceId = (id) => id;
|
|
54
|
-
const unsafeAsSiteId = (id) => id;
|
|
55
|
-
const unsafeAsApiKeyId = (id) => id;
|
|
56
|
-
const unsafeAsSiteRouteId = (id) => id;
|
|
57
|
-
const unsafeAsPageId = (id) => id;
|
|
58
|
-
const unsafeAsPageSurfaceId = (id) => id;
|
|
59
|
-
const unsafeAsEditLeaseToken = (id) => id;
|
|
60
|
-
const unsafeAsEditorClientId = (id) => id;
|
|
61
|
-
const unsafeAsEditorSessionGeneration = (id) => id;
|
|
62
50
|
const unsafeAsOccurrenceId = (id) => id;
|
|
63
51
|
const unsafeAsEventOfferingId = (id) => id;
|
|
64
52
|
const unsafeAsEventSeriesId = (id) => id;
|
|
@@ -68,11 +56,87 @@ const unsafeAsEventSeriesRegistrationId = (id) => id;
|
|
|
68
56
|
const unsafeAsEventCategoryId = (id) => id;
|
|
69
57
|
const unsafeAsVenueId = (id) => id;
|
|
70
58
|
const unsafeAsPricingOptionId = (id) => id;
|
|
59
|
+
const unsafeAsAttendeeId = (id) => id;
|
|
60
|
+
const unsafeAsEventRegistrationCommandId = (id) => id;
|
|
61
|
+
const unsafeAsEventRegistrationCommandRowId = (id) => id;
|
|
62
|
+
const parseOccurrenceId = (value) => parseUuidBrand(value, unsafeAsOccurrenceId);
|
|
63
|
+
const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
|
|
64
|
+
const parseEventAttendeeTicketLineId = (value) => parseUuidBrand(value, unsafeAsEventAttendeeTicketLineId);
|
|
65
|
+
const parsePricingOptionId = (value) => parseUuidBrand(value, unsafeAsPricingOptionId);
|
|
66
|
+
const asRetiredCourseId = (id) => id;
|
|
67
|
+
const parseRetiredCourseId = (value) => parseUuidBrand(value, asRetiredCourseId);
|
|
68
|
+
const parseAttendeeId = (value) => parseUuidBrand(value, unsafeAsAttendeeId);
|
|
69
|
+
const parseEventRegistrationCommandId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandId);
|
|
70
|
+
const parseEventRegistrationCommandRowId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandRowId);
|
|
71
|
+
const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
|
|
72
|
+
const parseEventSeriesRegistrationId = (value) => parseUuidBrand(value, unsafeAsEventSeriesRegistrationId);
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region ../core/src/branded/identity.ts
|
|
76
|
+
const unsafeAsSiteId = (id) => id;
|
|
77
|
+
const unsafeAsApiKeyId = (id) => id;
|
|
78
|
+
const unsafeAsUserId = (id) => id;
|
|
79
|
+
const unsafeAsActivityLogEntryId = (id) => id;
|
|
80
|
+
const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
|
|
81
|
+
const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
|
|
82
|
+
const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region ../core/src/branded/site.ts
|
|
86
|
+
const unsafeAsSiteRouteId = (id) => id;
|
|
87
|
+
const unsafeAsPageId = (id) => id;
|
|
88
|
+
const unsafeAsPageSurfaceId = (id) => id;
|
|
89
|
+
const unsafeAsEditLeaseToken = (id) => id;
|
|
90
|
+
const unsafeAsEditorClientId = (id) => id;
|
|
91
|
+
const unsafeAsEditorSessionGeneration = (id) => id;
|
|
92
|
+
const unsafeAsSiteFontId = (id) => id;
|
|
93
|
+
const unsafeAsNavigationMenuId = (id) => id;
|
|
94
|
+
const unsafeAsNavigationItemId = (id) => id;
|
|
95
|
+
const parseSiteRouteId = (value) => parseUuidBrand(value, unsafeAsSiteRouteId);
|
|
96
|
+
const parsePageId = (value) => parseUuidBrand(value, unsafeAsPageId);
|
|
97
|
+
const parsePageSurfaceId = (value) => parseUuidBrand(value, unsafeAsPageSurfaceId);
|
|
98
|
+
const parseEditLeaseToken = (value) => parseUuidBrand(value, unsafeAsEditLeaseToken);
|
|
99
|
+
const parseEditorClientId = (value) => parseUuidBrand(value, unsafeAsEditorClientId);
|
|
100
|
+
const parseEditorSessionGeneration = (value) => parseUuidBrand(value, unsafeAsEditorSessionGeneration);
|
|
101
|
+
const parseNavigationMenuId = (value) => parseUuidBrand(value, unsafeAsNavigationMenuId);
|
|
102
|
+
const parseNavigationItemId = (value) => parseUuidBrand(value, unsafeAsNavigationItemId);
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region ../core/src/branded/orders.ts
|
|
71
106
|
const unsafeAsMoneyDateString = (value) => value;
|
|
72
107
|
const unsafeAsStripeCheckoutSessionId = (value) => value;
|
|
108
|
+
const unsafeAsOrderRetirementOperationId = (id) => id;
|
|
109
|
+
const unsafeAsOrderId = (id) => id;
|
|
110
|
+
const unsafeAsOrderItemId = (id) => id;
|
|
111
|
+
const unsafeAsOrderRefundId = (id) => id;
|
|
112
|
+
const unsafeAsOrderPaymentReceiptId = (id) => id;
|
|
113
|
+
const unsafeAsOrderFlexibleBalanceContractId = (id) => id;
|
|
114
|
+
const unsafeAsOrderPaymentPlanId = (id) => id;
|
|
115
|
+
const unsafeAsOrderPaymentPlanInstalmentId = (id) => id;
|
|
116
|
+
const unsafeAsManualPaymentOperationId = (id) => id;
|
|
117
|
+
const unsafeAsCheckoutLineId = (id) => id;
|
|
118
|
+
const unsafeAsShipmentId = (id) => id;
|
|
119
|
+
const parseOrderItemId = (value) => parseUuidBrand(value, unsafeAsOrderItemId);
|
|
120
|
+
const parseOrderRetirementOperationId = (value) => parseUuidBrand(value, unsafeAsOrderRetirementOperationId);
|
|
121
|
+
const parseOrderId = (value) => parseUuidBrand(value, unsafeAsOrderId);
|
|
122
|
+
const parseOrderRefundId = (value) => parseUuidBrand(value, unsafeAsOrderRefundId);
|
|
123
|
+
const parseOrderPaymentReceiptId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentReceiptId);
|
|
124
|
+
const parseOrderFlexibleBalanceContractId = (value) => parseUuidBrand(value, unsafeAsOrderFlexibleBalanceContractId);
|
|
125
|
+
const parseOrderPaymentPlanId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanId);
|
|
126
|
+
const parseOrderPaymentPlanInstalmentId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanInstalmentId);
|
|
127
|
+
const parseManualPaymentOperationId = (value) => parseUuidBrand(value, unsafeAsManualPaymentOperationId);
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region ../core/src/branded/products.ts
|
|
73
131
|
const unsafeAsProductId = (id) => id;
|
|
74
132
|
const unsafeAsProductVariantId = (id) => id;
|
|
75
133
|
const unsafeAsProductCategoryId = (id) => id;
|
|
134
|
+
const parseProductId = (value) => parseUuidBrand(value, unsafeAsProductId);
|
|
135
|
+
const parseProductVariantId = (value) => parseUuidBrand(value, unsafeAsProductVariantId);
|
|
136
|
+
const parseProductCategoryId = (value) => parseUuidBrand(value, unsafeAsProductCategoryId);
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region ../core/src/branded/media.ts
|
|
76
140
|
const unsafeAsMediaAssetId = (id) => id;
|
|
77
141
|
const unsafeAsUploadSessionId = (id) => id;
|
|
78
142
|
const unsafeAsStorageBucketName = (value) => value;
|
|
@@ -86,6 +150,10 @@ const unsafeAsOriginalFilename = (value) => value;
|
|
|
86
150
|
const unsafeAsSafeDownloadFilename = (value) => value;
|
|
87
151
|
const unsafeAsPositiveByteCount = (value) => value;
|
|
88
152
|
const unsafeAsPositiveSeconds = (value) => value;
|
|
153
|
+
const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region ../core/src/branded/bookings.ts
|
|
89
157
|
const unsafeAsBookingSessionId = (id) => id;
|
|
90
158
|
const unsafeAsDatedOfferingCapacityHoldId = (value) => value;
|
|
91
159
|
const unsafeAsDatedOfferingCapacityHoldAuditRef = (value) => value;
|
|
@@ -93,31 +161,46 @@ const unsafeAsDatedOfferingRevocationAuditEventId = (value) => value;
|
|
|
93
161
|
const unsafeAsDatedOfferingWaitlistCapacityEffectId = (value) => value;
|
|
94
162
|
const unsafeAsDatedOfferingWaitlistCapacityEffectClaimToken = (value) => value;
|
|
95
163
|
const unsafeAsDatedOfferingRunCancellationOperationId = (value) => value;
|
|
164
|
+
const unsafeAsWaitlistEntryId = (id) => id;
|
|
165
|
+
const unsafeAsWaitlistHoldId = (id) => id;
|
|
166
|
+
const parseDatedOfferingCapacityHoldId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldId);
|
|
167
|
+
const parseDatedOfferingCapacityHoldAuditRef = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldAuditRef);
|
|
168
|
+
const parseDatedOfferingRevocationAuditEventId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRevocationAuditEventId);
|
|
169
|
+
const parseDatedOfferingWaitlistCapacityEffectId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectId);
|
|
170
|
+
const parseDatedOfferingWaitlistCapacityEffectClaimToken = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectClaimToken);
|
|
171
|
+
const parseDatedOfferingRunCancellationOperationId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRunCancellationOperationId);
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region ../core/src/branded/entitlements.ts
|
|
96
175
|
const unsafeAsEntitlementId = (id) => id;
|
|
97
|
-
const unsafeAsSiteFontId = (id) => id;
|
|
98
|
-
const unsafeAsUserId = (id) => id;
|
|
99
|
-
const unsafeAsFormId = (id) => id;
|
|
100
|
-
const unsafeAsFormSubmissionId = (id) => id;
|
|
101
176
|
const unsafeAsPassId = (id) => id;
|
|
102
177
|
const unsafeAsMembershipId = (id) => id;
|
|
178
|
+
const unsafeAsCustomerPassId = (id) => id;
|
|
179
|
+
const unsafeAsCustomerMembershipId = (id) => id;
|
|
180
|
+
const parsePassId = (value) => parseUuidBrand(value, unsafeAsPassId);
|
|
181
|
+
const parseMembershipId = (value) => parseUuidBrand(value, unsafeAsMembershipId);
|
|
182
|
+
const parseCustomerPassId = (value) => parseUuidBrand(value, unsafeAsCustomerPassId);
|
|
183
|
+
const parseCustomerMembershipId = (value) => parseUuidBrand(value, unsafeAsCustomerMembershipId);
|
|
184
|
+
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region ../core/src/branded/communications.ts
|
|
187
|
+
const unsafeAsFormId = (id) => id;
|
|
188
|
+
const unsafeAsFormSubmissionId = (id) => id;
|
|
189
|
+
const unsafeAsNewsletterSubscriberId = (id) => id;
|
|
190
|
+
const unsafeAsEmailAuditRowId = (id) => id;
|
|
191
|
+
const parseFormId = (value) => parseUuidBrand(value, unsafeAsFormId);
|
|
192
|
+
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region ../core/src/branded/customers.ts
|
|
103
195
|
const unsafeAsCustomerId = (id) => id;
|
|
104
196
|
const unsafeAsSiteTermsVersionId = (id) => id;
|
|
105
197
|
const unsafeAsSiteTermsAgreementId = (id) => id;
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const unsafeAsOrderPaymentPlanId = (id) => id;
|
|
113
|
-
const unsafeAsOrderPaymentPlanInstalmentId = (id) => id;
|
|
114
|
-
const unsafeAsManualPaymentOperationId = (id) => id;
|
|
115
|
-
const unsafeAsCheckoutLineId = (id) => id;
|
|
116
|
-
const unsafeAsAttendeeId = (id) => id;
|
|
117
|
-
const unsafeAsEventRegistrationCommandId = (id) => id;
|
|
118
|
-
const unsafeAsEventRegistrationCommandRowId = (id) => id;
|
|
119
|
-
const unsafeAsCustomerPassId = (id) => id;
|
|
120
|
-
const unsafeAsCustomerMembershipId = (id) => id;
|
|
198
|
+
const parseCustomerId = (value) => parseUuidBrand(value, unsafeAsCustomerId);
|
|
199
|
+
const parseSiteTermsVersionId = (value) => parseUuidBrand(value, unsafeAsSiteTermsVersionId);
|
|
200
|
+
const parseSiteTermsAgreementId = (value) => parseUuidBrand(value, unsafeAsSiteTermsAgreementId);
|
|
201
|
+
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region ../core/src/branded/appointments.ts
|
|
121
204
|
const unsafeAsAppointmentId = (id) => id;
|
|
122
205
|
const unsafeAsAppointmentServiceId = (id) => id;
|
|
123
206
|
const unsafeAsAppointmentResourceId = (id) => id;
|
|
@@ -125,25 +208,44 @@ const unsafeAsAppointmentReservationId = (id) => id;
|
|
|
125
208
|
const unsafeAsAppointmentReservationRunId = (id) => id;
|
|
126
209
|
const unsafeAsAppointmentPaymentRequestId = (id) => id;
|
|
127
210
|
const unsafeAsStaffMemberId = (id) => id;
|
|
211
|
+
const parseAppointmentId = (value) => parseUuidBrand(value, unsafeAsAppointmentId);
|
|
212
|
+
const parseAppointmentServiceId = (value) => parseUuidBrand(value, unsafeAsAppointmentServiceId);
|
|
213
|
+
const parseAppointmentResourceId = (value) => parseUuidBrand(value, unsafeAsAppointmentResourceId);
|
|
214
|
+
const parseAppointmentReservationId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationId);
|
|
215
|
+
const parseAppointmentReservationRunId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationRunId);
|
|
216
|
+
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region ../core/src/branded/calendar.ts
|
|
128
219
|
const unsafeAsBookingCalendarFeedTokenId = (id) => id;
|
|
129
220
|
const unsafeAsBookingCalendarFeedTokenPublicId = (id) => id;
|
|
130
221
|
const unsafeAsBookingCalendarFeedTokenSecret = (value) => value;
|
|
131
222
|
const unsafeAsBookingCalendarFeedTokenSecretHash = (value) => value;
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region ../core/src/branded/content.ts
|
|
226
|
+
const unsafeAsEntryId = (id) => id;
|
|
227
|
+
/**
|
|
228
|
+
* Mint a preview-fixture entry id. Unsafe at the type level because the
|
|
229
|
+
* function can't verify the input string is actually shaped as a preview
|
|
230
|
+
* id — the predicate `isPreviewEntryId` is the recommended narrowing path.
|
|
231
|
+
*/
|
|
232
|
+
const unsafeAsPreviewEntryId = (id) => id;
|
|
132
233
|
const unsafeAsContentEntryId = (id) => id;
|
|
133
234
|
const unsafeAsContentBlockId = (id) => id;
|
|
134
235
|
const unsafeAsContentVersionId = (id) => id;
|
|
135
236
|
const unsafeAsEntryContentHash = (value) => value;
|
|
237
|
+
const parseContentEntryId = (value) => parseUuidBrand(value, unsafeAsContentEntryId);
|
|
238
|
+
const parseContentBlockId = (value) => parseUuidBrand(value, unsafeAsContentBlockId);
|
|
239
|
+
const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
|
|
240
|
+
|
|
241
|
+
//#endregion
|
|
242
|
+
//#region ../core/src/branded/billing.ts
|
|
136
243
|
const unsafeAsStripeInvoiceId = (id) => id;
|
|
137
244
|
const unsafeAsStripeCustomerId = (id) => id;
|
|
138
245
|
const unsafeAsStripeSubscriptionId = (id) => id;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const unsafeAsEmailAuditRowId = (id) => id;
|
|
143
|
-
const unsafeAsWaitlistEntryId = (id) => id;
|
|
144
|
-
const unsafeAsWaitlistHoldId = (id) => id;
|
|
145
|
-
const unsafeAsShipmentId = (id) => id;
|
|
146
|
-
const unsafeAsActivityLogEntryId = (id) => id;
|
|
246
|
+
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region ../core/src/branded/demo.ts
|
|
147
249
|
const unsafeAsDemoBlueprintId = (id) => id;
|
|
148
250
|
const unsafeAsDemoBlueprintVersionId = (id) => id;
|
|
149
251
|
const unsafeAsDemoInstanceId = (id) => id;
|
|
@@ -152,8 +254,14 @@ const unsafeAsDemoLifecycleAuditEventId = (id) => id;
|
|
|
152
254
|
const unsafeAsDemoRuntimeId = (id) => id;
|
|
153
255
|
const unsafeAsDemoCapability = (value) => value;
|
|
154
256
|
const unsafeAsDemoPaymentFlowId = (id) => id;
|
|
257
|
+
|
|
258
|
+
//#endregion
|
|
259
|
+
//#region ../core/src/branded/gifting.ts
|
|
155
260
|
const unsafeAsGiftingOfferId = (id) => id;
|
|
156
261
|
const unsafeAsGiftingInstrumentId = (id) => id;
|
|
262
|
+
|
|
263
|
+
//#endregion
|
|
264
|
+
//#region ../core/src/branded/participants.ts
|
|
157
265
|
const unsafeAsBookingRequirementId = (id) => id;
|
|
158
266
|
const unsafeAsBookingRequirementEvidenceId = (id) => id;
|
|
159
267
|
const unsafeAsBookingRequirementDocumentUploadId = (id) => id;
|
|
@@ -162,69 +270,15 @@ const unsafeAsParticipantId = (id) => id;
|
|
|
162
270
|
const unsafeAsParticipantParticipationId = (id) => id;
|
|
163
271
|
const unsafeAsParticipantRosterAssertionJobId = (id) => id;
|
|
164
272
|
const unsafeAsParticipantBookingQuestionsTaskId = (id) => id;
|
|
273
|
+
const parseParticipantId = (value) => parseUuidBrand(value, unsafeAsParticipantId);
|
|
274
|
+
const parseParticipantParticipationId = (value) => parseUuidBrand(value, unsafeAsParticipantParticipationId);
|
|
275
|
+
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region ../core/src/branded/records.ts
|
|
165
278
|
const unsafeAsPersonRecordId = (id) => id;
|
|
166
279
|
const unsafeAsEncounterRecordId = (id) => id;
|
|
167
280
|
const unsafeAsRecordEntryId = (id) => id;
|
|
168
281
|
const unsafeAsProtectedPayloadKeyVersion = (id) => id;
|
|
169
|
-
const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
|
|
170
|
-
const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
|
|
171
|
-
const parseSiteRouteId = (value) => parseUuidBrand(value, unsafeAsSiteRouteId);
|
|
172
|
-
const parsePageId = (value) => parseUuidBrand(value, unsafeAsPageId);
|
|
173
|
-
const parsePageSurfaceId = (value) => parseUuidBrand(value, unsafeAsPageSurfaceId);
|
|
174
|
-
const parseEditLeaseToken = (value) => parseUuidBrand(value, unsafeAsEditLeaseToken);
|
|
175
|
-
const parseEditorClientId = (value) => parseUuidBrand(value, unsafeAsEditorClientId);
|
|
176
|
-
const parseEditorSessionGeneration = (value) => parseUuidBrand(value, unsafeAsEditorSessionGeneration);
|
|
177
|
-
const parseOccurrenceId = (value) => parseUuidBrand(value, unsafeAsOccurrenceId);
|
|
178
|
-
const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
|
|
179
|
-
const parseEventAttendeeTicketLineId = (value) => parseUuidBrand(value, unsafeAsEventAttendeeTicketLineId);
|
|
180
|
-
const parsePricingOptionId = (value) => parseUuidBrand(value, unsafeAsPricingOptionId);
|
|
181
|
-
const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
|
|
182
|
-
const parseProductId = (value) => parseUuidBrand(value, unsafeAsProductId);
|
|
183
|
-
const parseProductVariantId = (value) => parseUuidBrand(value, unsafeAsProductVariantId);
|
|
184
|
-
const parseProductCategoryId = (value) => parseUuidBrand(value, unsafeAsProductCategoryId);
|
|
185
|
-
const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
|
|
186
|
-
const parseContentEntryId = (value) => parseUuidBrand(value, unsafeAsContentEntryId);
|
|
187
|
-
const parseContentBlockId = (value) => parseUuidBrand(value, unsafeAsContentBlockId);
|
|
188
|
-
const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
|
|
189
|
-
const parseNavigationMenuId = (value) => parseUuidBrand(value, unsafeAsNavigationMenuId);
|
|
190
|
-
const parseNavigationItemId = (value) => parseUuidBrand(value, unsafeAsNavigationItemId);
|
|
191
|
-
const parsePassId = (value) => parseUuidBrand(value, unsafeAsPassId);
|
|
192
|
-
const parseMembershipId = (value) => parseUuidBrand(value, unsafeAsMembershipId);
|
|
193
|
-
const asRetiredCourseId = (id) => id;
|
|
194
|
-
const parseRetiredCourseId = (value) => parseUuidBrand(value, asRetiredCourseId);
|
|
195
|
-
const parseFormId = (value) => parseUuidBrand(value, unsafeAsFormId);
|
|
196
|
-
const parseAppointmentId = (value) => parseUuidBrand(value, unsafeAsAppointmentId);
|
|
197
|
-
const parseAppointmentServiceId = (value) => parseUuidBrand(value, unsafeAsAppointmentServiceId);
|
|
198
|
-
const parseAppointmentResourceId = (value) => parseUuidBrand(value, unsafeAsAppointmentResourceId);
|
|
199
|
-
const parseAppointmentReservationId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationId);
|
|
200
|
-
const parseAppointmentReservationRunId = (value) => parseUuidBrand(value, unsafeAsAppointmentReservationRunId);
|
|
201
|
-
const parseAttendeeId = (value) => parseUuidBrand(value, unsafeAsAttendeeId);
|
|
202
|
-
const parseEventRegistrationCommandId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandId);
|
|
203
|
-
const parseEventRegistrationCommandRowId = (value) => parseUuidBrand(value, unsafeAsEventRegistrationCommandRowId);
|
|
204
|
-
const parseDatedOfferingCapacityHoldId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldId);
|
|
205
|
-
const parseDatedOfferingCapacityHoldAuditRef = (value) => parseUuidBrand(value, unsafeAsDatedOfferingCapacityHoldAuditRef);
|
|
206
|
-
const parseDatedOfferingRevocationAuditEventId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRevocationAuditEventId);
|
|
207
|
-
const parseDatedOfferingWaitlistCapacityEffectId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectId);
|
|
208
|
-
const parseDatedOfferingWaitlistCapacityEffectClaimToken = (value) => parseUuidBrand(value, unsafeAsDatedOfferingWaitlistCapacityEffectClaimToken);
|
|
209
|
-
const parseDatedOfferingRunCancellationOperationId = (value) => parseUuidBrand(value, unsafeAsDatedOfferingRunCancellationOperationId);
|
|
210
|
-
const parseCustomerId = (value) => parseUuidBrand(value, unsafeAsCustomerId);
|
|
211
|
-
const parseSiteTermsVersionId = (value) => parseUuidBrand(value, unsafeAsSiteTermsVersionId);
|
|
212
|
-
const parseSiteTermsAgreementId = (value) => parseUuidBrand(value, unsafeAsSiteTermsAgreementId);
|
|
213
|
-
const parseCustomerPassId = (value) => parseUuidBrand(value, unsafeAsCustomerPassId);
|
|
214
|
-
const parseCustomerMembershipId = (value) => parseUuidBrand(value, unsafeAsCustomerMembershipId);
|
|
215
|
-
const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
|
|
216
|
-
const parseEventSeriesRegistrationId = (value) => parseUuidBrand(value, unsafeAsEventSeriesRegistrationId);
|
|
217
|
-
const parseParticipantId = (value) => parseUuidBrand(value, unsafeAsParticipantId);
|
|
218
|
-
const parseParticipantParticipationId = (value) => parseUuidBrand(value, unsafeAsParticipantParticipationId);
|
|
219
|
-
const parseOrderItemId = (value) => parseUuidBrand(value, unsafeAsOrderItemId);
|
|
220
|
-
const parseOrderRetirementOperationId = (value) => parseUuidBrand(value, unsafeAsOrderRetirementOperationId);
|
|
221
|
-
const parseOrderId = (value) => parseUuidBrand(value, unsafeAsOrderId);
|
|
222
|
-
const parseOrderRefundId = (value) => parseUuidBrand(value, unsafeAsOrderRefundId);
|
|
223
|
-
const parseOrderPaymentReceiptId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentReceiptId);
|
|
224
|
-
const parseOrderFlexibleBalanceContractId = (value) => parseUuidBrand(value, unsafeAsOrderFlexibleBalanceContractId);
|
|
225
|
-
const parseOrderPaymentPlanId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanId);
|
|
226
|
-
const parseOrderPaymentPlanInstalmentId = (value) => parseUuidBrand(value, unsafeAsOrderPaymentPlanInstalmentId);
|
|
227
|
-
const parseManualPaymentOperationId = (value) => parseUuidBrand(value, unsafeAsManualPaymentOperationId);
|
|
228
282
|
|
|
229
283
|
//#endregion
|
|
230
284
|
//#region ../core/src/date-math.ts
|
|
@@ -320,6 +374,12 @@ function clampDurationMinutes(value, min, max) {
|
|
|
320
374
|
return result;
|
|
321
375
|
}
|
|
322
376
|
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region ../core/src/assert-never.ts
|
|
379
|
+
function assertNever(value, message = "Unexpected variant") {
|
|
380
|
+
throw new Error(`${message}: ${String(value)}`);
|
|
381
|
+
}
|
|
382
|
+
|
|
323
383
|
//#endregion
|
|
324
384
|
//#region ../core/src/demo-capability-policy.ts
|
|
325
385
|
const demoSurfaceClassificationValues = [
|
|
@@ -535,12 +595,6 @@ function dedupeStrings(values) {
|
|
|
535
595
|
return [...new Set(values)];
|
|
536
596
|
}
|
|
537
597
|
|
|
538
|
-
//#endregion
|
|
539
|
-
//#region ../core/src/assert-never.ts
|
|
540
|
-
function assertNever(value, message = "Unexpected variant") {
|
|
541
|
-
throw new Error(`${message}: ${String(value)}`);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
598
|
//#endregion
|
|
545
599
|
//#region ../core/src/event-booking-offer.ts
|
|
546
600
|
const EVENT_PRICING_STRATEGIES = [
|
|
@@ -1632,6 +1686,23 @@ function createOriginalPaymentRefundCommand(options) {
|
|
|
1632
1686
|
function isAcceptedEventScheduleUpdate(response) {
|
|
1633
1687
|
return "kind" in response && response.kind === "accepted_unavailable";
|
|
1634
1688
|
}
|
|
1689
|
+
function refundDestinationAmounts(destination, amountCents) {
|
|
1690
|
+
return {
|
|
1691
|
+
cardCents: destination === "card" ? amountCents : 0,
|
|
1692
|
+
directCents: destination === "direct" ? amountCents : 0,
|
|
1693
|
+
creditCents: destination === "credit" ? amountCents : 0
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
function addRefundDestinationAmounts(a, b) {
|
|
1697
|
+
return {
|
|
1698
|
+
cardCents: a.cardCents + b.cardCents,
|
|
1699
|
+
directCents: a.directCents + b.directCents,
|
|
1700
|
+
creditCents: a.creditCents + b.creditCents
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
function hasDirectRefundFunding(funding) {
|
|
1704
|
+
return funding?.some((line$1) => line$1.destination === "direct" && line$1.remainingCents > 0) ?? false;
|
|
1705
|
+
}
|
|
1635
1706
|
|
|
1636
1707
|
//#endregion
|
|
1637
1708
|
//#region ../core/src/booking-instalments.ts
|
|
@@ -1850,6 +1921,13 @@ function decideContractClosure(status, reason) {
|
|
|
1850
1921
|
|
|
1851
1922
|
//#endregion
|
|
1852
1923
|
//#region ../core/src/booking-payment-options.ts
|
|
1924
|
+
/**
|
|
1925
|
+
* One way a customer may pay for a booking. This is the single definition of
|
|
1926
|
+
* the option type; `booking-payment-schemas.typetest.ts` keeps it equal to the
|
|
1927
|
+
* schema's output in both directions.
|
|
1928
|
+
*/
|
|
1929
|
+
/** When a course's instalments must all be paid by: before its first or its last live session. */
|
|
1930
|
+
const BOOKING_COURSE_INSTALMENT_DEADLINES = ["first_session", "last_session"];
|
|
1853
1931
|
/** Automatic instalments and a flexible balance cannot share one booking offer. */
|
|
1854
1932
|
function validateBookingPaymentOptionKinds(kinds) {
|
|
1855
1933
|
if (kinds.length === 0) return err("no_options");
|
|
@@ -1861,6 +1939,30 @@ function validateBookingPaymentOptionKinds(kinds) {
|
|
|
1861
1939
|
return ok(undefined);
|
|
1862
1940
|
}
|
|
1863
1941
|
|
|
1942
|
+
//#endregion
|
|
1943
|
+
//#region ../core/src/booking-date-time/instant.ts
|
|
1944
|
+
function parseUtcIsoDateTimeString(value) {
|
|
1945
|
+
const normalized = value.trim();
|
|
1946
|
+
const hasUtcSuffix = normalized.endsWith("Z");
|
|
1947
|
+
const hasExplicitOffset = /[+-]\d{2}:\d{2}$/u.test(normalized);
|
|
1948
|
+
if (!hasUtcSuffix && !hasExplicitOffset) {
|
|
1949
|
+
return err("missing-timezone-offset");
|
|
1950
|
+
}
|
|
1951
|
+
const date = new Date(normalized);
|
|
1952
|
+
if (Number.isNaN(date.getTime())) {
|
|
1953
|
+
return err("invalid-date-time");
|
|
1954
|
+
}
|
|
1955
|
+
return ok(date.toISOString());
|
|
1956
|
+
}
|
|
1957
|
+
function toUtcIsoDateTimeString(value) {
|
|
1958
|
+
const parsed = parseUtcIsoDateTimeString(value);
|
|
1959
|
+
if (!parsed.ok) {
|
|
1960
|
+
const message = parsed.error === "missing-timezone-offset" ? `Expected an offset-aware ISO datetime, received "${value}"` : `Expected a valid ISO datetime, received "${value}"`;
|
|
1961
|
+
throw new Error(message);
|
|
1962
|
+
}
|
|
1963
|
+
return parsed.value;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1864
1966
|
//#endregion
|
|
1865
1967
|
//#region ../core/src/date-time-formatter.ts
|
|
1866
1968
|
/** Shared Intl engine, internal to core's date presentation owners. */
|
|
@@ -1906,6 +2008,12 @@ function formatIntlRange(formatter, start, end) {
|
|
|
1906
2008
|
return output;
|
|
1907
2009
|
}
|
|
1908
2010
|
|
|
2011
|
+
//#endregion
|
|
2012
|
+
//#region ../core/src/booking-date-time/parts.ts
|
|
2013
|
+
function formatToPartsLookup(date, locale, timeZone, format) {
|
|
2014
|
+
return new Map(getDateTimeFormatter(locale, timeZone, format).formatToParts(date).map((part) => [part.type, part.value]));
|
|
2015
|
+
}
|
|
2016
|
+
|
|
1909
2017
|
//#endregion
|
|
1910
2018
|
//#region ../core/src/booking-time-zone.ts
|
|
1911
2019
|
const TIME_ZONE_VALIDITY_CACHE_LIMIT = 100;
|
|
@@ -1939,40 +2047,42 @@ function parseBookingTimeZone(timeZone) {
|
|
|
1939
2047
|
}
|
|
1940
2048
|
|
|
1941
2049
|
//#endregion
|
|
1942
|
-
//#region ../core/src/booking-date-time.ts
|
|
1943
|
-
const DEFAULT_LOCALE$1 = "en-US";
|
|
2050
|
+
//#region ../core/src/booking-date-time/time-zone.ts
|
|
1944
2051
|
const FALLBACK_TIMEZONE = "UTC";
|
|
1945
|
-
const DEFAULT_BOOKING_DATE_TIME_FORMAT = {
|
|
1946
|
-
weekday: "short",
|
|
1947
|
-
month: "short",
|
|
1948
|
-
day: "numeric",
|
|
1949
|
-
hour: "numeric",
|
|
1950
|
-
minute: "2-digit"
|
|
1951
|
-
};
|
|
1952
|
-
const START_OF_DAY = {
|
|
1953
|
-
hour: 0,
|
|
1954
|
-
minute: 0,
|
|
1955
|
-
second: 0
|
|
1956
|
-
};
|
|
1957
|
-
const LOCAL_DATE_PATTERN = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/u;
|
|
1958
2052
|
function getSafeTimeZone(timeZone) {
|
|
1959
2053
|
const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
|
|
1960
2054
|
return normalized.length > 0 && isValidBookingTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
|
|
1961
2055
|
}
|
|
1962
|
-
function
|
|
1963
|
-
|
|
1964
|
-
return parsed.ok ? parsed.value : null;
|
|
2056
|
+
function toBookingTimeZone(timeZone) {
|
|
2057
|
+
return getSafeTimeZone(timeZone);
|
|
1965
2058
|
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
case "invalid_ends_at": return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
|
|
1970
|
-
case "invalid_time_zone": return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
|
|
1971
|
-
}
|
|
2059
|
+
const DEFAULT_BOOKING_TIME_ZONE = FALLBACK_TIMEZONE;
|
|
2060
|
+
function resolveBookingTimezone(venueTimezone, siteDefaultTimezone) {
|
|
2061
|
+
return venueTimezone ?? siteDefaultTimezone;
|
|
1972
2062
|
}
|
|
1973
|
-
function
|
|
1974
|
-
|
|
2063
|
+
function resolveBookingTimeZoneId(...candidates) {
|
|
2064
|
+
const normalized = candidates.map((candidate$1) => typeof candidate$1 === "string" ? candidate$1.trim() : "");
|
|
2065
|
+
return normalized.find((candidate$1) => candidate$1.length > 0 && isValidBookingTimeZone(candidate$1)) ?? FALLBACK_TIMEZONE;
|
|
2066
|
+
}
|
|
2067
|
+
/** Canonical business-zone admission, shared by server and public wire boundaries. */
|
|
2068
|
+
const DEFAULT_BOOKING_BUSINESS_TIME_ZONE = "Europe/London";
|
|
2069
|
+
/** Stored site zones must be valid; a broken read must not silently choose another zone. */
|
|
2070
|
+
function requireBookingTimeZone(value) {
|
|
2071
|
+
const parsed = parseBookingTimeZone(value);
|
|
2072
|
+
if (!parsed.ok) throw new Error("Expected a valid canonical site time zone");
|
|
2073
|
+
return parsed.value;
|
|
2074
|
+
}
|
|
2075
|
+
/** Effect boundary for browser-authored local inputs; formats no displayed date. */
|
|
2076
|
+
function getRuntimeBookingTimeZone() {
|
|
2077
|
+
return resolveBookingTimeZoneId(new Intl.DateTimeFormat("en-GB").resolvedOptions().timeZone);
|
|
1975
2078
|
}
|
|
2079
|
+
function resolveBookingBusinessTimeZone(value) {
|
|
2080
|
+
return resolveBookingTimeZoneId(value, DEFAULT_BOOKING_BUSINESS_TIME_ZONE);
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
//#endregion
|
|
2084
|
+
//#region ../core/src/booking-date-time/local.ts
|
|
2085
|
+
const LOCAL_DATE_PATTERN = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/u;
|
|
1976
2086
|
function getZonedDateTimeParts(date, timeZone) {
|
|
1977
2087
|
const parts = formatToPartsLookup(date, "en-GB", timeZone, {
|
|
1978
2088
|
year: "numeric",
|
|
@@ -1999,70 +2109,201 @@ function formatDateKey(date) {
|
|
|
1999
2109
|
const day = String(date.day).padStart(2, "0");
|
|
2000
2110
|
return `${year}-${month}-${day}`;
|
|
2001
2111
|
}
|
|
2002
|
-
function
|
|
2003
|
-
return
|
|
2112
|
+
function getBookingLocalDateKey(input) {
|
|
2113
|
+
return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
|
|
2004
2114
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
return venueTimezone ?? siteDefaultTimezone;
|
|
2115
|
+
function compareLocalScheduleDates(left, right) {
|
|
2116
|
+
return Date.UTC(left.year, left.month - 1, left.day) - Date.UTC(right.year, right.month - 1, right.day);
|
|
2008
2117
|
}
|
|
2009
|
-
function
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2118
|
+
function parseBookingLocalDate(value) {
|
|
2119
|
+
const match = LOCAL_DATE_PATTERN.exec(value.trim());
|
|
2120
|
+
if (match === null || match.groups === undefined) {
|
|
2121
|
+
throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
|
|
2122
|
+
}
|
|
2123
|
+
const year = Number(match.groups.year);
|
|
2124
|
+
const month = Number(match.groups.month);
|
|
2125
|
+
const day = Number(match.groups.day);
|
|
2126
|
+
const candidate$1 = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
|
|
2127
|
+
if (Number.isNaN(candidate$1.getTime()) || candidate$1.getUTCFullYear() !== year || candidate$1.getUTCMonth() + 1 !== month || candidate$1.getUTCDate() !== day) {
|
|
2128
|
+
throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
|
|
2129
|
+
}
|
|
2130
|
+
return {
|
|
2131
|
+
year,
|
|
2132
|
+
month,
|
|
2133
|
+
day
|
|
2134
|
+
};
|
|
2135
|
+
}
|
|
2136
|
+
/** Canonical schedule text at command and SDK boundaries: HH:MM or HH:MM:SS. */
|
|
2137
|
+
const localScheduleTimePattern = /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/u;
|
|
2138
|
+
function parseLocalScheduleTime(value) {
|
|
2139
|
+
const match = /^(?<hour>[01]?\d|2[0-3]):(?<minute>[0-5]\d)(?::(?<second>[0-5]\d))?$/u.exec(value.trim());
|
|
2140
|
+
if (match === null || match.groups === undefined) {
|
|
2141
|
+
throw new Error(`Invalid start time format: "${value}" (expected HH:MM or HH:MM:SS)`);
|
|
2142
|
+
}
|
|
2143
|
+
const hour = Number(match.groups.hour);
|
|
2144
|
+
const minute = Number(match.groups.minute);
|
|
2145
|
+
const second = Number(match.groups.second ?? "0");
|
|
2146
|
+
return {
|
|
2147
|
+
hour,
|
|
2148
|
+
minute,
|
|
2149
|
+
second
|
|
2150
|
+
};
|
|
2151
|
+
}
|
|
2152
|
+
function getLocalScheduleDate(date, timeZone) {
|
|
2153
|
+
const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
|
|
2154
|
+
return {
|
|
2155
|
+
year: parts.year,
|
|
2156
|
+
month: parts.month,
|
|
2157
|
+
day: parts.day
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
function getLocalScheduleTime(date, timeZone) {
|
|
2161
|
+
const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
|
|
2162
|
+
return {
|
|
2163
|
+
hour: parts.hour,
|
|
2164
|
+
minute: parts.minute,
|
|
2165
|
+
second: parts.second
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
function formatLocalScheduleDate(date) {
|
|
2169
|
+
return formatDateKey(date);
|
|
2170
|
+
}
|
|
2171
|
+
function formatLocalScheduleTime(time) {
|
|
2172
|
+
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
|
|
2173
|
+
}
|
|
2174
|
+
function getDaysInLocalMonth(year, month) {
|
|
2175
|
+
return new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
2176
|
+
}
|
|
2177
|
+
function addLocalScheduleDays(date, days) {
|
|
2178
|
+
const utcDate = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12, 0, 0));
|
|
2179
|
+
return {
|
|
2180
|
+
year: utcDate.getUTCFullYear(),
|
|
2181
|
+
month: utcDate.getUTCMonth() + 1,
|
|
2182
|
+
day: utcDate.getUTCDate()
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
function addLocalScheduleMonths(date, months) {
|
|
2186
|
+
const targetMonthIndex = date.month - 1 + months;
|
|
2187
|
+
const base = new Date(Date.UTC(date.year, targetMonthIndex, 1, 12, 0, 0));
|
|
2188
|
+
const year = base.getUTCFullYear();
|
|
2189
|
+
const month = base.getUTCMonth() + 1;
|
|
2190
|
+
const day = Math.min(date.day, getDaysInLocalMonth(year, month));
|
|
2191
|
+
return {
|
|
2192
|
+
year,
|
|
2193
|
+
month,
|
|
2194
|
+
day
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2197
|
+
function getLocalScheduleDayOfWeek(date) {
|
|
2198
|
+
return new Date(Date.UTC(date.year, date.month - 1, date.day, 12, 0, 0)).getUTCDay();
|
|
2199
|
+
}
|
|
2200
|
+
function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
|
|
2201
|
+
const resolvedTimeZone = getSafeTimeZone(timeZone);
|
|
2202
|
+
const targetLocalMs = Date.UTC(localDate.year, localDate.month - 1, localDate.day, localTime.hour, localTime.minute, localTime.second, 0);
|
|
2203
|
+
return resolveLocalInstant(targetLocalMs, resolvedTimeZone, targetLocalMs, []);
|
|
2204
|
+
}
|
|
2205
|
+
function resolveLocalInstant(targetLocalMs, timeZone, guess, seen) {
|
|
2206
|
+
if (seen.length === 4) return new Date(guess);
|
|
2207
|
+
const actual = getZonedDateTimeParts(new Date(guess), timeZone);
|
|
2208
|
+
const actualLocalMs = Date.UTC(actual.year, actual.month - 1, actual.day, actual.hour, actual.minute, actual.second, 0);
|
|
2209
|
+
const diff = actualLocalMs - targetLocalMs;
|
|
2210
|
+
if (diff === 0) return new Date(guess);
|
|
2211
|
+
const nextGuess = guess - diff;
|
|
2212
|
+
if (nextGuess === guess || seen.includes(nextGuess)) return new Date(Math.max(guess, nextGuess));
|
|
2213
|
+
return resolveLocalInstant(targetLocalMs, timeZone, nextGuess, [...seen, guess]);
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
//#endregion
|
|
2217
|
+
//#region ../core/src/booking-date-time/window.ts
|
|
2218
|
+
const START_OF_DAY = {
|
|
2219
|
+
hour: 0,
|
|
2220
|
+
minute: 0,
|
|
2221
|
+
second: 0
|
|
2222
|
+
};
|
|
2223
|
+
function parseWindowDate(value, field) {
|
|
2224
|
+
try {
|
|
2225
|
+
return {
|
|
2226
|
+
ok: true,
|
|
2227
|
+
value: parseBookingLocalDate(value)
|
|
2228
|
+
};
|
|
2229
|
+
} catch {
|
|
2230
|
+
return {
|
|
2231
|
+
ok: false,
|
|
2232
|
+
field,
|
|
2233
|
+
reason: "invalid_date_format",
|
|
2234
|
+
value
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
function parseBookingUtcDateWindow(input) {
|
|
2239
|
+
const timeZone = resolveBookingTimeZoneId(input.timeZone);
|
|
2240
|
+
const start = parseWindowDate(input.startDate, "startDate");
|
|
2241
|
+
if (!start.ok) return start;
|
|
2242
|
+
const end = parseWindowDate(input.endDate, "endDate");
|
|
2243
|
+
if (!end.ok) return end;
|
|
2244
|
+
const startLocalDate = start.value;
|
|
2245
|
+
const endLocalDate = end.value;
|
|
2246
|
+
if (compareLocalScheduleDates(startLocalDate, endLocalDate) > 0) {
|
|
2247
|
+
return {
|
|
2248
|
+
ok: false,
|
|
2249
|
+
field: "endDate",
|
|
2250
|
+
reason: "invalid_date_range",
|
|
2251
|
+
value: input.endDate
|
|
2252
|
+
};
|
|
2253
|
+
}
|
|
2254
|
+
return {
|
|
2255
|
+
ok: true,
|
|
2256
|
+
value: {
|
|
2257
|
+
timeZone,
|
|
2258
|
+
startLocalDate,
|
|
2259
|
+
endLocalDate,
|
|
2260
|
+
startAt: localScheduleDateTimeToUtcDate(startLocalDate, START_OF_DAY, timeZone),
|
|
2261
|
+
endExclusive: localScheduleDateTimeToUtcDate(addLocalScheduleDays(endLocalDate, 1), START_OF_DAY, timeZone)
|
|
2014
2262
|
}
|
|
2015
|
-
}
|
|
2016
|
-
return FALLBACK_TIMEZONE;
|
|
2017
|
-
}
|
|
2018
|
-
/** Canonical business-zone admission, shared by server and public wire boundaries. */
|
|
2019
|
-
const DEFAULT_BOOKING_BUSINESS_TIME_ZONE = "Europe/London";
|
|
2020
|
-
/** Stored site zones must be valid; a broken read must not silently choose another zone. */
|
|
2021
|
-
function requireBookingTimeZone(value) {
|
|
2022
|
-
const parsed = parseBookingTimeZone(value);
|
|
2023
|
-
if (!parsed.ok) throw new Error("Expected a valid canonical site time zone");
|
|
2024
|
-
return parsed.value;
|
|
2025
|
-
}
|
|
2026
|
-
/** Effect boundary for browser-authored local inputs; formats no displayed date. */
|
|
2027
|
-
function getRuntimeBookingTimeZone() {
|
|
2028
|
-
return resolveBookingTimeZoneId(new Intl.DateTimeFormat("en-GB").resolvedOptions().timeZone);
|
|
2029
|
-
}
|
|
2030
|
-
function resolveBookingBusinessTimeZone(value) {
|
|
2031
|
-
return resolveBookingTimeZoneId(value, DEFAULT_BOOKING_BUSINESS_TIME_ZONE);
|
|
2263
|
+
};
|
|
2032
2264
|
}
|
|
2033
|
-
function
|
|
2034
|
-
const
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
if (!hasUtcSuffix && !hasExplicitOffset) {
|
|
2038
|
-
return err("missing-timezone-offset");
|
|
2265
|
+
function buildBookingUtcDateWindow(input) {
|
|
2266
|
+
const result = parseBookingUtcDateWindow(input);
|
|
2267
|
+
if (result.ok) {
|
|
2268
|
+
return result.value;
|
|
2039
2269
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
return err("invalid-date-time");
|
|
2270
|
+
if (result.reason === "invalid_date_range") {
|
|
2271
|
+
throw new Error(`Invalid booking date range: startDate "${input.startDate}" must be on or before endDate "${input.endDate}"`);
|
|
2043
2272
|
}
|
|
2044
|
-
|
|
2273
|
+
throw new Error(`Invalid booking date format: "${result.value}" (expected YYYY-MM-DD)`);
|
|
2045
2274
|
}
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2275
|
+
|
|
2276
|
+
//#endregion
|
|
2277
|
+
//#region ../core/src/booking-date-time/scheduled.ts
|
|
2278
|
+
function parseStrictBookingTimeZone(timeZone) {
|
|
2279
|
+
const parsed = parseBookingTimeZone(timeZone);
|
|
2280
|
+
return parsed.ok ? parsed.value : null;
|
|
2281
|
+
}
|
|
2282
|
+
function formatParseError(error) {
|
|
2283
|
+
switch (error.reason) {
|
|
2284
|
+
case "invalid_starts_at": return `Expected a valid UTC/offset-aware ISO datetime in startsAt, received "${error.value}"`;
|
|
2285
|
+
case "invalid_ends_at": return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
|
|
2286
|
+
case "invalid_time_zone": return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
|
|
2051
2287
|
}
|
|
2052
|
-
return parsed.value;
|
|
2053
2288
|
}
|
|
2054
|
-
function
|
|
2055
|
-
let startsAt;
|
|
2289
|
+
function parseScheduledStart(value) {
|
|
2056
2290
|
try {
|
|
2057
|
-
|
|
2291
|
+
return {
|
|
2292
|
+
ok: true,
|
|
2293
|
+
value: toUtcIsoDateTimeString(value)
|
|
2294
|
+
};
|
|
2058
2295
|
} catch {
|
|
2059
2296
|
return {
|
|
2060
2297
|
ok: false,
|
|
2061
2298
|
field: "startsAt",
|
|
2062
2299
|
reason: "invalid_starts_at",
|
|
2063
|
-
value
|
|
2300
|
+
value
|
|
2064
2301
|
};
|
|
2065
2302
|
}
|
|
2303
|
+
}
|
|
2304
|
+
function parseScheduledBookingDateTime(input) {
|
|
2305
|
+
const startsAt = parseScheduledStart(input.startsAt);
|
|
2306
|
+
if (!startsAt.ok) return startsAt;
|
|
2066
2307
|
const timeZone = parseStrictBookingTimeZone(input.timeZone);
|
|
2067
2308
|
if (timeZone === null) {
|
|
2068
2309
|
return {
|
|
@@ -2075,7 +2316,7 @@ function parseScheduledBookingDateTime(input) {
|
|
|
2075
2316
|
return {
|
|
2076
2317
|
ok: true,
|
|
2077
2318
|
value: {
|
|
2078
|
-
startsAt,
|
|
2319
|
+
startsAt: startsAt.value,
|
|
2079
2320
|
timeZone,
|
|
2080
2321
|
locale: input.locale
|
|
2081
2322
|
}
|
|
@@ -2123,6 +2364,17 @@ function toScheduledBookingDateRange(input) {
|
|
|
2123
2364
|
}
|
|
2124
2365
|
throw new Error(formatParseError(result));
|
|
2125
2366
|
}
|
|
2367
|
+
|
|
2368
|
+
//#endregion
|
|
2369
|
+
//#region ../core/src/booking-date-time/formatting.ts
|
|
2370
|
+
const DEFAULT_LOCALE$1 = "en-US";
|
|
2371
|
+
const DEFAULT_BOOKING_DATE_TIME_FORMAT = {
|
|
2372
|
+
weekday: "short",
|
|
2373
|
+
month: "short",
|
|
2374
|
+
day: "numeric",
|
|
2375
|
+
hour: "numeric",
|
|
2376
|
+
minute: "2-digit"
|
|
2377
|
+
};
|
|
2126
2378
|
function formatBookingInstant(isoString, options) {
|
|
2127
2379
|
const date = new Date(isoString);
|
|
2128
2380
|
if (Number.isNaN(date.getTime())) {
|
|
@@ -2214,83 +2466,6 @@ function formatBookingDateParts(input, options) {
|
|
|
2214
2466
|
})
|
|
2215
2467
|
};
|
|
2216
2468
|
}
|
|
2217
|
-
function getBookingLocalDateKey(input) {
|
|
2218
|
-
return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
|
|
2219
|
-
}
|
|
2220
|
-
function compareLocalScheduleDates(left, right) {
|
|
2221
|
-
return Date.UTC(left.year, left.month - 1, left.day) - Date.UTC(right.year, right.month - 1, right.day);
|
|
2222
|
-
}
|
|
2223
|
-
function parseBookingLocalDate(value) {
|
|
2224
|
-
const match = LOCAL_DATE_PATTERN.exec(value.trim());
|
|
2225
|
-
if (match === null || match.groups === undefined) {
|
|
2226
|
-
throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
|
|
2227
|
-
}
|
|
2228
|
-
const year = Number(match.groups.year);
|
|
2229
|
-
const month = Number(match.groups.month);
|
|
2230
|
-
const day = Number(match.groups.day);
|
|
2231
|
-
const candidate$1 = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
|
|
2232
|
-
if (Number.isNaN(candidate$1.getTime()) || candidate$1.getUTCFullYear() !== year || candidate$1.getUTCMonth() + 1 !== month || candidate$1.getUTCDate() !== day) {
|
|
2233
|
-
throw new Error(`Invalid booking date format: "${value}" (expected YYYY-MM-DD)`);
|
|
2234
|
-
}
|
|
2235
|
-
return {
|
|
2236
|
-
year,
|
|
2237
|
-
month,
|
|
2238
|
-
day
|
|
2239
|
-
};
|
|
2240
|
-
}
|
|
2241
|
-
function parseBookingUtcDateWindow(input) {
|
|
2242
|
-
const timeZone = resolveBookingTimeZoneId(input.timeZone);
|
|
2243
|
-
let startLocalDate;
|
|
2244
|
-
try {
|
|
2245
|
-
startLocalDate = parseBookingLocalDate(input.startDate);
|
|
2246
|
-
} catch {
|
|
2247
|
-
return {
|
|
2248
|
-
ok: false,
|
|
2249
|
-
field: "startDate",
|
|
2250
|
-
reason: "invalid_date_format",
|
|
2251
|
-
value: input.startDate
|
|
2252
|
-
};
|
|
2253
|
-
}
|
|
2254
|
-
let endLocalDate;
|
|
2255
|
-
try {
|
|
2256
|
-
endLocalDate = parseBookingLocalDate(input.endDate);
|
|
2257
|
-
} catch {
|
|
2258
|
-
return {
|
|
2259
|
-
ok: false,
|
|
2260
|
-
field: "endDate",
|
|
2261
|
-
reason: "invalid_date_format",
|
|
2262
|
-
value: input.endDate
|
|
2263
|
-
};
|
|
2264
|
-
}
|
|
2265
|
-
if (compareLocalScheduleDates(startLocalDate, endLocalDate) > 0) {
|
|
2266
|
-
return {
|
|
2267
|
-
ok: false,
|
|
2268
|
-
field: "endDate",
|
|
2269
|
-
reason: "invalid_date_range",
|
|
2270
|
-
value: input.endDate
|
|
2271
|
-
};
|
|
2272
|
-
}
|
|
2273
|
-
return {
|
|
2274
|
-
ok: true,
|
|
2275
|
-
value: {
|
|
2276
|
-
timeZone,
|
|
2277
|
-
startLocalDate,
|
|
2278
|
-
endLocalDate,
|
|
2279
|
-
startAt: localScheduleDateTimeToUtcDate(startLocalDate, START_OF_DAY, timeZone),
|
|
2280
|
-
endExclusive: localScheduleDateTimeToUtcDate(addLocalScheduleDays(endLocalDate, 1), START_OF_DAY, timeZone)
|
|
2281
|
-
}
|
|
2282
|
-
};
|
|
2283
|
-
}
|
|
2284
|
-
function buildBookingUtcDateWindow(input) {
|
|
2285
|
-
const result = parseBookingUtcDateWindow(input);
|
|
2286
|
-
if (result.ok) {
|
|
2287
|
-
return result.value;
|
|
2288
|
-
}
|
|
2289
|
-
if (result.reason === "invalid_date_range") {
|
|
2290
|
-
throw new Error(`Invalid booking date range: startDate "${input.startDate}" must be on or before endDate "${input.endDate}"`);
|
|
2291
|
-
}
|
|
2292
|
-
throw new Error(`Invalid booking date format: "${result.value}" (expected YYYY-MM-DD)`);
|
|
2293
|
-
}
|
|
2294
2469
|
function formatBookingRange(input, options) {
|
|
2295
2470
|
if (input.endsAt == null) {
|
|
2296
2471
|
const parts = formatBookingDateParts(input, options);
|
|
@@ -2320,94 +2495,6 @@ function formatBookingRange(input, options) {
|
|
|
2320
2495
|
});
|
|
2321
2496
|
return `${startDate}, ${startTime} - ${endDate}, ${endTime}`;
|
|
2322
2497
|
}
|
|
2323
|
-
/** Canonical schedule text at command and SDK boundaries: HH:MM or HH:MM:SS. */
|
|
2324
|
-
const localScheduleTimePattern = /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/u;
|
|
2325
|
-
function parseLocalScheduleTime(value) {
|
|
2326
|
-
const match = /^(?<hour>\d{1,2}):(?<minute>\d{2})(?::(?<second>\d{2}))?$/u.exec(value.trim());
|
|
2327
|
-
if (match === null || match.groups === undefined) {
|
|
2328
|
-
throw new Error(`Invalid start time format: "${value}" (expected HH:MM or HH:MM:SS)`);
|
|
2329
|
-
}
|
|
2330
|
-
const hour = Number(match.groups.hour);
|
|
2331
|
-
const minute = Number(match.groups.minute);
|
|
2332
|
-
const second = match.groups.second !== undefined ? Number(match.groups.second) : 0;
|
|
2333
|
-
if (Number.isNaN(hour) || Number.isNaN(minute) || Number.isNaN(second) || hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) {
|
|
2334
|
-
throw new Error(`Invalid start time format: "${value}" (expected HH:MM or HH:MM:SS)`);
|
|
2335
|
-
}
|
|
2336
|
-
return {
|
|
2337
|
-
hour,
|
|
2338
|
-
minute,
|
|
2339
|
-
second
|
|
2340
|
-
};
|
|
2341
|
-
}
|
|
2342
|
-
function getLocalScheduleDate(date, timeZone) {
|
|
2343
|
-
const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
|
|
2344
|
-
return {
|
|
2345
|
-
year: parts.year,
|
|
2346
|
-
month: parts.month,
|
|
2347
|
-
day: parts.day
|
|
2348
|
-
};
|
|
2349
|
-
}
|
|
2350
|
-
function getLocalScheduleTime(date, timeZone) {
|
|
2351
|
-
const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
|
|
2352
|
-
return {
|
|
2353
|
-
hour: parts.hour,
|
|
2354
|
-
minute: parts.minute,
|
|
2355
|
-
second: parts.second
|
|
2356
|
-
};
|
|
2357
|
-
}
|
|
2358
|
-
function formatLocalScheduleDate(date) {
|
|
2359
|
-
return formatDateKey(date);
|
|
2360
|
-
}
|
|
2361
|
-
function formatLocalScheduleTime(time) {
|
|
2362
|
-
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}`;
|
|
2363
|
-
}
|
|
2364
|
-
function getDaysInLocalMonth(year, month) {
|
|
2365
|
-
return new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
2366
|
-
}
|
|
2367
|
-
function addLocalScheduleDays(date, days) {
|
|
2368
|
-
const utcDate = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12, 0, 0));
|
|
2369
|
-
return {
|
|
2370
|
-
year: utcDate.getUTCFullYear(),
|
|
2371
|
-
month: utcDate.getUTCMonth() + 1,
|
|
2372
|
-
day: utcDate.getUTCDate()
|
|
2373
|
-
};
|
|
2374
|
-
}
|
|
2375
|
-
function addLocalScheduleMonths(date, months) {
|
|
2376
|
-
const targetMonthIndex = date.month - 1 + months;
|
|
2377
|
-
const base = new Date(Date.UTC(date.year, targetMonthIndex, 1, 12, 0, 0));
|
|
2378
|
-
const year = base.getUTCFullYear();
|
|
2379
|
-
const month = base.getUTCMonth() + 1;
|
|
2380
|
-
const day = Math.min(date.day, getDaysInLocalMonth(year, month));
|
|
2381
|
-
return {
|
|
2382
|
-
year,
|
|
2383
|
-
month,
|
|
2384
|
-
day
|
|
2385
|
-
};
|
|
2386
|
-
}
|
|
2387
|
-
function getLocalScheduleDayOfWeek(date) {
|
|
2388
|
-
return new Date(Date.UTC(date.year, date.month - 1, date.day, 12, 0, 0)).getUTCDay();
|
|
2389
|
-
}
|
|
2390
|
-
function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
|
|
2391
|
-
const resolvedTimeZone = getSafeTimeZone(timeZone);
|
|
2392
|
-
const targetLocalMs = Date.UTC(localDate.year, localDate.month - 1, localDate.day, localTime.hour, localTime.minute, localTime.second, 0);
|
|
2393
|
-
let guess = targetLocalMs;
|
|
2394
|
-
const seenGuesses = new Set();
|
|
2395
|
-
for (let iteration = 0; iteration < 4; iteration += 1) {
|
|
2396
|
-
seenGuesses.add(guess);
|
|
2397
|
-
const actual = getZonedDateTimeParts(new Date(guess), resolvedTimeZone);
|
|
2398
|
-
const actualLocalMs = Date.UTC(actual.year, actual.month - 1, actual.day, actual.hour, actual.minute, actual.second, 0);
|
|
2399
|
-
const diff = actualLocalMs - targetLocalMs;
|
|
2400
|
-
if (diff === 0) {
|
|
2401
|
-
return new Date(guess);
|
|
2402
|
-
}
|
|
2403
|
-
const nextGuess = guess - diff;
|
|
2404
|
-
if (seenGuesses.has(nextGuess)) {
|
|
2405
|
-
return new Date(Math.max(guess, nextGuess));
|
|
2406
|
-
}
|
|
2407
|
-
guess = nextGuess;
|
|
2408
|
-
}
|
|
2409
|
-
return new Date(guess);
|
|
2410
|
-
}
|
|
2411
2498
|
|
|
2412
2499
|
//#endregion
|
|
2413
2500
|
//#region ../core/src/date-display.ts
|
|
@@ -2430,6 +2517,31 @@ function resolveBookingDisplayContext(input) {
|
|
|
2430
2517
|
zone: input.surface !== "dashboard" && input.isOnline || input.sessionTimeZone !== input.siteTimeZone ? "always" : "omit"
|
|
2431
2518
|
};
|
|
2432
2519
|
}
|
|
2520
|
+
/** Dashboard and assistant site dates read in British English, whatever the site's own language. */
|
|
2521
|
+
const SITE_DISPLAY_LOCALE = "en-GB";
|
|
2522
|
+
/** The site display policy: `en-GB` in the given zone, falling back to the business zone the server uses. */
|
|
2523
|
+
function siteDisplayContext(timeZone) {
|
|
2524
|
+
return {
|
|
2525
|
+
locale: SITE_DISPLAY_LOCALE,
|
|
2526
|
+
timeZone: resolveBookingBusinessTimeZone(timeZone)
|
|
2527
|
+
};
|
|
2528
|
+
}
|
|
2529
|
+
/** A stored instant as a site date, `22 Sept 2026` by default; an unparseable value is shown as it came. */
|
|
2530
|
+
function formatSiteInstantDate(iso, timeZone, options = {}) {
|
|
2531
|
+
const parsed = parseUtcIsoDateTimeString(iso);
|
|
2532
|
+
return parsed.ok ? formatDate({
|
|
2533
|
+
kind: "instant",
|
|
2534
|
+
value: parsed.value
|
|
2535
|
+
}, siteDisplayContext(timeZone), {
|
|
2536
|
+
date: "short",
|
|
2537
|
+
...options
|
|
2538
|
+
}) : iso;
|
|
2539
|
+
}
|
|
2540
|
+
/** A stored instant as a site time, `2:05pm` without a zone label by default; an unparseable value is shown as it came. */
|
|
2541
|
+
function formatSiteInstantTime(iso, timeZone, options = { zone: "omit" }) {
|
|
2542
|
+
const parsed = parseUtcIsoDateTimeString(iso);
|
|
2543
|
+
return parsed.ok ? formatTime(parsed.value, siteDisplayContext(timeZone), options) : iso;
|
|
2544
|
+
}
|
|
2433
2545
|
const SDK_STANDARD_TIME_FORMAT = {
|
|
2434
2546
|
hour: "numeric",
|
|
2435
2547
|
minute: "2-digit"
|
|
@@ -4005,11 +4117,14 @@ const unsafeAsEditorSiteId = (value) => value;
|
|
|
4005
4117
|
const unsafeAsEditorPageId = (value) => value;
|
|
4006
4118
|
const unsafeAsEditorEntryId = (value) => value;
|
|
4007
4119
|
const unsafeAsEditorBlockId = (value) => value;
|
|
4120
|
+
/** The document id a slot owner names: the entry's or the surface's. */
|
|
4121
|
+
function slotOwnerDocumentId(owner) {
|
|
4122
|
+
return owner.kind === "entry" ? owner.entryId : owner.surfaceId;
|
|
4123
|
+
}
|
|
4008
4124
|
function editorBlockCollectionOwnerKey(owner) {
|
|
4009
4125
|
switch (owner.kind) {
|
|
4010
4126
|
case "page": return `page:${owner.pageId}`;
|
|
4011
|
-
case "
|
|
4012
|
-
case "surface-slot": return `surface-slot:${owner.pageSurfaceId}:${owner.slotKey}`;
|
|
4127
|
+
case "slot": return owner.owner.kind === "entry" ? `entry-slot:${owner.owner.contentType}:${owner.owner.entryId}:${owner.slotKey}` : `surface-slot:${owner.owner.surfaceId}:${owner.slotKey}`;
|
|
4013
4128
|
case "site-footer": return `site-footer:${owner.siteId}`;
|
|
4014
4129
|
}
|
|
4015
4130
|
}
|
|
@@ -5246,6 +5361,37 @@ function emptyPublicProfile() {
|
|
|
5246
5361
|
premises: null
|
|
5247
5362
|
};
|
|
5248
5363
|
}
|
|
5364
|
+
/** Preserve omitted parts, then use the profile parser as the only validation authority. */
|
|
5365
|
+
function mergeOpeningHoursPatch(profile, patch) {
|
|
5366
|
+
const current = profile.openingHours;
|
|
5367
|
+
if (current === null && (patch.timeZone === undefined || patch.timeZone === "" || publicProfileWeekdays.some((day) => patch.days?.[day] === undefined))) {
|
|
5368
|
+
return err({
|
|
5369
|
+
code: "invalid_weekdays",
|
|
5370
|
+
path: "openingHours",
|
|
5371
|
+
message: "No opening hours are saved yet. Ask for all seven days (including closed days) and the time zone."
|
|
5372
|
+
});
|
|
5373
|
+
}
|
|
5374
|
+
const days = publicProfileWeekdays.map((weekday) => {
|
|
5375
|
+
const intervals = patch.days?.[weekday];
|
|
5376
|
+
return intervals === undefined ? current?.days.find((day) => day.weekday === weekday) : intervals.length === 0 ? {
|
|
5377
|
+
kind: "closed",
|
|
5378
|
+
weekday
|
|
5379
|
+
} : {
|
|
5380
|
+
kind: "open",
|
|
5381
|
+
weekday,
|
|
5382
|
+
intervals
|
|
5383
|
+
};
|
|
5384
|
+
});
|
|
5385
|
+
const hours = parseWeeklyOpeningHours({
|
|
5386
|
+
days,
|
|
5387
|
+
timeZone: patch.timeZone ?? current?.timeZone,
|
|
5388
|
+
note: patch.note === undefined ? current?.note : patch.note
|
|
5389
|
+
});
|
|
5390
|
+
return hours.ok ? ok({
|
|
5391
|
+
...profile,
|
|
5392
|
+
openingHours: hours.value
|
|
5393
|
+
}) : hours;
|
|
5394
|
+
}
|
|
5249
5395
|
|
|
5250
5396
|
//#endregion
|
|
5251
5397
|
//#region ../core/src/opening-hours.ts
|
|
@@ -5936,7 +6082,7 @@ function buildGroups(sections, policy) {
|
|
|
5936
6082
|
}];
|
|
5937
6083
|
});
|
|
5938
6084
|
}
|
|
5939
|
-
function
|
|
6085
|
+
function footerMembershipKey(sections) {
|
|
5940
6086
|
const tokens = sections.map((section) => ({
|
|
5941
6087
|
rank: sectionKinds.indexOf(section.kind),
|
|
5942
6088
|
value: section.kind === "engagement" ? `engagement:${section.treatment}` : section.kind
|
|
@@ -5962,7 +6108,7 @@ function planFooterArrangement(renderableSections, policy) {
|
|
|
5962
6108
|
const unsortedMainGroups = layoutGroups.filter((group) => !legalGroups.includes(group));
|
|
5963
6109
|
const mainGroups = policy.arrangement === "centred" ? unsortedMainGroups : [...unsortedMainGroups.filter((group) => group.width === "column"), ...unsortedMainGroups.filter((group) => group.width === "full-row")];
|
|
5964
6110
|
return {
|
|
5965
|
-
membershipKey:
|
|
6111
|
+
membershipKey: footerMembershipKey(selectedSections),
|
|
5966
6112
|
regions: [
|
|
5967
6113
|
...renderRegion("engagement-row", separateEngagement, policy),
|
|
5968
6114
|
...renderRegion("main", mainGroups, policy),
|
|
@@ -7313,6 +7459,37 @@ function parseBoundedInt(value, min, max) {
|
|
|
7313
7459
|
if (truncated > max) return null;
|
|
7314
7460
|
return truncated;
|
|
7315
7461
|
}
|
|
7462
|
+
function clampToBounds(value, bounds) {
|
|
7463
|
+
const floor = bounds.min ?? Number.NEGATIVE_INFINITY;
|
|
7464
|
+
const ceiling = bounds.max ?? Number.POSITIVE_INFINITY;
|
|
7465
|
+
return Math.min(ceiling, Math.max(floor, value));
|
|
7466
|
+
}
|
|
7467
|
+
/** Decimal places in a step, so 0.5 steps don't drift into 1.4999999. */
|
|
7468
|
+
function stepPrecision(step) {
|
|
7469
|
+
const [, decimals = ""] = String(step).split(".");
|
|
7470
|
+
return decimals.length;
|
|
7471
|
+
}
|
|
7472
|
+
/** One press of − or +: moves by `step` and stays inside the bounds. */
|
|
7473
|
+
function stepNumber(value, direction, bounds = {}) {
|
|
7474
|
+
const step = bounds.step ?? 1;
|
|
7475
|
+
const next = Number((value + direction * step).toFixed(stepPrecision(step)));
|
|
7476
|
+
return clampToBounds(next, bounds);
|
|
7477
|
+
}
|
|
7478
|
+
/**
|
|
7479
|
+
* The same press for a number box that holds text. An empty or unreadable box
|
|
7480
|
+
* starts from the lowest allowed value (or 0), so the first + gives a real number.
|
|
7481
|
+
*/
|
|
7482
|
+
function stepNumericInput(raw, direction, bounds = {}) {
|
|
7483
|
+
const current = typeof raw === "number" ? raw : Number.parseFloat(raw);
|
|
7484
|
+
if (!Number.isFinite(current)) return String(clampToBounds(bounds.min ?? 0, bounds));
|
|
7485
|
+
return String(stepNumber(current, direction, bounds));
|
|
7486
|
+
}
|
|
7487
|
+
/** Whether a press would change the value; a button that wouldn't is disabled. */
|
|
7488
|
+
function canStepNumericInput(raw, direction, bounds = {}) {
|
|
7489
|
+
const current = typeof raw === "number" ? raw : Number.parseFloat(raw);
|
|
7490
|
+
if (!Number.isFinite(current)) return true;
|
|
7491
|
+
return stepNumber(current, direction, bounds) !== current;
|
|
7492
|
+
}
|
|
7316
7493
|
|
|
7317
7494
|
//#endregion
|
|
7318
7495
|
//#region ../core/src/field-errors.ts
|
|
@@ -8183,6 +8360,15 @@ function resolveWholeSeriesBookingPhase(run, now) {
|
|
|
8183
8360
|
}
|
|
8184
8361
|
}
|
|
8185
8362
|
}
|
|
8363
|
+
/** Resolve the course's two distinct dates from its surviving schedule once. */
|
|
8364
|
+
function resolveWholeSeriesPaymentDates(input) {
|
|
8365
|
+
const live = orderedLiveRunSessions(input.sessions);
|
|
8366
|
+
const option = input.paymentTerms.allowedOptions.find((option$1) => option$1.kind === "instalment_plan");
|
|
8367
|
+
return {
|
|
8368
|
+
bookingStartAt: live[0]?.startsAt ?? null,
|
|
8369
|
+
instalmentCollectionDeadlineAt: (option?.courseDeadline === "last_session" ? live[live.length - 1] : live[0])?.startsAt ?? null
|
|
8370
|
+
};
|
|
8371
|
+
}
|
|
8186
8372
|
|
|
8187
8373
|
//#endregion
|
|
8188
8374
|
//#region ../core/src/public-read-cache-contract.ts
|
|
@@ -10310,4 +10496,57 @@ function isEventEmailTemplateType(value) {
|
|
|
10310
10496
|
}
|
|
10311
10497
|
|
|
10312
10498
|
//#endregion
|
|
10313
|
-
|
|
10499
|
+
//#region ../core/src/editor-value-ownership.ts
|
|
10500
|
+
/** Captured editor payloads are deeply immutable; caller-owned inputs are never frozen in place. */
|
|
10501
|
+
const owned = new WeakSet();
|
|
10502
|
+
function freezeOwned(value) {
|
|
10503
|
+
Object.freeze(value);
|
|
10504
|
+
owned.add(value);
|
|
10505
|
+
return value;
|
|
10506
|
+
}
|
|
10507
|
+
function capturedObject(value) {
|
|
10508
|
+
return value !== null && typeof value === "object" && owned.has(value) && !Array.isArray(value);
|
|
10509
|
+
}
|
|
10510
|
+
function captureArray(value, previous) {
|
|
10511
|
+
const before = Array.isArray(previous) && owned.has(previous) ? previous : undefined;
|
|
10512
|
+
const next = Array.from(value, (item, index) => capture(item, before?.[index]));
|
|
10513
|
+
if (before !== undefined && before.length === next.length && next.every((item, index) => Object.is(item, before[index]))) return before;
|
|
10514
|
+
return owned.has(value) && next.every((item, index) => Object.is(item, value[index])) ? value : freezeOwned(next);
|
|
10515
|
+
}
|
|
10516
|
+
function captureObject(value, previous) {
|
|
10517
|
+
const before = capturedObject(previous) ? previous : undefined;
|
|
10518
|
+
const entries = Object.entries(value).map(([key, item]) => [key, capture(item, before?.[key])]);
|
|
10519
|
+
if (before !== undefined && Object.keys(before).length === entries.length && entries.every(([key, item]) => Object.prototype.hasOwnProperty.call(before, key) && Object.is(item, before[key]))) return before;
|
|
10520
|
+
return owned.has(value) && entries.every(([key, item]) => Object.is(item, value[key])) ? value : freezeOwned(Object.fromEntries(entries));
|
|
10521
|
+
}
|
|
10522
|
+
function plainRecord(value) {
|
|
10523
|
+
const prototype = Object.getPrototypeOf(value);
|
|
10524
|
+
return prototype === Object.prototype || prototype === null;
|
|
10525
|
+
}
|
|
10526
|
+
function capture(value, previous) {
|
|
10527
|
+
if (value === null || typeof value !== "object") return value;
|
|
10528
|
+
if (owned.has(value) && (previous === undefined || value === previous)) return value;
|
|
10529
|
+
if (Array.isArray(value)) return captureArray(value, previous);
|
|
10530
|
+
return plainRecord(value) ? captureObject(value, previous) : capture(JSON.parse(JSON.stringify(value)), previous);
|
|
10531
|
+
}
|
|
10532
|
+
/**
|
|
10533
|
+
* The snapshot/journal ingress boundary. Equal captured branches retain identity;
|
|
10534
|
+
* already-owned values pass through without a second clone or traversal.
|
|
10535
|
+
* The assertion preserves the caller's existing domain brand after capture.
|
|
10536
|
+
*/
|
|
10537
|
+
function captureEditorValue(value, previous) {
|
|
10538
|
+
return capture(value, previous);
|
|
10539
|
+
}
|
|
10540
|
+
|
|
10541
|
+
//#endregion
|
|
10542
|
+
//#region ../core/src/offline-payment-method.ts
|
|
10543
|
+
/** How money was received outside the online card checkout. */
|
|
10544
|
+
const OFFLINE_PAYMENT_METHODS = [
|
|
10545
|
+
"cash",
|
|
10546
|
+
"bank_transfer",
|
|
10547
|
+
"card_machine",
|
|
10548
|
+
"other"
|
|
10549
|
+
];
|
|
10550
|
+
|
|
10551
|
+
//#endregion
|
|
10552
|
+
export { locationValueSchema as $, parseEventSeriesId as $n, publicEventPricingDisplay as $t, parseMailingListContentVersionId as A, parseMediaAssetId as An, parseBookingTimeZone as At, footerNavigationLayouts as B, unsafeAsStorageBucketName as Bn, getBookingInstalmentDepositRefundability as Bt, resolveWholeSeriesBookingPhase as C, parseSiteTermsVersionId as Cn, getLocalScheduleTime as Ct, parseManagementKey as D, parseDatedOfferingCapacityHoldAuditRef as Dn, resolveBookingBusinessTimeZone as Dt, exposeSecret as E, unsafeAsPassId as En, parseLocalScheduleTime as Et, parseMailingListGlobalForm as F, unsafeAsOriginalFilename as Fn, isLiveOrderInstalmentPlanStatus as Ft, formatOpeningHoursRows as G, parseEditorSessionGeneration as Gn, resolveFlexibleBalanceDueAt as Gt, DEFAULT_MAILING_LIST_TARGETING as H, unsafeAsUploadSessionId as Hn, getBookingInstalmentProtectedDepositAmountCents as Ht, DEFAULT_MAILING_LIST_PRIVACY_NOTE as I, unsafeAsPositiveByteCount as In, isSettleableFlexibleBalanceContractStatus as It, assertAllowedPublicUrl as J, parseApiKeyId as Jn, parseEventPageSurfaceSubject as Jt, parsePublicContactDetails as K, parsePageId as Kn, resolveFlexibleBalanceInitialPaymentCents as Kt, DEFAULT_MAILING_LIST_SUCCESS_MESSAGE as L, unsafeAsPositiveSeconds as Ln, isSettleableOrderInstalmentPlanStatus as Lt, parseMailingListRuntimeContext as M, unsafeAsDetectedMimeType as Mn, toUtcIsoDateTimeString as Mt, assessMailingListTargeting as N, unsafeAsFileChecksumSha256 as Nn, BOOKING_COURSE_INSTALMENT_DEADLINES as Nt, slugify as O, parseDatedOfferingCapacityHoldId as On, resolveBookingTimeZoneId as Ot, parseConfiguredMailingListProvider as P, unsafeAsMediaAssetId as Pn, validateBookingPaymentOptionKinds as Pt, locationMapLinks as Q, unsafeAsUserId as Qn, publicEventPricingCurrency as Qt, parseMailingListProviderScope as R, unsafeAsSafeDownloadFilename as Rn, addIntervalPreservingMonthAnchor as Rt, orderedLiveRunSessions as S, parseCustomerId as Sn, getLocalScheduleDate as St, createSecret as T, unsafeAsEntitlementId as Tn, parseBookingLocalDate as Tt, planMailingListChoicePresentation as U, unsafeAsProductId as Un, omitZeroAmountFutureRows as Ut, parseMailingListPlacementTargeting as V, unsafeAsStoragePath as Vn, getBookingInstalmentPlanIntervalCount as Vt, isCanonicalRichTextDoc as W, unsafeAsCheckoutLineId as Wn, splitAmountWithRemainderInFirst as Wt, decideLocationSave as X, parseUserId as Xn, formatEventPricing as Xt, SENSITIVE_COLLECTION_MODES as Y, parseSiteId as Yn, formatBookingPriceDisplay as Yt, stableJsonStringify as Z, unsafeAsSiteId as Zn, isPublicEventPricingOptionDisplayable as Zt, WHOLE_SERIES_EVENT_PRESET_VALUES as _, formatDurationUnitLabel as _n, buildBookingUtcDateWindow as _t, resolveEventCatalogue as a, mapNonEmptyArray as an, unsafeAsPricingOptionId as ar, isPresent as at, CANCELLED_SESSION_STATUS as b, unsafeAsAppointmentResourceId as bn, formatLocalScheduleTime as bt, areConfiguredBookingVerticalConfigsEqual as c, parseNonNegativeCents as cn, blockInteractionContextSchema as cr, formatDate as ct, parseVerticalPresetId as d, toNonNegativeCents as dn, formatDateTimeRange as dt, publicEventPricingOptions as en, parseRetiredCourseId as er, normalizeLocationAddressText as et, resolveSiteVerticalBookingConfig as f, unsafeAsNonNegativeCents as fn, formatTime as ft, SURFACE_EVENT_PRESET_VALUES as g, assertNever as gn, toScheduledBookingDateTime as gt, ORDINARY_EVENT_PRESET_VALUES as h, parseCurrencyCode as hn, resolveBookingDisplayContext as ht, authoredValuesEqual as i, fromArray as in, unsafeAsOccurrenceId as ir, toLocationCoordinates as it, parseMailingListSignedSourceToken as j, unsafeAsDeclaredMimeType as jn, parseUtcIsoDateTimeString as jt, parseMailingListBlockId as k, unsafeAsBookingSessionId as kn, toBookingTimeZone as kt, canonicalizeConfiguredBookingVerticalConfig as l, parsePositiveCents as ln, formatDateRange as lt, EVENT_PRESET_VALUES as m, formatCurrencyAmount as mn, inferSiteDateLocale as mt, committedWriteProofSchema as n, resolveExactOrFreePriceDisplay as nn, unsafeAsEventOfferingId as nr, projectPublicLocation as nt, EVENT_PRESET_VOCABULARY as o, mapReadonlyNonEmptyArray as on, err as or, mapDrawingSchema as ot, DEFAULT_EVENT_TYPE_PRESETS as p, unsafeAsPositiveCents as pn, formatTimeRange as pt, parseWeeklyOpeningHours as q, unsafeAsSiteFontId as qn, deriveTotalTicketQuantity as qt, isRecord as r, resolvePricingOptionsPriceDisplay as rn, unsafeAsEventSeriesId as rr, publicLocationSchema as rt, NAVIGATION_LOCATIONS as s, isNonNegativeWholeCents as sn, ok as sr, selectCategoryView as st, OFFLINE_PAYMENT_METHODS as t, publicEventPricingType as tn, unsafeAsEventInstanceId as tr, parseLocationValue as tt, parseVerticalId as u, toCents as un, formatDateTime as ut, getPublicReadCachePolicy as v, unsafeAsBookingRequirementId as vn, compareLocalScheduleDates as vt, resolveWholeSeriesRunLifecycle as w, parseMembershipId as wn, localScheduleTimePattern as wt, nextLiveRunSessionStartMs as x, unsafeAsStaffMemberId as xn, getBookingLocalDateKey as xt, publicReadFreshnessSeconds as y, unsafeAsDemoCapability as yn, formatLocalScheduleDate as yt, parseFooterCompositionV1 as z, unsafeAsSiteScopedStoragePath as zn, clampConfiguredAmount as zt };
|