@wix/headless-bookings 1.0.10 → 1.0.12

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.
@@ -10,7 +10,7 @@
10
10
  * `{ services, pagingMetadata }` shape.
11
11
  */
12
12
  import { type Service, type Paging, type Sorting } from '@wix/auto_sdk_bookings_services';
13
- import { LocationType as AvailabilityLocationType, type AvailabilityFilter, type Attribute, type Location as AvailabilityLocation } from '@wix/auto_sdk_bookings_catalog-search';
13
+ import { LocationType as AvailabilityLocationType, type ServiceFilters as AvailabilityFilter, type Attribute, type Location as AvailabilityLocation } from '@wix/auto_sdk_bookings_catalog-search';
14
14
  import type { FilterValue as Filter } from '@wix/headless-components/react';
15
15
  /**
16
16
  * Synthetic location ID constants for non-business locations
@@ -241,9 +241,9 @@ async function queryServicesByAvailability({ appId, filter, availabilityFilter,
241
241
  sort,
242
242
  cursorPaging: { limit, ...(cursor ? { cursor } : {}) },
243
243
  };
244
- const response = await (0, auto_sdk_bookings_catalog_search_1.queryServicesByAvailability)({
244
+ const response = await (0, auto_sdk_bookings_catalog_search_1.queryServicesByFilters)({
245
245
  query: availabilityQuery,
246
- availabilityFilter,
246
+ serviceFilters: availabilityFilter,
247
247
  });
248
248
  const results = response.results ?? [];
249
249
  return {
@@ -6,6 +6,7 @@ import type { Signal } from '@wix/services-definitions/core-services/signals';
6
6
  import type { CalculateTotalsResponse } from '@wix/auto_sdk_ecom_totals-calculator';
7
7
  import type { Service } from '@wix/auto_sdk_bookings_services';
8
8
  import type { SelectedPaymentOption } from '../booking/book-action/types.js';
9
+ import type { ServiceSelectionTimeSlot } from '../booking/booking.js';
9
10
  /**
10
11
  * Service payment options derived from service.payment.options.
11
12
  * Describes which payment methods the service supports.
@@ -55,6 +56,8 @@ export interface PricingServiceSelection {
55
56
  localEndDate?: string;
56
57
  /** IANA time zone identifier for the selected slot (e.g. "America/New_York"). */
57
58
  timeZone?: string;
59
+ /** Individual slots for multi-slot selections (e.g. DAY-range rentals). When present, prices each slot separately rather than the collapsed start→end span. */
60
+ rangeTimeSlots?: ServiceSelectionTimeSlot[];
58
61
  }
