@v-office/website-sdk 2.11.0 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +6 -1
  2. package/dist/capabilities/search.d.mts +2 -0
  3. package/dist/capabilities/search.mjs +2 -0
  4. package/dist/cli.d.mts +1 -1
  5. package/dist/cli.mjs +2 -2
  6. package/dist/{client-DYAHnU5F.mjs → client-Ma0daa2H.mjs} +140 -68
  7. package/dist/index.d.mts +569 -344
  8. package/dist/index.mjs +1 -1
  9. package/dist/instructions/CHANGELOG.md +2 -0
  10. package/dist/instructions/MIGRATION.md +2 -0
  11. package/dist/instructions/README.md +12 -4
  12. package/dist/instructions/booking.md +56 -40
  13. package/dist/instructions/quote.md +100 -6
  14. package/dist/instructions/search.md +99 -12
  15. package/dist/instructions/versions/2.12.0/CHANGELOG.md +56 -0
  16. package/dist/instructions/versions/2.12.0/MIGRATION.md +194 -0
  17. package/dist/instructions/versions/2.13.0/CHANGELOG.md +87 -0
  18. package/dist/instructions/versions/2.13.0/MIGRATION.md +315 -0
  19. package/dist/instructions/versions/2.5.0/MIGRATION.md +3 -0
  20. package/dist/{quote-Cs6jGoRS.mjs → quote-Qy_affum.mjs} +4 -4
  21. package/dist/{rentals-CFod9H4m.mjs → rentals-BG1diZoo.mjs} +7 -4
  22. package/dist/{search-QlZrI7ue.mjs → search-Byi6XboR.mjs} +39 -19
  23. package/dist/{to-rental-highlights-B6a_fi0j.mjs → to-rental-highlights-BVikT4Iz.mjs} +4 -2
  24. package/dist/translations/shared/de-DE/booking.json +7 -0
  25. package/dist/translations/shared/en-US/booking.json +7 -0
  26. package/instructions/CHANGELOG.md +2 -0
  27. package/instructions/MIGRATION.md +2 -0
  28. package/instructions/README.md +12 -4
  29. package/instructions/booking.md +56 -40
  30. package/instructions/quote.md +100 -6
  31. package/instructions/search.md +99 -12
  32. package/instructions/versions/2.12.0/CHANGELOG.md +56 -0
  33. package/instructions/versions/2.12.0/MIGRATION.md +194 -0
  34. package/instructions/versions/2.13.0/CHANGELOG.md +87 -0
  35. package/instructions/versions/2.13.0/MIGRATION.md +315 -0
  36. package/instructions/versions/2.5.0/MIGRATION.md +3 -0
  37. package/package.json +16 -13
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Website-facing SDK facade for vOffice backends.
4
4
 
5
5
  The current SDK includes catalog-backed custom attributes, backend-aware search,
6
- and localized v10 REST search discount details.
6
+ localized search discount details, and quote booking-card modifier output.
7
7
  See `instructions/CHANGELOG.md` for the complete release history.
8
8
 
9
9
  ## Install
@@ -81,6 +81,11 @@ sdk.live.contact.submit(input);
81
81
  await sdk.dispose();
