@v-office/website-sdk 2.14.0 → 2.16.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-BvQRpzYY.mjs → client-CaZZGJAW.mjs} +8 -4
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +1 -1
- package/dist/instructions/CHANGELOG.md +2 -0
- package/dist/instructions/MIGRATION.md +2 -0
- package/dist/instructions/README.md +8 -2
- package/dist/instructions/quote.md +30 -0
- package/dist/instructions/rentals.md +36 -0
- package/dist/instructions/versions/2.15.0/CHANGELOG.md +66 -0
- package/dist/instructions/versions/2.15.0/MIGRATION.md +148 -0
- package/dist/instructions/versions/2.16.0/CHANGELOG.md +44 -0
- package/dist/instructions/versions/2.16.0/MIGRATION.md +109 -0
- package/dist/{quote-Qy_affum.mjs → quote-C-Bs3XTE.mjs} +1 -0
- package/dist/{rentals-CN01jEkv.mjs → rentals--cnnFS4I.mjs} +3 -1
- package/dist/{search-uXcReJdL.mjs → search-Dqiou4mc.mjs} +2 -2
- package/dist/{to-rental-highlights-D_VRHaaC.mjs → to-rental-highlights-BAsEuxoy.mjs} +43 -2
- package/instructions/CHANGELOG.md +2 -0
- package/instructions/MIGRATION.md +2 -0
- package/instructions/README.md +8 -2
- package/instructions/quote.md +30 -0
- package/instructions/rentals.md +36 -0
- package/instructions/versions/2.15.0/CHANGELOG.md +66 -0
- package/instructions/versions/2.15.0/MIGRATION.md +148 -0
- package/instructions/versions/2.16.0/CHANGELOG.md +44 -0
- package/instructions/versions/2.16.0/MIGRATION.md +109 -0
- package/package.json +2 -2
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-CaZZGJAW.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.16.0";
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/cli/output.ts
|
|
22
22
|
const toJson = (value) => Effect.try({
|
|
@@ -5202,7 +5202,7 @@ const bookV9Insurance = ({ quote, bookingNumber, guestToken, v1Client }) => Effe
|
|
|
5202
5202
|
//#region src/legacy-v9/live/quote.ts
|
|
5203
5203
|
const loadQuoteRuntime = Effect.tryPromise({
|
|
5204
5204
|
try: async () => {
|
|
5205
|
-
return { toGuestQuote: (await import("./quote-
|
|
5205
|
+
return { toGuestQuote: (await import("./quote-C-Bs3XTE.mjs")).toGuestQuote };
|
|
5206
5206
|
},
|
|
5207
5207
|
catch: (cause) => new CoreSDKError({
|
|
5208
5208
|
source: "v10",
|
|
@@ -5477,7 +5477,7 @@ const parseV9SearchCursor = (cursor) => Effect.gen(function* () {
|
|
|
5477
5477
|
return page;
|
|
5478
5478
|
});
|
|
5479
5479
|
const loadV9SearchRuntime = Effect.tryPromise({
|
|
5480
|
-
try: () => import("./search-
|
|
5480
|
+
try: () => import("./search-Dqiou4mc.mjs"),
|
|
5481
5481
|
catch: (cause) => new CoreSDKError({
|
|
5482
5482
|
source: "v10",
|
|
5483
5483
|
operation: "v9.search.runtime",
|
|
@@ -5820,7 +5820,11 @@ const makeV9FilterApi = ({ options }) => {
|
|
|
5820
5820
|
};
|
|
5821
5821
|
//#endregion
|
|
5822
5822
|
//#region src/legacy-v9/static/rentals.ts
|
|
5823
|
-
const DEFAULT_RENTAL_FACILITY_DATA_ATTRIBUTES = [
|
|
5823
|
+
const DEFAULT_RENTAL_FACILITY_DATA_ATTRIBUTES = [
|
|
5824
|
+
"name",
|
|
5825
|
+
"description",
|
|
5826
|
+
"images"
|
|
5827
|
+
];
|
|
5824
5828
|
const DEFAULT_RENTAL_RATING_DATA_ATTRIBUTES = [];
|
|
5825
5829
|
const DEFAULT_RENTAL_FEEDBACK_DATA_ATTRIBUTES = [
|
|
5826
5830
|
"id",
|
|
@@ -5840,7 +5844,7 @@ const DEFAULT_RENTAL_FEEDBACK_DATA_ATTRIBUTES = [
|
|
|
5840
5844
|
"avgRating"
|
|
5841
5845
|
];
|
|
5842
5846
|
const loadV9RentalsRuntime = Effect.tryPromise({
|
|
5843
|
-
try: () => import("./rentals
|
|
5847
|
+
try: () => import("./rentals--cnnFS4I.mjs"),
|
|
5844
5848
|
catch: (cause) => new CoreSDKError({
|
|
5845
5849
|
source: "v10",
|
|
5846
5850
|
operation: "v9.rentals.runtime",
|
package/dist/index.d.mts
CHANGED
|
@@ -7334,6 +7334,17 @@ type KnownVofficeImageDataAttribute = KnownDataAttribute<KnownVofficeImageData>;
|
|
|
7334
7334
|
declare const VofficeFacilityDataFieldSchemas: {
|
|
7335
7335
|
readonly name: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.String>]>;
|
|
7336
7336
|
readonly description: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.String>]>;
|
|
7337
|
+
readonly images: Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
7338
|
+
readonly id: Schema.optionalKey<Schema.Number>;
|
|
7339
|
+
readonly width: Schema.optionalKey<Schema.Number>;
|
|
7340
|
+
readonly height: Schema.optionalKey<Schema.Number>;
|
|
7341
|
+
readonly name: Schema.optionalKey<Schema.String>;
|
|
7342
|
+
readonly ask: Schema.optionalKey<Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.Number]>>>;
|
|
7343
|
+
readonly tag: Schema.optionalKey<Schema.String>;
|
|
7344
|
+
readonly otaId: Schema.optionalKey<Schema.Number>;
|
|
7345
|
+
readonly titles: Schema.optionalKey<Schema.Unknown>;
|
|
7346
|
+
readonly season: Schema.optionalKey<Schema.String>;
|
|
7347
|
+
}>>>;
|
|
7337
7348
|
};
|
|
7338
7349
|
type KnownVofficeFacilityData = KnownJsonData<typeof VofficeFacilityDataFieldSchemas>;
|
|
7339
7350
|
type ParsedVofficeFacilityData = ParsedJsonData<KnownVofficeFacilityData>;
|
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-CaZZGJAW.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,8 @@ This file is the versioned changelog index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Versions
|
|
6
6
|
|
|
7
|
+
- `versions/2.16.0/CHANGELOG.md`: `@v-office/website-sdk` 2.16.0 release notes.
|
|
8
|
+
- `versions/2.15.0/CHANGELOG.md`: `@v-office/website-sdk` 2.15.0 release notes.
|
|
7
9
|
- `versions/2.14.0/CHANGELOG.md`: `@v-office/website-sdk` 2.14.0 release notes.
|
|
8
10
|
- `versions/2.13.0/CHANGELOG.md`: `@v-office/website-sdk` 2.13.0 release notes.
|
|
9
11
|
- `versions/2.12.0/CHANGELOG.md`: `@v-office/website-sdk` 2.12.0 release notes.
|
|
@@ -4,6 +4,8 @@ This file is the versioned migration index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Available Guides
|
|
6
6
|
|
|
7
|
+
- `versions/2.16.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.15.0 to 2.16.0.
|
|
8
|
+
- `versions/2.15.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.14.0 to 2.15.0.
|
|
7
9
|
- `versions/2.14.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.13.0 to 2.14.0.
|
|
8
10
|
- `versions/2.13.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.12.0 to 2.13.0.
|
|
9
11
|
- `versions/2.12.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.11.0 to 2.12.0.
|
|
@@ -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.16.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,12 @@ 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.16.0/`: 2.16.0 machine-readable unavailable quote codes,
|
|
22
|
+
multi-rate configuration diagnostics, and the 2.15.0-to-2.16.0 migration
|
|
23
|
+
guide.
|
|
24
|
+
- `versions/2.15.0/`: 2.15.0 v9 facility images in normalized
|
|
25
|
+
`property.images`, responsive vOffice image URLs, and the 2.14.0-to-2.15.0
|
|
26
|
+
migration guide.
|
|
21
27
|
- `versions/2.14.0/`: 2.14.0 catalog-backed v9 property types and options,
|
|
22
28
|
corrected option/count rendering and translations, and the 2.13.0-to-2.14.0
|
|
23
29
|
migration guide.
|
|
@@ -90,5 +96,5 @@ website-sdk --backend v10 search --locale de-DE --query "adults=2" --sort '{"by"
|
|
|
90
96
|
```
|
|
91
97
|
|
|
92
98
|
Config file examples in these docs use the flat `WebsiteSDKConfig` shape introduced
|
|
93
|
-
in 2.0.0 and kept in 2.
|
|
99
|
+
in 2.0.0 and kept in 2.16.0. v10 config additionally requires `searchEndpoint` as
|
|
94
100
|
of 2.5.0.
|
|
@@ -133,10 +133,40 @@ Unavailable sample:
|
|
|
133
133
|
```json
|
|
134
134
|
{
|
|
135
135
|
"status": "unavailable",
|
|
136
|
+
"code": "NotBookable",
|
|
136
137
|
"reason": "Rental is not available for the selected period."
|
|
137
138
|
}
|
|
138
139
|
```
|
|
139
140
|
|
|
141
|
+
From 2.16.0, every unavailable quote includes a machine-readable `code`:
|
|
142
|
+
|
|
143
|
+
- `NotBookable`: the backend did not return a bookable price, including normal
|
|
144
|
+
availability failures. Legacy v9 unavailable quotes always use this code.
|
|
145
|
+
- `AmbiguousMultiRate`: v10 priced the stay, but more than one multi-rate
|
|
146
|
+
matched the default cancellation policy.
|
|
147
|
+
- `UnresolvableMultiRate`: v10 priced the stay, but no multi-rate could be
|
|
148
|
+
resolved for the default cancellation policy.
|
|
149
|
+
|
|
150
|
+
Use `code` for application behavior and logging. `reason` remains localized
|
|
151
|
+
display text and can be identical for inventory and multi-rate failures. The SDK
|
|
152
|
+
keeps ambiguous and unresolvable v10 quotes unavailable because booking requires
|
|
153
|
+
one exact multi-rate.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const result = await sdk.live.quote.quote(input);
|
|
157
|
+
|
|
158
|
+
if (result.status === "unavailable") {
|
|
159
|
+
if (result.code === "AmbiguousMultiRate" || result.code === "UnresolvableMultiRate") {
|
|
160
|
+
reportQuoteConfigurationProblem(result.code);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
showUnavailableMessage(result.reason);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
See `versions/2.16.0/CHANGELOG.md` and
|
|
168
|
+
`versions/2.16.0/MIGRATION.md` for release and upgrade details.
|
|
169
|
+
|
|
140
170
|
Selection methods return `{ ok: true, quote }` or `{ ok: false, error }`. Possible selection errors include unknown additional service, additional service limit exceeded, unknown cancellation policy, unavailable cancellation policy quote, and unavailable quote combination.
|
|
141
171
|
|
|
142
172
|
## Booking-Card Breakdown
|
|
@@ -87,6 +87,42 @@ Sample item:
|
|
|
87
87
|
|
|
88
88
|
Optional fields include `scope`, `address`, `property`, `rooms`, `roomSummary`, `vicinity`, and `reviews`.
|
|
89
89
|
|
|
90
|
+
### Legacy v9 Facility Images
|
|
91
|
+
|
|
92
|
+
From 2.15.0, v9 static rentals request facility image metadata and return it in
|
|
93
|
+
`property.images`:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"property": {
|
|
98
|
+
"id": "1512",
|
|
99
|
+
"nameOrLabel": "Haus Köbesine",
|
|
100
|
+
"images": [
|
|
101
|
+
{
|
|
102
|
+
"idOrPath": "28458352",
|
|
103
|
+
"src": "https://dyn.v-office.com/image/xl/28458352.jpg",
|
|
104
|
+
"srcset": "https://dyn.v-office.com/image/tn/28458352.jpg 141w, https://dyn.v-office.com/image/tnx/28458352.jpg 225w, https://dyn.v-office.com/image/s/28458352.jpg 450w, https://dyn.v-office.com/image/m/28458352.jpg 600w, https://dyn.v-office.com/image/xl/28458352.jpg 1440w, https://dyn.v-office.com/image/xxl/28458352.jpg 2400w",
|
|
105
|
+
"alt": "Hauptansicht",
|
|
106
|
+
"title": "Hauptansicht",
|
|
107
|
+
"category": "buildingMain"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Facility image `src` and `srcset` URLs use `dyn.v-office.com`. Top-level v9
|
|
115
|
+
rental `images` continue to use the configured `imageProxyBaseUrl`. Consumers
|
|
116
|
+
must allow both origins when they render both collections.
|
|
117
|
+
|
|
118
|
+
The SDK supplies width-descriptor `srcset`; the UI remains responsible for an
|
|
119
|
+
HTML `sizes` attribute that matches its layout. `property.images` is omitted
|
|
120
|
+
when the facility has no usable image IDs. Because the service returns one item
|
|
121
|
+
per rental, rentals in the same facility contain the same nested property image
|
|
122
|
+
list.
|
|
123
|
+
|
|
124
|
+
See `versions/2.15.0/CHANGELOG.md` and `versions/2.15.0/MIGRATION.md`.
|
|
125
|
+
|
|
90
126
|
### Legacy v9 Built-In Attributes
|
|
91
127
|
|
|
92
128
|
From 2.14.0, built-in v9 property types and ordered option values come from the
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Changelog: 2.15.0
|
|
2
|
+
|
|
3
|
+
This release adds facility images to normalized v9 static rental output. v9
|
|
4
|
+
consumers can now read responsive property images from the same
|
|
5
|
+
`property.images` field already used by the shared rental contract.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- v9 static rentals request the facility `images` data attribute through the
|
|
10
|
+
existing GraphQL `all` query.
|
|
11
|
+
- Parsed facility images are exposed under:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
rental.property?.images;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Every mapped facility image includes:
|
|
18
|
+
- `idOrPath` from the vOffice image ID
|
|
19
|
+
- an `xl` fallback `src`
|
|
20
|
+
- a responsive width-descriptor `srcset`
|
|
21
|
+
- localized `alt` and `title` when a title is available
|
|
22
|
+
- `category` when vOffice supplies an image tag
|
|
23
|
+
- the original v9 image metadata under `metadata.dataImage`
|
|
24
|
+
- The generated v9 facility-data schema recognizes facility image records and
|
|
25
|
+
validates them with the existing `ImageDataSchema`.
|
|
26
|
+
- Facility `srcset` candidates use the unique vOffice dynamic-image presets:
|
|
27
|
+
`141w`, `225w`, `450w`, `600w`, `1440w`, and `2400w`. Candidates are capped
|
|
28
|
+
at the known original image width and duplicate widths are omitted.
|
|
29
|
+
|
|
30
|
+
## Changed
|
|
31
|
+
|
|
32
|
+
- v9 facility image bytes are served by the documented vOffice dynamic-image
|
|
33
|
+
origin:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
https://dyn.v-office.com/image/<size>/<image-id>.jpg
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- Facility images no longer need to be inferred from a rental image storage
|
|
40
|
+
path. That inference was invalid because facility image IDs are not present
|
|
41
|
+
in the v9 rental image rows.
|
|
42
|
+
- A v9 property shared by several rentals carries the same facility image list
|
|
43
|
+
on each normalized rental's nested `property` object.
|
|
44
|
+
|
|
45
|
+
## Unchanged
|
|
46
|
+
|
|
47
|
+
- `sdk.static.rentals.getRentals({ locale })` and its input are unchanged.
|
|
48
|
+
- The public `RentalPropertySchema` and image shape are unchanged because
|
|
49
|
+
`property.images` was already part of the shared contract.
|
|
50
|
+
- Top-level v9 rental `images` continue to use the configured
|
|
51
|
+
`imageProxyBaseUrl`.
|
|
52
|
+
- v10 rental and property image behavior is unchanged.
|
|
53
|
+
- No new SDK configuration or environment variable is required.
|
|
54
|
+
|
|
55
|
+
## Compatibility
|
|
56
|
+
|
|
57
|
+
- This is an additive output change. v9 consumers that ignore
|
|
58
|
+
`property.images` do not need code changes.
|
|
59
|
+
- Content Security Policy or image-host allowlists must permit
|
|
60
|
+
`https://dyn.v-office.com` before rendering the new v9 property images.
|
|
61
|
+
- Snapshots that include complete v9 property objects must account for the new
|
|
62
|
+
optional `images` field.
|
|
63
|
+
- Facility image entries without a numeric vOffice image ID are omitted because
|
|
64
|
+
no deterministic dynamic-image URL can be constructed.
|
|
65
|
+
|
|
66
|
+
See `versions/2.15.0/MIGRATION.md` and `../../rentals.md`.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Migration: 2.14.0 to 2.15.0
|
|
2
|
+
|
|
3
|
+
2.15.0 adds facility images to v9 static rental properties. The SDK call,
|
|
4
|
+
configuration, and public TypeScript shape are unchanged, but complete v9
|
|
5
|
+
property objects can now contain `images`.
|
|
6
|
+
|
|
7
|
+
Consumers that use only v10 are not affected.
|
|
8
|
+
|
|
9
|
+
## 1. Allow the vOffice Image Origin
|
|
10
|
+
|
|
11
|
+
v9 facility image URLs use:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
https://dyn.v-office.com
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add that origin to image-host allowlists and Content Security Policy before
|
|
18
|
+
rendering `property.images`. For example:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Content-Security-Policy: img-src 'self' https://dyn.v-office.com
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Top-level v9 rental images still use the configured `imageProxyBaseUrl`. A page
|
|
25
|
+
that renders both image kinds must allow both origins.
|
|
26
|
+
|
|
27
|
+
## 2. Read Facility Images from `property.images`
|
|
28
|
+
|
|
29
|
+
No new service call is required:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const rentals = await sdk.static.rentals.getRentals({ locale: "de-DE" });
|
|
33
|
+
|
|
34
|
+
for (const rental of rentals) {
|
|
35
|
+
for (const image of rental.property?.images ?? []) {
|
|
36
|
+
renderPropertyImage(image);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The field remains optional. It is omitted when a rental has no facility, when
|
|
42
|
+
the facility has no images, or when no facility image has a usable numeric ID.
|
|
43
|
+
|
|
44
|
+
Example image:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"idOrPath": "28458352",
|
|
49
|
+
"src": "https://dyn.v-office.com/image/xl/28458352.jpg",
|
|
50
|
+
"srcset": "https://dyn.v-office.com/image/tn/28458352.jpg 141w, https://dyn.v-office.com/image/tnx/28458352.jpg 225w, https://dyn.v-office.com/image/s/28458352.jpg 450w, https://dyn.v-office.com/image/m/28458352.jpg 600w, https://dyn.v-office.com/image/xl/28458352.jpg 1440w, https://dyn.v-office.com/image/xxl/28458352.jpg 2400w",
|
|
51
|
+
"alt": "Hauptansicht",
|
|
52
|
+
"title": "Hauptansicht",
|
|
53
|
+
"category": "buildingMain"
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 3. Provide the Layout-Specific `sizes` Attribute
|
|
58
|
+
|
|
59
|
+
The SDK provides `src` and `srcset`. The consuming UI must provide `sizes`
|
|
60
|
+
because only the application knows the rendered layout:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
<img
|
|
64
|
+
src={image.src}
|
|
65
|
+
srcSet={image.srcset}
|
|
66
|
+
sizes="(max-width: 768px) 100vw, 50vw"
|
|
67
|
+
alt={image.alt ?? ""}
|
|
68
|
+
/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Do not copy that example `sizes` value blindly. Match it to the actual image
|
|
72
|
+
width in the application's responsive layout.
|
|
73
|
+
|
|
74
|
+
The fallback `src` uses the `xl` vOffice preset. Browsers that support `srcset`
|
|
75
|
+
select an appropriate candidate using `srcset`, `sizes`, viewport width, and
|
|
76
|
+
device pixel ratio.
|
|
77
|
+
|
|
78
|
+
## 4. Keep Rental and Property Images Distinct
|
|
79
|
+
|
|
80
|
+
The two image collections represent different entities:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
rental.images; // images belonging to the rental/unit
|
|
84
|
+
rental.property?.images; // images belonging to the facility/property
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
They also use different origins in v9:
|
|
88
|
+
|
|
89
|
+
- `rental.images`: configured `imageProxyBaseUrl`
|
|
90
|
+
- `rental.property.images`: `https://dyn.v-office.com`
|
|
91
|
+
|
|
92
|
+
Do not merge the arrays unless the UI deliberately presents a combined gallery.
|
|
93
|
+
Keeping them separate prevents facility images from being mistaken for
|
|
94
|
+
unit-specific rooms or amenities.
|
|
95
|
+
|
|
96
|
+
## 5. Account for Repeated Property Data
|
|
97
|
+
|
|
98
|
+
The normalized rentals API returns one item per rental. When several rentals
|
|
99
|
+
belong to the same facility, each rental contains the same nested property image
|
|
100
|
+
list.
|
|
101
|
+
|
|
102
|
+
Applications that build a property-level view can deduplicate by `property.id`:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const properties = new Map(
|
|
106
|
+
rentals.flatMap((rental) =>
|
|
107
|
+
rental.property == null ? [] : [[rental.property.id, rental.property] as const],
|
|
108
|
+
),
|
|
109
|
+
);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
No separate property endpoint or persistence layer was added in 2.15.0.
|
|
113
|
+
|
|
114
|
+
## 6. Update Snapshots and Complete-Object Assertions
|
|
115
|
+
|
|
116
|
+
Tests that compare only selected property fields are unaffected. Tests that
|
|
117
|
+
snapshot or deeply compare complete v9 rental output can now observe:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
rental.property.images;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Update those expectations without making `property.images` mandatory. Backend
|
|
124
|
+
facilities are allowed to have no usable images.
|
|
125
|
+
|
|
126
|
+
## Required Consumer Work
|
|
127
|
+
|
|
128
|
+
For applications that render v9 property images:
|
|
129
|
+
|
|
130
|
+
1. Allow `https://dyn.v-office.com` in CSP and image-host configuration.
|
|
131
|
+
2. Render `rental.property.images` separately from top-level rental images.
|
|
132
|
+
3. Supply an HTML `sizes` value appropriate for the layout.
|
|
133
|
+
4. Keep empty and missing image arrays valid.
|
|
134
|
+
5. Update complete-output snapshots.
|
|
135
|
+
|
|
136
|
+
Applications that do not render v9 property images require no migration work.
|
|
137
|
+
|
|
138
|
+
## Recommended Verification
|
|
139
|
+
|
|
140
|
+
1. Fetch v9 static rentals in both `de-DE` and `en-US`.
|
|
141
|
+
2. Confirm facilities with images expose `property.images`.
|
|
142
|
+
3. Confirm localized image titles populate `alt` and `title`.
|
|
143
|
+
4. Confirm the browser selects responsive candidates after adding `sizes`.
|
|
144
|
+
5. Confirm `dyn.v-office.com` is accepted by production CSP.
|
|
145
|
+
6. Confirm top-level rental images still use the configured image proxy.
|
|
146
|
+
7. Confirm a shared facility does not create duplicate property cards when the
|
|
147
|
+
application deduplicates by `property.id`.
|
|
148
|
+
8. Confirm v10 rental and property image rendering remains unchanged.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog: 2.16.0
|
|
2
|
+
|
|
3
|
+
This release makes unavailable quote results machine-readable. Applications can
|
|
4
|
+
now distinguish normal booking unavailability from v10 multi-rate
|
|
5
|
+
configuration failures without parsing localized text.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- Every unavailable `GuestQuoteResult` contains a `code`:
|
|
10
|
+
- `NotBookable`
|
|
11
|
+
- `AmbiguousMultiRate`
|
|
12
|
+
- `UnresolvableMultiRate`
|
|
13
|
+
- The public quote output schema validates the new code.
|
|
14
|
+
- v10 reports `AmbiguousMultiRate` when a priced default cancellation policy
|
|
15
|
+
matches more than one multi-rate.
|
|
16
|
+
- v10 reports `UnresolvableMultiRate` when a priced default cancellation policy
|
|
17
|
+
cannot be mapped to a multi-rate.
|
|
18
|
+
|
|
19
|
+
## Changed
|
|
20
|
+
|
|
21
|
+
- Legacy v9 unavailable quotes now include `code: "NotBookable"`.
|
|
22
|
+
- Normal v10 quote failures also use `code: "NotBookable"`.
|
|
23
|
+
- v10 retains the exact default-policy multi-rate resolution result instead of
|
|
24
|
+
reducing it to a boolean before creating the public unavailable result.
|
|
25
|
+
|
|
26
|
+
## Unchanged
|
|
27
|
+
|
|
28
|
+
- `sdk.live.quote.quote(input)` and its input are unchanged.
|
|
29
|
+
- Available quote results remain `{ status: "available", quote }`.
|
|
30
|
+
- Unavailable results retain the localized `reason` field.
|
|
31
|
+
- Ambiguous or unresolvable v10 multi-rates remain unavailable. The SDK does not
|
|
32
|
+
select an arbitrary fallback because booking requires one exact multi-rate.
|
|
33
|
+
- Search and calendar availability behavior are unchanged.
|
|
34
|
+
|
|
35
|
+
## Compatibility
|
|
36
|
+
|
|
37
|
+
- Consumers that only inspect `status` and display `reason` continue to work.
|
|
38
|
+
- TypeScript mocks, complete-object assertions, snapshots, and schema fixtures
|
|
39
|
+
for unavailable quotes must include `code`.
|
|
40
|
+
- Application behavior should branch on `code`, not localized `reason`.
|
|
41
|
+
- `AmbiguousMultiRate` and `UnresolvableMultiRate` indicate configuration or
|
|
42
|
+
mapping problems and should normally be reported to site operations.
|
|
43
|
+
|
|
44
|
+
See `versions/2.16.0/MIGRATION.md` and `../../quote.md`.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Migration: 2.15.0 to 2.16.0
|
|
2
|
+
|
|
3
|
+
2.16.0 adds a required machine-readable `code` to unavailable quote results.
|
|
4
|
+
The service call, quote input, available result, and localized unavailable
|
|
5
|
+
`reason` are unchanged.
|
|
6
|
+
|
|
7
|
+
## 1. Handle the Unavailable Code
|
|
8
|
+
|
|
9
|
+
An unavailable result now has this shape:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
type UnavailableGuestQuoteResult = {
|
|
13
|
+
readonly status: "unavailable";
|
|
14
|
+
readonly code: "NotBookable" | "AmbiguousMultiRate" | "UnresolvableMultiRate";
|
|
15
|
+
readonly reason: string;
|
|
16
|
+
};
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Branch on `code` after narrowing by `status`:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const result = await sdk.live.quote.quote(input);
|
|
23
|
+
|
|
24
|
+
if (result.status === "unavailable") {
|
|
25
|
+
switch (result.code) {
|
|
26
|
+
case "AmbiguousMultiRate":
|
|
27
|
+
case "UnresolvableMultiRate":
|
|
28
|
+
reportQuoteConfigurationProblem(result.code);
|
|
29
|
+
break;
|
|
30
|
+
case "NotBookable":
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
showUnavailableMessage(result.reason);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Keep displaying `reason` when appropriate, but do not parse or compare it to
|
|
39
|
+
select application behavior. It is localized and can still contain the same
|
|
40
|
+
text for different codes.
|
|
41
|
+
|
|
42
|
+
## 2. Treat Multi-Rate Codes as Operational Failures
|
|
43
|
+
|
|
44
|
+
The v10-specific codes mean:
|
|
45
|
+
|
|
46
|
+
- `AmbiguousMultiRate`: the stay was priced, but more than one multi-rate
|
|
47
|
+
matched the default cancellation policy.
|
|
48
|
+
- `UnresolvableMultiRate`: the stay was priced, but no multi-rate could be
|
|
49
|
+
resolved for the default cancellation policy.
|
|
50
|
+
|
|
51
|
+
These are not proof that another guest booked the period. Keep the public quote
|
|
52
|
+
unavailable, show suitable fallback copy, and send the code to monitoring or
|
|
53
|
+
site operations so the rental configuration can be corrected.
|
|
54
|
+
|
|
55
|
+
Do not retry booking with an arbitrary multi-rate. The price alone does not
|
|
56
|
+
identify the exact multi-rate required by the booking request.
|
|
57
|
+
|
|
58
|
+
## 3. Keep Normal Unavailability Handling
|
|
59
|
+
|
|
60
|
+
`NotBookable` represents ordinary unavailable quote results, including backend
|
|
61
|
+
responses without a bookable price:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
if (result.status === "unavailable" && result.code === "NotBookable") {
|
|
65
|
+
showUnavailableMessage(result.reason);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Legacy v9 unavailable quotes always use `NotBookable`. No v9 configuration or
|
|
70
|
+
request change is required.
|
|
71
|
+
|
|
72
|
+
## 4. Update Mocks, Fixtures, and Snapshots
|
|
73
|
+
|
|
74
|
+
Add `code` anywhere an unavailable result is constructed or compared:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const unavailableQuote = {
|
|
78
|
+
status: "unavailable",
|
|
79
|
+
code: "NotBookable",
|
|
80
|
+
reason: "Not available",
|
|
81
|
+
} as const;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Update:
|
|
85
|
+
|
|
86
|
+
1. TypeScript mocks typed as `GuestQuoteResult` or `QuoteQuoteOutput`.
|
|
87
|
+
2. JSON fixtures decoded with `QuoteQuoteOutputSchema`.
|
|
88
|
+
3. Complete-object assertions and snapshots.
|
|
89
|
+
4. API adapters that persist or forward quote results.
|
|
90
|
+
|
|
91
|
+
Available-result fixtures require no changes.
|
|
92
|
+
|
|
93
|
+
## Required Consumer Work
|
|
94
|
+
|
|
95
|
+
1. Add `code` to unavailable quote mocks and fixtures.
|
|
96
|
+
2. Replace reason-string comparisons with code checks.
|
|
97
|
+
3. Route `AmbiguousMultiRate` and `UnresolvableMultiRate` to operational
|
|
98
|
+
diagnostics.
|
|
99
|
+
4. Keep all three codes unavailable in booking UI.
|
|
100
|
+
|
|
101
|
+
## Recommended Verification
|
|
102
|
+
|
|
103
|
+
1. Confirm a normal blocked period returns `NotBookable`.
|
|
104
|
+
2. Confirm unavailable copy still uses the localized `reason`.
|
|
105
|
+
3. Confirm monitoring distinguishes both multi-rate codes from
|
|
106
|
+
`NotBookable`.
|
|
107
|
+
4. Confirm the UI never enables booking for either multi-rate code.
|
|
108
|
+
5. Confirm available quote, option selection, and booking flows are unchanged.
|
|
109
|
+
6. Confirm legacy v9 unavailable quote snapshots include `NotBookable`.
|
|
@@ -286,6 +286,7 @@ const toGuestQuote = (input, guestQuoteResult, locale, translations, options) =>
|
|
|
286
286
|
const errorReason = toErrorReason(guestQuoteResult);
|
|
287
287
|
if (errorReason !== void 0) return {
|
|
288
288
|
status: "unavailable",
|
|
289
|
+
code: "NotBookable",
|
|
289
290
|
reason: errorReason
|
|
290
291
|
};
|
|
291
292
|
const sections = yield* toSections({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as toAddress, c as rentalsAllFeedbacksQuery, d as VofficeUnitDataPropertyCategoryLabelKeys, f as VofficeUnitDataPropertyCategoryValues, g as parseVofficeUnitData, h as parseVofficeFeedbackData, i as toImages, l as rentalsAllWithoutFeedbacksQuery, m as parseVofficeFacilityData, n as renderVofficePropertyAttribute, o as toLocalizedString, p as VofficeUnitDataPropertyMetadata, r as toFacilityImages, t as toRentalHighlights, u as VofficeUnitDataFieldSchemas } from "./to-rental-highlights-BAsEuxoy.mjs";
|
|
2
2
|
import { makeTranslate, renderResolvedCustomAttribute, toCustomAttributeList, toResolvedCustomAttributeCategoryTranslationKey } from "@v-office/sdk-core";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
//#region src/legacy-v9/parser/rentals/to-description.ts
|
|
@@ -38,11 +38,13 @@ const toProperty = (facility, locale) => {
|
|
|
38
38
|
const data = parseVofficeFacilityData(facility.data);
|
|
39
39
|
const name = toLocalizedString(data.known.name, locale);
|
|
40
40
|
const description = toLocalizedString(data.known.description, locale);
|
|
41
|
+
const images = toFacilityImages(data.known.images ?? [], locale);
|
|
41
42
|
const property = {
|
|
42
43
|
id: facility.id,
|
|
43
44
|
nameOrLabel: name ?? facility.name
|
|
44
45
|
};
|
|
45
46
|
if (description != null) property.description = { description };
|
|
47
|
+
if (images.length > 0) property.images = images;
|
|
46
48
|
return property;
|
|
47
49
|
};
|
|
48
50
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as parseQueryParameters, i as collectQueryParameters, n as makeV9CustomAttributeFilterCapabilities, o as toQueryString, r as toBasicQueryInputs, s as applyVofficeFilterDerivedBasicQueryInputs } from "./client-
|
|
2
|
-
import {
|
|
1
|
+
import { a as parseQueryParameters, i as collectQueryParameters, n as makeV9CustomAttributeFilterCapabilities, o as toQueryString, r as toBasicQueryInputs, s as applyVofficeFilterDerivedBasicQueryInputs } from "./client-CaZZGJAW.mjs";
|
|
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";
|
|
5
5
|
//#region src/legacy-v9/parser/search/input/search-input-error.ts
|
|
@@ -4861,7 +4861,8 @@ Schema.String, Schema.String;
|
|
|
4861
4861
|
/** Known structure of VofficeFacility.data attributes. */
|
|
4862
4862
|
const VofficeFacilityDataFieldSchemas = {
|
|
4863
4863
|
name: localizedString,
|
|
4864
|
-
description: localizedString
|
|
4864
|
+
description: localizedString,
|
|
4865
|
+
images: Schema.mutable(Schema.Array(ImageDataSchema))
|
|
4865
4866
|
};
|
|
4866
4867
|
const parseVofficeFacilityData = (input) => parseJsonData(VofficeFacilityDataFieldSchemas, input);
|
|
4867
4868
|
Schema.String, Schema.String, Schema.Number, Schema.String;
|
|
@@ -6754,12 +6755,33 @@ const IMAGE_SRCSET_WIDTHS = [
|
|
|
6754
6755
|
2560
|
|
6755
6756
|
];
|
|
6756
6757
|
const IMAGE_DEFAULT_WIDTH = 960;
|
|
6758
|
+
const VOFFICE_DYNAMIC_IMAGE_BASE_URL = "https://dyn.v-office.com/image";
|
|
6759
|
+
const VOFFICE_DYNAMIC_IMAGE_SIZES = [
|
|
6760
|
+
["tn", 141],
|
|
6761
|
+
["tnx", 225],
|
|
6762
|
+
["s", 450],
|
|
6763
|
+
["m", 600],
|
|
6764
|
+
["xl", 1440],
|
|
6765
|
+
["xxl", 2400]
|
|
6766
|
+
];
|
|
6767
|
+
const VOFFICE_DYNAMIC_IMAGE_DEFAULT_SIZE = "xl";
|
|
6757
6768
|
const buildImageUrl = (imageProxyBaseUrl, path, width) => {
|
|
6758
6769
|
const base = imageProxyBaseUrl.replace(/\/$/, "");
|
|
6759
6770
|
const normalizedPath = path.replace(/^\/+/, "");
|
|
6760
6771
|
return `${base}/_/rs:fill:${width}:${Math.round(width / IMAGE_ASPECT_RATIO)}:0/plain/${normalizedPath}`;
|
|
6761
6772
|
};
|
|
6762
6773
|
const buildSrcset = (imageProxyBaseUrl, path) => IMAGE_SRCSET_WIDTHS.map((width) => `${buildImageUrl(imageProxyBaseUrl, path, width)} ${width}w`).join(", ");
|
|
6774
|
+
const buildVofficeDynamicImageUrl = (imageId, size) => `${VOFFICE_DYNAMIC_IMAGE_BASE_URL}/${size}/${imageId}.jpg`;
|
|
6775
|
+
const buildVofficeDynamicImageSrcset = (imageId, originalImageWidth) => {
|
|
6776
|
+
const originalWidth = originalImageWidth != null && originalImageWidth > 0 ? originalImageWidth : void 0;
|
|
6777
|
+
const seenWidths = /* @__PURE__ */ new Set();
|
|
6778
|
+
return VOFFICE_DYNAMIC_IMAGE_SIZES.flatMap(([size, maximumWidth]) => {
|
|
6779
|
+
const width = originalWidth == null ? maximumWidth : Math.min(maximumWidth, originalWidth);
|
|
6780
|
+
if (seenWidths.has(width)) return [];
|
|
6781
|
+
seenWidths.add(width);
|
|
6782
|
+
return [`${buildVofficeDynamicImageUrl(imageId, size)} ${width}w`];
|
|
6783
|
+
}).join(", ");
|
|
6784
|
+
};
|
|
6763
6785
|
const isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
6764
6786
|
const toDataImageId = (dataImage) => dataImage?.id?.toString();
|
|
6765
6787
|
const getImagePath = (entry) => entry.image?.path ?? entry.normalizedPath;
|
|
@@ -6864,6 +6886,25 @@ const toImage = (imageProxyBaseUrl, entry, locale) => {
|
|
|
6864
6886
|
const toImages = (imageProxyBaseUrl, rental, locale, data) => {
|
|
6865
6887
|
return mergeImageEntries(getImageEntries(rental, data)).map((entry) => toImage(imageProxyBaseUrl, entry, locale));
|
|
6866
6888
|
};
|
|
6889
|
+
const toFacilityImages = (images, locale) => images.flatMap((image) => {
|
|
6890
|
+
if (image.id == null) return [];
|
|
6891
|
+
const title = toLocalizedString(image.titles, locale);
|
|
6892
|
+
const item = {
|
|
6893
|
+
idOrPath: image.id.toString(),
|
|
6894
|
+
src: buildVofficeDynamicImageUrl(image.id, VOFFICE_DYNAMIC_IMAGE_DEFAULT_SIZE),
|
|
6895
|
+
srcset: buildVofficeDynamicImageSrcset(image.id, image.width),
|
|
6896
|
+
metadata: {
|
|
6897
|
+
source: "voffice_facility_data_images",
|
|
6898
|
+
dataImage: image
|
|
6899
|
+
}
|
|
6900
|
+
};
|
|
6901
|
+
if (title != null) {
|
|
6902
|
+
item.alt = title;
|
|
6903
|
+
item.title = title;
|
|
6904
|
+
}
|
|
6905
|
+
if (image.tag != null) item.category = image.tag;
|
|
6906
|
+
return [item];
|
|
6907
|
+
});
|
|
6867
6908
|
//#endregion
|
|
6868
6909
|
//#region src/legacy-v9/parser/rentals/render-property-attribute.ts
|
|
6869
6910
|
const countLabelKey = (labelKey, value) => `${labelKey.slice(0, -6)}.count.${value === 1 ? "one" : "other"}`;
|
|
@@ -7278,4 +7319,4 @@ const toRentalHighlights = ({ locale, translations, highlightPrioritization, cus
|
|
|
7278
7319
|
return highlights;
|
|
7279
7320
|
});
|
|
7280
7321
|
//#endregion
|
|
7281
|
-
export {
|
|
7322
|
+
export { toAddress as a, rentalsAllFeedbacksQuery as c, VofficeUnitDataPropertyCategoryLabelKeys as d, VofficeUnitDataPropertyCategoryValues as f, parseVofficeUnitData as g, parseVofficeFeedbackData as h, toImages as i, rentalsAllWithoutFeedbacksQuery as l, parseVofficeFacilityData as m, renderVofficePropertyAttribute as n, toLocalizedString as o, VofficeUnitDataPropertyMetadata as p, toFacilityImages as r, searchQuery as s, toRentalHighlights as t, VofficeUnitDataFieldSchemas as u };
|
|
@@ -4,6 +4,8 @@ This file is the versioned changelog index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Versions
|
|
6
6
|
|
|
7
|
+
- `versions/2.16.0/CHANGELOG.md`: `@v-office/website-sdk` 2.16.0 release notes.
|
|
8
|
+
- `versions/2.15.0/CHANGELOG.md`: `@v-office/website-sdk` 2.15.0 release notes.
|
|
7
9
|
- `versions/2.14.0/CHANGELOG.md`: `@v-office/website-sdk` 2.14.0 release notes.
|
|
8
10
|
- `versions/2.13.0/CHANGELOG.md`: `@v-office/website-sdk` 2.13.0 release notes.
|
|
9
11
|
- `versions/2.12.0/CHANGELOG.md`: `@v-office/website-sdk` 2.12.0 release notes.
|
|
@@ -4,6 +4,8 @@ This file is the versioned migration index for the website SDK instructions.
|
|
|
4
4
|
|
|
5
5
|
## Available Guides
|
|
6
6
|
|
|
7
|
+
- `versions/2.16.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.15.0 to 2.16.0.
|
|
8
|
+
- `versions/2.15.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.14.0 to 2.15.0.
|
|
7
9
|
- `versions/2.14.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.13.0 to 2.14.0.
|
|
8
10
|
- `versions/2.13.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.12.0 to 2.13.0.
|
|
9
11
|
- `versions/2.12.0/MIGRATION.md`: migrate from `@v-office/website-sdk` 2.11.0 to 2.12.0.
|
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.16.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,12 @@ 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.16.0/`: 2.16.0 machine-readable unavailable quote codes,
|
|
22
|
+
multi-rate configuration diagnostics, and the 2.15.0-to-2.16.0 migration
|
|
23
|
+
guide.
|
|
24
|
+
- `versions/2.15.0/`: 2.15.0 v9 facility images in normalized
|
|
25
|
+
`property.images`, responsive vOffice image URLs, and the 2.14.0-to-2.15.0
|
|
26
|
+
migration guide.
|
|
21
27
|
- `versions/2.14.0/`: 2.14.0 catalog-backed v9 property types and options,
|
|
22
28
|
corrected option/count rendering and translations, and the 2.13.0-to-2.14.0
|
|
23
29
|
migration guide.
|
|
@@ -90,5 +96,5 @@ website-sdk --backend v10 search --locale de-DE --query "adults=2" --sort '{"by"
|
|
|
90
96
|
```
|
|
91
97
|
|
|
92
98
|
Config file examples in these docs use the flat `WebsiteSDKConfig` shape introduced
|
|
93
|
-
in 2.0.0 and kept in 2.
|
|
99
|
+
in 2.0.0 and kept in 2.16.0. v10 config additionally requires `searchEndpoint` as
|
|
94
100
|
of 2.5.0.
|
package/instructions/quote.md
CHANGED
|
@@ -133,10 +133,40 @@ Unavailable sample:
|
|
|
133
133
|
```json
|
|
134
134
|
{
|
|
135
135
|
"status": "unavailable",
|
|
136
|
+
"code": "NotBookable",
|
|
136
137
|
"reason": "Rental is not available for the selected period."
|
|
137
138
|
}
|
|
138
139
|
```
|
|
139
140
|
|
|
141
|
+
From 2.16.0, every unavailable quote includes a machine-readable `code`:
|
|
142
|
+
|
|
143
|
+
- `NotBookable`: the backend did not return a bookable price, including normal
|
|
144
|
+
availability failures. Legacy v9 unavailable quotes always use this code.
|
|
145
|
+
- `AmbiguousMultiRate`: v10 priced the stay, but more than one multi-rate
|
|
146
|
+
matched the default cancellation policy.
|
|
147
|
+
- `UnresolvableMultiRate`: v10 priced the stay, but no multi-rate could be
|
|
148
|
+
resolved for the default cancellation policy.
|
|
149
|
+
|
|
150
|
+
Use `code` for application behavior and logging. `reason` remains localized
|
|
151
|
+
display text and can be identical for inventory and multi-rate failures. The SDK
|
|
152
|
+
keeps ambiguous and unresolvable v10 quotes unavailable because booking requires
|
|
153
|
+
one exact multi-rate.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const result = await sdk.live.quote.quote(input);
|
|
157
|
+
|
|
158
|
+
if (result.status === "unavailable") {
|
|
159
|
+
if (result.code === "AmbiguousMultiRate" || result.code === "UnresolvableMultiRate") {
|
|
160
|
+
reportQuoteConfigurationProblem(result.code);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
showUnavailableMessage(result.reason);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
See `versions/2.16.0/CHANGELOG.md` and
|
|
168
|
+
`versions/2.16.0/MIGRATION.md` for release and upgrade details.
|
|
169
|
+
|
|
140
170
|
Selection methods return `{ ok: true, quote }` or `{ ok: false, error }`. Possible selection errors include unknown additional service, additional service limit exceeded, unknown cancellation policy, unavailable cancellation policy quote, and unavailable quote combination.
|
|
141
171
|
|
|
142
172
|
## Booking-Card Breakdown
|
package/instructions/rentals.md
CHANGED
|
@@ -87,6 +87,42 @@ Sample item:
|
|
|
87
87
|
|
|
88
88
|
Optional fields include `scope`, `address`, `property`, `rooms`, `roomSummary`, `vicinity`, and `reviews`.
|
|
89
89
|
|
|
90
|
+
### Legacy v9 Facility Images
|
|
91
|
+
|
|
92
|
+
From 2.15.0, v9 static rentals request facility image metadata and return it in
|
|
93
|
+
`property.images`:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"property": {
|
|
98
|
+
"id": "1512",
|
|
99
|
+
"nameOrLabel": "Haus Köbesine",
|
|
100
|
+
"images": [
|
|
101
|
+
{
|
|
102
|
+
"idOrPath": "28458352",
|
|
103
|
+
"src": "https://dyn.v-office.com/image/xl/28458352.jpg",
|
|
104
|
+
"srcset": "https://dyn.v-office.com/image/tn/28458352.jpg 141w, https://dyn.v-office.com/image/tnx/28458352.jpg 225w, https://dyn.v-office.com/image/s/28458352.jpg 450w, https://dyn.v-office.com/image/m/28458352.jpg 600w, https://dyn.v-office.com/image/xl/28458352.jpg 1440w, https://dyn.v-office.com/image/xxl/28458352.jpg 2400w",
|
|
105
|
+
"alt": "Hauptansicht",
|
|
106
|
+
"title": "Hauptansicht",
|
|
107
|
+
"category": "buildingMain"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Facility image `src` and `srcset` URLs use `dyn.v-office.com`. Top-level v9
|
|
115
|
+
rental `images` continue to use the configured `imageProxyBaseUrl`. Consumers
|
|
116
|
+
must allow both origins when they render both collections.
|
|
117
|
+
|
|
118
|
+
The SDK supplies width-descriptor `srcset`; the UI remains responsible for an
|
|
119
|
+
HTML `sizes` attribute that matches its layout. `property.images` is omitted
|
|
120
|
+
when the facility has no usable image IDs. Because the service returns one item
|
|
121
|
+
per rental, rentals in the same facility contain the same nested property image
|
|
122
|
+
list.
|
|
123
|
+
|
|
124
|
+
See `versions/2.15.0/CHANGELOG.md` and `versions/2.15.0/MIGRATION.md`.
|
|
125
|
+
|
|
90
126
|
### Legacy v9 Built-In Attributes
|
|
91
127
|
|
|
92
128
|
From 2.14.0, built-in v9 property types and ordered option values come from the
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Changelog: 2.15.0
|
|
2
|
+
|
|
3
|
+
This release adds facility images to normalized v9 static rental output. v9
|
|
4
|
+
consumers can now read responsive property images from the same
|
|
5
|
+
`property.images` field already used by the shared rental contract.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- v9 static rentals request the facility `images` data attribute through the
|
|
10
|
+
existing GraphQL `all` query.
|
|
11
|
+
- Parsed facility images are exposed under:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
rental.property?.images;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Every mapped facility image includes:
|
|
18
|
+
- `idOrPath` from the vOffice image ID
|
|
19
|
+
- an `xl` fallback `src`
|
|
20
|
+
- a responsive width-descriptor `srcset`
|
|
21
|
+
- localized `alt` and `title` when a title is available
|
|
22
|
+
- `category` when vOffice supplies an image tag
|
|
23
|
+
- the original v9 image metadata under `metadata.dataImage`
|
|
24
|
+
- The generated v9 facility-data schema recognizes facility image records and
|
|
25
|
+
validates them with the existing `ImageDataSchema`.
|
|
26
|
+
- Facility `srcset` candidates use the unique vOffice dynamic-image presets:
|
|
27
|
+
`141w`, `225w`, `450w`, `600w`, `1440w`, and `2400w`. Candidates are capped
|
|
28
|
+
at the known original image width and duplicate widths are omitted.
|
|
29
|
+
|
|
30
|
+
## Changed
|
|
31
|
+
|
|
32
|
+
- v9 facility image bytes are served by the documented vOffice dynamic-image
|
|
33
|
+
origin:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
https://dyn.v-office.com/image/<size>/<image-id>.jpg
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- Facility images no longer need to be inferred from a rental image storage
|
|
40
|
+
path. That inference was invalid because facility image IDs are not present
|
|
41
|
+
in the v9 rental image rows.
|
|
42
|
+
- A v9 property shared by several rentals carries the same facility image list
|
|
43
|
+
on each normalized rental's nested `property` object.
|
|
44
|
+
|
|
45
|
+
## Unchanged
|
|
46
|
+
|
|
47
|
+
- `sdk.static.rentals.getRentals({ locale })` and its input are unchanged.
|
|
48
|
+
- The public `RentalPropertySchema` and image shape are unchanged because
|
|
49
|
+
`property.images` was already part of the shared contract.
|
|
50
|
+
- Top-level v9 rental `images` continue to use the configured
|
|
51
|
+
`imageProxyBaseUrl`.
|
|
52
|
+
- v10 rental and property image behavior is unchanged.
|
|
53
|
+
- No new SDK configuration or environment variable is required.
|
|
54
|
+
|
|
55
|
+
## Compatibility
|
|
56
|
+
|
|
57
|
+
- This is an additive output change. v9 consumers that ignore
|
|
58
|
+
`property.images` do not need code changes.
|
|
59
|
+
- Content Security Policy or image-host allowlists must permit
|
|
60
|
+
`https://dyn.v-office.com` before rendering the new v9 property images.
|
|
61
|
+
- Snapshots that include complete v9 property objects must account for the new
|
|
62
|
+
optional `images` field.
|
|
63
|
+
- Facility image entries without a numeric vOffice image ID are omitted because
|
|
64
|
+
no deterministic dynamic-image URL can be constructed.
|
|
65
|
+
|
|
66
|
+
See `versions/2.15.0/MIGRATION.md` and `../../rentals.md`.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Migration: 2.14.0 to 2.15.0
|
|
2
|
+
|
|
3
|
+
2.15.0 adds facility images to v9 static rental properties. The SDK call,
|
|
4
|
+
configuration, and public TypeScript shape are unchanged, but complete v9
|
|
5
|
+
property objects can now contain `images`.
|
|
6
|
+
|
|
7
|
+
Consumers that use only v10 are not affected.
|
|
8
|
+
|
|
9
|
+
## 1. Allow the vOffice Image Origin
|
|
10
|
+
|
|
11
|
+
v9 facility image URLs use:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
https://dyn.v-office.com
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add that origin to image-host allowlists and Content Security Policy before
|
|
18
|
+
rendering `property.images`. For example:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Content-Security-Policy: img-src 'self' https://dyn.v-office.com
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Top-level v9 rental images still use the configured `imageProxyBaseUrl`. A page
|
|
25
|
+
that renders both image kinds must allow both origins.
|
|
26
|
+
|
|
27
|
+
## 2. Read Facility Images from `property.images`
|
|
28
|
+
|
|
29
|
+
No new service call is required:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const rentals = await sdk.static.rentals.getRentals({ locale: "de-DE" });
|
|
33
|
+
|
|
34
|
+
for (const rental of rentals) {
|
|
35
|
+
for (const image of rental.property?.images ?? []) {
|
|
36
|
+
renderPropertyImage(image);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The field remains optional. It is omitted when a rental has no facility, when
|
|
42
|
+
the facility has no images, or when no facility image has a usable numeric ID.
|
|
43
|
+
|
|
44
|
+
Example image:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"idOrPath": "28458352",
|
|
49
|
+
"src": "https://dyn.v-office.com/image/xl/28458352.jpg",
|
|
50
|
+
"srcset": "https://dyn.v-office.com/image/tn/28458352.jpg 141w, https://dyn.v-office.com/image/tnx/28458352.jpg 225w, https://dyn.v-office.com/image/s/28458352.jpg 450w, https://dyn.v-office.com/image/m/28458352.jpg 600w, https://dyn.v-office.com/image/xl/28458352.jpg 1440w, https://dyn.v-office.com/image/xxl/28458352.jpg 2400w",
|
|
51
|
+
"alt": "Hauptansicht",
|
|
52
|
+
"title": "Hauptansicht",
|
|
53
|
+
"category": "buildingMain"
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 3. Provide the Layout-Specific `sizes` Attribute
|
|
58
|
+
|
|
59
|
+
The SDK provides `src` and `srcset`. The consuming UI must provide `sizes`
|
|
60
|
+
because only the application knows the rendered layout:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
<img
|
|
64
|
+
src={image.src}
|
|
65
|
+
srcSet={image.srcset}
|
|
66
|
+
sizes="(max-width: 768px) 100vw, 50vw"
|
|
67
|
+
alt={image.alt ?? ""}
|
|
68
|
+
/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Do not copy that example `sizes` value blindly. Match it to the actual image
|
|
72
|
+
width in the application's responsive layout.
|
|
73
|
+
|
|
74
|
+
The fallback `src` uses the `xl` vOffice preset. Browsers that support `srcset`
|
|
75
|
+
select an appropriate candidate using `srcset`, `sizes`, viewport width, and
|
|
76
|
+
device pixel ratio.
|
|
77
|
+
|
|
78
|
+
## 4. Keep Rental and Property Images Distinct
|
|
79
|
+
|
|
80
|
+
The two image collections represent different entities:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
rental.images; // images belonging to the rental/unit
|
|
84
|
+
rental.property?.images; // images belonging to the facility/property
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
They also use different origins in v9:
|
|
88
|
+
|
|
89
|
+
- `rental.images`: configured `imageProxyBaseUrl`
|
|
90
|
+
- `rental.property.images`: `https://dyn.v-office.com`
|
|
91
|
+
|
|
92
|
+
Do not merge the arrays unless the UI deliberately presents a combined gallery.
|
|
93
|
+
Keeping them separate prevents facility images from being mistaken for
|
|
94
|
+
unit-specific rooms or amenities.
|
|
95
|
+
|
|
96
|
+
## 5. Account for Repeated Property Data
|
|
97
|
+
|
|
98
|
+
The normalized rentals API returns one item per rental. When several rentals
|
|
99
|
+
belong to the same facility, each rental contains the same nested property image
|
|
100
|
+
list.
|
|
101
|
+
|
|
102
|
+
Applications that build a property-level view can deduplicate by `property.id`:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const properties = new Map(
|
|
106
|
+
rentals.flatMap((rental) =>
|
|
107
|
+
rental.property == null ? [] : [[rental.property.id, rental.property] as const],
|
|
108
|
+
),
|
|
109
|
+
);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
No separate property endpoint or persistence layer was added in 2.15.0.
|
|
113
|
+
|
|
114
|
+
## 6. Update Snapshots and Complete-Object Assertions
|
|
115
|
+
|
|
116
|
+
Tests that compare only selected property fields are unaffected. Tests that
|
|
117
|
+
snapshot or deeply compare complete v9 rental output can now observe:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
rental.property.images;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Update those expectations without making `property.images` mandatory. Backend
|
|
124
|
+
facilities are allowed to have no usable images.
|
|
125
|
+
|
|
126
|
+
## Required Consumer Work
|
|
127
|
+
|
|
128
|
+
For applications that render v9 property images:
|
|
129
|
+
|
|
130
|
+
1. Allow `https://dyn.v-office.com` in CSP and image-host configuration.
|
|
131
|
+
2. Render `rental.property.images` separately from top-level rental images.
|
|
132
|
+
3. Supply an HTML `sizes` value appropriate for the layout.
|
|
133
|
+
4. Keep empty and missing image arrays valid.
|
|
134
|
+
5. Update complete-output snapshots.
|
|
135
|
+
|
|
136
|
+
Applications that do not render v9 property images require no migration work.
|
|
137
|
+
|
|
138
|
+
## Recommended Verification
|
|
139
|
+
|
|
140
|
+
1. Fetch v9 static rentals in both `de-DE` and `en-US`.
|
|
141
|
+
2. Confirm facilities with images expose `property.images`.
|
|
142
|
+
3. Confirm localized image titles populate `alt` and `title`.
|
|
143
|
+
4. Confirm the browser selects responsive candidates after adding `sizes`.
|
|
144
|
+
5. Confirm `dyn.v-office.com` is accepted by production CSP.
|
|
145
|
+
6. Confirm top-level rental images still use the configured image proxy.
|
|
146
|
+
7. Confirm a shared facility does not create duplicate property cards when the
|
|
147
|
+
application deduplicates by `property.id`.
|
|
148
|
+
8. Confirm v10 rental and property image rendering remains unchanged.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog: 2.16.0
|
|
2
|
+
|
|
3
|
+
This release makes unavailable quote results machine-readable. Applications can
|
|
4
|
+
now distinguish normal booking unavailability from v10 multi-rate
|
|
5
|
+
configuration failures without parsing localized text.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- Every unavailable `GuestQuoteResult` contains a `code`:
|
|
10
|
+
- `NotBookable`
|
|
11
|
+
- `AmbiguousMultiRate`
|
|
12
|
+
- `UnresolvableMultiRate`
|
|
13
|
+
- The public quote output schema validates the new code.
|
|
14
|
+
- v10 reports `AmbiguousMultiRate` when a priced default cancellation policy
|
|
15
|
+
matches more than one multi-rate.
|
|
16
|
+
- v10 reports `UnresolvableMultiRate` when a priced default cancellation policy
|
|
17
|
+
cannot be mapped to a multi-rate.
|
|
18
|
+
|
|
19
|
+
## Changed
|
|
20
|
+
|
|
21
|
+
- Legacy v9 unavailable quotes now include `code: "NotBookable"`.
|
|
22
|
+
- Normal v10 quote failures also use `code: "NotBookable"`.
|
|
23
|
+
- v10 retains the exact default-policy multi-rate resolution result instead of
|
|
24
|
+
reducing it to a boolean before creating the public unavailable result.
|
|
25
|
+
|
|
26
|
+
## Unchanged
|
|
27
|
+
|
|
28
|
+
- `sdk.live.quote.quote(input)` and its input are unchanged.
|
|
29
|
+
- Available quote results remain `{ status: "available", quote }`.
|
|
30
|
+
- Unavailable results retain the localized `reason` field.
|
|
31
|
+
- Ambiguous or unresolvable v10 multi-rates remain unavailable. The SDK does not
|
|
32
|
+
select an arbitrary fallback because booking requires one exact multi-rate.
|
|
33
|
+
- Search and calendar availability behavior are unchanged.
|
|
34
|
+
|
|
35
|
+
## Compatibility
|
|
36
|
+
|
|
37
|
+
- Consumers that only inspect `status` and display `reason` continue to work.
|
|
38
|
+
- TypeScript mocks, complete-object assertions, snapshots, and schema fixtures
|
|
39
|
+
for unavailable quotes must include `code`.
|
|
40
|
+
- Application behavior should branch on `code`, not localized `reason`.
|
|
41
|
+
- `AmbiguousMultiRate` and `UnresolvableMultiRate` indicate configuration or
|
|
42
|
+
mapping problems and should normally be reported to site operations.
|
|
43
|
+
|
|
44
|
+
See `versions/2.16.0/MIGRATION.md` and `../../quote.md`.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Migration: 2.15.0 to 2.16.0
|
|
2
|
+
|
|
3
|
+
2.16.0 adds a required machine-readable `code` to unavailable quote results.
|
|
4
|
+
The service call, quote input, available result, and localized unavailable
|
|
5
|
+
`reason` are unchanged.
|
|
6
|
+
|
|
7
|
+
## 1. Handle the Unavailable Code
|
|
8
|
+
|
|
9
|
+
An unavailable result now has this shape:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
type UnavailableGuestQuoteResult = {
|
|
13
|
+
readonly status: "unavailable";
|
|
14
|
+
readonly code: "NotBookable" | "AmbiguousMultiRate" | "UnresolvableMultiRate";
|
|
15
|
+
readonly reason: string;
|
|
16
|
+
};
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Branch on `code` after narrowing by `status`:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const result = await sdk.live.quote.quote(input);
|
|
23
|
+
|
|
24
|
+
if (result.status === "unavailable") {
|
|
25
|
+
switch (result.code) {
|
|
26
|
+
case "AmbiguousMultiRate":
|
|
27
|
+
case "UnresolvableMultiRate":
|
|
28
|
+
reportQuoteConfigurationProblem(result.code);
|
|
29
|
+
break;
|
|
30
|
+
case "NotBookable":
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
showUnavailableMessage(result.reason);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Keep displaying `reason` when appropriate, but do not parse or compare it to
|
|
39
|
+
select application behavior. It is localized and can still contain the same
|
|
40
|
+
text for different codes.
|
|
41
|
+
|
|
42
|
+
## 2. Treat Multi-Rate Codes as Operational Failures
|
|
43
|
+
|
|
44
|
+
The v10-specific codes mean:
|
|
45
|
+
|
|
46
|
+
- `AmbiguousMultiRate`: the stay was priced, but more than one multi-rate
|
|
47
|
+
matched the default cancellation policy.
|
|
48
|
+
- `UnresolvableMultiRate`: the stay was priced, but no multi-rate could be
|
|
49
|
+
resolved for the default cancellation policy.
|
|
50
|
+
|
|
51
|
+
These are not proof that another guest booked the period. Keep the public quote
|
|
52
|
+
unavailable, show suitable fallback copy, and send the code to monitoring or
|
|
53
|
+
site operations so the rental configuration can be corrected.
|
|
54
|
+
|
|
55
|
+
Do not retry booking with an arbitrary multi-rate. The price alone does not
|
|
56
|
+
identify the exact multi-rate required by the booking request.
|
|
57
|
+
|
|
58
|
+
## 3. Keep Normal Unavailability Handling
|
|
59
|
+
|
|
60
|
+
`NotBookable` represents ordinary unavailable quote results, including backend
|
|
61
|
+
responses without a bookable price:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
if (result.status === "unavailable" && result.code === "NotBookable") {
|
|
65
|
+
showUnavailableMessage(result.reason);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Legacy v9 unavailable quotes always use `NotBookable`. No v9 configuration or
|
|
70
|
+
request change is required.
|
|
71
|
+
|
|
72
|
+
## 4. Update Mocks, Fixtures, and Snapshots
|
|
73
|
+
|
|
74
|
+
Add `code` anywhere an unavailable result is constructed or compared:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const unavailableQuote = {
|
|
78
|
+
status: "unavailable",
|
|
79
|
+
code: "NotBookable",
|
|
80
|
+
reason: "Not available",
|
|
81
|
+
} as const;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Update:
|
|
85
|
+
|
|
86
|
+
1. TypeScript mocks typed as `GuestQuoteResult` or `QuoteQuoteOutput`.
|
|
87
|
+
2. JSON fixtures decoded with `QuoteQuoteOutputSchema`.
|
|
88
|
+
3. Complete-object assertions and snapshots.
|
|
89
|
+
4. API adapters that persist or forward quote results.
|
|
90
|
+
|
|
91
|
+
Available-result fixtures require no changes.
|
|
92
|
+
|
|
93
|
+
## Required Consumer Work
|
|
94
|
+
|
|
95
|
+
1. Add `code` to unavailable quote mocks and fixtures.
|
|
96
|
+
2. Replace reason-string comparisons with code checks.
|
|
97
|
+
3. Route `AmbiguousMultiRate` and `UnresolvableMultiRate` to operational
|
|
98
|
+
diagnostics.
|
|
99
|
+
4. Keep all three codes unavailable in booking UI.
|
|
100
|
+
|
|
101
|
+
## Recommended Verification
|
|
102
|
+
|
|
103
|
+
1. Confirm a normal blocked period returns `NotBookable`.
|
|
104
|
+
2. Confirm unavailable copy still uses the localized `reason`.
|
|
105
|
+
3. Confirm monitoring distinguishes both multi-rate codes from
|
|
106
|
+
`NotBookable`.
|
|
107
|
+
4. Confirm the UI never enables booking for either multi-rate code.
|
|
108
|
+
5. Confirm available quote, option selection, and booking flows are unchanged.
|
|
109
|
+
6. Confirm legacy v9 unavailable quote snapshots include `NotBookable`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-office/website-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.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.16.0",
|
|
46
46
|
"effect": "4.0.0-beta.85",
|
|
47
47
|
"graphql": "17.0.2",
|
|
48
48
|
"yaml": "^2.9.0"
|