59
62
  /**
60
63
  * Public config for PaymentService (SSR mode only):
@@ -112,17 +112,10 @@ function buildLineItem(service, totalParticipants, lineItemId, selectedPaymentOp
112
112
  function getDurationRange(service) {
113
113
  return service.schedule?.availabilityConstraints?.durationRange;
114
114
  }
115
- async function getPreviewedPrice(service, localStartDate, localEndDate, timeZone, numberOfParticipants) {
116
- if (!service._id)
115
+ async function getPreviewedPrice(bookingLineItems) {
116
+ if (!bookingLineItems.length)
117
117
  return null;
118
- const lineItemInput = {
119
- serviceId: service._id,
120
- localStartDate,
121
- localEndDate,
122
- numberOfParticipants,
123
- ...(timeZone ? { timeZone } : {}),
124
- };
125
- const result = await (0, auto_sdk_bookings_pricing_1.previewPrice)([lineItemInput]);
118
+ const result = await (0, auto_sdk_bookings_pricing_1.previewPrice)(bookingLineItems);
126
119
  const price = result.priceInfo?.calculatedPrice;
127
120
  if (price == null)
128
121
  return null;
@@ -132,10 +125,28 @@ async function getPreviewedPrice(service, localStartDate, localEndDate, timeZone
132
125
  };
133
126
  }
134
127
  async function buildLineItemWithPreview(item, totalParticipants, selectedPaymentOption) {
135
- if (item.localStartDate &&
136
- item.localEndDate &&
137
- getDurationRange(item.service)) {
138
- const previewedPrice = await getPreviewedPrice(item.service, item.localStartDate, item.localEndDate, item.timeZone, totalParticipants).catch(() => null);
128
+ const slots = item.rangeTimeSlots && item.rangeTimeSlots.length > 0
129
+ ? item.rangeTimeSlots.map((s) => ({
130
+ localStartDate: s.startDate,
131
+ localEndDate: s.endDate,
132
+ }))
133
+ : item.localStartDate && item.localEndDate
134
+ ? [
135
+ {
136
+ localStartDate: item.localStartDate,
137
+ localEndDate: item.localEndDate,
138
+ },
139
+ ]
140
+ : [];
141
+ if (item.service._id && slots.length && getDurationRange(item.service)) {
142
+ const bookingLineItems = slots.map((slot) => ({
143
+ serviceId: item.service._id,
144
+ localStartDate: slot.localStartDate,
145
+ localEndDate: slot.localEndDate,
146
+ numberOfParticipants: totalParticipants,
147
+ ...(item.timeZone ? { timeZone: item.timeZone } : {}),
148
+ }));
149
+ const previewedPrice = await getPreviewedPrice(bookingLineItems).catch(() => null);
139
150
  if (previewedPrice != null) {
140
151
  const depositValue = item.service.payment?.fixed?.deposit?.value;
141
152
  const previewedDeposit = previewedPrice.deposit;
@@ -244,11 +255,16 @@ exports.PaymentService = services_definitions_1.implementService.withConfig()(pa
244
255
  const selections = bookingService?.serviceSelections.get() || [];
245
256
  const timezone = bookingService?.timezone.get();
246
257
  const selectedPaymentOption = bookingService?.selectedPaymentOption.get();
247
- return (selections
248
- .map((s) => `${s.service._id}:${s.timeSlot?.startDate ?? ''}:${s.timeSlot?.endDate ?? ''}`)
249
- .join(',') +
250
- `:${timezone ?? ''}` +
251
- `:${selectedPaymentOption ?? ''}`);
258
+ return JSON.stringify({
259
+ selections: selections.map((s) => ({
260
+ serviceId: s.service._id,
261
+ slots: s.rangeTimeSlots && s.rangeTimeSlots.length > 0
262
+ ? s.rangeTimeSlots.map((r) => [r.startDate, r.endDate])
263
+ : [[s.timeSlot?.startDate, s.timeSlot?.endDate]],
264
+ })),
265
+ timezone,
266
+ selectedPaymentOption,
267
+ });
252
268
  });
253
269
  signalsService.effect(() => {
254
270
  // Subscribe to servicesKey to trigger effect when service, time
@@ -267,6 +283,7 @@ exports.PaymentService = services_definitions_1.implementService.withConfig()(pa
267
283
  localStartDate: selection.timeSlot?.startDate,
268
284
  localEndDate: selection.timeSlot?.endDate,
269
285
  timeZone: timezone,
286
+ rangeTimeSlots: selection.rangeTimeSlots,
270
287
  }));
271
288
  if (pricingServiceSelections.length) {
272
289
  serviceOptionsSignal.set(deriveServiceOptions(pricingServiceSelections));
@@ -10,7 +10,7 @@
10
10
  * `{ services, pagingMetadata }` shape.
11
11
  */
12
12
  import { type Service, type Paging, type Sorting } from '@wix/auto_sdk_bookings_services';
13
- import { LocationType as AvailabilityLocationType, type AvailabilityFilter, type Attribute, type Location as AvailabilityLocation } from '@wix/auto_sdk_bookings_catalog-search';
13
+ import { LocationType as AvailabilityLocationType, type ServiceFilters as AvailabilityFilter, type Attribute, type Location as AvailabilityLocation } from '@wix/auto_sdk_bookings_catalog-search';
14
14
  import type { FilterValue as Filter } from '@wix/headless-components/react';
15
15
  /**
16
16
  * Synthetic location ID constants for non-business locations
@@ -10,7 +10,7 @@
10
10
  * `{ services, pagingMetadata }` shape.
11
11
  */