82
82
  ```
83
83
 
84
+ Both backends support fixed `start`/`end` search periods. Flexible-period query
85
+ keys (`month`, `dates`, `nights`, and `weekend`) are v10-only and are rejected
86
+ before transport by the v9 facade. An empty v9 query browses the scoped searchable
87
+ inventory without requiring a dummy occupancy value.
88
+
84
89
  Quote mutation helpers are available under `sdk.live.quote`:
85
90
 
86
91
  - `addAdditionalService`
@@ -0,0 +1,2 @@
1
+ import { BackendKind, SearchPeriodQueryKey, getSupportedPeriodQueryKeys, supportsFlexiblePeriodSearch } from "@v-office/sdk-core/capabilities/search";
2
+ export { type BackendKind, type SearchPeriodQueryKey, getSupportedPeriodQueryKeys, supportsFlexiblePeriodSearch };
@@ -0,0 +1,2 @@
1
+ import { getSupportedPeriodQueryKeys, supportsFlexiblePeriodSearch } from "@v-office/sdk-core/capabilities/search";
2
+ export { getSupportedPeriodQueryKeys, supportsFlexiblePeriodSearch };
package/dist/cli.d.mts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as createWebsiteSDK, zt as defineWebsiteSDKOptions } from "./client-DYAHnU5F.mjs";
2
+ import { t as createWebsiteSDK, zt as defineWebsiteSDKOptions } from "./client-Ma0daa2H.mjs";
3
3
  import { SearchSearchSortSchema, defineCustomAttributesFromUnknown } from "@v-office/sdk-core";
4
4
  import { Console, Effect, FileSystem, Layer, Option, Path, Schema, Stdio, Terminal } from "effect";
5
5
  import { Command, Flag } from "effect/unstable/cli";
@@ -16,7 +16,7 @@ var CLICheckFailed = class extends Error {
16
16
  const toCLIError = (message, cause) => cause instanceof Error ? new CLICheckFailed(`${message}: ${cause.message}`, { cause }) : new CLICheckFailed(message, { cause });
17
17
  //#endregion
18
18
  //#region package.json
19
- var version = "2.11.0";
19
+ var version = "2.13.0";
20
20
  //#endregion
21
21
  //#region src/cli/output.ts
22
22
  const toJson = (value) => Effect.try({
@@ -1,4 +1,4 @@
1
- import { AvailabilityService, BookingService, ContactService, CoreSDKError, DEFAULT_RENTAL_HIGHLIGHT_PRIORITIZATION, DEFAULT_RENTAL_PROPERTY_HIGHLIGHT_PRIORITIZATION, DocumentsService, EMPTY_CUSTOM_ATTRIBUTE_REGISTRY, FilterService, QuoteService, RentalService, SearchService, TranslationService, addGuestQuoteAdditionalServiceSelection, asArray, asRecord, assertNoNestedCustomAttributeFilterCompositions, assertNoReservedQueryKeys, assertUniqueCustomFilterQueryKeys, assertUniqueFilterQueryKeys, clearGuestQuoteAdditionalServiceSelections, collectQueryParameters, createCoreRuntime, expandCustomAttributeFilterCompositions, firstNumber, firstString, formatCurrency, formatLocalDate, getGuestQuoteBackendContext, getGuestQuoteInput, isDisplayableCustomAttribute, localeToLanguage, makeMinIntervalLimiter, makeTranslationLive, parseQueryParameters, refreshGuestQuoteInsurancePassthrough, removeGuestQuoteAdditionalServiceSelection, selectGuestQuoteCancellationPolicySelection, toCustomAttributeFilterLabel, toCustomAttributeFilterOutputItem, toCustomAttributeList, toInitialAvailabilityCalendarDays, toQueryString, toResolvedCustomAttributeCategoryTranslationKey, toStartDateSelectedCalendarDays, validateContactSubmitInput, withGuestQuoteInsurance, withGuestQuoteInsuranceRefresh } from "@v-office/sdk-core";
1
+ import { AvailabilityService, BookingBookOutput, BookingService, ContactService, CoreSDKError, DEFAULT_RENTAL_HIGHLIGHT_PRIORITIZATION, DEFAULT_RENTAL_PROPERTY_HIGHLIGHT_PRIORITIZATION, DocumentsService, EMPTY_CUSTOM_ATTRIBUTE_REGISTRY, FilterService, QuoteService, RentalService, SearchService, TranslationService, addGuestQuoteAdditionalServiceSelection, asArray, asRecord, assertNoNestedCustomAttributeFilterCompositions, assertNoReservedQueryKeys, assertUniqueCustomFilterQueryKeys, assertUniqueFilterQueryKeys, clearGuestQuoteAdditionalServiceSelections, collectQueryParameters, createCoreRuntime, expandCustomAttributeFilterCompositions, firstNumber, firstString, formatCurrency, formatLocalDate, getBookingBookGuestToken, getGuestQuoteBackendContext, getGuestQuoteInput, isDisplayableCustomAttribute, localeToLanguage, makeMinIntervalLimiter, makeTranslationLive, parseQueryParameters, refreshGuestQuoteInsurancePassthrough, removeGuestQuoteAdditionalServiceSelection, selectGuestQuoteCancellationPolicySelection, toCustomAttributeFilterLabel, toCustomAttributeFilterOutputItem, toCustomAttributeList, toInitialAvailabilityCalendarDays, toQueryString, toResolvedCustomAttributeCategoryTranslationKey, toStartDateSelectedCalendarDays, validateContactSubmitInput, withGuestQuoteInsurance, withGuestQuoteInsuranceRefresh } from "@v-office/sdk-core";
2
2
  import { Context, Data, DateTime, Effect, Layer, Schema } from "effect";
3
3
  import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
4
4
  import { print } from "graphql";
@@ -2448,14 +2448,16 @@ const makeV9AvailabilityApi = ({ config, options }) => {
2448
2448
  getInitialAvailability: (input) => Effect.runPromise(Effect.gen(function* () {
2449
2449
  const now = yield* DateTime.now;
2450
2450
  const availability = yield* loadAvailability(input);
2451
+ const firstCalculationDate = toFirstCalculationDate({
2452
+ availability,
2453
+ now
2454
+ });
2455
+ const availabilityRestrictionsByDate = toAvailabilityRestrictionsByDate({ availability });
2451
2456
  return {
2452
2457
  calendarDays: yield* toInitialAvailabilityCalendarDays({
2453
2458
  input,
2454
- firstCalculationDate: toFirstCalculationDate({
2455
- availability,
2456
- now
2457
- }),
2458
- availabilityRestrictionsByDate: toAvailabilityRestrictionsByDate({ availability }),
2459
+ firstCalculationDate,
2460
+ availabilityRestrictionsByDate,
2459
2461
  translations
2460
2462
  }),
2461
2463
  minPersons: null,
@@ -2466,13 +2468,15 @@ const makeV9AvailabilityApi = ({ config, options }) => {
2466
2468
  getStartDateSelectedAvailability: (input) => Effect.runPromise(Effect.gen(function* () {
2467
2469
  const now = yield* DateTime.now;
2468
2470
  const availability = yield* loadAvailability(input);
2471
+ const firstCalculationDate = toFirstCalculationDate({
2472
+ availability,
2473
+ now
2474
+ });
2475
+ const availabilityRestrictionsByDate = toAvailabilityRestrictionsByDate({ availability });
2469
2476
  return { calendarDays: yield* toStartDateSelectedCalendarDays({
2470
2477
  input,
2471
- firstCalculationDate: toFirstCalculationDate({
2472
- availability,
2473
- now
2474
- }),
2475
- availabilityRestrictionsByDate: toAvailabilityRestrictionsByDate({ availability }),
2478
+ firstCalculationDate,
2479
+ availabilityRestrictionsByDate,
2476
2480
  translations
2477
2481
  }) };
2478
2482
  }))
@@ -3554,7 +3558,8 @@ const toUrvInsuranceOptions = ({ locale, plans, resourceLabels }) => plans.flatM
3554
3558
  const getErgoPlans = (raw) => {
3555
3559
  const record = asRecord(raw);
3556
3560
  const body = asRecord(record.body);
3557
- const availablePlanEntries = asArray(asRecord(record.AvailablePlans ?? body.AvailablePlans).AvailablePlan);
3561
+ const availablePlans = asRecord(record.AvailablePlans ?? body.AvailablePlans);
3562
+ const availablePlanEntries = asArray(availablePlans.AvailablePlan);
3558
3563
  return [
3559
3564
  ...asArray(record.insurancePlans),
3560
3565
  ...asArray(body.insurancePlans),
@@ -3576,7 +3581,9 @@ const toSelectableErgoAvailablePlans = (plans) => {
3576
3581
  };
3577
3582
  const getErgoPlanPrice = (plan) => {
3578
3583
  const premium = asRecord(plan.premium);
3579
- const totalPremium = asRecord(asRecord(asRecord(plan.Quote).Services).TotalPremium);
3584
+ const quote = asRecord(plan.Quote);
3585
+ const services = asRecord(quote.Services);
3586
+ const totalPremium = asRecord(services.TotalPremium);
3580
3587
  const amount = firstNumber(premium.amount, totalPremium.Amount);
3581
3588
  const currency = firstString(premium.currency, totalPremium.CurrencyCode) ?? "EUR";
3582
3589
  const decimals = firstNumber(premium.decimals, totalPremium.DecimalPlaces) ?? 2;
@@ -3586,7 +3593,8 @@ const getErgoPlanPrice = (plan) => {
3586
3593
  };
3587
3594
  };
3588
3595
  const getErgoDocuments = ({ plan, infLabel }) => {
3589
- const urls = asArray(asRecord(plan.PlanDetail).DescriptionURL).flatMap((entry) => {
3596
+ const planDetail = asRecord(plan.PlanDetail);
3597
+ const urls = asArray(planDetail.DescriptionURL).flatMap((entry) => {
3590
3598
  const resource = asRecord(entry);
3591
3599
  const type = firstString(resource.Type);
3592
3600
  const url = firstString(resource._);
@@ -3598,7 +3606,9 @@ const getErgoDocuments = ({ plan, infLabel }) => {
3598
3606
  return urls.length === 0 ? void 0 : urls;
3599
3607
  };
3600
3608
  const getErgoInsuranceTypes = (plan) => {
3601
- return asArray(asRecord(asRecord(plan.Quote).InsuranceTypes).InsuranceType).flatMap((entry) => {
3609
+ const quote = asRecord(plan.Quote);
3610
+ const insuranceTypes = asRecord(quote.InsuranceTypes);
3611
+ return asArray(insuranceTypes.InsuranceType).flatMap((entry) => {
3602
3612
  const insuranceType = asRecord(entry);
3603
3613
  const code = firstString(insuranceType.Code, insuranceType.Title);
3604
3614
  return code === void 0 ? [] : [code];
@@ -3607,7 +3617,11 @@ const getErgoInsuranceTypes = (plan) => {
3607
3617
  const isErgoPlanWithoutDeductible = (plan) => {
3608
3618
  const planCode = firstString(plan.plan_code, plan.PlanCode, plan.tariff_code);
3609
3619
  const planDetail = asRecord(plan.PlanDetail);
3610
- const tariffDescription = asRecord(asRecord(asRecord(asArray(asRecord(asRecord(plan.Quote).Services).Service)[0]).Tariff).TariffDescription);
3620
+ const quote = asRecord(plan.Quote);
3621
+ const services = asRecord(quote.Services);
3622
+ const service = asRecord(asArray(services.Service)[0]);
3623
+ const tariff = asRecord(service.Tariff);
3624
+ const tariffDescription = asRecord(tariff.TariffDescription);
3611
3625
  const titles = [firstString(plan.name, planDetail.Title), firstString(tariffDescription.Title)].filter((title) => title !== void 0);
3612
3626
  return planCode?.endsWith("O") === true || titles.some((title) => /\(ohne SB\)|ohne Selbstbeteiligung/i.test(title));
3613
3627
  };
@@ -3636,7 +3650,8 @@ const toInsuranceDocuments = (value) => {
3636
3650
  const getErgoPreContractDocuments = (raw) => {
3637
3651
  const record = asRecord(raw);
3638
3652
  const body = asRecord(record.body);
3639
- return toInsuranceDocuments(asArray(asRecord(record.PreContractualInformationServices ?? body.PreContractualInformationServices).PreContractualInformationService).flatMap((service) => asArray(asRecord(service).PreContractualInformation)));
3653
+ const services = asRecord(record.PreContractualInformationServices ?? body.PreContractualInformationServices);
3654
+ return toInsuranceDocuments(asArray(services.PreContractualInformationService).flatMap((service) => asArray(asRecord(service).PreContractualInformation)));
3640
3655
  };
3641
3656
  const toErgoInsuranceOptions = ({ featureLabels, infResourceLabel, locale, raw }) => getErgoPlans(raw).flatMap((entry) => {
3642
3657
  const plan = asRecord(entry);
@@ -3821,7 +3836,7 @@ const toTotalPriceAmount = ({ fullAmount, prepaymentAmount, prepaymentPercent, r
3821
3836
  if (fullAmount !== void 0 && prepaymentAmount !== void 0 && prepaymentPercent !== void 0 && prepaymentPercent > 0 && prepaymentPercent < 100) return fullAmount - (prepaymentAmount - fullAmount * (prepaymentPercent / 100)) / (1 - prepaymentPercent / 100);
3822
3837
  };
3823
3838
  const toDepositAmount = ({ fullAmount, totalPriceAmount }) => fullAmount === void 0 || totalPriceAmount === void 0 ? void 0 : fullAmount - totalPriceAmount;
3824
- const toScheduleOption = ({ currency, depositAmount, forceFullAmount, scheduleItem, scheduleKey, totalPriceAmount, quotePaymentSchedule }) => {
3839
+ const toScheduleOption = ({ currency, depositAmount, forceFullAmount, payableNow, scheduleItem, scheduleKey, totalPriceAmount, quotePaymentSchedule }) => {
3825
3840
  const amount = positiveNumber(scheduleItem.amount);
3826
3841
  if (amount === void 0) return void 0;
3827
3842
  const percent = toPercent(scheduleKey, quotePaymentSchedule);
@@ -3832,6 +3847,7 @@ const toScheduleOption = ({ currency, depositAmount, forceFullAmount, scheduleIt
3832
3847
  scheduleKey,
3833
3848
  amount,
3834
3849
  currency,
3850
+ payableNow,
3835
3851
  ...scheduleDepositAmount === void 0 ? {} : { depositAmount: scheduleDepositAmount },
3836
3852
  ...scheduleItem.date === void 0 ? {} : { dueOn: scheduleItem.date },
3837
3853
  ...includesDeposit === void 0 ? {} : { includesDeposit },
@@ -3840,19 +3856,21 @@ const toScheduleOption = ({ currency, depositAmount, forceFullAmount, scheduleIt
3840
3856
  ...forceFullAmount && totalPriceAmount !== void 0 ? { priceAmount: totalPriceAmount } : {}
3841
3857
  };
3842
3858
  };
3843
- const removeInstallmentDuplicates = (paymentScheduleOptions) => paymentScheduleOptions.filter((option) => option.kind === "full_amount" || !paymentScheduleOptions.some((candidate) => candidate.kind === "full_amount" && candidate.amount === option.amount && candidate.currency === option.currency));
3859
+ const removeInstallmentDuplicates = (paymentScheduleOptions) => paymentScheduleOptions.filter((option) => option.kind !== "full_amount" || !paymentScheduleOptions.some((candidate) => candidate.kind === "installment" && candidate.payableNow && candidate.amount === option.amount && candidate.currency === option.currency));
3844
3860
  const toPaymentScheduleOptions = ({ bookResponse, currency, quotePaymentSchedule }) => Effect.succeed((() => {
3845
3861
  const paymentSchedule = bookResponse.reservation?.paymentSchedule;
3846
3862
  if (paymentSchedule === void 0) return [];
3847
3863
  const prepaymentAmount = positiveNumber(paymentSchedule.prepayment?.amount);
3848
3864
  const restAmount = positiveNumber(paymentSchedule.rest?.amount);
3849
3865
  const fullAmount = positiveNumber(paymentSchedule.total?.amount) ?? (prepaymentAmount === void 0 || restAmount === void 0 ? void 0 : prepaymentAmount + restAmount);
3866
+ const prepaymentPercent = toPercent("prepayment", quotePaymentSchedule);
3867
+ const restPercent = toPercent("rest", quotePaymentSchedule);
3850
3868
  const totalPriceAmount = toTotalPriceAmount({
3851
3869
  fullAmount,
3852
3870
  prepaymentAmount,
3853
- prepaymentPercent: toPercent("prepayment", quotePaymentSchedule),
3871
+ prepaymentPercent,
3854
3872
  restAmount,
3855
- restPercent: toPercent("rest", quotePaymentSchedule)
3873
+ restPercent
3856
3874
  });
3857
3875
  const depositAmount = toDepositAmount({
3858
3876
  fullAmount,
@@ -3861,32 +3879,48 @@ const toPaymentScheduleOptions = ({ bookResponse, currency, quotePaymentSchedule
3861
3879
  const prepaymentOption = paymentSchedule.prepayment === void 0 ? void 0 : toScheduleOption({
3862
3880
  currency,
3863
3881
  depositAmount,
3882
+ payableNow: true,
3864
3883
  scheduleItem: paymentSchedule.prepayment,
3865
3884
  scheduleKey: "prepayment",
3866
3885
  totalPriceAmount,
3867
3886
  ...quotePaymentSchedule === void 0 ? {} : { quotePaymentSchedule }
3868
3887
  });
3888
+ const restOption = paymentSchedule.rest === void 0 ? void 0 : toScheduleOption({
3889
+ currency,
3890
+ depositAmount,
3891
+ payableNow: false,
3892
+ scheduleItem: paymentSchedule.rest,
3893
+ scheduleKey: "rest",
3894
+ totalPriceAmount,
3895
+ ...quotePaymentSchedule === void 0 ? {} : { quotePaymentSchedule }
3896
+ });
3869
3897
  const totalScheduleItem = paymentSchedule.total ?? (fullAmount === void 0 ? void 0 : {
3870
3898
  amount: fullAmount,
3871
- date: paymentSchedule.prepayment?.date ?? paymentSchedule.rest?.date,
3872
3899
  includesDeposit: true
3873
3900
  });
3874
- return removeInstallmentDuplicates([prepaymentOption, totalScheduleItem === void 0 ? void 0 : toScheduleOption({
3901
+ const totalOption = totalScheduleItem === void 0 ? void 0 : toScheduleOption({
3875
3902
  currency,
3876
3903
  depositAmount,
3877
3904
  forceFullAmount: true,
3905
+ payableNow: true,
3878
3906
  scheduleItem: totalScheduleItem,
3879
3907
  scheduleKey: "total",
3880
3908
  totalPriceAmount,
3881
3909
  ...quotePaymentSchedule === void 0 ? {} : { quotePaymentSchedule }
3882
- })].flatMap((option) => option === void 0 ? [] : [option]));
3910
+ });
3911
+ return removeInstallmentDuplicates([
3912
+ prepaymentOption,
3913
+ restOption,
3914
+ totalOption
3915
+ ].flatMap((option) => option === void 0 ? [] : [option]));
3883
3916
  })());
3884
3917
  //#endregion
3885
3918
  //#region src/legacy-v9/parser/booking/output/to-payment-schedules.ts
3886
3919
  const getDepositAmount = (bookResponse) => firstNumber(...(bookResponse.reservation?.bookings ?? []).map((booking) => booking.lines?.deposit?.amount));
3887
3920
  const getBookingTotal = (bookResponse) => firstNumber(bookResponse.reservation?.total);
3888
3921
  const toUrvInsurancePaymentOptions = (bookResponse, label) => {
3889
- const travelInsurance = asRecord(asRecord(asRecord(bookResponse).travelInsuranceResult).travelInsurance ?? asRecord(bookResponse).travelInsurance);
3922
+ const travelInsuranceResult = asRecord(asRecord(bookResponse).travelInsuranceResult);
3923
+ const travelInsurance = asRecord(travelInsuranceResult.travelInsurance ?? asRecord(bookResponse).travelInsurance);
3890
3924
  const url = firstString(travelInsurance.paymentUrl, travelInsurance.paymentURL, travelInsurance.paymenturl);
3891
3925
  return url === void 0 ? [] : [{
3892
3926
  kind: "external_url",
@@ -3993,14 +4027,17 @@ const toPaymentSchedules = ({ bookResponse, locale, paymentScheduleOptionWithStr
3993
4027
  const payInstallmentLabel = yield* translations.translate(locale, "booking.payment.schedule.installment.label");
3994
4028
  const payPrepaymentLabel = yield* translations.translate(locale, "booking.payment.schedule.prepayment.label");
3995
4029
  const payRestLabel = yield* translations.translate(locale, "booking.payment.schedule.rest.label");
4030
+ const dueOnLabel = yield* translations.translate(locale, "booking.payment.schedule.dueOn");
3996
4031
  const depositLabel = yield* translations.translate(locale, "booking.payment.schedule.deposit");
3997
4032
  const totalAmountLabel = yield* translations.translate(locale, "booking.payment.schedule.totalAmount");
3998
4033
  const remittanceTextLabel = yield* translations.translate(locale, "booking.payment.option.bankTransfer.remittanceText");
3999
- const bankTransferOption = toBankTransferOption(findPaymentMethod(bookResponse, "BANKACCOUNT"), bankTransferLabel, `${remittanceTextLabel} ${bookResponse.reservation?.nr ?? ""}`.trim(), firstString((bookResponse.reservation?.customer)?.showAs));
4034
+ const bankTransferOption = toBankTransferOption(findPaymentMethod(bookResponse, "BANKACCOUNT"), bankTransferLabel, `${remittanceTextLabel}: ${bookResponse.reservation?.nr ?? ""}`.trim(), firstString((bookResponse.reservation?.customer)?.showAs));
4000
4035
  const paypalPaymentMethod = findPaymentMethod(bookResponse, "PAYPAL");
4001
4036
  const v9BookingTotal = getBookingTotal(bookResponse) ?? quoteBookingTotal ?? deriveBookingTotal(paymentScheduleOptionWithStripeResults);
4002
4037
  const v9DepositAmount = getDepositAmount(bookResponse);
4003
- return paymentScheduleOptionWithStripeResults.map(({ paymentScheduleOption, stripeResult }) => {
4038
+ const schedule = [];
4039
+ const alternatives = [];
4040
+ for (const { paymentScheduleOption, stripeResult } of paymentScheduleOptionWithStripeResults) {
4004
4041
  const lines = toPaymentScheduleLines({
4005
4042
  depositLabel,
4006
4043
  locale,
@@ -4009,28 +4046,49 @@ const toPaymentSchedules = ({ bookResponse, locale, paymentScheduleOptionWithStr
4009
4046
  totalAmountLabel,
4010
4047
  v9BookingTotal
4011
4048
  });
4012
- return {
4013
- label: toPaymentScheduleLabel({
4014
- locale,
4015
- paymentScheduleOption,
4016
- payFullAmountLabel,
4017
- payInstallmentLabel,
4018
- payPrepaymentLabel,
4019
- payRestLabel
4020
- }),
4021
- ...paymentScheduleOption.dueOn === void 0 ? {} : { dueOn: formatLocalDate({
4022
- date: paymentScheduleOption.dueOn,
4023
- locale
4024
- }) },
4049
+ const label = toPaymentScheduleLabel({
4050
+ locale,
4051
+ paymentScheduleOption,
4052
+ payFullAmountLabel,
4053
+ payInstallmentLabel,
4054
+ payPrepaymentLabel,
4055
+ payRestLabel
4056
+ });
4057
+ const dueOn = paymentScheduleOption.dueOn === void 0 ? void 0 : `${dueOnLabel} ${formatLocalDate({
4058
+ date: paymentScheduleOption.dueOn,
4059
+ locale,
4060
+ style: "long"
4061
+ })}`;
4062
+ const availablePaymentOptions = [
4063
+ bankTransferOption,
4064
+ toPaypalOption(paypalPaymentMethod, paypalLabel, paymentScheduleOption),
4065
+ toStripeOption(stripeResult, stripeLabel)
4066
+ ].flatMap((paymentOption) => paymentOption === void 0 ? [] : [paymentOption]);
4067
+ const paymentOptions = paymentScheduleOption.payableNow && availablePaymentOptions.length > 0 ? availablePaymentOptions : void 0;
4068
+ if (paymentScheduleOption.kind === "full_amount") {
4069
+ alternatives.push({
4070
+ kind: "full_amount",
4071
+ label,
4072
+ amount: formatCurrency(paymentScheduleOption.amount, locale, paymentScheduleOption.currency),
4073
+ ...dueOn === void 0 ? {} : { dueOn },
4074
+ ...lines === void 0 || lines.length === 0 ? {} : { lines },
4075
+ paymentOptions: paymentOptions ?? []
4076
+ });
4077
+ continue;
4078
+ }
4079
+ schedule.push({
4080
+ kind: paymentScheduleOption.scheduleKey === "prepayment" ? "prepayment" : "remaining_payment",
4081
+ label,
4082
+ amount: formatCurrency(paymentScheduleOption.amount, locale, paymentScheduleOption.currency),
4083
+ ...dueOn === void 0 ? {} : { dueOn },
4025
4084
  ...lines === void 0 || lines.length === 0 ? {} : { lines },
4026
- total: formatCurrency(paymentScheduleOption.amount, locale, paymentScheduleOption.currency),
4027
- paymentOptions: [
4028
- bankTransferOption,
4029
- toPaypalOption(paypalPaymentMethod, paypalLabel, paymentScheduleOption),
4030
- toStripeOption(stripeResult, stripeLabel)
4031
- ].flatMap((paymentOption) => paymentOption === void 0 ? [] : [paymentOption])
4032
- };
4033
- });
4085
+ ...paymentOptions === void 0 ? {} : { paymentOptions }
4086
+ });
4087
+ }
4088
+ return {
4089
+ schedule,
4090
+ alternatives
4091
+ };
4034
4092
  });
4035
4093
  //#endregion
4036
4094
  //#region src/legacy-v9/parser/booking/output/to-stripe-payment-input.ts
@@ -4129,6 +4187,7 @@ const book = ({ client, input, translations }) => Effect.gen(function* () {
4129
4187
  const stripePaymentMethod = findPaymentMethod(bookResponse, "STRIPE");
4130
4188
  const stripePaymentKey = bookResponse.reservation.guestToken;
4131
4189
  const paymentScheduleOptionWithStripeResults = yield* Effect.all(paymentScheduleOptions.map((paymentScheduleOption) => Effect.gen(function* () {
4190
+ if (!paymentScheduleOption.payableNow) return { paymentScheduleOption };
4132
4191
  if (stripePaymentMethod === void 0) return { paymentScheduleOption };
4133
4192
  if (stripePaymentKey === void 0) return yield* Effect.fail(new CoreSDKError({
4134
4193
  source: "v10",
@@ -4166,7 +4225,7 @@ const book = ({ client, input, translations }) => Effect.gen(function* () {
4166
4225
  stripeResult: stripeResponse
4167
4226
  };
4168
4227
  })));
4169
- const paymentSchedules = yield* toPaymentSchedules({
4228
+ const payment = yield* toPaymentSchedules({
4170
4229
  bookResponse,
4171
4230
  locale: quoteInput.locale,
4172
4231
  paymentScheduleOptionWithStripeResults,
@@ -4183,12 +4242,12 @@ const book = ({ client, input, translations }) => Effect.gen(function* () {
4183
4242
  sepaDebitDescription: insuranceSepaDebitDescription,
4184
4243
  canBookInsurance: reservation.guestToken !== void 0
4185
4244
  });
4186
- return {
4245
+ return new BookingBookOutput({
4187
4246
  bookingNumber,
4188
- ...reservation.guestToken === void 0 ? {} : { guestToken: reservation.guestToken },
4189
- paymentSchedules,
4190
- insurancePaymentOptions: [...urvInsurancePaymentOptions, ...postBookingInsurancePaymentOptions]
4191
- };
4247
+ payment,
4248
+ insurancePaymentOptions: [...urvInsurancePaymentOptions, ...postBookingInsurancePaymentOptions],
4249
+ ...reservation.guestToken === void 0 ? {} : { guestToken: reservation.guestToken }
4250
+ });
4192
4251
  });
4193
4252
  const makeV9BookingApi = ({ config, options }) => {
4194
4253
  const translations = makeV9TranslationService(options.translationOverrides);
@@ -4206,8 +4265,9 @@ const makeV9BookingApi = ({ config, options }) => {
4206
4265
  })
4207
4266
  }));
4208
4267
  return { book: (input) => Effect.runPromise(Effect.gen(function* () {
4268
+ const client = yield* V0OpenApiClient;
4209
4269
  return yield* limitBooking(book({
4210
- client: yield* V0OpenApiClient,
4270
+ client,
4211
4271
  input,
4212
4272
  translations
4213
4273
  }));
@@ -4303,8 +4363,9 @@ const makeV9ContactApi = ({ config, options }) => {
4303
4363
  input,
4304
4364
  translations
4305
4365
  });
4366
+ const client = yield* V0OpenApiClient;
4306
4367
  return yield* limitContact(submit({
4307
- client: yield* V0OpenApiClient,
4368
+ client,
4308
4369
  input
4309
4370
  }));
4310
4371
  }).pipe(Effect.provide(openApiClientLive))) };
@@ -4564,7 +4625,8 @@ const refreshUrvInsuranceOptions = ({ quote, mode, translations, v0Client }) =>
4564
4625
  });
4565
4626
  });
4566
4627
  const refreshV9InsuranceOptions = ({ quote, destinationCountryCode, translations, v0Client, v1Client }) => Effect.gen(function* () {
4567
- const settings = toConfiguredInsuranceSettings((yield* v1Client.execute("getSetup", { query: { include: "booking,search,common" } }).pipe(Effect.mapError(toInsuranceError("Failed to load v9 insurance settings.")))).data.data);
4628
+ const setup = yield* v1Client.execute("getSetup", { query: { include: "booking,search,common" } }).pipe(Effect.mapError(toInsuranceError("Failed to load v9 insurance settings.")));
4629
+ const settings = toConfiguredInsuranceSettings(setup.data.data);
4568
4630
  switch (settings.provider) {
4569
4631
  case "ergo": return withInsurance(quote, yield* refreshErgoInsuranceOptions({
4570
4632
  quote,
@@ -4610,11 +4672,12 @@ const createV9InsurancePreContract = ({ quote, customerInformation, v1Client })
4610
4672
  customerInformation,
4611
4673
  preContract: { kind: "not_required" }
4612
4674
  });
4675
+ const travelers = yield* getErgoTravelers(quote);
4613
4676
  const body = {
4614
4677
  ...toErgoTripAndCustomerInput({
4615
4678
  quote,
4616
4679
  customerInformation,
4617
- travelers: yield* getErgoTravelers(quote)
4680
+ travelers
4618
4681
  }),
4619
4682
  plan_code: option.id
4620
4683
  };
@@ -4685,7 +4748,7 @@ const bookV9Insurance = ({ quote, bookingNumber, guestToken, v1Client }) => Effe
4685
4748
  //#region src/legacy-v9/live/quote.ts
4686
4749
  const loadQuoteRuntime = Effect.tryPromise({
4687
4750
  try: async () => {
4688
- return { toGuestQuote: (await import("./quote-Cs6jGoRS.mjs")).toGuestQuote };
4751
+ return { toGuestQuote: (await import("./quote-Qy_affum.mjs")).toGuestQuote };
4689
4752
  },
4690
4753
  catch: (cause) => new CoreSDKError({
4691
4754
  source: "v10",
@@ -4802,11 +4865,19 @@ const makeV9QuoteApi = ({ config, options }) => {
4802
4865
  v1Client
4803
4866
  })),
4804
4867
  selectInsurancePayment: (input) => withClients(() => selectV9InsurancePayment(input)),
4805
- bookInsurance: ({ quote, bookingNumber, guestToken }) => withClients(({ v1Client }) => bookV9Insurance({
4806
- quote,
4807
- bookingNumber,
4808
- guestToken,
4809
- v1Client
4868
+ bookInsurance: ({ quote, booking }) => withClients(({ v1Client }) => Effect.gen(function* () {
4869
+ const guestToken = getBookingBookGuestToken(booking);
4870
+ if (guestToken === void 0) return yield* Effect.fail(new CoreSDKError({
4871
+ source: "v9",
4872
+ operation: "v9.insurance",
4873
+ message: "The booking does not contain the private v9 guest token required to book insurance."
4874
+ }));
4875
+ return yield* bookV9Insurance({
4876
+ quote,
4877
+ bookingNumber: booking.bookingNumber,
4878
+ guestToken,
4879
+ v1Client
4880
+ });
4810
4881
  }))
4811
4882
  };
4812
4883
  };
@@ -4952,7 +5023,7 @@ const parseV9SearchCursor = (cursor) => Effect.gen(function* () {
4952
5023
  return page;
4953
5024
  });
4954
5025
  const loadV9SearchRuntime = Effect.tryPromise({
4955
- try: () => import("./search-QlZrI7ue.mjs"),
5026
+ try: () => import("./search-Byi6XboR.mjs"),
4956
5027
  catch: (cause) => new CoreSDKError({
4957
5028
  source: "v10",
4958
5029
  operation: "v9.search.runtime",
@@ -5315,7 +5386,7 @@ const DEFAULT_RENTAL_FEEDBACK_DATA_ATTRIBUTES = [
5315
5386
  "avgRating"
5316
5387
  ];
5317
5388
  const loadV9RentalsRuntime = Effect.tryPromise({
5318
- try: () => import("./rentals-CFod9H4m.mjs"),
5389
+ try: () => import("./rentals-BG1diZoo.mjs"),
5319
5390
  catch: (cause) => new CoreSDKError({
5320
5391
  source: "v10",
5321
5392
  operation: "v9.rentals.runtime",
@@ -5334,12 +5405,13 @@ const makeV9RentalsApi = ({ config, options }) => {
5334
5405
  ...config.rentalDataAttributes ?? [],
5335
5406
  ...toCustomAttributeRentalDataAttributes(options.customAttributes)
5336
5407
  ];
5337
- const scopedRentalsWithoutFeedbacks = filterV9RentalsByScope((yield* graphql.execute(rentalsAllWithoutFeedbacksQuery, {
5408
+ const rentalsData = yield* graphql.execute(rentalsAllWithoutFeedbacksQuery, {
5338
5409
  language,
5339
5410
  rentalDataAttributes,
5340
5411
  rentalFacilityDataAttributes: [...DEFAULT_RENTAL_FACILITY_DATA_ATTRIBUTES],
5341
5412
  rentalRatingDataAttributes: [...DEFAULT_RENTAL_RATING_DATA_ATTRIBUTES]
5342
- })).all, options.rentalScope);
5413
+ });
5414
+ const scopedRentalsWithoutFeedbacks = filterV9RentalsByScope(rentalsData.all, options.rentalScope);
5343
5415
  if (scopedRentalsWithoutFeedbacks.length === 0) return [];
5344
5416
  const feedbacksData = yield* graphql.execute(rentalsAllFeedbacksQuery, {
5345
5417
  language,