@v-office/website-sdk 2.0.0 → 2.1.1
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/README.md +33 -31
- package/dist/cli.mjs +6 -4
- package/dist/{client-BSUd3vuc.mjs → client-xkXV7Nf-.mjs} +32 -16
- package/dist/index.d.mts +613 -1140
- package/dist/index.mjs +3 -3
- package/dist/instructions/CHANGELOG.md +1 -0
- package/dist/instructions/MIGRATION.md +1 -0
- package/dist/instructions/README.md +14 -12
- package/dist/instructions/availability.md +9 -9
- package/dist/instructions/booking.md +33 -33
- package/dist/instructions/contact.md +34 -16
- package/dist/instructions/creation.md +48 -48
- package/dist/instructions/document-structured-json.md +100 -0
- package/dist/instructions/filter.md +5 -3
- package/dist/instructions/quote.md +72 -48
- package/dist/instructions/rentals.md +3 -3
- package/dist/instructions/search.md +36 -31
- package/dist/instructions/versions/2.0.0/MIGRATION.md +17 -17
- package/dist/instructions/versions/2.1.0/CHANGELOG.md +32 -0
- package/dist/instructions/versions/2.1.0/MIGRATION.md +89 -0
- package/dist/{quote-1uEIO44v.mjs → quote--25SMlYS.mjs} +27 -4
- package/dist/{rentals-Quwc78o2.mjs → rentals-DCKUaLnB.mjs} +1 -1
- package/dist/{search-GRQeXDvo.mjs → search-8iCC0Nel.mjs} +2 -2
- package/dist/{to-rental-highlights-FNZBR4aD.mjs → to-rental-highlights-CZYJeR1D.mjs} +12 -12
- package/dist/translations/shared/de-DE/contact.json +19 -0
- package/dist/translations/shared/de-DE/quote.json +5 -1
- package/dist/translations/shared/en-US/contact.json +19 -0
- package/dist/translations/shared/en-US/quote.json +5 -1
- package/dist/translations/v10/de-DE/mapped-search-filters.json +3 -0
- package/dist/translations/v10/en-US/mapped-search-filters.json +3 -0
- package/instructions/CHANGELOG.md +1 -0
- package/instructions/MIGRATION.md +1 -0
- package/instructions/README.md +14 -12
- package/instructions/availability.md +9 -9
- package/instructions/booking.md +33 -33
- package/instructions/contact.md +34 -16
- package/instructions/creation.md +48 -48
- package/instructions/document-structured-json.md +100 -0
- package/instructions/filter.md +5 -3
- package/instructions/quote.md +72 -48
- package/instructions/rentals.md +3 -3
- package/instructions/search.md +36 -31
- package/instructions/versions/2.0.0/MIGRATION.md +17 -17
- package/instructions/versions/2.1.0/CHANGELOG.md +32 -0
- package/instructions/versions/2.1.0/MIGRATION.md +89 -0
- package/package.json +4 -3
|
@@ -5,36 +5,36 @@
|
|
|
5
5
|
Use the live quote API to price a stay and get selectable booking options:
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
const result = await sdk.live.quote.quote(input)
|
|
8
|
+
const result = await sdk.live.quote.quote(input);
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
If the quote is available, the returned `GuestQuote` can be updated through selection helpers:
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
const withService = await sdk.live.quote.addAdditionalService({ quote, id:
|
|
15
|
-
const withPolicy = await sdk.live.quote.selectCancellationPolicy({ quote, id:
|
|
14
|
+
const withService = await sdk.live.quote.addAdditionalService({ quote, id: "linen" });
|
|
15
|
+
const withPolicy = await sdk.live.quote.selectCancellationPolicy({ quote, id: "alternative" });
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Input
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
21
|
type QuoteQuoteInput = {
|
|
22
|
-
locale:
|
|
23
|
-
rentalId: string
|
|
22
|
+
locale: "de-DE" | "en-US";
|
|
23
|
+
rentalId: string;
|
|
24
24
|
period: {
|
|
25
|
-
start: string
|
|
26
|
-
end: string
|
|
27
|
-
}
|
|
25
|
+
start: string;
|
|
26
|
+
end: string;
|
|
27
|
+
};
|
|
28
28
|
occupancy: {
|
|
29
|
-
adults: number
|
|
30
|
-
children: number
|
|
31
|
-
childrenAges?: number[]
|
|
32
|
-
babies: number
|
|
33
|
-
pets: number
|
|
34
|
-
}
|
|
35
|
-
destinationCountryCode?: string
|
|
36
|
-
voucher?: string
|
|
37
|
-
}
|
|
29
|
+
adults: number;
|
|
30
|
+
children: number;
|
|
31
|
+
childrenAges?: number[];
|
|
32
|
+
babies: number;
|
|
33
|
+
pets: number;
|
|
34
|
+
};
|
|
35
|
+
destinationCountryCode?: string;
|
|
36
|
+
voucher?: string;
|
|
37
|
+
};
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
`GuestQuoteInput` remains available as a legacy alias.
|
|
@@ -62,6 +62,7 @@ Sample:
|
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Dates are local dates formatted as `YYYY-MM-DD`. For `v9`, `rentalId` must be a numeric vOffice unit id.
|
|
65
|
+
Both backends accept `voucher` on quote and booking flows. `v10` can expose voucher discounts as booking-card modifiers when the backend returns voucher modifiers; `v9` reflects voucher effects in the quoted totals but does not expose a separate voucher modifier line.
|
|
65
66
|
|
|
66
67
|
## Output
|
|
67
68
|
|
|
@@ -88,6 +89,11 @@ Available sample:
|
|
|
88
89
|
],
|
|
89
90
|
"total": "1,200.00 EUR"
|
|
90
91
|
},
|
|
92
|
+
"voucher": {
|
|
93
|
+
"code": "SUMMER26",
|
|
94
|
+
"status": "applied",
|
|
95
|
+
"message": "The voucher code was applied."
|
|
96
|
+
},
|
|
91
97
|
"additionalServices": [
|
|
92
98
|
{
|
|
93
99
|
"id": "linen",
|
|
@@ -131,7 +137,23 @@ Unavailable sample:
|
|
|
131
137
|
}
|
|
132
138
|
```
|
|
133
139
|
|
|
134
|
-
Selection methods return `{ ok: true, quote }` or `{ ok: false, error }`. Possible selection errors include unknown additional service, additional service limit exceeded, unknown cancellation policy,
|
|
140
|
+
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
|
+
|
|
142
|
+
## Vouchers
|
|
143
|
+
|
|
144
|
+
When `voucher` is provided in the quote input, an available quote may include `quote.voucher`:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"code": "SUMMER26",
|
|
149
|
+
"status": "applied",
|
|
150
|
+
"message": "The voucher code was applied."
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`status` is `"applied"`, `"not_applied"`, or `"unknown"`. `v10` reports `"applied"` when the backend returns a non-zero voucher modifier and `"not_applied"` when no voucher modifier is returned for the requested voucher. `v9` returns `"unknown"` for available voucher quotes because the legacy response does not provide a reliable voucher modifier signal.
|
|
155
|
+
|
|
156
|
+
Voucher modifiers can appear in `bookingCardInformation.sections`. Sections are returned in display order.
|
|
135
157
|
|
|
136
158
|
## Additional Services
|
|
137
159
|
|
|
@@ -142,6 +164,7 @@ Additional services are exposed on an available quote as `quote.additionalServic
|
|
|
142
164
|
"id": "linen",
|
|
143
165
|
"label": "Bed linen",
|
|
144
166
|
"charge": "25.00 EUR",
|
|
167
|
+
"available": true,
|
|
145
168
|
"maxPerBooking": 1,
|
|
146
169
|
"description": "Bed linen package"
|
|
147
170
|
}
|
|
@@ -150,17 +173,17 @@ Additional services are exposed on an available quote as `quote.additionalServic
|
|
|
150
173
|
Use the service `id` to add or remove a service selection:
|
|
151
174
|
|
|
152
175
|
```ts
|
|
153
|
-
const added = await sdk.live.quote.addAdditionalService({ quote, id:
|
|
154
|
-
if (added.ok) quote = added.quote
|
|
176
|
+
const added = await sdk.live.quote.addAdditionalService({ quote, id: "linen" });
|
|
177
|
+
if (added.ok) quote = added.quote;
|
|
155
178
|
|
|
156
|
-
const removed = await sdk.live.quote.removeAdditionalService({ quote, id:
|
|
157
|
-
if (removed.ok) quote = removed.quote
|
|
179
|
+
const removed = await sdk.live.quote.removeAdditionalService({ quote, id: "linen" });
|
|
180
|
+
if (removed.ok) quote = removed.quote;
|
|
158
181
|
|
|
159
|
-
const cleared = await sdk.live.quote.clearAdditionalServices({ quote })
|
|
160
|
-
if (cleared.ok) quote = cleared.quote
|
|
182
|
+
const cleared = await sdk.live.quote.clearAdditionalServices({ quote });
|
|
183
|
+
if (cleared.ok) quote = cleared.quote;
|
|
161
184
|
```
|
|
162
185
|
|
|
163
|
-
Each successful change returns a new quote with recalculated `bookingCardInformation.total`. Handle `{ ok: false, error }` for unknown service ids
|
|
186
|
+
Each successful change returns a new quote with recalculated `bookingCardInformation.total`. v10 can mark unavailable service/policy combinations with `available: false` and `unavailableReason`; disable those options in the UI. Handle `{ ok: false, error }` for unknown service ids, quantity limits, or `UnavailableQuoteCombination`.
|
|
164
187
|
|
|
165
188
|
## Cancellation Policies
|
|
166
189
|
|
|
@@ -171,6 +194,7 @@ Cancellation policies are exposed on `quote.cancellationPolicies` when the backe
|
|
|
171
194
|
"id": "alternative",
|
|
172
195
|
"label": "Flexible cancellation",
|
|
173
196
|
"selected": false,
|
|
197
|
+
"available": true,
|
|
174
198
|
"markUpPercentage": "10%",
|
|
175
199
|
"processingFee": "25.00 EUR",
|
|
176
200
|
"rules": [
|
|
@@ -187,10 +211,10 @@ Select a policy by id:
|
|
|
187
211
|
```ts
|
|
188
212
|
const selected = await sdk.live.quote.selectCancellationPolicy({
|
|
189
213
|
quote,
|
|
190
|
-
id:
|
|
191
|
-
})
|
|
214
|
+
id: "alternative",
|
|
215
|
+
});
|
|
192
216
|
|
|
193
|
-
if (selected.ok) quote = selected.quote
|
|
217
|
+
if (selected.ok) quote = selected.quote;
|
|
194
218
|
```
|
|
195
219
|
|
|
196
220
|
The selected policy is marked with `selected: true`, and the booking card total is recalculated if the policy changes the price. Handle selection errors for unknown or unavailable policy ids.
|
|
@@ -228,18 +252,18 @@ Use `selectInsurance` to choose no insurance or a product:
|
|
|
228
252
|
quote = await sdk.live.quote.selectInsurance({
|
|
229
253
|
quote,
|
|
230
254
|
selection: {
|
|
231
|
-
kind:
|
|
232
|
-
id:
|
|
255
|
+
kind: "insurance",
|
|
256
|
+
id: "ergo",
|
|
233
257
|
travelers: [
|
|
234
258
|
{
|
|
235
|
-
salutation:
|
|
236
|
-
forename:
|
|
237
|
-
surname:
|
|
238
|
-
birthday:
|
|
259
|
+
salutation: "Ms",
|
|
260
|
+
forename: "Jane",
|
|
261
|
+
surname: "Doe",
|
|
262
|
+
birthday: "1990-01-01",
|
|
239
263
|
},
|
|
240
264
|
],
|
|
241
265
|
},
|
|
242
|
-
})
|
|
266
|
+
});
|
|
243
267
|
```
|
|
244
268
|
|
|
245
269
|
For insurance products that require a pre-contract, provide customer information:
|
|
@@ -248,18 +272,18 @@ For insurance products that require a pre-contract, provide customer information
|
|
|
248
272
|
quote = await sdk.live.quote.createInsurancePreContract({
|
|
249
273
|
quote,
|
|
250
274
|
customerInformation: {
|
|
251
|
-
destinationCountryCode:
|
|
275
|
+
destinationCountryCode: "DE",
|
|
252
276
|
address: {
|
|
253
|
-
street:
|
|
254
|
-
housenumber:
|
|
255
|
-
postalcode:
|
|
256
|
-
city:
|
|
257
|
-
countryCode:
|
|
277
|
+
street: "Main Street",
|
|
278
|
+
housenumber: "1",
|
|
279
|
+
postalcode: "12345",
|
|
280
|
+
city: "Berlin",
|
|
281
|
+
countryCode: "DE",
|
|
258
282
|
},
|
|
259
|
-
email:
|
|
260
|
-
mobile:
|
|
283
|
+
email: "jane@example.com",
|
|
284
|
+
mobile: "+49123456789",
|
|
261
285
|
},
|
|
262
|
-
})
|
|
286
|
+
});
|
|
263
287
|
```
|
|
264
288
|
|
|
265
289
|
Select an insurance payment method before booking insurance:
|
|
@@ -268,10 +292,10 @@ Select an insurance payment method before booking insurance:
|
|
|
268
292
|
quote = await sdk.live.quote.selectInsurancePayment({
|
|
269
293
|
quote,
|
|
270
294
|
paymentInformation: {
|
|
271
|
-
kind:
|
|
272
|
-
iban:
|
|
295
|
+
kind: "sepa_debit",
|
|
296
|
+
iban: "DE02120300000000202051",
|
|
273
297
|
},
|
|
274
|
-
})
|
|
298
|
+
});
|
|
275
299
|
```
|
|
276
300
|
|
|
277
301
|
After the rental booking is created, complete insurance booking with the booking number and guest token:
|
|
@@ -281,7 +305,7 @@ const insuranceBooking = await sdk.live.quote.bookInsurance({
|
|
|
281
305
|
quote,
|
|
282
306
|
bookingNumber: booking.bookingNumber,
|
|
283
307
|
guestToken: booking.guestToken,
|
|
284
|
-
})
|
|
308
|
+
});
|
|
285
309
|
```
|
|
286
310
|
|
|
287
311
|
`v9` supports real insurance option refresh, pre-contract, payment selection, and booking. `v10` currently returns a no-insurance placeholder and insurance actions resolve as not required.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Use the static rentals API to fetch localized rental summaries:
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
const rentals = await sdk.static.rentals.getRentals({ locale:
|
|
8
|
+
const rentals = await sdk.static.rentals.getRentals({ locale: "de-DE" });
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
The service is implemented for both `v9` and `v10` backends and returns one normalized item per rental.
|
|
@@ -14,8 +14,8 @@ The service is implemented for both `v9` and `v10` backends and returns one norm
|
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
16
|
type RentalRentalsInput = {
|
|
17
|
-
locale:
|
|
18
|
-
}
|
|
17
|
+
locale: "de-DE" | "en-US";
|
|
18
|
+
};
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Sample:
|
|
@@ -6,9 +6,9 @@ Use the live search API to search rentals with a URL query-string style input:
|
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
const result = await sdk.live.search.search({
|
|
9
|
-
locale:
|
|
10
|
-
query:
|
|
11
|
-
})
|
|
9
|
+
locale: "de-DE",
|
|
10
|
+
query: "start=01-07-2026&end=08-07-2026&adults=2&wifi=true",
|
|
11
|
+
});
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
The service is implemented for both `v9` and `v10` backends and returns normalized rental result items. Filtering by `rentalIdsIn` is currently implemented for `v10` only.
|
|
@@ -17,12 +17,13 @@ The service is implemented for both `v9` and `v10` backends and returns normaliz
|
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
type RentalSearchInput = {
|
|
20
|
-
locale:
|
|
21
|
-
query: string
|
|
22
|
-
rentalIdsIn?: readonly string[]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
locale: "de-DE" | "en-US";
|
|
21
|
+
query: string;
|
|
22
|
+
rentalIdsIn?: readonly string[];
|
|
23
|
+
voucher?: string;
|
|
24
|
+
limit?: number;
|
|
25
|
+
cursor?: string;
|
|
26
|
+
};
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
Sample:
|
|
@@ -32,6 +33,7 @@ Sample:
|
|
|
32
33
|
"locale": "de-DE",
|
|
33
34
|
"query": "start=01-07-2026&end=08-07-2026&adults=2&children=1&wifi=true",
|
|
34
35
|
"rentalIdsIn": ["123", "456"],
|
|
36
|
+
"voucher": "SUMMER26",
|
|
35
37
|
"limit": 20
|
|
36
38
|
}
|
|
37
39
|
```
|
|
@@ -49,7 +51,7 @@ The `query` field is a URL query-string style value without a leading `?`.
|
|
|
49
51
|
Use `&` to combine period, occupancy, and filter parameters:
|
|
50
52
|
|
|
51
53
|
```ts
|
|
52
|
-
|
|
54
|
+
"start=20-06-2026&end=27-06-2026&adults=2&wifi";
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
### Period Queries
|
|
@@ -59,25 +61,25 @@ Use one supported period structure per query.
|
|
|
59
61
|
Exact period search:
|
|
60
62
|
|
|
61
63
|
```ts
|
|
62
|
-
|
|
64
|
+
"start=20-06-2026&end=27-06-2026";
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
Flexible search by month:
|
|
66
68
|
|
|
67
69
|
```ts
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
"month=06-2026&nights=7";
|
|
71
|
+
"month=06-2026&month=07-2026&nights=7";
|
|
72
|
+
"month=06-2026&weekend";
|
|
73
|
+
"month=06-2026&month=07-2026&weekend";
|
|
72
74
|
```
|
|
73
75
|
|
|
74
76
|
Flexible search by exact date tuples:
|
|
75
77
|
|
|
76
78
|
```ts
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
"dates=20-06-2026,22-06-2026&nights=2";
|
|
80
|
+
"dates=20-06-2026,22-06-2026&dates=04-07-2026,11-07-2026&nights=2";
|
|
81
|
+
"dates=20-06-2026,22-06-2026&weekend";
|
|
82
|
+
"dates=20-06-2026,22-06-2026&dates=04-07-2026,11-07-2026&weekend";
|
|
81
83
|
```
|
|
82
84
|
|
|
83
85
|
### Occupancy And Filters
|
|
@@ -85,16 +87,16 @@ Flexible search by exact date tuples:
|
|
|
85
87
|
Append occupancy and filter parameters with `&`:
|
|
86
88
|
|
|
87
89
|
```ts
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
"start=20-06-2026&end=27-06-2026&adults=2";
|
|
91
|
+
"start=20-06-2026&end=27-06-2026&adults=2&childrenAges=5%2C13&babies=1&pets=1";
|
|
92
|
+
"start=20-06-2026&end=27-06-2026&adults=2&wifi";
|
|
91
93
|
```
|
|
92
94
|
|
|
93
95
|
Boolean filters can be provided as presence-only flags when supported:
|
|
94
96
|
|
|
95
97
|
```ts
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
"wifi";
|
|
99
|
+
"wifi&bbq=true";
|
|
98
100
|
```
|
|
99
101
|
|
|
100
102
|
### Invalid Combinations
|
|
@@ -102,27 +104,29 @@ Boolean filters can be provided as presence-only flags when supported:
|
|
|
102
104
|
Do not mix exact period search with flexible period options:
|
|
103
105
|
|
|
104
106
|
```ts
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
"start=20-06-2026&end=27-06-2026&nights=7";
|
|
108
|
+
"start=20-06-2026&end=27-06-2026&weekend";
|
|
107
109
|
```
|
|
108
110
|
|
|
109
111
|
Do not mix `month` and `dates` in the same flexible query:
|
|
110
112
|
|
|
111
113
|
```ts
|
|
112
|
-
|
|
114
|
+
"month=06-2026&dates=20-06-2026,22-06-2026&nights=2";
|
|
113
115
|
```
|
|
114
116
|
|
|
115
117
|
Flexible queries require either `nights` or `weekend`, but not both:
|
|
116
118
|
|
|
117
119
|
```ts
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
"month=06-2026";
|
|
121
|
+
"dates=20-06-2026,22-06-2026";
|
|
122
|
+
"month=06-2026&nights=7&weekend";
|
|
121
123
|
```
|
|
122
124
|
|
|
123
125
|
Dates should use `DD-MM-YYYY`; months should use `MM-YYYY`.
|
|
124
126
|
|
|
125
127
|
Use `rentalIdsIn` to restrict results to specific rental IDs. This option is currently supported by `v10` only.
|
|
128
|
+
Use `voucher` to price v10 search results with a voucher code. This option is currently supported by `v10` only.
|
|
129
|
+
For v10, `pets` is a mapped BooleanFilter exposed by `getFilters` and maps to one pet; use `petsCount` for an exact count and do not send both keys in one query.
|
|
126
130
|
|
|
127
131
|
`limit` defaults to `20`. Treat `cursor` as opaque and pass back `pageInfo.nextCursor` unchanged.
|
|
128
132
|
|
|
@@ -209,10 +213,11 @@ website-sdk --backend v10 search --locale de-DE --query "adults=2" --limit 10
|
|
|
209
213
|
website-sdk --backend v10 search --locale de-DE --query "adults=2" --limit 10 --cursor "10"
|
|
210
214
|
```
|
|
211
215
|
|
|
212
|
-
Restrict results to specific rental IDs with
|
|
216
|
+
Restrict results to specific rental IDs or price with a voucher code (`v10` only):
|
|
213
217
|
|
|
214
218
|
```sh
|
|
215
219
|
website-sdk --backend v10 search --locale de-DE --query "adults=2" --rental-ids-in "123,456"
|
|
220
|
+
website-sdk --backend v10 search --locale de-DE --query "adults=2" --voucher SUMMER26
|
|
216
221
|
```
|
|
217
222
|
|
|
218
223
|
Use files instead of environment variables:
|
|
@@ -25,7 +25,7 @@ Legacy 1.x-style API:
|
|
|
25
25
|
## Package Import
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import { createWebsiteSDK, defineWebsiteSDKOptions } from
|
|
28
|
+
import { createWebsiteSDK, defineWebsiteSDKOptions } from "@v-office/website-sdk";
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The new package still exports `defineCMSSDKOptions` as an alias for `defineWebsiteSDKOptions`, but new code should use the Website naming.
|
|
@@ -35,41 +35,41 @@ The new package still exports `defineCMSSDKOptions` as an alias for `defineWebsi
|
|
|
35
35
|
Before:
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
|
-
import { createCMSSDKFromParsedConfig, defineCMSSDKOptions } from
|
|
38
|
+
import { createCMSSDKFromParsedConfig, defineCMSSDKOptions } from "@v-office/website-sdk";
|
|
39
39
|
|
|
40
40
|
const sdk = createCMSSDKFromParsedConfig({
|
|
41
|
-
backend:
|
|
41
|
+
backend: "v10",
|
|
42
42
|
v10: {
|
|
43
|
-
apiEndpoint:
|
|
44
|
-
accessToken:
|
|
45
|
-
imageBaseUrl:
|
|
43
|
+
apiEndpoint: "https://api.example.com/graphql",
|
|
44
|
+
accessToken: "...",
|
|
45
|
+
imageBaseUrl: "https://images.example.com",
|
|
46
46
|
},
|
|
47
47
|
options: defineCMSSDKOptions({
|
|
48
48
|
rentalScope: {
|
|
49
|
-
propertyId:
|
|
49
|
+
propertyId: "property-1",
|
|
50
50
|
},
|
|
51
51
|
}),
|
|
52
|
-
})
|
|
52
|
+
});
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
After:
|
|
56
56
|
|
|
57
57
|
```ts
|
|
58
|
-
import { createWebsiteSDK, defineWebsiteSDKOptions } from
|
|
58
|
+
import { createWebsiteSDK, defineWebsiteSDKOptions } from "@v-office/website-sdk";
|
|
59
59
|
|
|
60
60
|
const sdk = createWebsiteSDK({
|
|
61
61
|
config: {
|
|
62
|
-
backend:
|
|
63
|
-
apiEndpoint:
|
|
64
|
-
accessToken:
|
|
65
|
-
imageBaseUrl:
|
|
62
|
+
backend: "v10",
|
|
63
|
+
apiEndpoint: "https://api.example.com/graphql",
|
|
64
|
+
accessToken: "...",
|
|
65
|
+
imageBaseUrl: "https://images.example.com",
|
|
66
66
|
},
|
|
67
67
|
options: defineWebsiteSDKOptions({
|
|
68
68
|
rentalScope: {
|
|
69
|
-
propertyId:
|
|
69
|
+
propertyId: "property-1",
|
|
70
70
|
},
|
|
71
71
|
}),
|
|
72
|
-
})
|
|
72
|
+
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
## Config Shape
|
|
@@ -123,7 +123,7 @@ Several legacy domain aliases remain exported, including `BookingInput`, `Bookin
|
|
|
123
123
|
Legacy errors exposed `CMSError` with a `backend` field:
|
|
124
124
|
|
|
125
125
|
```ts
|
|
126
|
-
if (error instanceof CMSError && error.backend ===
|
|
126
|
+
if (error instanceof CMSError && error.backend === "v9") {
|
|
127
127
|
// legacy handling
|
|
128
128
|
}
|
|
129
129
|
```
|
|
@@ -132,7 +132,7 @@ if (error instanceof CMSError && error.backend === 'v9') {
|
|
|
132
132
|
|
|
133
133
|
```ts
|
|
134
134
|
if (error instanceof CoreSDKError) {
|
|
135
|
-
console.error(error.source, error.operation, error.message)
|
|
135
|
+
console.error(error.source, error.operation, error.message);
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog: 2.1.0
|
|
2
|
+
|
|
3
|
+
Release date: 2026-07-08
|
|
4
|
+
|
|
5
|
+
This release extends the 2.0.0 website SDK facade without changing the flat config shape or main SDK construction API.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- Added v10 legal document access through `sdk.static.documents.getTermsAndPrivacyPolicy({ locale })` and `getTermsAndPrivacyPolicyEffect`.
|
|
10
|
+
- Added `document-structured-json.md` instructions for legal document output and structured document rendering.
|
|
11
|
+
- Added v10 contact submission through `messengeremail_newContactRequest`, with shared validation for v9 and v10 contact requests.
|
|
12
|
+
- Added `validateContactSubmitInput`, `ContactSubmitValidationIssue`, and `ContactSubmitValidationIssueCode` exports.
|
|
13
|
+
- Added v10 search voucher pricing via `SearchSearchInput.voucher` and CLI `--voucher`.
|
|
14
|
+
- Added `quote.voucher` metadata for quoted voucher status.
|
|
15
|
+
- Added v10 mapped `pets` search filter, exposed by `static.filter.getFilters` as a localized BooleanFilter.
|
|
16
|
+
- Added backend-specific website SDK facade types such as `WebsiteSDKV9`, `WebsiteSDKV10`, `WebsiteSDKV10Static`, and `WebsiteSDKV10Live`.
|
|
17
|
+
|
|
18
|
+
## Changed
|
|
19
|
+
|
|
20
|
+
- v10 quote multi-rate handling now marks unavailable additional services and cancellation policies with `available: false` and `unavailableReason`.
|
|
21
|
+
- Quote selection errors can now include `UnavailableQuoteCombination` when a selected add-on/policy combination cannot be priced.
|
|
22
|
+
- Booking card sections now use a stable display order so included lines, selected add-ons, taxes, modifiers, and fallback sections render predictably.
|
|
23
|
+
- Contact validation now rejects blank required fields, invalid email addresses, invalid country codes, and overly long values before backend submission.
|
|
24
|
+
- v9 contact submission now uses the same core contact input and validation path as v10.
|
|
25
|
+
|
|
26
|
+
## Migration Impact
|
|
27
|
+
|
|
28
|
+
- No config migration is required from 2.0.0.
|
|
29
|
+
- Existing search calls continue to work; use `voucher` only for v10 voucher pricing and use either `pets` or `petsCount`, not both.
|
|
30
|
+
- Existing quote rendering should tolerate the new optional `voucher`, `available`, and `unavailableReason` fields.
|
|
31
|
+
- Existing quote selection error handling should add a fallback for `UnavailableQuoteCombination`.
|
|
32
|
+
- Existing contact forms should surface `CoreSDKError` validation issues from `error.cause.issues`.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Migration: 2.0.0 to 2.1.0
|
|
2
|
+
|
|
3
|
+
This guide covers upgrading `@v-office/website-sdk` from 2.0.0 to 2.1.0.
|
|
4
|
+
|
|
5
|
+
2.1.0 is a minor release. Keep using `createWebsiteSDK({ config, options })`, the flat `WebsiteSDKConfig`, and separate `WebsiteSDKOptions`.
|
|
6
|
+
|
|
7
|
+
## What To Review
|
|
8
|
+
|
|
9
|
+
### Documents
|
|
10
|
+
|
|
11
|
+
v10 SDK instances now expose:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const documents = await sdk.static.documents.getTermsAndPrivacyPolicy({ locale: "de-DE" });
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The output may contain `terms` and/or `privacyPolicy`, each with `{ subject, data }`. `data` is the published document revision data as a string. If your app renders this data, see `../../document-structured-json.md`.
|
|
18
|
+
|
|
19
|
+
This API is v10-only. Code that handles both backends should narrow by `sdk.backend === "v10"` before calling `sdk.static.documents`.
|
|
20
|
+
|
|
21
|
+
### Contact
|
|
22
|
+
|
|
23
|
+
Contact requests are validated before submission on both v9 and v10. Validation failures reject with `CoreSDKError` using `operation: "contact.submit.validation"` and field details in `error.cause.issues`.
|
|
24
|
+
|
|
25
|
+
Required fields are `title`, `surname`, `email`, `subject`, and `message`. Validation also checks email format, two-letter uppercase country codes, and maximum field lengths.
|
|
26
|
+
|
|
27
|
+
Migration: update contact forms to display field-level validation issues instead of treating every contact error as a backend failure.
|
|
28
|
+
|
|
29
|
+
### Search
|
|
30
|
+
|
|
31
|
+
`SearchSearchInput` now accepts `voucher?: string` for v10 pricing:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
await sdk.live.search.search({
|
|
35
|
+
locale: "de-DE",
|
|
36
|
+
query: "adults=2",
|
|
37
|
+
voucher: "SUMMER26",
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The CLI equivalent is `--voucher SUMMER26`.
|
|
42
|
+
|
|
43
|
+
v10 filters now expose a mapped BooleanFilter with `searchParameterQueryKey: "pets"` and localized labels (`Dogs welcome` / `Hunde willkommen`). It maps to one pet in occupancy. Use either `pets` or `petsCount`, not both.
|
|
44
|
+
|
|
45
|
+
### Quote
|
|
46
|
+
|
|
47
|
+
Available quotes can include:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
quote.voucher; // { code, status, message? }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`status` is `"applied"`, `"not_applied"`, or `"unknown"`. v10 can detect applied voucher modifiers; v9 uses `"unknown"` for available voucher quotes.
|
|
54
|
+
|
|
55
|
+
Additional services and cancellation policies may now include:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
{
|
|
59
|
+
available: false,
|
|
60
|
+
unavailableReason: "..."
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Migration: disable unavailable options in the UI and keep handling unknown optional fields gracefully.
|
|
65
|
+
|
|
66
|
+
Quote selection errors can now include `UnavailableQuoteCombination` when a selected add-on/cancellation-policy combination cannot be priced. Add a generic message for unsupported combinations.
|
|
67
|
+
|
|
68
|
+
### Public Types
|
|
69
|
+
|
|
70
|
+
The root package now exports backend-specific facade types:
|
|
71
|
+
|
|
72
|
+
- `WebsiteSDKV9`
|
|
73
|
+
- `WebsiteSDKV10`
|
|
74
|
+
- `WebsiteSDKSharedStatic`
|
|
75
|
+
- `WebsiteSDKSharedLive`
|
|
76
|
+
- `WebsiteSDKV10Static`
|
|
77
|
+
- `WebsiteSDKV10Live`
|
|
78
|
+
|
|
79
|
+
Use these only when you need backend-specific narrowing. Existing `WebsiteSDK` imports remain valid.
|
|
80
|
+
|
|
81
|
+
## Recommended Steps
|
|
82
|
+
|
|
83
|
+
1. Upgrade to `@v-office/website-sdk` 2.1.0.
|
|
84
|
+
2. Update contact form error handling for `error.cause.issues`.
|
|
85
|
+
3. If you render quotes, support optional `quote.voucher`, `available`, and `unavailableReason`.
|
|
86
|
+
4. Add handling for `UnavailableQuoteCombination` in quote selection failures.
|
|
87
|
+
5. If you use v10 search filters, render the new `pets` BooleanFilter and avoid combining it with `petsCount`.
|
|
88
|
+
6. Use `sdk.static.documents.getTermsAndPrivacyPolicy` for v10 terms/privacy output where needed.
|
|
89
|
+
7. Run a focused smoke test for search, quote selection, booking, contact submission, and v10 documents.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GuestQuote, addGuestQuoteAdditionalServiceSelection, formatCurrency, toNightCount } from "@v-office/sdk-core";
|
|
1
|
+
import { GuestQuote, GuestQuoteBookingCardDisplayOrder, addGuestQuoteAdditionalServiceSelection, formatCurrency, toNightCount } from "@v-office/sdk-core";
|
|
2
2
|
import { DateTime, Effect } from "effect";
|
|
3
3
|
//#region src/legacy-v9/parser/quote/to-additional-service-calculation.ts
|
|
4
4
|
const toAdditionalServiceCalculation = (line) => {
|
|
@@ -243,9 +243,18 @@ const toSections = ({ input, guestQuoteResult, locale, translations }) => Effect
|
|
|
243
243
|
locale,
|
|
244
244
|
translations
|
|
245
245
|
});
|
|
246
|
-
if (hasSectionLineContent(sectionsIncluded)) sections.push({
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
if (hasSectionLineContent(sectionsIncluded)) sections.push({
|
|
247
|
+
lines: [sectionsIncluded],
|
|
248
|
+
displayOrder: GuestQuoteBookingCardDisplayOrder.inclusive
|
|
249
|
+
});
|
|
250
|
+
if (hasSectionLineContent(sectionsTax)) sections.push({
|
|
251
|
+
lines: [sectionsTax],
|
|
252
|
+
displayOrder: GuestQuoteBookingCardDisplayOrder.tax
|
|
253
|
+
});
|
|
254
|
+
if (sectionsOther.length > 0) sections.push({
|
|
255
|
+
lines: sectionsOther,
|
|
256
|
+
displayOrder: GuestQuoteBookingCardDisplayOrder.other
|
|
257
|
+
});
|
|
249
258
|
return sections;
|
|
250
259
|
});
|
|
251
260
|
//#endregion
|
|
@@ -261,6 +270,14 @@ const toErrorReason = (guestQuoteResult) => {
|
|
|
261
270
|
const messages = (Array.isArray(errors) ? errors : [errors]).flatMap((error) => Object.values(error).filter((value) => typeof value === "string" && value.trim().length > 0));
|
|
262
271
|
return messages.length === 0 ? void 0 : messages.join(" ");
|
|
263
272
|
};
|
|
273
|
+
const toVoucher = ({ input, locale, translations }) => Effect.gen(function* () {
|
|
274
|
+
if (input.voucher === void 0) return void 0;
|
|
275
|
+
return {
|
|
276
|
+
code: input.voucher,
|
|
277
|
+
status: "unknown",
|
|
278
|
+
message: yield* translations.translate(locale, "quote.voucher.unknown", "The backend did not confirm whether the voucher code was applied.")
|
|
279
|
+
};
|
|
280
|
+
});
|
|
264
281
|
const toGuestQuote = (input, guestQuoteResult, locale, translations) => Effect.gen(function* () {
|
|
265
282
|
const errorReason = toErrorReason(guestQuoteResult);
|
|
266
283
|
if (errorReason !== void 0) return {
|
|
@@ -281,6 +298,11 @@ const toGuestQuote = (input, guestQuoteResult, locale, translations) => Effect.g
|
|
|
281
298
|
});
|
|
282
299
|
const baseTotal = toBaseTotal(guestQuoteResult);
|
|
283
300
|
const currency = guestQuoteResult?.currency ?? "EUR";
|
|
301
|
+
const voucher = yield* toVoucher({
|
|
302
|
+
input,
|
|
303
|
+
locale,
|
|
304
|
+
translations
|
|
305
|
+
});
|
|
284
306
|
let guestQuote = new GuestQuote({
|
|
285
307
|
input,
|
|
286
308
|
bookingCardInformation: {
|
|
@@ -290,6 +312,7 @@ const toGuestQuote = (input, guestQuoteResult, locale, translations) => Effect.g
|
|
|
290
312
|
baseTotal,
|
|
291
313
|
currency,
|
|
292
314
|
additionalServices,
|
|
315
|
+
...voucher === void 0 ? {} : { voucher },
|
|
293
316
|
backendContext: toV9QuoteBackendContext(input, guestQuoteResult),
|
|
294
317
|
updateBackendContext: updateV9QuoteBackendContext
|
|
295
318
|
});
|