12
12
  import { queryServices as queryServicesApi, LocationTypeEnumLocationType as LocationType, } from '@wix/auto_sdk_bookings_services';
13
- import { queryServicesByAvailability as queryServicesByAvailabilitySdk, LocationType as AvailabilityLocationType, } from '@wix/auto_sdk_bookings_catalog-search';
13
+ import { queryServicesByFilters as queryServicesByAvailabilitySdk, LocationType as AvailabilityLocationType, } from '@wix/auto_sdk_bookings_catalog-search';
14
14
  import { BOOKING_APP_ID, DEFAULT_QUERY_LIMIT, } from '../../services/constants.js';
15
15
  /**
16
16
  * Synthetic location ID constants for non-business locations
@@ -239,7 +239,7 @@ async function queryServicesByAvailability({ appId, filter, availabilityFilter,
239
239
  };
240
240
  const response = await queryServicesByAvailabilitySdk({
241
241
  query: availabilityQuery,
242
- availabilityFilter,
242
+ serviceFilters: availabilityFilter,
243
243
  });
244
244
  const results = response.results ?? [];
245
245
  return {
@@ -6,6 +6,7 @@ import type { Signal } from '@wix/services-definitions/core-services/signals';
6
6
  import type { CalculateTotalsResponse } from '@wix/auto_sdk_ecom_totals-calculator';
7
7
  import type { Service } from '@wix/auto_sdk_bookings_services';
8
8
  import type { SelectedPaymentOption } from '../booking/book-action/types.js';
9
+ import type { ServiceSelectionTimeSlot } from '../booking/booking.js';
9
10
  /**
10
11
  * Service payment options derived from service.payment.options.
11
12
  * Describes which payment methods the service supports.
@@ -55,6 +56,8 @@ export interface PricingServiceSelection {
55
56
  localEndDate?: string;
56
57
  /** IANA time zone identifier for the selected slot (e.g. "America/New_York"). */
57
58
  timeZone?: string;
59
+ /** Individual slots for multi-slot selections (e.g. DAY-range rentals). When present, prices each slot separately rather than the collapsed start→end span. */
60
+ rangeTimeSlots?: ServiceSelectionTimeSlot[];
58
61
  }
