@v-office/website-sdk 2.16.3 → 2.17.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.
- package/dist/cli.mjs +2 -2
- package/dist/{client-CaZZGJAW.mjs → client-ScO68LGg.mjs} +40 -5
- package/dist/index.mjs +1 -1
- package/dist/instructions/CHANGELOG.md +1 -0
- package/dist/instructions/MIGRATION.md +1 -0
- package/dist/instructions/README.md +4 -2
- package/dist/instructions/availability.md +25 -0
- package/dist/instructions/rentals.md +41 -0
- package/dist/instructions/versions/2.17.0/CHANGELOG.md +83 -0
- package/dist/instructions/versions/2.17.0/MIGRATION.md +207 -0
- package/dist/{rentals--cnnFS4I.mjs → rentals-BokBV-ze.mjs} +54 -0
- package/dist/{search-Dqiou4mc.mjs → search-zsnAfUtc.mjs} +1 -1
- package/dist/translations/v10/de-DE/core.json +10 -0
- package/dist/translations/v10/en-US/core.json +10 -0
- package/instructions/CHANGELOG.md +1 -0
- package/instructions/MIGRATION.md +1 -0
- package/instructions/README.md +4 -2
- package/instructions/availability.md +25 -0
- package/instructions/rentals.md +41 -0
- package/instructions/versions/2.17.0/CHANGELOG.md +83 -0
- package/instructions/versions/2.17.0/MIGRATION.md +207 -0
- package/package.json +5 -4
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-
|
|
2
|
+
import { t as createWebsiteSDK, zt as defineWebsiteSDKOptions } from "./client-ScO68LGg.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.
|
|
19
|
+
var version = "2.17.0";
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/cli/output.ts
|
|
22
22
|
const toJson = (value) => Effect.try({
|
|
@@ -1370,6 +1370,25 @@ const toFirstCalculationDate = ({ availability, now }) => {
|
|
|
1370
1370
|
return [Object.keys(availability.caldata_beon).toSorted()[0], today].filter((date) => date != null).toSorted().at(-1);
|
|
1371
1371
|
};
|
|
1372
1372
|
//#endregion
|
|
1373
|
+
//#region src/legacy-v9/parser/availability/to-initial-availability-calendar-days.ts
|
|
1374
|
+
const applyV9CalendarPrices = ({ availability, calendarDays, locale, currency }) => {
|
|
1375
|
+
const result = { ...calendarDays };
|
|
1376
|
+
for (const [date, day] of Object.entries(calendarDays)) {
|
|
1377
|
+
const price = availability.caldata_beon[date]?.price;
|
|
1378
|
+
if (day.canBeStartDate && typeof price === "number" && currency !== void 0) result[date] = {
|
|
1379
|
+
...day,
|
|
1380
|
+
formattedPrice: formatCurrency(price, locale, currency)
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
return result;
|
|
1384
|
+
};
|
|
1385
|
+
const toInitialAvailabilityCalendarDays$1 = ({ availability, currency, ...input }) => toInitialAvailabilityCalendarDays(input).pipe(Effect.map((calendarDays) => applyV9CalendarPrices({
|
|
1386
|
+
availability,
|
|
1387
|
+
calendarDays,
|
|
1388
|
+
locale: input.input.locale,
|
|
1389
|
+
...currency === void 0 ? {} : { currency }
|
|
1390
|
+
})));
|
|
1391
|
+
//#endregion
|
|
1373
1392
|
//#region translations/v9/de-DE/core.json
|
|
1374
1393
|
var core_default$1 = {
|
|
1375
1394
|
"Rental.rentalType.option.HOUSE": "Haus",
|
|
@@ -2885,6 +2904,7 @@ const makeV9AvailabilityApi = ({ config, options }) => {
|
|
|
2885
2904
|
apiKey: config.apiKey,
|
|
2886
2905
|
...config.v1ApiBaseUrl === void 0 ? {} : { baseUrl: config.v1ApiBaseUrl }
|
|
2887
2906
|
});
|
|
2907
|
+
const bookingCurrencyByUnitId = /* @__PURE__ */ new Map();
|
|
2888
2908
|
const loadAvailability = (input) => Effect.gen(function* () {
|
|
2889
2909
|
const client = yield* V1OpenApiClient;
|
|
2890
2910
|
const unitId = yield* toVofficeUnitId$2(input);
|
|
@@ -2898,21 +2918,36 @@ const makeV9AvailabilityApi = ({ config, options }) => {
|
|
|
2898
2918
|
cause
|
|
2899
2919
|
})))).data;
|
|
2900
2920
|
}).pipe(Effect.provide(openApiClientLive));
|
|
2921
|
+
const loadBookingCurrency = (input) => Effect.gen(function* () {
|
|
2922
|
+
const client = yield* V1OpenApiClient;
|
|
2923
|
+
const unitId = yield* toVofficeUnitId$2(input);
|
|
2924
|
+
if (bookingCurrencyByUnitId.has(unitId)) return bookingCurrencyByUnitId.get(unitId);
|
|
2925
|
+
const result = yield* client.execute("getUnit", { path: { voffice_unit: unitId } }).pipe(Effect.match({
|
|
2926
|
+
onFailure: () => void 0,
|
|
2927
|
+
onSuccess: (result) => result
|
|
2928
|
+
}));
|
|
2929
|
+
if (result === void 0) return void 0;
|
|
2930
|
+
const currency = firstString(result.data.data.currency);
|
|
2931
|
+
bookingCurrencyByUnitId.set(unitId, currency);
|
|
2932
|
+
return currency;
|
|
2933
|
+
}).pipe(Effect.provide(openApiClientLive));
|
|
2901
2934
|
return {
|
|
2902
2935
|
getInitialAvailability: (input) => Effect.runPromise(Effect.gen(function* () {
|
|
2903
2936
|
const now = yield* DateTime.now;
|
|
2904
|
-
const availability = yield* loadAvailability(input);
|
|
2937
|
+
const [availability, currency] = yield* Effect.all([loadAvailability(input), loadBookingCurrency(input)]);
|
|
2905
2938
|
const firstCalculationDate = toFirstCalculationDate({
|
|
2906
2939
|
availability,
|
|
2907
2940
|
now
|
|
2908
2941
|
});
|
|
2909
2942
|
const availabilityRestrictionsByDate = toAvailabilityRestrictionsByDate({ availability });
|
|
2910
2943
|
return {
|
|
2911
|
-
calendarDays: yield* toInitialAvailabilityCalendarDays({
|
|
2944
|
+
calendarDays: yield* toInitialAvailabilityCalendarDays$1({
|
|
2945
|
+
availability,
|
|
2912
2946
|
input,
|
|
2913
2947
|
firstCalculationDate,
|
|
2914
2948
|
availabilityRestrictionsByDate,
|
|
2915
|
-
translations
|
|
2949
|
+
translations,
|
|
2950
|
+
...currency === void 0 ? {} : { currency }
|
|
2916
2951
|
}),
|
|
2917
2952
|
minPersons: null,
|
|
2918
2953
|
maxPersons: null,
|
|
@@ -5477,7 +5512,7 @@ const parseV9SearchCursor = (cursor) => Effect.gen(function* () {
|
|
|
5477
5512
|
return page;
|
|
5478
5513
|
});
|
|
5479
5514
|
const loadV9SearchRuntime = Effect.tryPromise({
|
|
5480
|
-
try: () => import("./search-
|
|
5515
|
+
try: () => import("./search-zsnAfUtc.mjs"),
|
|
5481
5516
|
catch: (cause) => new CoreSDKError({
|
|
5482
5517
|
source: "v10",
|
|
5483
5518
|
operation: "v9.search.runtime",
|
|
@@ -5844,7 +5879,7 @@ const DEFAULT_RENTAL_FEEDBACK_DATA_ATTRIBUTES = [
|
|
|
5844
5879
|
"avgRating"
|
|
5845
5880
|
];
|
|
5846
5881
|
const loadV9RentalsRuntime = Effect.tryPromise({
|
|
5847
|
-
try: () => import("./rentals
|
|
5882
|
+
try: () => import("./rentals-BokBV-ze.mjs"),
|
|
5848
5883
|
catch: (cause) => new CoreSDKError({
|
|
5849
5884
|
source: "v10",
|
|
5850
5885
|
operation: "v9.rentals.runtime",
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as ServiceBeonDataSchema, A as ErgoBookRequestSchema, At as quoteEffect, B as OnOfficeUnitSchema, C as DocumentResourceSchema, Ct as clearAdditionalServicesEffect, D as DocumentTypeSchema, Dt as getRentalsEffect, E as DocumentSummarySchema, Et as getInitialAvailabilityEffect, F as ErgoPolicyNumberRequestSchema, Ft as selectInsurancePaymentEffect, G as QuotePricesResponseSchema, H as PaymentScheduleSchema, I as ErgoReadPreContractRequestSchema, It as submitContactEffect, J as RawObjectResponseSchema, K as QuoteSchema, L as ErgoTripAndCustomerRequestSchema, Lt as submitPaymentOption, M as ErgoCreatePreContractRequestSchema, Mt as searchEffect, N as ErgoPersonSchema, Nt as selectCancellationPolicyEffect, O as ErgoAddressSchema, Ot as getStartDateSelectedAvailabilityEffect, P as ErgoPlanSearchRequestSchema, Pt as selectInsuranceEffect, Q as SearchPropertiesResponseSchema, R as FacilityListResponseSchema, Rt as submitPaymentOptionEffect, S as DocumentResourceResponseSchema, St as bookInsuranceEffect, T as DocumentStatusUpdateRequestSchema, Tt as getFiltersEffect, U as QuoteLineSchema, V as PaymentScheduleItemSchema, W as QuotePricesPayloadSchema, X as RegionListResponseSchema, Y as RawVofficeObjectSchema, Z as RoomImageSchema, _ as CalendarDaySchema, _t as V1_OPERATIONS, at as TileCollectionResponseSchema, b as CustomerUnitSummarySchema, bt as addAdditionalServiceEffect, c as V0OpenApiClient, ct as TravelInsuranceBookingSchema, d as makeV0OpenApiClientLive, dt as UnitListItemSchema, et as ServiceImageSchema, f as V1OpenApiClient, ft as UnitListResponseSchema, g as ApiEnvelopeBaseSchema, gt as V1_BASE_URL, h as makeV1OpenApiClientLive, ht as UnitServicePriceSchema, it as SetupResponseSchema, j as ErgoCommonFieldsSchema, jt as removeAdditionalServiceEffect, k as ErgoBankSchema, kt as getTermsAndPrivacyPolicyEffect, l as V0OpenApiClientError, lt as TravelInsuranceBookingStoreRequestSchema, m as makeV1OpenApiClientFetchLive, mt as UnitResponseSchema, nt as ServiceListResponseSchema, ot as TileSchema, p as V1OpenApiClientError, pt as UnitOfferSchema, q as QuoteServiceSchema, rt as SetupDataSchema, st as TileTagSchema, t as createWebsiteSDK, tt as ServiceLimitSchema, u as makeV0OpenApiClientFetchLive, ut as UnitIdsResponseSchema, v as CalendarResponseSchema, vt as VideoResponseSchema, w as DocumentStatusSchema, wt as createInsurancePreContractEffect, x as DocumentCollectionResponseSchema, xt as bookEffect, y as CurrentMemberResponseSchema, yt as decodeV1OperationResponse, z as OnOfficeUnitCollectionResponseSchema, zt as defineWebsiteSDKOptions } from "./client-
|
|
1
|
+
import { $ as ServiceBeonDataSchema, A as ErgoBookRequestSchema, At as quoteEffect, B as OnOfficeUnitSchema, C as DocumentResourceSchema, Ct as clearAdditionalServicesEffect, D as DocumentTypeSchema, Dt as getRentalsEffect, E as DocumentSummarySchema, Et as getInitialAvailabilityEffect, F as ErgoPolicyNumberRequestSchema, Ft as selectInsurancePaymentEffect, G as QuotePricesResponseSchema, H as PaymentScheduleSchema, I as ErgoReadPreContractRequestSchema, It as submitContactEffect, J as RawObjectResponseSchema, K as QuoteSchema, L as ErgoTripAndCustomerRequestSchema, Lt as submitPaymentOption, M as ErgoCreatePreContractRequestSchema, Mt as searchEffect, N as ErgoPersonSchema, Nt as selectCancellationPolicyEffect, O as ErgoAddressSchema, Ot as getStartDateSelectedAvailabilityEffect, P as ErgoPlanSearchRequestSchema, Pt as selectInsuranceEffect, Q as SearchPropertiesResponseSchema, R as FacilityListResponseSchema, Rt as submitPaymentOptionEffect, S as DocumentResourceResponseSchema, St as bookInsuranceEffect, T as DocumentStatusUpdateRequestSchema, Tt as getFiltersEffect, U as QuoteLineSchema, V as PaymentScheduleItemSchema, W as QuotePricesPayloadSchema, X as RegionListResponseSchema, Y as RawVofficeObjectSchema, Z as RoomImageSchema, _ as CalendarDaySchema, _t as V1_OPERATIONS, at as TileCollectionResponseSchema, b as CustomerUnitSummarySchema, bt as addAdditionalServiceEffect, c as V0OpenApiClient, ct as TravelInsuranceBookingSchema, d as makeV0OpenApiClientLive, dt as UnitListItemSchema, et as ServiceImageSchema, f as V1OpenApiClient, ft as UnitListResponseSchema, g as ApiEnvelopeBaseSchema, gt as V1_BASE_URL, h as makeV1OpenApiClientLive, ht as UnitServicePriceSchema, it as SetupResponseSchema, j as ErgoCommonFieldsSchema, jt as removeAdditionalServiceEffect, k as ErgoBankSchema, kt as getTermsAndPrivacyPolicyEffect, l as V0OpenApiClientError, lt as TravelInsuranceBookingStoreRequestSchema, m as makeV1OpenApiClientFetchLive, mt as UnitResponseSchema, nt as ServiceListResponseSchema, ot as TileSchema, p as V1OpenApiClientError, pt as UnitOfferSchema, q as QuoteServiceSchema, rt as SetupDataSchema, st as TileTagSchema, t as createWebsiteSDK, tt as ServiceLimitSchema, u as makeV0OpenApiClientFetchLive, ut as UnitIdsResponseSchema, v as CalendarResponseSchema, vt as VideoResponseSchema, w as DocumentStatusSchema, wt as createInsurancePreContractEffect, x as DocumentCollectionResponseSchema, xt as bookEffect, y as CurrentMemberResponseSchema, yt as decodeV1OperationResponse, z as OnOfficeUnitCollectionResponseSchema, zt as defineWebsiteSDKOptions } from "./client-ScO68LGg.mjs";
|
|
2
2
|
import { AdditionalServiceLimitExceeded, CoreSDKError, CoreSDKError as CMSError, CustomAttributeCatalogSchema, GuestQuoteSchema, InvalidAdditionalServiceQuantity, LocaleSchema, SearchSearchFieldOrderBySchema, SearchSearchFieldSortSchema, SearchSearchInputSchema, SearchSearchOutputSchema, SearchSearchPriceSortSchema, SearchSearchRandomSortSchema, SearchSearchRatingSortSchema, SearchSearchSortSchema, SearchSortDirectionSchema, UnknownAdditionalService, defineCustomAttributes, defineCustomAttributesFromUnknown, fetchCustomAttributeCatalog, parseCustomAttributeCatalog, validateContactSubmitInput } from "@v-office/sdk-core";
|
|
3
3
|
//#region codegen/v9/heuristic-generation/public-api.ts
|
|
4
4
|
const customDataAttribute = (name) => name;
|
|
@@ -4,6 +4,7 @@ This file is the versioned changelog index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Versions
|
|
6
6
|
|
|
7
|
+
- `versions/2.17.0/CHANGELOG.md`: `@v-office/website-sdk` 2.17.0 release notes.
|
|
7
8
|
- `versions/2.16.3/CHANGELOG.md`: `@v-office/website-sdk` 2.16.3 release notes.
|
|
8
9
|
- `versions/2.16.2/CHANGELOG.md`: `@v-office/website-sdk` 2.16.2 documentation release notes.
|
|
9
10
|
- `versions/2.16.1/CHANGELOG.md`: `@v-office/website-sdk` 2.16.1 release notes.
|
|
@@ -4,6 +4,7 @@ This file is the versioned migration index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Available Guides
|
|
6
6
|
|
|
7
|
+
- `versions/2.17.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.3 to 2.17.0.
|
|
7
8
|
- `versions/2.16.3/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.2 to 2.16.3.
|
|
8
9
|
- `versions/2.16.2/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.1 to 2.16.2.
|
|
9
10
|
- `versions/2.16.1/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.0 to 2.16.1.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Website SDK Instructions
|
|
2
2
|
|
|
3
3
|
These instructions describe the current source targeted for
|
|
4
|
-
`@v-office/website-sdk` 2.
|
|
4
|
+
`@v-office/website-sdk` 2.17.0. Package versions remain unchanged until the release
|
|
5
5
|
workflow performs the coordinated core and website bumps.
|
|
6
6
|
|
|
7
7
|
Use this directory as the consumer-facing reference for the package:
|
|
@@ -18,6 +18,8 @@ Use this directory as the consumer-facing reference for the package:
|
|
|
18
18
|
- `document-structured-json.md`: `sdk.static.documents.getTermsAndPrivacyPolicy` and structured document JSON rendering rules.
|
|
19
19
|
- `CHANGELOG.md`: versioned changelog index.
|
|
20
20
|
- `MIGRATION.md`: versioned migration index.
|
|
21
|
+
- `versions/2.17.0/`: 2.17.0 legacy-v9 calendar-day prices and structured
|
|
22
|
+
rooms, shared bed-amount expansion, and the 2.16.3-to-2.17.0 migration guide.
|
|
21
23
|
- `versions/2.16.3/`: 2.16.3 browser-origin resolution for relative payment
|
|
22
24
|
return URLs and the 2.16.2-to-2.16.3 migration guide.
|
|
23
25
|
- `versions/2.16.2/`: 2.16.2 documentation release notes and migration guide.
|
|
@@ -102,5 +104,5 @@ website-sdk --backend v10 search --locale de-DE --query "adults=2" --sort '{"by"
|
|
|
102
104
|
```
|
|
103
105
|
|
|
104
106
|
Config file examples in these docs use the flat `WebsiteSDKConfig` shape introduced
|
|
105
|
-
in 2.0.0 and kept in 2.
|
|
107
|
+
in 2.0.0 and kept in 2.17.0. v10 config additionally requires `searchEndpoint` as
|
|
106
108
|
of 2.5.0.
|
|
@@ -96,6 +96,31 @@ Start-date-selected availability returns `Promise<StartDateSelectedAvailabilityO
|
|
|
96
96
|
|
|
97
97
|
Common statuses include `available`, `before_today`, `check_in_not_allowed`, `no_valid_check_out_from_start`, `after_last_bookable_date`, and `unavailable`. End-date results can also return `same_day`, `not_after_selected_start`, `minimum_stay_not_met`, `check_out_not_allowed`, and range-crossing statuses.
|
|
98
98
|
|
|
99
|
+
### Legacy v9 Calendar-Day Prices
|
|
100
|
+
|
|
101
|
+
From 2.17.0, v9 initial availability uses the numeric price supplied by the v1
|
|
102
|
+
calendar to populate `formattedPrice` on valid start dates. The value is already
|
|
103
|
+
localized and formatted in the rental unit's configured booking currency.
|
|
104
|
+
Render it directly rather than parsing or reformatting it.
|
|
105
|
+
|
|
106
|
+
`formattedPrice` remains `null` when the date cannot be used as a start date,
|
|
107
|
+
the date is unavailable, the v1 calendar supplies no numeric price, or the
|
|
108
|
+
unit's currency cannot be loaded. Start-date-selected availability does not
|
|
109
|
+
include calendar prices.
|
|
110
|
+
|
|
111
|
+
When no successful unit lookup is cached, a v9 initial-availability request loads
|
|
112
|
+
the calendar and a unit record. Successful unit responses are cached by unit ID
|
|
113
|
+
for the lifetime of the SDK instance, including responses without a currency.
|
|
114
|
+
Failed unit requests are not cached and are retried on the next call. A missing
|
|
115
|
+
currency or failed unit request does not fail availability; calendar prices
|
|
116
|
+
remain `null`.
|
|
117
|
+
|
|
118
|
+
No new configuration is required. The currency lookup uses the existing
|
|
119
|
+
`v1ApiBaseUrl` and `apiKey`.
|
|
120
|
+
|
|
121
|
+
See `versions/2.17.0/CHANGELOG.md` and
|
|
122
|
+
`versions/2.17.0/MIGRATION.md`.
|
|
123
|
+
|
|
99
124
|
## Configuration
|
|
100
125
|
|
|
101
126
|
Use flat `WebsiteSDKConfig` files.
|
|
@@ -123,6 +123,47 @@ list.
|
|
|
123
123
|
|
|
124
124
|
See `versions/2.15.0/CHANGELOG.md` and `versions/2.15.0/MIGRATION.md`.
|
|
125
125
|
|
|
126
|
+
### Structured Bed Quantities
|
|
127
|
+
|
|
128
|
+
From 2.17.0, both backends expand each source bed according to its `amount`.
|
|
129
|
+
Because the public bed shape has no quantity field, a source amount greater than
|
|
130
|
+
one is returned as that many identical entries in `rooms[].beds`. Each entry
|
|
131
|
+
represents one bed and must not be deduplicated by its visible value.
|
|
132
|
+
|
|
133
|
+
The v10 behavior is delivered by `@v-office/sdk-core`. Refresh the lockfile when
|
|
134
|
+
upgrading so the website package resolves the coordinated core version shipped
|
|
135
|
+
for 2.17.0.
|
|
136
|
+
|
|
137
|
+
### Legacy v9 Structured Rooms
|
|
138
|
+
|
|
139
|
+
From 2.17.0, when vOffice supplies `roomDetails`, v9 rentals return them as
|
|
140
|
+
`rooms`. Room types, bed types, bed kinds, and supported room and bed attributes
|
|
141
|
+
are localized.
|
|
142
|
+
|
|
143
|
+
Supported per-room Boolean attributes are `hasPrivateBathroom`,
|
|
144
|
+
`roomDarkeningOption`, and `wardrobe`. Supported per-bed Boolean attributes are
|
|
145
|
+
`childrenOnly`, `extraLongBeds`, `openFootsection`, and `raisedBeds`.
|
|
146
|
+
|
|
147
|
+
Translation overrides use:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
Room.type.option.<TYPE>
|
|
151
|
+
RoomAttributes.<attribute>.label
|
|
152
|
+
Bed.type.option.<TYPE>
|
|
153
|
+
Bed.kind.option.<KIND>
|
|
154
|
+
Bed.<attribute>.label
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Incomplete room details are handled independently: rooms without a type and beds
|
|
158
|
+
without a type or positive integer amount are omitted. The rental remains
|
|
159
|
+
available, and `rooms` is omitted when no usable room remains.
|
|
160
|
+
|
|
161
|
+
v9 rooms do not expose per-room descriptions, source `maxGuests`, a structured
|
|
162
|
+
bed amount, room IDs or room-image associations, or `roomSummary`.
|
|
163
|
+
|
|
164
|
+
See `versions/2.17.0/CHANGELOG.md` and
|
|
165
|
+
`versions/2.17.0/MIGRATION.md`.
|
|
166
|
+
|
|
126
167
|
### Legacy v9 Built-In Attributes
|
|
127
168
|
|
|
128
169
|
From 2.14.0, built-in v9 property types and ordered option values come from the
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog: 2.17.0
|
|
2
|
+
|
|
3
|
+
This release restores presentation-ready prices to legacy-v9 initial
|
|
4
|
+
availability calendars and exposes structured v9 room and bed data through the
|
|
5
|
+
shared rental contract. Bed quantities are represented consistently on v9 and
|
|
6
|
+
v10 by returning one public bed entry for each source bed amount.
|
|
7
|
+
|
|
8
|
+
## Added
|
|
9
|
+
|
|
10
|
+
- Legacy-v9 static rentals expose source `roomDetails` through the existing
|
|
11
|
+
optional `rooms` field.
|
|
12
|
+
- v9 room output includes localized room types, bed types, bed kinds, and the
|
|
13
|
+
supported room and bed attributes supplied by vOffice.
|
|
14
|
+
- Supported v9 room attributes are `hasPrivateBathroom`,
|
|
15
|
+
`roomDarkeningOption`, and `wardrobe`. Supported bed attributes are
|
|
16
|
+
`childrenOnly`, `extraLongBeds`, `openFootsection`, and `raisedBeds`.
|
|
17
|
+
|
|
18
|
+
## Fixed
|
|
19
|
+
|
|
20
|
+
- Legacy-v9 initial availability calendar days once again expose a localized
|
|
21
|
+
`formattedPrice` when the date is a valid start date and the v1 calendar
|
|
22
|
+
supplies a numeric price.
|
|
23
|
+
- Unavailable dates, dates that cannot be used as a start date, and dates without
|
|
24
|
+
a numeric source price continue to return `formattedPrice: null`.
|
|
25
|
+
|
|
26
|
+
## Changed
|
|
27
|
+
|
|
28
|
+
- v9 calendar prices use the rental unit's configured booking currency. The SDK
|
|
29
|
+
loads that currency through the existing v1 unit endpoint and caches successful
|
|
30
|
+
unit lookups for the lifetime of the SDK instance.
|
|
31
|
+
- v9 calendar prices remain `null` when the unit currency is missing or cannot
|
|
32
|
+
be loaded. A currency lookup failure does not make the availability request
|
|
33
|
+
fail.
|
|
34
|
+
- A source bed with `amount: 3` is represented as three identical entries in
|
|
35
|
+
`rooms[].beds`. This applies to v9 and v10, whose shared public bed shape does
|
|
36
|
+
not contain a separate amount field.
|
|
37
|
+
- The first initial v9 availability request for a unit loads both its calendar
|
|
38
|
+
and unit record. Subsequent calls reuse a successfully loaded unit response,
|
|
39
|
+
including one that contains no currency. Failed unit requests are not cached
|
|
40
|
+
and are retried on the next call.
|
|
41
|
+
- v9 room data that does not satisfy the stricter generated heuristic schema is
|
|
42
|
+
read leniently from the preserved unknown data instead of being discarded as a
|
|
43
|
+
complete array.
|
|
44
|
+
- One incomplete v9 room or bed does not remove otherwise usable room data or
|
|
45
|
+
fail the rental.
|
|
46
|
+
|
|
47
|
+
## Unchanged
|
|
48
|
+
|
|
49
|
+
- `sdk.live.availability.getInitialAvailability(input)` and
|
|
50
|
+
`sdk.static.rentals.getRentals({ locale })` keep their existing signatures and
|
|
51
|
+
public TypeScript contracts.
|
|
52
|
+
- No new v9 configuration value or endpoint is required. The existing
|
|
53
|
+
`v1ApiBaseUrl` and API key are used for the unit-currency lookup, and
|
|
54
|
+
`roomDetails` is already requested by the v9 rentals GraphQL operation.
|
|
55
|
+
- v10 initial-availability pricing is unchanged.
|
|
56
|
+
- Start-date-selected availability output does not gain calendar prices.
|
|
57
|
+
- v9 `rooms` remains optional and is omitted when vOffice supplies no usable
|
|
58
|
+
room details.
|
|
59
|
+
- v9 still does not expose per-room descriptions, source `maxGuests`, a
|
|
60
|
+
structured bed amount, room IDs or room-image associations, or `roomSummary`.
|
|
61
|
+
- Existing localized `attributes` and `highlights` remain available and are not
|
|
62
|
+
removed when structured rooms are present.
|
|
63
|
+
|
|
64
|
+
## Compatibility
|
|
65
|
+
|
|
66
|
+
- Both features are additive for consumers that read selected fields.
|
|
67
|
+
- Complete v9 availability snapshots can now contain non-null `formattedPrice`
|
|
68
|
+
values on valid start dates.
|
|
69
|
+
- Complete v9 rental snapshots can now contain `rooms`.
|
|
70
|
+
- v9 and v10 snapshots or UIs that assumed one public bed entry per source bed
|
|
71
|
+
record must account for repeated entries when the source amount is greater
|
|
72
|
+
than one.
|
|
73
|
+
- Consumers must not deduplicate identical bed entries: repetition represents
|
|
74
|
+
the source quantity.
|
|
75
|
+
- The v10 bed expansion is delivered through `@v-office/sdk-core`. Refresh the
|
|
76
|
+
lockfile when upgrading so the website package resolves the coordinated core
|
|
77
|
+
version shipped for 2.17.0.
|
|
78
|
+
- A first initial-availability request for a v9 rental can perform one additional
|
|
79
|
+
v1 unit request for its currency. Applications with request-level mocks or
|
|
80
|
+
network assertions must account for it.
|
|
81
|
+
|
|
82
|
+
See `versions/2.17.0/MIGRATION.md`, `../../availability.md`, and
|
|
83
|
+
`../../rentals.md`.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Migration: 2.16.3 to 2.17.0
|
|
2
|
+
|
|
3
|
+
2.17.0 adds presentation-ready prices to legacy-v9 initial availability days
|
|
4
|
+
and structured rooms to legacy-v9 rental output. It also represents source bed
|
|
5
|
+
amounts consistently on v9 and v10 by returning one public entry per bed.
|
|
6
|
+
|
|
7
|
+
Service inputs, configuration, and public TypeScript shapes are unchanged.
|
|
8
|
+
|
|
9
|
+
## 1. Render Initial Calendar Prices Directly
|
|
10
|
+
|
|
11
|
+
For v9, `getInitialAvailability` can now return a non-null `formattedPrice` on
|
|
12
|
+
valid start dates:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const availability = await sdk.live.availability.getInitialAvailability(input);
|
|
16
|
+
|
|
17
|
+
for (const [date, day] of Object.entries(availability.calendarDays)) {
|
|
18
|
+
renderCalendarDay({
|
|
19
|
+
date,
|
|
20
|
+
status: day.status,
|
|
21
|
+
price: day.formattedPrice,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`formattedPrice` is already localized for the input locale and formatted in the
|
|
27
|
+
unit's configured booking currency. Render it directly. Do not parse it for
|
|
28
|
+
arithmetic and do not replace its currency based on site assumptions.
|
|
29
|
+
|
|
30
|
+
The field remains `null` when:
|
|
31
|
+
|
|
32
|
+
- the day cannot be used as a start date
|
|
33
|
+
- the calendar marks the day unavailable
|
|
34
|
+
- the v1 calendar supplies no numeric price
|
|
35
|
+
- the unit currency is missing or cannot be loaded
|
|
36
|
+
|
|
37
|
+
## 2. Account for the Unit-Currency Request
|
|
38
|
+
|
|
39
|
+
When no successful unit lookup is cached, a v9 initial-availability call loads
|
|
40
|
+
two resources:
|
|
41
|
+
|
|
42
|
+
1. the v1 unit calendar
|
|
43
|
+
2. the v1 unit record used to read its booking currency
|
|
44
|
+
|
|
45
|
+
Successful unit responses are cached by unit ID for the lifetime of the SDK
|
|
46
|
+
instance, including responses without a currency. Failed unit requests are not
|
|
47
|
+
cached and are retried by later initial-availability calls. A failed currency
|
|
48
|
+
request does not fail availability; calendar prices remain `null` instead.
|
|
49
|
+
|
|
50
|
+
Update HTTP mocks, request-count assertions, and service-worker fixtures that
|
|
51
|
+
previously expected only the calendar request.
|
|
52
|
+
|
|
53
|
+
No additional config is required. The lookup uses the existing `v1ApiBaseUrl`
|
|
54
|
+
and `apiKey`.
|
|
55
|
+
|
|
56
|
+
## 3. Read Structured v9 Rooms
|
|
57
|
+
|
|
58
|
+
When vOffice supplies `roomDetails`, v9 rentals can now contain `rooms`:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const rentals = await sdk.static.rentals.getRentals({ locale: "de-DE" });
|
|
62
|
+
|
|
63
|
+
for (const rental of rentals) {
|
|
64
|
+
for (const room of rental.rooms ?? []) {
|
|
65
|
+
renderRoomHeading(room.type);
|
|
66
|
+
renderRoomAttributes(room.attributes ?? []);
|
|
67
|
+
|
|
68
|
+
for (const bed of room.beds ?? []) {
|
|
69
|
+
renderBed({
|
|
70
|
+
type: bed.type,
|
|
71
|
+
kind: bed.kind,
|
|
72
|
+
attributes: bed.attributes ?? [],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Room types, bed types, bed kinds, and attributes are already localized. Render
|
|
80
|
+
them directly rather than comparing their visible text.
|
|
81
|
+
|
|
82
|
+
The v9 source supports these per-room Boolean attributes:
|
|
83
|
+
|
|
84
|
+
- `hasPrivateBathroom`
|
|
85
|
+
- `roomDarkeningOption`
|
|
86
|
+
- `wardrobe`
|
|
87
|
+
|
|
88
|
+
It supports these per-bed Boolean attributes:
|
|
89
|
+
|
|
90
|
+
- `childrenOnly`
|
|
91
|
+
- `extraLongBeds`
|
|
92
|
+
- `openFootsection`
|
|
93
|
+
- `raisedBeds`
|
|
94
|
+
|
|
95
|
+
Translation overrides use the same stable keys as v10:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
Room.type.option.<TYPE>
|
|
99
|
+
RoomAttributes.<attribute>.label
|
|
100
|
+
Bed.type.option.<TYPE>
|
|
101
|
+
Bed.kind.option.<KIND>
|
|
102
|
+
Bed.<attribute>.label
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`rooms` remains optional. Keep an absent array valid when vOffice has no
|
|
106
|
+
structured room details or no usable room remains after validation.
|
|
107
|
+
|
|
108
|
+
## 4. Treat Repeated Beds as Quantity
|
|
109
|
+
|
|
110
|
+
The public room-bed shape has no `amount` property. From 2.17.0, the SDK expands
|
|
111
|
+
the source amount:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Source
|
|
115
|
+
{ type: "ORDINARY", kind: "SINGLE", amount: 2 }
|
|
116
|
+
|
|
117
|
+
// Public rooms[].beds
|
|
118
|
+
[
|
|
119
|
+
{ type: "Standard bed", kind: "Single bed" },
|
|
120
|
+
{ type: "Standard bed", kind: "Single bed" },
|
|
121
|
+
]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Each public entry represents one bed. Do not deduplicate entries merely because
|
|
125
|
+
their type, kind, and attributes are identical.
|
|
126
|
+
|
|
127
|
+
This behavior applies to both backends:
|
|
128
|
+
|
|
129
|
+
- v9 expands `roomDetails[].beds[].amount`
|
|
130
|
+
- v10 expands `rooms[].beds[].amount`
|
|
131
|
+
|
|
132
|
+
The v10 change is delivered by `@v-office/sdk-core`. Refresh the lockfile when
|
|
133
|
+
upgrading the website SDK so it resolves the coordinated core version shipped
|
|
134
|
+
for 2.17.0.
|
|
135
|
+
|
|
136
|
+
Invalid, missing, zero, negative, and fractional v9 amounts do not produce bed
|
|
137
|
+
entries. Other usable rooms and beds remain available.
|
|
138
|
+
|
|
139
|
+
## 5. Keep Unsupported v9 Room Fields Optional
|
|
140
|
+
|
|
141
|
+
The v9 source does not provide every v10 room capability. In particular, public
|
|
142
|
+
v9 rooms do not currently expose:
|
|
143
|
+
|
|
144
|
+
- per-room descriptions
|
|
145
|
+
- source `maxGuests`
|
|
146
|
+
- a structured bed amount; source quantities are represented by repeated entries
|
|
147
|
+
- room IDs or room-image associations
|
|
148
|
+
- `roomSummary`
|
|
149
|
+
|
|
150
|
+
Do not derive these values from translated room labels or property-description
|
|
151
|
+
prose. Existing top-level `attributes` and `highlights` remain the supported
|
|
152
|
+
display sources for aggregate v9 facts such as bedrooms, bathrooms, rooms, and
|
|
153
|
+
sleeping accommodations.
|
|
154
|
+
|
|
155
|
+
## 6. Update Snapshots and Complete-Object Assertions
|
|
156
|
+
|
|
157
|
+
Update expectations that previously assumed:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
day.formattedPrice === null;
|
|
161
|
+
rental.rooms === undefined;
|
|
162
|
+
room.beds?.length === sourceRoom.beds.length;
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
New valid behavior includes:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
day.formattedPrice; // localized string on a priced, valid v9 start date
|
|
169
|
+
rental.rooms; // localized structured v9 rooms when roomDetails exists
|
|
170
|
+
room.beds?.length; // total expanded bed amount, not source record count
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Keep both `formattedPrice: null` and missing `rooms` valid because they still
|
|
174
|
+
represent legitimate backend data.
|
|
175
|
+
|
|
176
|
+
## Required Consumer Work
|
|
177
|
+
|
|
178
|
+
Applications that use only selected fields and ignore the new output require no
|
|
179
|
+
code changes.
|
|
180
|
+
|
|
181
|
+
Applications that render or snapshot these areas should:
|
|
182
|
+
|
|
183
|
+
1. Render `formattedPrice` directly when non-null.
|
|
184
|
+
2. Account for the first v9 initial-availability currency request in mocks.
|
|
185
|
+
3. Render `rental.rooms` as optional structured content.
|
|
186
|
+
4. Treat every `rooms[].beds` entry as one bed and avoid value-based
|
|
187
|
+
deduplication.
|
|
188
|
+
5. Refresh the lockfile so v10 resolves the coordinated core release.
|
|
189
|
+
6. Update complete-output fixtures and snapshots.
|
|
190
|
+
|
|
191
|
+
## Recommended Verification
|
|
192
|
+
|
|
193
|
+
1. Load v9 initial availability for a non-EUR rental and confirm the configured
|
|
194
|
+
currency is used.
|
|
195
|
+
2. Confirm a missing or failed currency lookup keeps calendar prices `null`
|
|
196
|
+
without failing availability.
|
|
197
|
+
3. Confirm unavailable, non-start, and price-less dates retain
|
|
198
|
+
`formattedPrice: null`.
|
|
199
|
+
4. Call initial availability twice for the same rental and confirm a successful
|
|
200
|
+
unit response is reused; confirm a failed unit request is retried.
|
|
201
|
+
5. Fetch v9 rentals with populated `roomDetails` in both supported locales.
|
|
202
|
+
6. Confirm room and bed labels are localized.
|
|
203
|
+
7. Confirm a source bed amount of two produces two public bed entries on v9 and
|
|
204
|
+
v10.
|
|
205
|
+
8. Confirm incomplete v9 rooms do not remove other usable rooms or fail the
|
|
206
|
+
rental.
|
|
207
|
+
9. Confirm rentals without structured source rooms still omit `rooms`.
|
|
@@ -228,6 +228,54 @@ const toReviews = ({ locale, translations, rental }) => Effect.gen(function* ()
|
|
|
228
228
|
};
|
|
229
229
|
});
|
|
230
230
|
//#endregion
|
|
231
|
+
//#region src/legacy-v9/parser/rentals/to-rooms.ts
|
|
232
|
+
const ROOM_TYPE_KEY_PREFIX = "Room.type.option";
|
|
233
|
+
const BED_TYPE_KEY_PREFIX = "Bed.type.option";
|
|
234
|
+
const BED_KIND_KEY_PREFIX = "Bed.kind.option";
|
|
235
|
+
const ROOM_ATTRIBUTE_LABEL_KEYS = {
|
|
236
|
+
hasPrivateBathroom: "RoomAttributes.hasPrivateBathroom.label",
|
|
237
|
+
roomDarkeningOption: "RoomAttributes.roomDarkeningOption.label",
|
|
238
|
+
wardrobe: "RoomAttributes.wardrobe.label"
|
|
239
|
+
};
|
|
240
|
+
const BED_ATTRIBUTE_LABEL_KEYS = {
|
|
241
|
+
childrenOnly: "Bed.childrenOnly.label",
|
|
242
|
+
extraLongBeds: "Bed.extraLongBeds.label",
|
|
243
|
+
openFootsection: "Bed.openFootsection.label",
|
|
244
|
+
raisedBeds: "Bed.raisedBeds.label"
|
|
245
|
+
};
|
|
246
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
247
|
+
const nonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
248
|
+
const positiveInteger = (value) => typeof value === "number" && Number.isInteger(value) && value > 0 ? value : 0;
|
|
249
|
+
const toRooms = ({ locale, translations, roomDetails }) => Effect.gen(function* () {
|
|
250
|
+
const result = [];
|
|
251
|
+
const translate = makeTranslate(translations, locale);
|
|
252
|
+
for (const room of Array.isArray(roomDetails) ? roomDetails : []) {
|
|
253
|
+
if (!isRecord(room)) continue;
|
|
254
|
+
const roomType = nonEmptyString(room.type);
|
|
255
|
+
if (roomType == null) continue;
|
|
256
|
+
const attributes = [];
|
|
257
|
+
for (const [key, labelKey] of Object.entries(ROOM_ATTRIBUTE_LABEL_KEYS)) if (room[key] === true) attributes.push(yield* translate(labelKey, key));
|
|
258
|
+
const beds = [];
|
|
259
|
+
for (const bed of Array.isArray(room.beds) ? room.beds : []) {
|
|
260
|
+
if (!isRecord(bed)) continue;
|
|
261
|
+
const bedType = nonEmptyString(bed.type);
|
|
262
|
+
if (bedType == null) continue;
|
|
263
|
+
const bedValue = { type: yield* translate(`${BED_TYPE_KEY_PREFIX}.${bedType}`, bedType) };
|
|
264
|
+
const bedKind = nonEmptyString(bed.kind);
|
|
265
|
+
if (bedKind != null) bedValue.kind = yield* translate(`${BED_KIND_KEY_PREFIX}.${bedKind}`, bedKind);
|
|
266
|
+
const bedAttributes = [];
|
|
267
|
+
for (const [key, labelKey] of Object.entries(BED_ATTRIBUTE_LABEL_KEYS)) if (bed[key] === true) bedAttributes.push(yield* translate(labelKey, key));
|
|
268
|
+
if (bedAttributes.length > 0) bedValue.attributes = bedAttributes;
|
|
269
|
+
for (let index = 0; index < positiveInteger(bed.amount); index++) beds.push(bedValue);
|
|
270
|
+
}
|
|
271
|
+
const roomValue = { type: yield* translate(`${ROOM_TYPE_KEY_PREFIX}.${roomType}`, roomType) };
|
|
272
|
+
if (attributes.length > 0) roomValue.attributes = attributes;
|
|
273
|
+
if (beds.length > 0) roomValue.beds = beds;
|
|
274
|
+
result.push(roomValue);
|
|
275
|
+
}
|
|
276
|
+
return result;
|
|
277
|
+
});
|
|
278
|
+
//#endregion
|
|
231
279
|
//#region src/legacy-v9/parser/rentals/to-rental-list-item.ts
|
|
232
280
|
const toRentalRentalsOutput = ({ rental, locale, translations, imageProxyBaseUrl, rentalHighlightPrioritization, customAttributes }) => Effect.gen(function* () {
|
|
233
281
|
const data = parseVofficeUnitData(rental.data);
|
|
@@ -259,6 +307,11 @@ const toRentalRentalsOutput = ({ rental, locale, translations, imageProxyBaseUrl
|
|
|
259
307
|
customAttributes,
|
|
260
308
|
attributes: data
|
|
261
309
|
});
|
|
310
|
+
const rooms = yield* toRooms({
|
|
311
|
+
locale,
|
|
312
|
+
translations,
|
|
313
|
+
roomDetails: data.known.roomDetails ?? data.unknown.roomDetails
|
|
314
|
+
});
|
|
262
315
|
const reviews = yield* toReviews({
|
|
263
316
|
locale,
|
|
264
317
|
translations,
|
|
@@ -277,6 +330,7 @@ const toRentalRentalsOutput = ({ rental, locale, translations, imageProxyBaseUrl
|
|
|
277
330
|
if (attributes != null) item.attributes = attributes;
|
|
278
331
|
if (vicinity != null) item.vicinity = vicinity;
|
|
279
332
|
if (highlights != null) item.highlights = highlights;
|
|
333
|
+
if (rooms.length > 0) item.rooms = rooms;
|
|
280
334
|
if (rental.voffice_facility != null) item.property = toProperty(rental.voffice_facility, locale);
|
|
281
335
|
if (reviews != null) item.reviews = reviews;
|
|
282
336
|
return item;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as parseQueryParameters, i as collectQueryParameters, n as makeV9CustomAttributeFilterCapabilities, o as toQueryString, r as toBasicQueryInputs, s as applyVofficeFilterDerivedBasicQueryInputs } from "./client-
|
|
1
|
+
import { a as parseQueryParameters, i as collectQueryParameters, n as makeV9CustomAttributeFilterCapabilities, o as toQueryString, r as toBasicQueryInputs, s as applyVofficeFilterDerivedBasicQueryInputs } from "./client-ScO68LGg.mjs";
|
|
2
2
|
import { a as toAddress, g as parseVofficeUnitData, i as toImages, s as searchQuery, t as toRentalHighlights, u as VofficeUnitDataFieldSchemas } from "./to-rental-highlights-BAsEuxoy.mjs";
|
|
3
3
|
import { CoreSDKError, STABLE_SEARCH_INPUTS, daysBetweenLocalDates, expandCustomAttributeFilterCompositions, parseChildrenAges, parseOccupancyCount, resolveExpandedCompositions, toFormattedSearchPrice, toIsoDateFromPeriodQueryDate, toStableSearchInputBackendQueryKeys, toStableSearchInputParameterValues, toStableSearchInputQueryKeys, toUnusedFilterKeys } from "@v-office/sdk-core";
|
|
4
4
|
import { Effect } from "effect";
|
|
@@ -3004,6 +3004,8 @@
|
|
|
3004
3004
|
"PropertyAttributes.communalLoungeTvRoom.label": "Fernsehzimmer",
|
|
3005
3005
|
"PropertyAttributes.conciergeService.help": "Concierge Hilfe",
|
|
3006
3006
|
"PropertyAttributes.conciergeService.label": "Concierge",
|
|
3007
|
+
"PropertyAttributes.constructionDate.help": "Jahr oder Datum, in dem die Immobilie gebaut wurde",
|
|
3008
|
+
"PropertyAttributes.constructionDate.label": "Baudatum",
|
|
3007
3009
|
"PropertyAttributes.contactlessCheckinAvailable.help": "Kontaktloser Check-in verfügbar Hilfe",
|
|
3008
3010
|
"PropertyAttributes.contactlessCheckinAvailable.label": "Kontaktloser Check-in verfügbar",
|
|
3009
3011
|
"PropertyAttributes.couplesMassage.help": "Paar Massagen Hilfe",
|
|
@@ -3121,6 +3123,8 @@
|
|
|
3121
3123
|
"PropertyAttributes.kidMeals.label": "Kinder Gerichte",
|
|
3122
3124
|
"PropertyAttributes.kidsClub.help": "Kinder-Club Hilfe",
|
|
3123
3125
|
"PropertyAttributes.kidsClub.label": "Kinder-Club",
|
|
3126
|
+
"PropertyAttributes.lastRenovationDate.help": "Datum der letzten Renovierung",
|
|
3127
|
+
"PropertyAttributes.lastRenovationDate.label": "Letzte Renovierung",
|
|
3124
3128
|
"PropertyAttributes.laundryService.help": "PropertyAttributes.laundryService.help",
|
|
3125
3129
|
"PropertyAttributes.laundryService.label": "Wäscheservice",
|
|
3126
3130
|
"PropertyAttributes.library.help": "Bibliothek Hilfe",
|
|
@@ -4516,9 +4520,15 @@
|
|
|
4516
4520
|
"RentalAttributes.marquee.help": "Pavillon / Partyzelt verfügbar",
|
|
4517
4521
|
"RentalAttributes.marquee.label": "Festzelt",
|
|
4518
4522
|
"RentalAttributes.marquee.placeholder": "Platzhalter",
|
|
4523
|
+
"RentalAttributes.maxAge.help": "Höchstalter der Gäste",
|
|
4524
|
+
"RentalAttributes.maxAge.label": "Höchstalter",
|
|
4525
|
+
"RentalAttributes.maxAge.placeholder": "Platzhalter",
|
|
4519
4526
|
"RentalAttributes.microwave.help": "Mikrowelle vorhanden",
|
|
4520
4527
|
"RentalAttributes.microwave.label": "Mikrowelle",
|
|
4521
4528
|
"RentalAttributes.microwave.placeholder": "Platzhalter",
|
|
4529
|
+
"RentalAttributes.minAge.help": "Mindestalter der Gäste",
|
|
4530
|
+
"RentalAttributes.minAge.label": "Mindestalter",
|
|
4531
|
+
"RentalAttributes.minAge.placeholder": "Platzhalter",
|
|
4522
4532
|
"RentalAttributes.minibar.help": "Minibar (gefüllt oder leer) vorhanden",
|
|
4523
4533
|
"RentalAttributes.minibar.label": "Minibar",
|
|
4524
4534
|
"RentalAttributes.minibar.placeholder": "Platzhalter",
|
|
@@ -3004,6 +3004,8 @@
|
|
|
3004
3004
|
"PropertyAttributes.communalLoungeTvRoom.label": "communal lounge / tv room",
|
|
3005
3005
|
"PropertyAttributes.conciergeService.help": "Concierge HELP",
|
|
3006
3006
|
"PropertyAttributes.conciergeService.label": "Concierge",
|
|
3007
|
+
"PropertyAttributes.constructionDate.help": "Year or date the property was built",
|
|
3008
|
+
"PropertyAttributes.constructionDate.label": "Construction Date",
|
|
3007
3009
|
"PropertyAttributes.contactlessCheckinAvailable.help": "contactless check-in available HELP",
|
|
3008
3010
|
"PropertyAttributes.contactlessCheckinAvailable.label": "contactless check-in available",
|
|
3009
3011
|
"PropertyAttributes.couplesMassage.help": "Couples massages HELP",
|
|
@@ -3121,6 +3123,8 @@
|
|
|
3121
3123
|
"PropertyAttributes.kidMeals.label": "Kids meals",
|
|
3122
3124
|
"PropertyAttributes.kidsClub.help": "Kids club HELP",
|
|
3123
3125
|
"PropertyAttributes.kidsClub.label": "Kids club",
|
|
3126
|
+
"PropertyAttributes.lastRenovationDate.help": "Date of the most recent renovation",
|
|
3127
|
+
"PropertyAttributes.lastRenovationDate.label": "Last Renovation Date",
|
|
3124
3128
|
"PropertyAttributes.laundryService.help": "Propertyattributes.laundryservice.help",
|
|
3125
3129
|
"PropertyAttributes.laundryService.label": "Laundry Service",
|
|
3126
3130
|
"PropertyAttributes.library.help": "Library HELP",
|
|
@@ -4516,9 +4520,15 @@
|
|
|
4516
4520
|
"RentalAttributes.marquee.help": "Marquee / garden tent available",
|
|
4517
4521
|
"RentalAttributes.marquee.label": "Marquee",
|
|
4518
4522
|
"RentalAttributes.marquee.placeholder": "RentalAttributes.marquee.placeholder",
|
|
4523
|
+
"RentalAttributes.maxAge.help": "Maximum guest age allowed",
|
|
4524
|
+
"RentalAttributes.maxAge.label": "Maximum Age",
|
|
4525
|
+
"RentalAttributes.maxAge.placeholder": "RentalAttributes.maxAge.placeholder",
|
|
4519
4526
|
"RentalAttributes.microwave.help": "Microwave available",
|
|
4520
4527
|
"RentalAttributes.microwave.label": "Microwave",
|
|
4521
4528
|
"RentalAttributes.microwave.placeholder": "RentalAttributes.microwave.placeholder",
|
|
4529
|
+
"RentalAttributes.minAge.help": "Minimum guest age required",
|
|
4530
|
+
"RentalAttributes.minAge.label": "Minimum Age",
|
|
4531
|
+
"RentalAttributes.minAge.placeholder": "RentalAttributes.minAge.placeholder",
|
|
4522
4532
|
"RentalAttributes.minibar.help": "Minibar available (stocked or empty)",
|
|
4523
4533
|
"RentalAttributes.minibar.label": "Mini-bar",
|
|
4524
4534
|
"RentalAttributes.minibar.placeholder": "RentalAttributes.minibar.placeholder",
|
|
@@ -4,6 +4,7 @@ This file is the versioned changelog index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Versions
|
|
6
6
|
|
|
7
|
+
- `versions/2.17.0/CHANGELOG.md`: `@v-office/website-sdk` 2.17.0 release notes.
|
|
7
8
|
- `versions/2.16.3/CHANGELOG.md`: `@v-office/website-sdk` 2.16.3 release notes.
|
|
8
9
|
- `versions/2.16.2/CHANGELOG.md`: `@v-office/website-sdk` 2.16.2 documentation release notes.
|
|
9
10
|
- `versions/2.16.1/CHANGELOG.md`: `@v-office/website-sdk` 2.16.1 release notes.
|
|
@@ -4,6 +4,7 @@ This file is the versioned migration index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Available Guides
|
|
6
6
|
|
|
7
|
+
- `versions/2.17.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.3 to 2.17.0.
|
|
7
8
|
- `versions/2.16.3/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.2 to 2.16.3.
|
|
8
9
|
- `versions/2.16.2/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.1 to 2.16.2.
|
|
9
10
|
- `versions/2.16.1/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.16.0 to 2.16.1.
|
package/instructions/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Website SDK Instructions
|
|
2
2
|
|
|
3
3
|
These instructions describe the current source targeted for
|
|
4
|
-
`@v-office/website-sdk` 2.
|
|
4
|
+
`@v-office/website-sdk` 2.17.0. Package versions remain unchanged until the release
|
|
5
5
|
workflow performs the coordinated core and website bumps.
|
|
6
6
|
|
|
7
7
|
Use this directory as the consumer-facing reference for the package:
|
|
@@ -18,6 +18,8 @@ Use this directory as the consumer-facing reference for the package:
|
|
|
18
18
|
- `document-structured-json.md`: `sdk.static.documents.getTermsAndPrivacyPolicy` and structured document JSON rendering rules.
|
|
19
19
|
- `CHANGELOG.md`: versioned changelog index.
|
|
20
20
|
- `MIGRATION.md`: versioned migration index.
|
|
21
|
+
- `versions/2.17.0/`: 2.17.0 legacy-v9 calendar-day prices and structured
|
|
22
|
+
rooms, shared bed-amount expansion, and the 2.16.3-to-2.17.0 migration guide.
|
|
21
23
|
- `versions/2.16.3/`: 2.16.3 browser-origin resolution for relative payment
|
|
22
24
|
return URLs and the 2.16.2-to-2.16.3 migration guide.
|
|
23
25
|
- `versions/2.16.2/`: 2.16.2 documentation release notes and migration guide.
|
|
@@ -102,5 +104,5 @@ website-sdk --backend v10 search --locale de-DE --query "adults=2" --sort '{"by"
|
|
|
102
104
|
```
|
|
103
105
|
|
|
104
106
|
Config file examples in these docs use the flat `WebsiteSDKConfig` shape introduced
|
|
105
|
-
in 2.0.0 and kept in 2.
|
|
107
|
+
in 2.0.0 and kept in 2.17.0. v10 config additionally requires `searchEndpoint` as
|
|
106
108
|
of 2.5.0.
|
|
@@ -96,6 +96,31 @@ Start-date-selected availability returns `Promise<StartDateSelectedAvailabilityO
|
|
|
96
96
|
|
|
97
97
|
Common statuses include `available`, `before_today`, `check_in_not_allowed`, `no_valid_check_out_from_start`, `after_last_bookable_date`, and `unavailable`. End-date results can also return `same_day`, `not_after_selected_start`, `minimum_stay_not_met`, `check_out_not_allowed`, and range-crossing statuses.
|
|
98
98
|
|
|
99
|
+
### Legacy v9 Calendar-Day Prices
|
|
100
|
+
|
|
101
|
+
From 2.17.0, v9 initial availability uses the numeric price supplied by the v1
|
|
102
|
+
calendar to populate `formattedPrice` on valid start dates. The value is already
|
|
103
|
+
localized and formatted in the rental unit's configured booking currency.
|
|
104
|
+
Render it directly rather than parsing or reformatting it.
|
|
105
|
+
|
|
106
|
+
`formattedPrice` remains `null` when the date cannot be used as a start date,
|
|
107
|
+
the date is unavailable, the v1 calendar supplies no numeric price, or the
|
|
108
|
+
unit's currency cannot be loaded. Start-date-selected availability does not
|
|
109
|
+
include calendar prices.
|
|
110
|
+
|
|
111
|
+
When no successful unit lookup is cached, a v9 initial-availability request loads
|
|
112
|
+
the calendar and a unit record. Successful unit responses are cached by unit ID
|
|
113
|
+
for the lifetime of the SDK instance, including responses without a currency.
|
|
114
|
+
Failed unit requests are not cached and are retried on the next call. A missing
|
|
115
|
+
currency or failed unit request does not fail availability; calendar prices
|
|
116
|
+
remain `null`.
|
|
117
|
+
|
|
118
|
+
No new configuration is required. The currency lookup uses the existing
|
|
119
|
+
`v1ApiBaseUrl` and `apiKey`.
|
|
120
|
+
|
|
121
|
+
See `versions/2.17.0/CHANGELOG.md` and
|
|
122
|
+
`versions/2.17.0/MIGRATION.md`.
|
|
123
|
+
|
|
99
124
|
## Configuration
|
|
100
125
|
|
|
101
126
|
Use flat `WebsiteSDKConfig` files.
|
package/instructions/rentals.md
CHANGED
|
@@ -123,6 +123,47 @@ list.
|
|
|
123
123
|
|
|
124
124
|
See `versions/2.15.0/CHANGELOG.md` and `versions/2.15.0/MIGRATION.md`.
|
|
125
125
|
|
|
126
|
+
### Structured Bed Quantities
|
|
127
|
+
|
|
128
|
+
From 2.17.0, both backends expand each source bed according to its `amount`.
|
|
129
|
+
Because the public bed shape has no quantity field, a source amount greater than
|
|
130
|
+
one is returned as that many identical entries in `rooms[].beds`. Each entry
|
|
131
|
+
represents one bed and must not be deduplicated by its visible value.
|
|
132
|
+
|
|
133
|
+
The v10 behavior is delivered by `@v-office/sdk-core`. Refresh the lockfile when
|
|
134
|
+
upgrading so the website package resolves the coordinated core version shipped
|
|
135
|
+
for 2.17.0.
|
|
136
|
+
|
|
137
|
+
### Legacy v9 Structured Rooms
|
|
138
|
+
|
|
139
|
+
From 2.17.0, when vOffice supplies `roomDetails`, v9 rentals return them as
|
|
140
|
+
`rooms`. Room types, bed types, bed kinds, and supported room and bed attributes
|
|
141
|
+
are localized.
|
|
142
|
+
|
|
143
|
+
Supported per-room Boolean attributes are `hasPrivateBathroom`,
|
|
144
|
+
`roomDarkeningOption`, and `wardrobe`. Supported per-bed Boolean attributes are
|
|
145
|
+
`childrenOnly`, `extraLongBeds`, `openFootsection`, and `raisedBeds`.
|
|
146
|
+
|
|
147
|
+
Translation overrides use:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
Room.type.option.<TYPE>
|
|
151
|
+
RoomAttributes.<attribute>.label
|
|
152
|
+
Bed.type.option.<TYPE>
|
|
153
|
+
Bed.kind.option.<KIND>
|
|
154
|
+
Bed.<attribute>.label
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Incomplete room details are handled independently: rooms without a type and beds
|
|
158
|
+
without a type or positive integer amount are omitted. The rental remains
|
|
159
|
+
available, and `rooms` is omitted when no usable room remains.
|
|
160
|
+
|
|
161
|
+
v9 rooms do not expose per-room descriptions, source `maxGuests`, a structured
|
|
162
|
+
bed amount, room IDs or room-image associations, or `roomSummary`.
|
|
163
|
+
|
|
164
|
+
See `versions/2.17.0/CHANGELOG.md` and
|
|
165
|
+
`versions/2.17.0/MIGRATION.md`.
|
|
166
|
+
|
|
126
167
|
### Legacy v9 Built-In Attributes
|
|
127
168
|
|
|
128
169
|
From 2.14.0, built-in v9 property types and ordered option values come from the
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog: 2.17.0
|
|
2
|
+
|
|
3
|
+
This release restores presentation-ready prices to legacy-v9 initial
|
|
4
|
+
availability calendars and exposes structured v9 room and bed data through the
|
|
5
|
+
shared rental contract. Bed quantities are represented consistently on v9 and
|
|
6
|
+
v10 by returning one public bed entry for each source bed amount.
|
|
7
|
+
|
|
8
|
+
## Added
|
|
9
|
+
|
|
10
|
+
- Legacy-v9 static rentals expose source `roomDetails` through the existing
|
|
11
|
+
optional `rooms` field.
|
|
12
|
+
- v9 room output includes localized room types, bed types, bed kinds, and the
|
|
13
|
+
supported room and bed attributes supplied by vOffice.
|
|
14
|
+
- Supported v9 room attributes are `hasPrivateBathroom`,
|
|
15
|
+
`roomDarkeningOption`, and `wardrobe`. Supported bed attributes are
|
|
16
|
+
`childrenOnly`, `extraLongBeds`, `openFootsection`, and `raisedBeds`.
|
|
17
|
+
|
|
18
|
+
## Fixed
|
|
19
|
+
|
|
20
|
+
- Legacy-v9 initial availability calendar days once again expose a localized
|
|
21
|
+
`formattedPrice` when the date is a valid start date and the v1 calendar
|
|
22
|
+
supplies a numeric price.
|
|
23
|
+
- Unavailable dates, dates that cannot be used as a start date, and dates without
|
|
24
|
+
a numeric source price continue to return `formattedPrice: null`.
|
|
25
|
+
|
|
26
|
+
## Changed
|
|
27
|
+
|
|
28
|
+
- v9 calendar prices use the rental unit's configured booking currency. The SDK
|
|
29
|
+
loads that currency through the existing v1 unit endpoint and caches successful
|
|
30
|
+
unit lookups for the lifetime of the SDK instance.
|
|
31
|
+
- v9 calendar prices remain `null` when the unit currency is missing or cannot
|
|
32
|
+
be loaded. A currency lookup failure does not make the availability request
|
|
33
|
+
fail.
|
|
34
|
+
- A source bed with `amount: 3` is represented as three identical entries in
|
|
35
|
+
`rooms[].beds`. This applies to v9 and v10, whose shared public bed shape does
|
|
36
|
+
not contain a separate amount field.
|
|
37
|
+
- The first initial v9 availability request for a unit loads both its calendar
|
|
38
|
+
and unit record. Subsequent calls reuse a successfully loaded unit response,
|
|
39
|
+
including one that contains no currency. Failed unit requests are not cached
|
|
40
|
+
and are retried on the next call.
|
|
41
|
+
- v9 room data that does not satisfy the stricter generated heuristic schema is
|
|
42
|
+
read leniently from the preserved unknown data instead of being discarded as a
|
|
43
|
+
complete array.
|
|
44
|
+
- One incomplete v9 room or bed does not remove otherwise usable room data or
|
|
45
|
+
fail the rental.
|
|
46
|
+
|
|
47
|
+
## Unchanged
|
|
48
|
+
|
|
49
|
+
- `sdk.live.availability.getInitialAvailability(input)` and
|
|
50
|
+
`sdk.static.rentals.getRentals({ locale })` keep their existing signatures and
|
|
51
|
+
public TypeScript contracts.
|
|
52
|
+
- No new v9 configuration value or endpoint is required. The existing
|
|
53
|
+
`v1ApiBaseUrl` and API key are used for the unit-currency lookup, and
|
|
54
|
+
`roomDetails` is already requested by the v9 rentals GraphQL operation.
|
|
55
|
+
- v10 initial-availability pricing is unchanged.
|
|
56
|
+
- Start-date-selected availability output does not gain calendar prices.
|
|
57
|
+
- v9 `rooms` remains optional and is omitted when vOffice supplies no usable
|
|
58
|
+
room details.
|
|
59
|
+
- v9 still does not expose per-room descriptions, source `maxGuests`, a
|
|
60
|
+
structured bed amount, room IDs or room-image associations, or `roomSummary`.
|
|
61
|
+
- Existing localized `attributes` and `highlights` remain available and are not
|
|
62
|
+
removed when structured rooms are present.
|
|
63
|
+
|
|
64
|
+
## Compatibility
|
|
65
|
+
|
|
66
|
+
- Both features are additive for consumers that read selected fields.
|
|
67
|
+
- Complete v9 availability snapshots can now contain non-null `formattedPrice`
|
|
68
|
+
values on valid start dates.
|
|
69
|
+
- Complete v9 rental snapshots can now contain `rooms`.
|
|
70
|
+
- v9 and v10 snapshots or UIs that assumed one public bed entry per source bed
|
|
71
|
+
record must account for repeated entries when the source amount is greater
|
|
72
|
+
than one.
|
|
73
|
+
- Consumers must not deduplicate identical bed entries: repetition represents
|
|
74
|
+
the source quantity.
|
|
75
|
+
- The v10 bed expansion is delivered through `@v-office/sdk-core`. Refresh the
|
|
76
|
+
lockfile when upgrading so the website package resolves the coordinated core
|
|
77
|
+
version shipped for 2.17.0.
|
|
78
|
+
- A first initial-availability request for a v9 rental can perform one additional
|
|
79
|
+
v1 unit request for its currency. Applications with request-level mocks or
|
|
80
|
+
network assertions must account for it.
|
|
81
|
+
|
|
82
|
+
See `versions/2.17.0/MIGRATION.md`, `../../availability.md`, and
|
|
83
|
+
`../../rentals.md`.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Migration: 2.16.3 to 2.17.0
|
|
2
|
+
|
|
3
|
+
2.17.0 adds presentation-ready prices to legacy-v9 initial availability days
|
|
4
|
+
and structured rooms to legacy-v9 rental output. It also represents source bed
|
|
5
|
+
amounts consistently on v9 and v10 by returning one public entry per bed.
|
|
6
|
+
|
|
7
|
+
Service inputs, configuration, and public TypeScript shapes are unchanged.
|
|
8
|
+
|
|
9
|
+
## 1. Render Initial Calendar Prices Directly
|
|
10
|
+
|
|
11
|
+
For v9, `getInitialAvailability` can now return a non-null `formattedPrice` on
|
|
12
|
+
valid start dates:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const availability = await sdk.live.availability.getInitialAvailability(input);
|
|
16
|
+
|
|
17
|
+
for (const [date, day] of Object.entries(availability.calendarDays)) {
|
|
18
|
+
renderCalendarDay({
|
|
19
|
+
date,
|
|
20
|
+
status: day.status,
|
|
21
|
+
price: day.formattedPrice,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`formattedPrice` is already localized for the input locale and formatted in the
|
|
27
|
+
unit's configured booking currency. Render it directly. Do not parse it for
|
|
28
|
+
arithmetic and do not replace its currency based on site assumptions.
|
|
29
|
+
|
|
30
|
+
The field remains `null` when:
|
|
31
|
+
|
|
32
|
+
- the day cannot be used as a start date
|
|
33
|
+
- the calendar marks the day unavailable
|
|
34
|
+
- the v1 calendar supplies no numeric price
|
|
35
|
+
- the unit currency is missing or cannot be loaded
|
|
36
|
+
|
|
37
|
+
## 2. Account for the Unit-Currency Request
|
|
38
|
+
|
|
39
|
+
When no successful unit lookup is cached, a v9 initial-availability call loads
|
|
40
|
+
two resources:
|
|
41
|
+
|
|
42
|
+
1. the v1 unit calendar
|
|
43
|
+
2. the v1 unit record used to read its booking currency
|
|
44
|
+
|
|
45
|
+
Successful unit responses are cached by unit ID for the lifetime of the SDK
|
|
46
|
+
instance, including responses without a currency. Failed unit requests are not
|
|
47
|
+
cached and are retried by later initial-availability calls. A failed currency
|
|
48
|
+
request does not fail availability; calendar prices remain `null` instead.
|
|
49
|
+
|
|
50
|
+
Update HTTP mocks, request-count assertions, and service-worker fixtures that
|
|
51
|
+
previously expected only the calendar request.
|
|
52
|
+
|
|
53
|
+
No additional config is required. The lookup uses the existing `v1ApiBaseUrl`
|
|
54
|
+
and `apiKey`.
|
|
55
|
+
|
|
56
|
+
## 3. Read Structured v9 Rooms
|
|
57
|
+
|
|
58
|
+
When vOffice supplies `roomDetails`, v9 rentals can now contain `rooms`:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const rentals = await sdk.static.rentals.getRentals({ locale: "de-DE" });
|
|
62
|
+
|
|
63
|
+
for (const rental of rentals) {
|
|
64
|
+
for (const room of rental.rooms ?? []) {
|
|
65
|
+
renderRoomHeading(room.type);
|
|
66
|
+
renderRoomAttributes(room.attributes ?? []);
|
|
67
|
+
|
|
68
|
+
for (const bed of room.beds ?? []) {
|
|
69
|
+
renderBed({
|
|
70
|
+
type: bed.type,
|
|
71
|
+
kind: bed.kind,
|
|
72
|
+
attributes: bed.attributes ?? [],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Room types, bed types, bed kinds, and attributes are already localized. Render
|
|
80
|
+
them directly rather than comparing their visible text.
|
|
81
|
+
|
|
82
|
+
The v9 source supports these per-room Boolean attributes:
|
|
83
|
+
|
|
84
|
+
- `hasPrivateBathroom`
|
|
85
|
+
- `roomDarkeningOption`
|
|
86
|
+
- `wardrobe`
|
|
87
|
+
|
|
88
|
+
It supports these per-bed Boolean attributes:
|
|
89
|
+
|
|
90
|
+
- `childrenOnly`
|
|
91
|
+
- `extraLongBeds`
|
|
92
|
+
- `openFootsection`
|
|
93
|
+
- `raisedBeds`
|
|
94
|
+
|
|
95
|
+
Translation overrides use the same stable keys as v10:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
Room.type.option.<TYPE>
|
|
99
|
+
RoomAttributes.<attribute>.label
|
|
100
|
+
Bed.type.option.<TYPE>
|
|
101
|
+
Bed.kind.option.<KIND>
|
|
102
|
+
Bed.<attribute>.label
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`rooms` remains optional. Keep an absent array valid when vOffice has no
|
|
106
|
+
structured room details or no usable room remains after validation.
|
|
107
|
+
|
|
108
|
+
## 4. Treat Repeated Beds as Quantity
|
|
109
|
+
|
|
110
|
+
The public room-bed shape has no `amount` property. From 2.17.0, the SDK expands
|
|
111
|
+
the source amount:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Source
|
|
115
|
+
{ type: "ORDINARY", kind: "SINGLE", amount: 2 }
|
|
116
|
+
|
|
117
|
+
// Public rooms[].beds
|
|
118
|
+
[
|
|
119
|
+
{ type: "Standard bed", kind: "Single bed" },
|
|
120
|
+
{ type: "Standard bed", kind: "Single bed" },
|
|
121
|
+
]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Each public entry represents one bed. Do not deduplicate entries merely because
|
|
125
|
+
their type, kind, and attributes are identical.
|
|
126
|
+
|
|
127
|
+
This behavior applies to both backends:
|
|
128
|
+
|
|
129
|
+
- v9 expands `roomDetails[].beds[].amount`
|
|
130
|
+
- v10 expands `rooms[].beds[].amount`
|
|
131
|
+
|
|
132
|
+
The v10 change is delivered by `@v-office/sdk-core`. Refresh the lockfile when
|
|
133
|
+
upgrading the website SDK so it resolves the coordinated core version shipped
|
|
134
|
+
for 2.17.0.
|
|
135
|
+
|
|
136
|
+
Invalid, missing, zero, negative, and fractional v9 amounts do not produce bed
|
|
137
|
+
entries. Other usable rooms and beds remain available.
|
|
138
|
+
|
|
139
|
+
## 5. Keep Unsupported v9 Room Fields Optional
|
|
140
|
+
|
|
141
|
+
The v9 source does not provide every v10 room capability. In particular, public
|
|
142
|
+
v9 rooms do not currently expose:
|
|
143
|
+
|
|
144
|
+
- per-room descriptions
|
|
145
|
+
- source `maxGuests`
|
|
146
|
+
- a structured bed amount; source quantities are represented by repeated entries
|
|
147
|
+
- room IDs or room-image associations
|
|
148
|
+
- `roomSummary`
|
|
149
|
+
|
|
150
|
+
Do not derive these values from translated room labels or property-description
|
|
151
|
+
prose. Existing top-level `attributes` and `highlights` remain the supported
|
|
152
|
+
display sources for aggregate v9 facts such as bedrooms, bathrooms, rooms, and
|
|
153
|
+
sleeping accommodations.
|
|
154
|
+
|
|
155
|
+
## 6. Update Snapshots and Complete-Object Assertions
|
|
156
|
+
|
|
157
|
+
Update expectations that previously assumed:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
day.formattedPrice === null;
|
|
161
|
+
rental.rooms === undefined;
|
|
162
|
+
room.beds?.length === sourceRoom.beds.length;
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
New valid behavior includes:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
day.formattedPrice; // localized string on a priced, valid v9 start date
|
|
169
|
+
rental.rooms; // localized structured v9 rooms when roomDetails exists
|
|
170
|
+
room.beds?.length; // total expanded bed amount, not source record count
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Keep both `formattedPrice: null` and missing `rooms` valid because they still
|
|
174
|
+
represent legitimate backend data.
|
|
175
|
+
|
|
176
|
+
## Required Consumer Work
|
|
177
|
+
|
|
178
|
+
Applications that use only selected fields and ignore the new output require no
|
|
179
|
+
code changes.
|
|
180
|
+
|
|
181
|
+
Applications that render or snapshot these areas should:
|
|
182
|
+
|
|
183
|
+
1. Render `formattedPrice` directly when non-null.
|
|
184
|
+
2. Account for the first v9 initial-availability currency request in mocks.
|
|
185
|
+
3. Render `rental.rooms` as optional structured content.
|
|
186
|
+
4. Treat every `rooms[].beds` entry as one bed and avoid value-based
|
|
187
|
+
deduplication.
|
|
188
|
+
5. Refresh the lockfile so v10 resolves the coordinated core release.
|
|
189
|
+
6. Update complete-output fixtures and snapshots.
|
|
190
|
+
|
|
191
|
+
## Recommended Verification
|
|
192
|
+
|
|
193
|
+
1. Load v9 initial availability for a non-EUR rental and confirm the configured
|
|
194
|
+
currency is used.
|
|
195
|
+
2. Confirm a missing or failed currency lookup keeps calendar prices `null`
|
|
196
|
+
without failing availability.
|
|
197
|
+
3. Confirm unavailable, non-start, and price-less dates retain
|
|
198
|
+
`formattedPrice: null`.
|
|
199
|
+
4. Call initial availability twice for the same rental and confirm a successful
|
|
200
|
+
unit response is reused; confirm a failed unit request is retried.
|
|
201
|
+
5. Fetch v9 rentals with populated `roomDetails` in both supported locales.
|
|
202
|
+
6. Confirm room and bed labels are localized.
|
|
203
|
+
7. Confirm a source bed amount of two produces two public bed entries on v9 and
|
|
204
|
+
v10.
|
|
205
|
+
8. Confirm incomplete v9 rooms do not remove other usable rooms or fail the
|
|
206
|
+
rental.
|
|
207
|
+
9. Confirm rentals without structured source rooms still omit `rooms`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-office/website-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Website-facing SDK facade backed by @v-office/sdk-core",
|
|
5
5
|
"bin": {
|
|
6
6
|
"website-sdk": "./dist/cli.mjs"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@graphql-typed-document-node/core": "3.2.0",
|
|
45
|
-
"@v-office/sdk-core": "^1.
|
|
45
|
+
"@v-office/sdk-core": "^1.18.0",
|
|
46
46
|
"effect": "4.0.0-beta.85",
|
|
47
47
|
"graphql": "17.0.2",
|
|
48
48
|
"yaml": "^2.9.0"
|
|
@@ -77,8 +77,9 @@
|
|
|
77
77
|
"fmt": "oxfmt",
|
|
78
78
|
"fmt:check": "oxfmt --check",
|
|
79
79
|
"check": "pnpm run typecheck && pnpm run lint && pnpm run fmt:check",
|
|
80
|
-
"test": "pnpm run test:v9:properties && pnpm run build && node --test test/*.test.mjs",
|
|
81
|
-
"test:v9:properties": "node --test codegen/v9/heuristic-generation/generate/property.test.ts src/legacy-v9/parser/rentals/render-property-attribute.test.ts",
|
|
80
|
+
"test": "pnpm run test:v9:properties && pnpm run test:v9:availability && pnpm run build && node --test test/*.test.mjs",
|
|
81
|
+
"test:v9:properties": "node --test codegen/v9/heuristic-generation/generate/property.test.ts src/legacy-v9/parser/rentals/render-property-attribute.test.ts src/legacy-v9/parser/rentals/to-rooms.test.ts",
|
|
82
|
+
"test:v9:availability": "node --test src/legacy-v9/parser/availability/to-initial-availability-calendar-days.test.ts",
|
|
82
83
|
"playground:custom-attributes": "pnpm run build && node --env-file=.env playground/custom-attributes.ts"
|
|
83
84
|
}
|
|
84
85
|
}
|