@v-office/website-sdk 2.4.0 → 2.4.2

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/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Pt as defineWebsiteSDKOptions, t as createWebsiteSDK } from "./client-DcBxVHpl.mjs";
2
+ import { Pt as defineWebsiteSDKOptions, t as createWebsiteSDK } from "./client-BORwUo4_.mjs";
3
3
  import { Console, Effect, FileSystem, Layer, Option, Path, Schema, Stdio, Terminal } from "effect";
4
4
  import { Command, Flag } from "effect/unstable/cli";
5
5
  import { inspect } from "node:util";
@@ -15,7 +15,7 @@ var CLICheckFailed = class extends Error {
15
15
  const toCLIError = (message, cause) => cause instanceof Error ? new CLICheckFailed(`${message}: ${cause.message}`, { cause }) : new CLICheckFailed(message, { cause });
16
16
  //#endregion
17
17
  //#region package.json
18
- var version = "2.4.0";
18
+ var version = "2.4.2";
19
19
  //#endregion
20
20
  //#region src/cli/output.ts
21
21
  const toJson = (value) => Effect.try({
@@ -8,13 +8,15 @@ const normalizeWebsiteSDKOptions = (options = {}) => ({
8
8
  customAttributeFilterDefinitions: options.customAttributeFilterDefinitions ?? [],
9
9
  rentalHighlightPrioritization: options.rentalHighlightPrioritization ?? DEFAULT_RENTAL_HIGHLIGHT_PRIORITIZATION,
10
10
  rentalPropertyHighlightPrioritization: options.rentalPropertyHighlightPrioritization ?? DEFAULT_RENTAL_PROPERTY_HIGHLIGHT_PRIORITIZATION,
11
- rentalScope: options.rentalScope ?? {}
11
+ rentalScope: options.rentalScope ?? {},
12
+ shouldAddProposedAdditionalServiceAmount: options.shouldAddProposedAdditionalServiceAmount ?? false
12
13
  });
13
14
  const toV9Options = (options) => ({
14
15
  ...options.translationOverrides === void 0 ? {} : { translationOverrides: options.translationOverrides },
15
16
  customAttributeFilterDefinitions: options.customAttributeFilterDefinitions,
16
17
  rentalHighlightPrioritization: options.rentalHighlightPrioritization,
17
- rentalScope: options.rentalScope
18
+ rentalScope: options.rentalScope,
19
+ shouldAddProposedAdditionalServiceAmount: options.shouldAddProposedAdditionalServiceAmount
18
20
  });
19
21
  const defineWebsiteSDKOptions = (options) => options;
20
22
  //#endregion
@@ -4415,7 +4417,7 @@ const bookV9Insurance = ({ quote, bookingNumber, guestToken, v1Client }) => Effe
4415
4417
  //#region src/legacy-v9/live/quote.ts
4416
4418
  const loadQuoteRuntime = Effect.tryPromise({
4417
4419
  try: async () => {
4418
- return { toGuestQuote: (await import("./quote-_lvxNgiO.mjs")).toGuestQuote };
4420
+ return { toGuestQuote: (await import("./quote-Cs6jGoRS.mjs")).toGuestQuote };
4419
4421
  },
4420
4422
  catch: (cause) => new CoreSDKError({
4421
4423
  source: "v10",
@@ -4433,7 +4435,7 @@ const toVofficeUnitId = (input) => {
4433
4435
  message: `Expected rentalId to be a vOffice unit ID, received "${input.rentalId}".`
4434
4436
  }));
4435
4437
  };
4436
- const quote = (client, v0Client, translations, limitQuote, input) => Effect.gen(function* () {
4438
+ const quote = (client, v0Client, translations, limitQuote, input, shouldAddProposedAdditionalServiceAmount) => Effect.gen(function* () {
4437
4439
  const unitId = yield* toVofficeUnitId(input);
4438
4440
  const result = yield* limitQuote(client.execute("getUnitQuotePrices", {
4439
4441
  path: { voffice_unit: unitId },
@@ -4455,7 +4457,7 @@ const quote = (client, v0Client, translations, limitQuote, input) => Effect.gen(
4455
4457
  cause
4456
4458
  }))));
4457
4459
  const { toGuestQuote } = yield* loadQuoteRuntime;
4458
- const guestQuoteResult = yield* toGuestQuote(input, result.raw?.data.quote ?? result.data.data.quote, input.locale, translations);
4460
+ const guestQuoteResult = yield* toGuestQuote(input, result.raw?.data.quote ?? result.data.data.quote, input.locale, translations, { shouldAddProposedAdditionalServiceAmount });
4459
4461
  if (guestQuoteResult.status === "unavailable") return guestQuoteResult;
4460
4462
  return {
4461
4463
  status: "available",
@@ -4499,7 +4501,7 @@ const makeV9QuoteApi = ({ config, options }) => {
4499
4501
  v1Client: clients.v1Client
4500
4502
  });
4501
4503
  return {
4502
- quote: (input) => withClients(({ v0Client, v1Client }) => quote(v1Client, v0Client, translations, limitQuote, input)),
4504
+ quote: (input) => withClients(({ v0Client, v1Client }) => quote(v1Client, v0Client, translations, limitQuote, input, options.shouldAddProposedAdditionalServiceAmount)),
4503
4505
  addAdditionalService: ({ quote, id }) => withClients((clients) => withGuestQuoteInsuranceRefresh({
4504
4506
  result: addGuestQuoteAdditionalServiceSelection({
4505
4507
  quote,
@@ -4670,7 +4672,7 @@ const parseV9SearchCursor = (cursor) => Effect.gen(function* () {
4670
4672
  return page;
4671
4673
  });
4672
4674
  const loadV9SearchRuntime = Effect.tryPromise({
4673
- try: () => import("./search-CnE272WG.mjs"),
4675
+ try: () => import("./search-Ckz48lwV.mjs"),
4674
4676
  catch: (cause) => new CoreSDKError({
4675
4677
  source: "v10",
4676
4678
  operation: "v9.search.runtime",
package/dist/index.d.mts CHANGED
@@ -24,6 +24,7 @@ type WebsiteSDKOptions = {
24
24
  readonly rentalHighlightPrioritization?: readonly RentalHighlightPrioritizationKey$1[];
25
25
  readonly rentalPropertyHighlightPrioritization?: readonly RentalPropertyHighlightPrioritizationKey$1[];
26
26
  readonly rentalScope?: RentalScope;
27
+ readonly shouldAddProposedAdditionalServiceAmount?: boolean;
27
28
  };
28
29
  declare const defineWebsiteSDKOptions: <Options extends WebsiteSDKOptions>(options: Options) => Options;
29
30
  //#endregion
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as SetupResponseSchema, A as ErgoPolicyNumberRequestSchema, At as selectInsurancePaymentEffect, B as QuotePricesResponseSchema, C as ErgoAddressSchema, Ct as getStartDateSelectedAvailabilityEffect, D as ErgoCreatePreContractRequestSchema, Dt as searchEffect, E as ErgoCommonFieldsSchema, Et as removeAdditionalServiceEffect, F as OnOfficeUnitSchema, G as RegionListResponseSchema, H as QuoteServiceSchema, I as PaymentScheduleItemSchema, J as ServiceBeonDataSchema, K as RoomImageSchema, L as PaymentScheduleSchema, M as ErgoTripAndCustomerRequestSchema, Mt as submitPaymentOption, N as FacilityListResponseSchema, Nt as submitPaymentOptionEffect, O as ErgoPersonSchema, Ot as selectCancellationPolicyEffect, P as OnOfficeUnitCollectionResponseSchema, Pt as defineWebsiteSDKOptions, Q as SetupDataSchema, R as QuoteLineSchema, S as DocumentTypeSchema, St as getRentalsEffect, T as ErgoBookRequestSchema, Tt as quoteEffect, U as RawObjectResponseSchema, V as QuoteSchema, W as RawVofficeObjectSchema, X as ServiceLimitSchema, Y as ServiceImageSchema, Z as ServiceListResponseSchema, _ as DocumentResourceResponseSchema, _t as bookInsuranceEffect, a as makeV0OpenApiClientFetchLive, at as UnitIdsResponseSchema, b as DocumentStatusUpdateRequestSchema, bt as getFiltersEffect, c as V1OpenApiClientError, ct as UnitOfferSchema, d as ApiEnvelopeBaseSchema, dt as V1_BASE_URL, et as TileCollectionResponseSchema, f as CalendarDaySchema, ft as V1_OPERATIONS, g as DocumentCollectionResponseSchema, gt as bookEffect, h as CustomerUnitSummarySchema, ht as addAdditionalServiceEffect, i as V0OpenApiClientError, it as TravelInsuranceBookingStoreRequestSchema, j as ErgoReadPreContractRequestSchema, jt as submitContactEffect, k as ErgoPlanSearchRequestSchema, kt as selectInsuranceEffect, l as makeV1OpenApiClientFetchLive, lt as UnitResponseSchema, m as CurrentMemberResponseSchema, mt as decodeV1OperationResponse, nt as TileTagSchema, o as makeV0OpenApiClientLive, ot as UnitListItemSchema, p as CalendarResponseSchema, pt as VideoResponseSchema, q as SearchPropertiesResponseSchema, r as V0OpenApiClient, rt as TravelInsuranceBookingSchema, s as V1OpenApiClient, st as UnitListResponseSchema, t as createWebsiteSDK, tt as TileSchema, u as makeV1OpenApiClientLive, ut as UnitServicePriceSchema, v as DocumentResourceSchema, vt as clearAdditionalServicesEffect, w as ErgoBankSchema, wt as getTermsAndPrivacyPolicyEffect, x as DocumentSummarySchema, xt as getInitialAvailabilityEffect, y as DocumentStatusSchema, yt as createInsurancePreContractEffect, z as QuotePricesPayloadSchema } from "./client-DcBxVHpl.mjs";
1
+ import { $ as SetupResponseSchema, A as ErgoPolicyNumberRequestSchema, At as selectInsurancePaymentEffect, B as QuotePricesResponseSchema, C as ErgoAddressSchema, Ct as getStartDateSelectedAvailabilityEffect, D as ErgoCreatePreContractRequestSchema, Dt as searchEffect, E as ErgoCommonFieldsSchema, Et as removeAdditionalServiceEffect, F as OnOfficeUnitSchema, G as RegionListResponseSchema, H as QuoteServiceSchema, I as PaymentScheduleItemSchema, J as ServiceBeonDataSchema, K as RoomImageSchema, L as PaymentScheduleSchema, M as ErgoTripAndCustomerRequestSchema, Mt as submitPaymentOption, N as FacilityListResponseSchema, Nt as submitPaymentOptionEffect, O as ErgoPersonSchema, Ot as selectCancellationPolicyEffect, P as OnOfficeUnitCollectionResponseSchema, Pt as defineWebsiteSDKOptions, Q as SetupDataSchema, R as QuoteLineSchema, S as DocumentTypeSchema, St as getRentalsEffect, T as ErgoBookRequestSchema, Tt as quoteEffect, U as RawObjectResponseSchema, V as QuoteSchema, W as RawVofficeObjectSchema, X as ServiceLimitSchema, Y as ServiceImageSchema, Z as ServiceListResponseSchema, _ as DocumentResourceResponseSchema, _t as bookInsuranceEffect, a as makeV0OpenApiClientFetchLive, at as UnitIdsResponseSchema, b as DocumentStatusUpdateRequestSchema, bt as getFiltersEffect, c as V1OpenApiClientError, ct as UnitOfferSchema, d as ApiEnvelopeBaseSchema, dt as V1_BASE_URL, et as TileCollectionResponseSchema, f as CalendarDaySchema, ft as V1_OPERATIONS, g as DocumentCollectionResponseSchema, gt as bookEffect, h as CustomerUnitSummarySchema, ht as addAdditionalServiceEffect, i as V0OpenApiClientError, it as TravelInsuranceBookingStoreRequestSchema, j as ErgoReadPreContractRequestSchema, jt as submitContactEffect, k as ErgoPlanSearchRequestSchema, kt as selectInsuranceEffect, l as makeV1OpenApiClientFetchLive, lt as UnitResponseSchema, m as CurrentMemberResponseSchema, mt as decodeV1OperationResponse, nt as TileTagSchema, o as makeV0OpenApiClientLive, ot as UnitListItemSchema, p as CalendarResponseSchema, pt as VideoResponseSchema, q as SearchPropertiesResponseSchema, r as V0OpenApiClient, rt as TravelInsuranceBookingSchema, s as V1OpenApiClient, st as UnitListResponseSchema, t as createWebsiteSDK, tt as TileSchema, u as makeV1OpenApiClientLive, ut as UnitServicePriceSchema, v as DocumentResourceSchema, vt as clearAdditionalServicesEffect, w as ErgoBankSchema, wt as getTermsAndPrivacyPolicyEffect, x as DocumentSummarySchema, xt as getInitialAvailabilityEffect, y as DocumentStatusSchema, yt as createInsurancePreContractEffect, z as QuotePricesPayloadSchema } from "./client-BORwUo4_.mjs";
2
2
  import { AdditionalServiceLimitExceeded, CoreSDKError, CoreSDKError as CMSError, GuestQuoteSchema, InvalidAdditionalServiceQuantity, LocaleSchema, SearchSearchInputSchema, SearchSearchOutputSchema, UnknownAdditionalService, validateContactSubmitInput } from "@v-office/sdk-core";
3
3
  //#region codegen/v9/heuristic-generation/public-api.ts
4
4
  const customDataAttribute = (name) => name;
@@ -91,6 +91,7 @@ type WebsiteSDKOptions = {
91
91
  rentalHighlightPrioritization?: readonly RentalHighlightPrioritizationKey[];
92
92
  rentalPropertyHighlightPrioritization?: readonly RentalPropertyHighlightPrioritizationKey[];
93
93
  rentalScope?: RentalScope;
94
+ shouldAddProposedAdditionalServiceAmount?: boolean;
94
95
  };
95
96
  ```
96
97
 
@@ -100,6 +101,7 @@ Unset options are normalized by the SDK:
100
101
  - `rentalHighlightPrioritization` defaults to the SDK default rental highlight order.
101
102
  - `rentalPropertyHighlightPrioritization` defaults to the SDK default property highlight order.
102
103
  - `rentalScope` defaults to `{}`.
104
+ - `shouldAddProposedAdditionalServiceAmount` defaults to `false`.
103
105
  - `translationOverrides` is omitted unless provided.
104
106
 
105
107
  ## Rental Scope
@@ -165,11 +165,14 @@ Additional services are exposed on an available quote as `quote.additionalServic
165
165
  "label": "Bed linen",
166
166
  "charge": "25.00 EUR",
167
167
  "available": true,
168
+ "proposedQuantity": 1,
168
169
  "maxPerBooking": 1,
169
170
  "description": "Bed linen package"
170
171
  }
171
172
  ```
172
173
 
174
+ When the backend provides a line amount for an optional service, it is exposed as `proposedQuantity` (including `0`). By default this is informational only and is not added to the quote. Set `shouldAddProposedAdditionalServiceAmount: true` in `WebsiteSDKOptions` to automatically select proposed quantities greater than zero when the quote is created.
175
+
173
176
  Use the service `id` to add or remove a service selection:
174
177
 
175
178
  ```ts
@@ -314,6 +317,8 @@ const insuranceBooking = await sdk.live.quote.bookInsurance({
314
317
 
315
318
  Quote requests are rate-limited to one backend request per second with a queue size of five. `v9` supports insurance option refresh and insurance actions; `v10` currently returns a no-insurance placeholder and insurance actions resolve as not required.
316
319
 
320
+ `shouldAddProposedAdditionalServiceAmount` defaults to `false`. When `true`, proposed optional service quantities greater than zero are automatically selected on quote creation. `proposedQuantity` is returned whenever the backend provides a line amount (including `0`), regardless of this setting.
321
+
317
322
  ## CLI Usage
318
323
 
319
324
  Create `quote-input.json` with a `QuoteQuoteInput` object, then run:
@@ -69,15 +69,10 @@ Sample item:
69
69
  "reviews": {
70
70
  "items": [
71
71
  {
72
- "id": "rating-answer-1",
72
+ "id": "form-response-1",
73
+ "author": "Ada Lovelace, visited in July 2026",
73
74
  "rating": "5",
74
- "label": "Overall satisfaction",
75
- "createdAt": "2026-07-10T10:00:00.000Z"
76
- },
77
- {
78
- "id": "text-answer-1",
79
- "label": "Personal feedback",
80
- "createdAt": "2026-07-10T10:00:01.000Z",
75
+ "createdAt": "2026-07-10T10:00:00.000Z",
81
76
  "text": "Great stay."
82
77
  }
83
78
  ],
@@ -116,9 +111,9 @@ type RentalReview =
116
111
  };
117
112
  ```
118
113
 
119
- For v10, public `STARS` and `TEXT` answers may be returned as separate items because the backend does not always expose a reliable relationship between them. Do not assign a rating-only item to a text-only item. Missing public customer data leaves `author` undefined.
114
+ For v10, public answers with the same form-response ID are combined into one review item. Its `rating` is the average of the valid `STARS` answers in that response, and its `text` contains the non-empty `TEXT` answers. Missing public customer data leaves `author` undefined.
120
115
 
121
- `createdAt` is the feedback answer's creation timestamp, not a travel date. A text-only rental can have `reviews.items` without `reviews.summary`, so check the summary independently. The localized `summary.count` describes aggregated rating answers and does not necessarily equal `items.length`.
116
+ `createdAt` is the form response's creation timestamp, not a travel date. A text-only rental can have `reviews.items` without `reviews.summary`, so check the summary independently. The localized `summary.count` describes form responses with valid ratings and does not necessarily equal `items.length`.
122
117
 
123
118
  ## Configuration
124
119
 
@@ -22,13 +22,13 @@ const toCharge = ({ serviceLine, chargeAmount, currency, locale, translations })
22
22
  //#endregion
23
23
  //#region src/legacy-v9/parser/quote/to-charge-amount.ts
24
24
  const toChargeAmount = ({ input, serviceLine }) => {
25
- const amount = serviceLine.amount ?? 1;
26
- if (amount <= 0 || serviceLine.total == null) return void 0;
25
+ if (serviceLine.total == null) return void 0;
26
+ const quantity = serviceLine.amount != null && serviceLine.amount > 0 ? serviceLine.amount : 1;
27
27
  switch (serviceLine.calculation) {
28
- case "NIGHT": return serviceLine.total / toNightCount(input.period) / amount;
29
- case "DAY": return serviceLine.total / toNightCount(input.period) / amount;
30
- case "USAGE": return serviceLine.total / amount;
31
- default: return serviceLine.total / amount;
28
+ case "NIGHT": return serviceLine.total / toNightCount(input.period) / quantity;
29
+ case "DAY": return serviceLine.total / toNightCount(input.period) / quantity;
30
+ case "USAGE": return serviceLine.total / quantity;
31
+ default: return serviceLine.total / quantity;
32
32
  }
33
33
  };
34
34
  //#endregion
@@ -67,6 +67,7 @@ const toImages = (line) => {
67
67
  return images.length === 0 ? void 0 : images;
68
68
  };
69
69
  const toPositiveQuantity = (value) => value == null || value <= 0 ? void 0 : value;
70
+ const toNonNegativeQuantity = (value) => value == null || value < 0 ? void 0 : value;
70
71
  const toAdditionalServices = ({ input, guestQuoteResult, locale, translations }) => Effect.gen(function* () {
71
72
  const additionalServices = [];
72
73
  const currency = guestQuoteResult?.currency ?? "EUR";
@@ -99,8 +100,8 @@ const toAdditionalServices = ({ input, guestQuoteResult, locale, translations })
99
100
  translations
100
101
  });
101
102
  const maxPerBooking = toPositiveQuantity(limit?.maxPerBooking);
102
- const lineAmount = toPositiveQuantity(line.amount);
103
- const preSelectedQuantity = lineAmount === void 0 ? void 0 : Math.min(lineAmount, maxPerBooking ?? lineAmount);
103
+ const lineAmount = toNonNegativeQuantity(line.amount);
104
+ const proposedQuantity = lineAmount === void 0 ? void 0 : Math.min(lineAmount, maxPerBooking ?? lineAmount);
104
105
  const description = toDescription(line);
105
106
  const images = toImages(line);
106
107
  additionalServices.push({
@@ -109,7 +110,7 @@ const toAdditionalServices = ({ input, guestQuoteResult, locale, translations })
109
110
  charge,
110
111
  chargeAmount,
111
112
  calculation: toAdditionalServiceCalculation(line),
112
- ...preSelectedQuantity === void 0 ? {} : { preSelectedQuantity },
113
+ ...proposedQuantity === void 0 ? {} : { proposedQuantity },
113
114
  ...maxPerBooking === void 0 ? {} : { maxPerBooking },
114
115
  ...leadTimeDays === void 0 ? {} : { leadTimeDays },
115
116
  ...description === void 0 ? {} : { description },
@@ -281,7 +282,7 @@ const toVoucher = ({ input, locale, translations }) => Effect.gen(function* () {
281
282
  message: yield* translations.translate(locale, "quote.voucher.unknown", "The backend did not confirm whether the voucher code was applied.")
282
283
  };
283
284
  });
284
- const toGuestQuote = (input, guestQuoteResult, locale, translations) => Effect.gen(function* () {
285
+ const toGuestQuote = (input, guestQuoteResult, locale, translations, options) => Effect.gen(function* () {
285
286
  const errorReason = toErrorReason(guestQuoteResult);
286
287
  if (errorReason !== void 0) return {
287
288
  status: "unavailable",
@@ -319,9 +320,9 @@ const toGuestQuote = (input, guestQuoteResult, locale, translations) => Effect.g
319
320
  backendContext: toV9QuoteBackendContext(input, guestQuoteResult),
320
321
  updateBackendContext: updateV9QuoteBackendContext
321
322
  });
322
- for (const additionalService of additionalServices) {
323
- if (additionalService.preSelectedQuantity === void 0) continue;
324
- for (let quantity = 0; quantity < additionalService.preSelectedQuantity; quantity++) {
323
+ if (options?.shouldAddProposedAdditionalServiceAmount === true) for (const additionalService of additionalServices) {
324
+ if (additionalService.proposedQuantity === void 0 || additionalService.proposedQuantity <= 0) continue;
325
+ for (let quantity = 0; quantity < additionalService.proposedQuantity; quantity++) {
325
326
  const result = addGuestQuoteAdditionalServiceSelection({
326
327
  quote: guestQuote,
327
328
  id: additionalService.id
@@ -1,4 +1,4 @@
1
- import { n as stable_filters_default } from "./client-DcBxVHpl.mjs";
1
+ import { n as stable_filters_default } from "./client-BORwUo4_.mjs";
2
2
  import { a as searchQuery, c as VofficeUnitDataFieldSchemas, m as parseVofficeUnitData, n as toImages, r as toAddress, t as toRentalHighlights } from "./to-rental-highlights-CxWlq76f.mjs";
3
3
  import { CoreSDKError, STABLE_SEARCH_INPUTS, collectQueryParameters, daysBetweenLocalDates, expandCustomAttributeFilterCompositions, parseChildrenAges, parseOccupancyCount, parseQueryParameters, toCustomAttributeFilterLabel, toFormattedSearchPrice, toIsoDateFromPeriodQueryDate, toQueryString, toStableSearchInputBackendQueryKeys, toStableSearchInputParameterValues, toStableSearchInputQueryKeys, toUnusedFilterKeys } from "@v-office/sdk-core";
4
4
  import { Effect } from "effect";
@@ -91,6 +91,7 @@ type WebsiteSDKOptions = {
91
91
  rentalHighlightPrioritization?: readonly RentalHighlightPrioritizationKey[];
92
92
  rentalPropertyHighlightPrioritization?: readonly RentalPropertyHighlightPrioritizationKey[];
93
93
  rentalScope?: RentalScope;
94
+ shouldAddProposedAdditionalServiceAmount?: boolean;
94
95
  };
95
96
  ```
96
97
 
@@ -100,6 +101,7 @@ Unset options are normalized by the SDK:
100
101
  - `rentalHighlightPrioritization` defaults to the SDK default rental highlight order.
101
102
  - `rentalPropertyHighlightPrioritization` defaults to the SDK default property highlight order.
102
103
  - `rentalScope` defaults to `{}`.
104
+ - `shouldAddProposedAdditionalServiceAmount` defaults to `false`.
103
105
  - `translationOverrides` is omitted unless provided.
104
106
 
105
107
  ## Rental Scope
@@ -165,11 +165,14 @@ Additional services are exposed on an available quote as `quote.additionalServic
165
165
  "label": "Bed linen",
166
166
  "charge": "25.00 EUR",
167
167
  "available": true,
168
+ "proposedQuantity": 1,
168
169
  "maxPerBooking": 1,
169
170
  "description": "Bed linen package"
170
171
  }
171
172
  ```
172
173
 
174
+ When the backend provides a line amount for an optional service, it is exposed as `proposedQuantity` (including `0`). By default this is informational only and is not added to the quote. Set `shouldAddProposedAdditionalServiceAmount: true` in `WebsiteSDKOptions` to automatically select proposed quantities greater than zero when the quote is created.
175
+
173
176
  Use the service `id` to add or remove a service selection:
174
177
 
175
178
  ```ts
@@ -314,6 +317,8 @@ const insuranceBooking = await sdk.live.quote.bookInsurance({
314
317
 
315
318
  Quote requests are rate-limited to one backend request per second with a queue size of five. `v9` supports insurance option refresh and insurance actions; `v10` currently returns a no-insurance placeholder and insurance actions resolve as not required.
316
319
 
320
+ `shouldAddProposedAdditionalServiceAmount` defaults to `false`. When `true`, proposed optional service quantities greater than zero are automatically selected on quote creation. `proposedQuantity` is returned whenever the backend provides a line amount (including `0`), regardless of this setting.
321
+
317
322
  ## CLI Usage
318
323
 
319
324
  Create `quote-input.json` with a `QuoteQuoteInput` object, then run:
@@ -69,15 +69,10 @@ Sample item:
69
69
  "reviews": {
70
70
  "items": [
71
71
  {
72
- "id": "rating-answer-1",
72
+ "id": "form-response-1",
73
+ "author": "Ada Lovelace, visited in July 2026",
73
74
  "rating": "5",
74
- "label": "Overall satisfaction",
75
- "createdAt": "2026-07-10T10:00:00.000Z"
76
- },
77
- {
78
- "id": "text-answer-1",
79
- "label": "Personal feedback",
80
- "createdAt": "2026-07-10T10:00:01.000Z",
75
+ "createdAt": "2026-07-10T10:00:00.000Z",
81
76
  "text": "Great stay."
82
77
  }
83
78
  ],
@@ -116,9 +111,9 @@ type RentalReview =
116
111
  };
117
112
  ```
118
113
 
119
- For v10, public `STARS` and `TEXT` answers may be returned as separate items because the backend does not always expose a reliable relationship between them. Do not assign a rating-only item to a text-only item. Missing public customer data leaves `author` undefined.
114
+ For v10, public answers with the same form-response ID are combined into one review item. Its `rating` is the average of the valid `STARS` answers in that response, and its `text` contains the non-empty `TEXT` answers. Missing public customer data leaves `author` undefined.
120
115
 
121
- `createdAt` is the feedback answer's creation timestamp, not a travel date. A text-only rental can have `reviews.items` without `reviews.summary`, so check the summary independently. The localized `summary.count` describes aggregated rating answers and does not necessarily equal `items.length`.
116
+ `createdAt` is the form response's creation timestamp, not a travel date. A text-only rental can have `reviews.items` without `reviews.summary`, so check the summary independently. The localized `summary.count` describes form responses with valid ratings and does not necessarily equal `items.length`.
122
117
 
123
118
  ## Configuration
124
119
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v-office/website-sdk",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "Website-facing SDK facade backed by @v-office/sdk-core",
5
5
  "bin": {
6
6
  "website-sdk": "./dist/cli.mjs"
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@graphql-typed-document-node/core": "3.2.0",
44
- "@v-office/sdk-core": "^1.5.0",
44
+ "@v-office/sdk-core": "^1.5.2",
45
45
  "effect": "4.0.0-beta.85",
46
46
  "graphql": "16.14.2",
47
47
  "yaml": "^2.9.0"