59
62
  /**
60
63
  * Public config for PaymentService (SSR mode only):
@@ -107,17 +107,10 @@ function buildLineItem(service, totalParticipants, lineItemId, selectedPaymentOp
107
107
  function getDurationRange(service) {
108
108
  return service.schedule?.availabilityConstraints?.durationRange;
109
109
  }
110
- async function getPreviewedPrice(service, localStartDate, localEndDate, timeZone, numberOfParticipants) {
111
- if (!service._id)
110
+ async function getPreviewedPrice(bookingLineItems) {
111
+ if (!bookingLineItems.length)
112
112
  return null;
113
- const lineItemInput = {
114
- serviceId: service._id,
115
- localStartDate,
116
- localEndDate,
117
- numberOfParticipants,
118
- ...(timeZone ? { timeZone } : {}),
119
- };
120
- const result = await previewPrice([lineItemInput]);
113
+ const result = await previewPrice(bookingLineItems);
121
114
  const price = result.priceInfo?.calculatedPrice;
122
115
  if (price == null)
123
116
  return null;
@@ -127,10 +120,28 @@ async function getPreviewedPrice(service, localStartDate, localEndDate, timeZone
127
120
  };
128
121
  }
129
122
  async function buildLineItemWithPreview(item, totalParticipants, selectedPaymentOption) {
130
- if (item.localStartDate &&
131
- item.localEndDate &&
132
- getDurationRange(item.service)) {
133
- const previewedPrice = await getPreviewedPrice(item.service, item.localStartDate, item.localEndDate, item.timeZone, totalParticipants).catch(() => null);
123
+ const slots = item.rangeTimeSlots && item.rangeTimeSlots.length > 0
124
+ ? item.rangeTimeSlots.map((s) => ({
125
+ localStartDate: s.startDate,
126
+ localEndDate: s.endDate,
127
+ }))
128
+ : item.localStartDate && item.localEndDate
129
+ ? [
130
+ {
131
+ localStartDate: item.localStartDate,
132
+ localEndDate: item.localEndDate,
133
+ },
134
+ ]
135
+ : [];
136
+ if (item.service._id && slots.length && getDurationRange(item.service)) {
137
+ const bookingLineItems = slots.map((slot) => ({
138
+ serviceId: item.service._id,
139
+ localStartDate: slot.localStartDate,
140
+ localEndDate: slot.localEndDate,
141
+ numberOfParticipants: totalParticipants,
142
+ ...(item.timeZone ? { timeZone: item.timeZone } : {}),
143
+ }));
144
+ const previewedPrice = await getPreviewedPrice(bookingLineItems).catch(() => null);
134
145
  if (previewedPrice != null) {
135
146
  const depositValue = item.service.payment?.fixed?.deposit?.value;
136
147
  const previewedDeposit = previewedPrice.deposit;
@@ -239,11 +250,16 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
239
250
  const selections = bookingService?.serviceSelections.get() || [];
240
251
  const timezone = bookingService?.timezone.get();
241
252
  const selectedPaymentOption = bookingService?.selectedPaymentOption.get();
242
- return (selections
243
- .map((s) => `${s.service._id}:${s.timeSlot?.startDate ?? ''}:${s.timeSlot?.endDate ?? ''}`)
244
- .join(',') +
245
- `:${timezone ?? ''}` +
246
- `:${selectedPaymentOption ?? ''}`);
253
+ return JSON.stringify({
254
+ selections: selections.map((s) => ({
255
+ serviceId: s.service._id,
256
+ slots: s.rangeTimeSlots && s.rangeTimeSlots.length > 0
257
+ ? s.rangeTimeSlots.map((r) => [r.startDate, r.endDate])
258
+ : [[s.timeSlot?.startDate, s.timeSlot?.endDate]],
259
+ })),
260
+ timezone,
261
+ selectedPaymentOption,
262
+ });
247
263
  });
248
264
  signalsService.effect(() => {
249
265
  // Subscribe to servicesKey to trigger effect when service, time
@@ -262,6 +278,7 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
262
278
  localStartDate: selection.timeSlot?.startDate,
263
279
  localEndDate: selection.timeSlot?.endDate,
264
280
  timeZone: timezone,
281
+ rangeTimeSlots: selection.rangeTimeSlots,
265
282
  }));
266
283
  if (pricingServiceSelections.length) {
267
284
  serviceOptionsSignal.set(deriveServiceOptions(pricingServiceSelections));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/headless-bookings",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -38,10 +38,10 @@
38
38
  "dependencies": {
39
39
  "@wix/auto_sdk_bookings_availability-time-slots": "^1.0.244",
40
40
  "@wix/auto_sdk_bookings_bookings": "^1.0.192",
41
- "@wix/auto_sdk_bookings_catalog-search": "^1.0.0",
41
+ "@wix/auto_sdk_bookings_catalog-search": "^1.0.2",
42
42
  "@wix/auto_sdk_bookings_event-time-slots": "^1.0.112",
43
43
  "@wix/auto_sdk_bookings_pricing": "^1.0.87",
44
- "@wix/auto_sdk_bookings_services": "^1.0.226",
44
+ "@wix/auto_sdk_bookings_services": "^1.0.244",
45
45
  "@wix/auto_sdk_ecom_cart-v-2": "^1.0.86",
46
46
  "@wix/forms": "^1.0.384",
47
47
  "@wix/headless-media": "0.0.25",
@@ -91,5 +91,5 @@
91
91
  "groupId": "com.wixpress.headless-components"
92
92
  }
93
93
  },
94
- "falconPackageHash": "982db1d1e4f6337441d55feaf920c8b04f62f86edf8adc4b7d268a60"
94
+ "falconPackageHash": "a3b1cc5e12b33bd58dd7a4e7bacc6a47fc3ab1a8b16aa142e6302570"
95
95
  }