@v-office/website-sdk 1.2.1 → 2.0.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/README.md +91 -232
- package/dist/cli.mjs +102 -83
- package/dist/client-BSUd3vuc.mjs +5111 -0
- package/dist/index.d.mts +2463 -11751
- package/dist/index.mjs +16 -4
- package/dist/instructions/CHANGELOG.md +9 -0
- package/dist/instructions/MIGRATION.md +9 -0
- package/dist/instructions/README.md +62 -0
- package/dist/instructions/availability.md +157 -0
- package/dist/instructions/booking.md +165 -0
- package/dist/instructions/contact.md +92 -0
- package/dist/instructions/creation.md +223 -0
- package/dist/instructions/filter.md +156 -0
- package/dist/instructions/quote.md +318 -0
- package/dist/instructions/rentals.md +152 -0
- package/dist/instructions/search.md +233 -0
- package/dist/instructions/versions/2.0.0/CHANGELOG.md +69 -0
- package/dist/instructions/versions/2.0.0/MIGRATION.md +223 -0
- package/dist/{quote-DQGps4dy.mjs → quote-1uEIO44v.mjs} +15 -16
- package/dist/{rentals-plxPVx83.mjs → rentals-Quwc78o2.mjs} +22 -16
- package/dist/{search-BuR5apFw.mjs → search-GRQeXDvo.mjs} +40 -23
- package/dist/to-rental-highlights-FNZBR4aD.mjs +5905 -0
- package/instructions/CHANGELOG.md +9 -0
- package/instructions/MIGRATION.md +9 -0
- package/instructions/README.md +62 -0
- package/instructions/availability.md +157 -0
- package/instructions/booking.md +165 -0
- package/instructions/contact.md +92 -0
- package/instructions/creation.md +223 -0
- package/instructions/filter.md +156 -0
- package/instructions/quote.md +318 -0
- package/instructions/rentals.md +152 -0
- package/instructions/search.md +233 -0
- package/instructions/versions/2.0.0/CHANGELOG.md +69 -0
- package/instructions/versions/2.0.0/MIGRATION.md +223 -0
- package/package.json +41 -56
- package/dist/client-DeEUMMOh.mjs +0 -33237
- package/dist/custom-attribute-D5Kb1YHA.mjs +0 -54
- package/dist/errors-2cuUGSvi.mjs +0 -5
- package/dist/operations-B4IgNB3E.mjs +0 -12618
- package/dist/operations-DcU1qt7g.mjs +0 -1158
- package/dist/quote-BVx3TAHE.mjs +0 -513
- package/dist/quote-CRjV_lf-.mjs +0 -609
- package/dist/rentals-H3RYtMqT.mjs +0 -323
- package/dist/search-filter-metadata-DZP0-Udc.mjs +0 -4294
- package/dist/to-rental-highlights-CAATPqan.mjs +0 -524
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Creation
|
|
2
|
+
|
|
3
|
+
## Service
|
|
4
|
+
|
|
5
|
+
Create the SDK with `createWebsiteSDK`:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { createWebsiteSDK, defineWebsiteSDKOptions } from '@v-office/website-sdk'
|
|
9
|
+
|
|
10
|
+
const sdk = createWebsiteSDK({
|
|
11
|
+
config: {
|
|
12
|
+
backend: 'v10',
|
|
13
|
+
apiEndpoint: 'https://api.example.com/graphql',
|
|
14
|
+
accessToken: '...',
|
|
15
|
+
imageBaseUrl: 'https://images.example.com',
|
|
16
|
+
},
|
|
17
|
+
options: defineWebsiteSDKOptions({
|
|
18
|
+
rentalScope: {
|
|
19
|
+
propertyId: 'property-1',
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const rentals = await sdk.static.rentals.getRentals({ locale: 'de-DE' })
|
|
26
|
+
console.log(rentals)
|
|
27
|
+
} finally {
|
|
28
|
+
await sdk.dispose()
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`createWebsiteSDK` returns the public `WebsiteSDK` facade with `static`, `live`, and `dispose` APIs. Call `dispose()` when the SDK instance is no longer needed. For v9, `dispose()` currently resolves without tearing down shared runtime state because the v9 facade does not hold one.
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
Backend config is required when creating the SDK.
|
|
37
|
+
|
|
38
|
+
`v9`:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const sdk = createWebsiteSDK({
|
|
42
|
+
config: {
|
|
43
|
+
backend: 'v9',
|
|
44
|
+
graphqlUrl: 'https://example.com/graphql',
|
|
45
|
+
v1ApiBaseUrl: 'https://example.com/api/v1',
|
|
46
|
+
v0ApiBaseUrl: 'https://example.com/api/v0',
|
|
47
|
+
apiKey: '...',
|
|
48
|
+
imageProxyBaseUrl: 'https://images.example.com',
|
|
49
|
+
rentalDataAttributes: ['name', 'description'],
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`v10`:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const sdk = createWebsiteSDK({
|
|
58
|
+
config: {
|
|
59
|
+
backend: 'v10',
|
|
60
|
+
apiEndpoint: 'https://api.example.com/graphql',
|
|
61
|
+
accessToken: '...',
|
|
62
|
+
imageBaseUrl: 'https://images.example.com',
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For v10, `backend: "v10"` is optional in TypeScript, but including it is clearer when config files are shared with the CLI.
|
|
68
|
+
|
|
69
|
+
## WebsiteSDKOptions
|
|
70
|
+
|
|
71
|
+
`options` is optional and is passed separately from backend config:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
const options = defineWebsiteSDKOptions({
|
|
75
|
+
rentalScope: {
|
|
76
|
+
propertyId: 'property-1',
|
|
77
|
+
},
|
|
78
|
+
rentalHighlightPrioritization: ['bedrooms', 'bathrooms', 'maxPersons', 'wifi'],
|
|
79
|
+
rentalPropertyHighlightPrioritization: ['wifi', 'parking'],
|
|
80
|
+
customAttributeFilterDefinitions: [],
|
|
81
|
+
translationOverrides: {},
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`defineWebsiteSDKOptions` is a typed identity helper. It is useful when defining options separately because TypeScript checks the option structure without changing the runtime value. `defineCMSSDKOptions` remains exported as a compatibility alias, but new code should use `defineWebsiteSDKOptions`.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
type WebsiteSDKOptions = {
|
|
89
|
+
translationOverrides?: TranslationOverrides
|
|
90
|
+
customAttributeFilterDefinitions?: readonly CustomAttributeFilterDefinition[]
|
|
91
|
+
rentalHighlightPrioritization?: readonly RentalHighlightPrioritizationKey[]
|
|
92
|
+
rentalPropertyHighlightPrioritization?: readonly RentalPropertyHighlightPrioritizationKey[]
|
|
93
|
+
rentalScope?: RentalScope
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Unset options are normalized by the SDK:
|
|
98
|
+
|
|
99
|
+
- `customAttributeFilterDefinitions` defaults to `[]`.
|
|
100
|
+
- `rentalHighlightPrioritization` defaults to the SDK default rental highlight order.
|
|
101
|
+
- `rentalPropertyHighlightPrioritization` defaults to the SDK default property highlight order.
|
|
102
|
+
- `rentalScope` defaults to `{}`.
|
|
103
|
+
- `translationOverrides` is omitted unless provided.
|
|
104
|
+
|
|
105
|
+
## Rental Scope
|
|
106
|
+
|
|
107
|
+
Use `rentalScope` to restrict all rental lists and searches created by this SDK instance:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const options = defineWebsiteSDKOptions({
|
|
111
|
+
rentalScope: {
|
|
112
|
+
propertyId: 'property-1',
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`propertyId` is a unified SDK option:
|
|
118
|
+
|
|
119
|
+
- `v9` static rentals are filtered by `voffice_facility_id`.
|
|
120
|
+
- `v9` live search maps it to the generated `VofficeFilter.falicityid` field.
|
|
121
|
+
- `v10` static rentals and live search map it to the generated `rentals_RentalSummaryFilter.propertyId` field.
|
|
122
|
+
|
|
123
|
+
The scope is always applied internally and is not returned by `static.filter.getFilters(...)`. Use it for website-level or tenant-level constraints.
|
|
124
|
+
|
|
125
|
+
## Custom Attribute Filter Definitions
|
|
126
|
+
|
|
127
|
+
Use `customAttributeFilterDefinitions` to add SDK-known filter keys for custom attributes, v9 backend filters, or composed filters:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const options = defineWebsiteSDKOptions({
|
|
131
|
+
customAttributeFilterDefinitions: [
|
|
132
|
+
{
|
|
133
|
+
key: 'region',
|
|
134
|
+
source: 'customAttribute',
|
|
135
|
+
category: 'ESSENTIALS',
|
|
136
|
+
label: {
|
|
137
|
+
'de-DE': 'Region',
|
|
138
|
+
'en-US': 'Region',
|
|
139
|
+
},
|
|
140
|
+
type: 'option',
|
|
141
|
+
options: [
|
|
142
|
+
{
|
|
143
|
+
value: 'north',
|
|
144
|
+
label: {
|
|
145
|
+
'de-DE': 'Nord',
|
|
146
|
+
'en-US': 'North',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
searchable: true,
|
|
151
|
+
internal: false,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Supported filter types:
|
|
158
|
+
|
|
159
|
+
- `boolean`: accepts enabled query values such as `?key`, `?key=true`, or `?key=1`.
|
|
160
|
+
- `int`: accepts integer query values and can expose optional `numericBounds` for UI controls.
|
|
161
|
+
- `option`: accepts one of the configured `options` values and exposes those options through `getFilters`.
|
|
162
|
+
- `string`: accepts any non-empty query value as an exact raw value.
|
|
163
|
+
- `complex`: composition-only type that expands one boolean query-string filter into other configured filters.
|
|
164
|
+
|
|
165
|
+
Supported sources:
|
|
166
|
+
|
|
167
|
+
- `customAttribute`: backed by custom attributes.
|
|
168
|
+
- `backendFilter`: backed by backend-defined search filter keys, mainly for v9 hub filters.
|
|
169
|
+
- `composition`: expands one boolean query-string filter into other configured filters.
|
|
170
|
+
|
|
171
|
+
Visibility:
|
|
172
|
+
|
|
173
|
+
- `internal: false` exposes searchable filters through `static.filter.getFilters(...)`.
|
|
174
|
+
- `internal: true` keeps filters usable by search and compositions but hides them from `getFilters`.
|
|
175
|
+
- `searchable: false` keeps custom attributes as display metadata only.
|
|
176
|
+
|
|
177
|
+
## Translation Overrides
|
|
178
|
+
|
|
179
|
+
Use `translationOverrides` to override SDK translation keys:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
const options = defineWebsiteSDKOptions({
|
|
183
|
+
translationOverrides: {
|
|
184
|
+
'de-DE': {
|
|
185
|
+
'filter.wifi.label': 'WLAN',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Overrides are applied by the SDK translation service and affect labels generated by filters, rentals, search, availability, and quote output.
|
|
192
|
+
|
|
193
|
+
## CLI Usage
|
|
194
|
+
|
|
195
|
+
The CLI reads flat `WebsiteSDKConfig` JSON files and separate `WebsiteSDKOptions` JSON files:
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
website-sdk --backend v10 --config ./website-sdk-config.json --options ./website-sdk-options.json rentals --locale de-DE
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Example `website-sdk-config.v10.json`:
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"backend": "v10",
|
|
206
|
+
"apiEndpoint": "https://api.example.com/graphql",
|
|
207
|
+
"accessToken": "...",
|
|
208
|
+
"imageBaseUrl": "https://images.example.com"
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Example `website-sdk-options.json`:
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
{
|
|
216
|
+
"rentalScope": {
|
|
217
|
+
"propertyId": "property-1"
|
|
218
|
+
},
|
|
219
|
+
"rentalHighlightPrioritization": ["bedrooms", "bathrooms", "maxPersons", "wifi"],
|
|
220
|
+
"customAttributeFilterDefinitions": [],
|
|
221
|
+
"translationOverrides": {}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Filter
|
|
2
|
+
|
|
3
|
+
## Service
|
|
4
|
+
|
|
5
|
+
Use the static filter API to fetch localized search filter definitions:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
const filters = await sdk.static.filter.getFilters({ locale: 'de-DE' })
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The service is implemented for both `v9` and `v10` backends and returns normalized filters for building search UIs.
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
type FilterGetFiltersInput = {
|
|
17
|
+
locale: 'de-DE' | 'en-US'
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Sample:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"locale": "de-DE"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Output
|
|
30
|
+
|
|
31
|
+
Returns `Promise<FilterGetFiltersOutput>`, an array of filter definitions.
|
|
32
|
+
|
|
33
|
+
Sample:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
[
|
|
37
|
+
{
|
|
38
|
+
"searchParameterQueryKey": "wifi",
|
|
39
|
+
"label": "WiFi",
|
|
40
|
+
"category": "ESSENTIALS",
|
|
41
|
+
"type": "BooleanFilter"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"searchParameterQueryKey": "bedrooms",
|
|
45
|
+
"label": "Bedrooms",
|
|
46
|
+
"category": "ROOMS",
|
|
47
|
+
"type": "IntFilter",
|
|
48
|
+
"numericBounds": {
|
|
49
|
+
"min": 1,
|
|
50
|
+
"max": 8
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"searchParameterQueryKey": "region",
|
|
55
|
+
"label": "Region",
|
|
56
|
+
"category": "LOCATION",
|
|
57
|
+
"type": "OptionFilter",
|
|
58
|
+
"options": [
|
|
59
|
+
{
|
|
60
|
+
"value": "north",
|
|
61
|
+
"label": "North"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Filter variants:
|
|
69
|
+
|
|
70
|
+
- `BooleanFilter`: on/off query parameter.
|
|
71
|
+
- `IntFilter`: numeric query parameter, optionally with `numericBounds`.
|
|
72
|
+
- `OptionFilter`: query parameter with localized selectable `options`.
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
`v9` config:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"backend": "v9",
|
|
81
|
+
"graphqlUrl": "https://example.com/graphql",
|
|
82
|
+
"v1ApiBaseUrl": "https://example.com/api/v1",
|
|
83
|
+
"apiKey": "...",
|
|
84
|
+
"imageProxyBaseUrl": "https://images.example.com"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`v10` config:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"backend": "v10",
|
|
93
|
+
"apiEndpoint": "https://api.example.com/graphql",
|
|
94
|
+
"accessToken": "...",
|
|
95
|
+
"imageBaseUrl": "https://images.example.com"
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Optional `WebsiteSDKOptions` can add public custom filters:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"customAttributeFilterDefinitions": [
|
|
104
|
+
{
|
|
105
|
+
"key": "region",
|
|
106
|
+
"source": "customAttribute",
|
|
107
|
+
"category": "ESSENTIALS",
|
|
108
|
+
"label": {
|
|
109
|
+
"de-DE": "Region",
|
|
110
|
+
"en-US": "Region"
|
|
111
|
+
},
|
|
112
|
+
"type": "option",
|
|
113
|
+
"options": [
|
|
114
|
+
{
|
|
115
|
+
"value": "north",
|
|
116
|
+
"label": {
|
|
117
|
+
"de-DE": "Norden",
|
|
118
|
+
"en-US": "North"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"searchable": true,
|
|
123
|
+
"internal": false
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"translationOverrides": {}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Only custom definitions with `searchable: true` and `internal: false` are exposed by `getFilters`.
|
|
131
|
+
|
|
132
|
+
## CLI Usage
|
|
133
|
+
|
|
134
|
+
Fetch filters with environment-based config:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
website-sdk --backend v9 filters --locale en-US
|
|
138
|
+
website-sdk --backend v10 filters --locale de-DE
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Use files instead of environment variables:
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
website-sdk --backend v10 --config ./website-sdk-config.json --options ./website-sdk-options.json filters --locale de-DE
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Output defaults to JSON. Use `--output pretty` for inspected terminal output:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
website-sdk --backend v10 filters --locale de-DE --output pretty
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Environment variables:
|
|
154
|
+
|
|
155
|
+
- `v9`: `HUB_GRAPHQL_URL`, `HUB_V1_API_BASE_URL`, optional `HUB_V0_API_BASE_URL`, `HUB_API_KEY`, `IMAGE_PROXY_BASE_URL`.
|
|
156
|
+
- `v10`: `VOFFICE_API_ENDPOINT`, `VOFFICE_LOCAL_DEV_ACCESS_TOKEN`, `VOFFICE_IMAGE_BASE_URL`.
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Quote
|
|
2
|
+
|
|
3
|
+
## Service
|
|
4
|
+
|
|
5
|
+
Use the live quote API to price a stay and get selectable booking options:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
const result = await sdk.live.quote.quote(input)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
If the quote is available, the returned `GuestQuote` can be updated through selection helpers:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const withService = await sdk.live.quote.addAdditionalService({ quote, id: 'linen' })
|
|
15
|
+
const withPolicy = await sdk.live.quote.selectCancellationPolicy({ quote, id: 'alternative' })
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
type QuoteQuoteInput = {
|
|
22
|
+
locale: 'de-DE' | 'en-US'
|
|
23
|
+
rentalId: string
|
|
24
|
+
period: {
|
|
25
|
+
start: string
|
|
26
|
+
end: string
|
|
27
|
+
}
|
|
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
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`GuestQuoteInput` remains available as a legacy alias.
|
|
41
|
+
|
|
42
|
+
Sample:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"locale": "de-DE",
|
|
47
|
+
"rentalId": "123",
|
|
48
|
+
"period": {
|
|
49
|
+
"start": "2026-07-01",
|
|
50
|
+
"end": "2026-07-08"
|
|
51
|
+
},
|
|
52
|
+
"occupancy": {
|
|
53
|
+
"adults": 2,
|
|
54
|
+
"children": 1,
|
|
55
|
+
"childrenAges": [8],
|
|
56
|
+
"babies": 0,
|
|
57
|
+
"pets": 1
|
|
58
|
+
},
|
|
59
|
+
"destinationCountryCode": "DE",
|
|
60
|
+
"voucher": "SUMMER26"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Dates are local dates formatted as `YYYY-MM-DD`. For `v9`, `rentalId` must be a numeric vOffice unit id.
|
|
65
|
+
|
|
66
|
+
## Output
|
|
67
|
+
|
|
68
|
+
Returns `Promise<GuestQuoteResult>`.
|
|
69
|
+
|
|
70
|
+
Available sample:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"status": "available",
|
|
75
|
+
"quote": {
|
|
76
|
+
"bookingCardInformation": {
|
|
77
|
+
"sections": [
|
|
78
|
+
{
|
|
79
|
+
"lines": [
|
|
80
|
+
{
|
|
81
|
+
"item": {
|
|
82
|
+
"position": "Rent",
|
|
83
|
+
"appliedCharge": "1,200.00 EUR"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"total": "1,200.00 EUR"
|
|
90
|
+
},
|
|
91
|
+
"additionalServices": [
|
|
92
|
+
{
|
|
93
|
+
"id": "linen",
|
|
94
|
+
"label": "Bed linen",
|
|
95
|
+
"charge": "25.00 EUR",
|
|
96
|
+
"maxPerBooking": 1
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"cancellationPolicies": [
|
|
100
|
+
{
|
|
101
|
+
"id": "default",
|
|
102
|
+
"label": "Default cancellation policy",
|
|
103
|
+
"selected": true
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"insurance": {
|
|
107
|
+
"options": [
|
|
108
|
+
{
|
|
109
|
+
"kind": "none",
|
|
110
|
+
"label": "No insurance"
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"selected": {
|
|
114
|
+
"kind": "none"
|
|
115
|
+
},
|
|
116
|
+
"preContract": {
|
|
117
|
+
"kind": "none_selected"
|
|
118
|
+
},
|
|
119
|
+
"paymentOptions": []
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Unavailable sample:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"status": "unavailable",
|
|
130
|
+
"reason": "Rental is not available for the selected period."
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
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, and unavailable cancellation policy quote.
|
|
135
|
+
|
|
136
|
+
## Additional Services
|
|
137
|
+
|
|
138
|
+
Additional services are exposed on an available quote as `quote.additionalServices`.
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"id": "linen",
|
|
143
|
+
"label": "Bed linen",
|
|
144
|
+
"charge": "25.00 EUR",
|
|
145
|
+
"maxPerBooking": 1,
|
|
146
|
+
"description": "Bed linen package"
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Use the service `id` to add or remove a service selection:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const added = await sdk.live.quote.addAdditionalService({ quote, id: 'linen' })
|
|
154
|
+
if (added.ok) quote = added.quote
|
|
155
|
+
|
|
156
|
+
const removed = await sdk.live.quote.removeAdditionalService({ quote, id: 'linen' })
|
|
157
|
+
if (removed.ok) quote = removed.quote
|
|
158
|
+
|
|
159
|
+
const cleared = await sdk.live.quote.clearAdditionalServices({ quote })
|
|
160
|
+
if (cleared.ok) quote = cleared.quote
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Each successful change returns a new quote with recalculated `bookingCardInformation.total`. Handle `{ ok: false, error }` for unknown service ids or quantity limits.
|
|
164
|
+
|
|
165
|
+
## Cancellation Policies
|
|
166
|
+
|
|
167
|
+
Cancellation policies are exposed on `quote.cancellationPolicies` when the backend offers selectable policies.
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"id": "alternative",
|
|
172
|
+
"label": "Flexible cancellation",
|
|
173
|
+
"selected": false,
|
|
174
|
+
"markUpPercentage": "10%",
|
|
175
|
+
"processingFee": "25.00 EUR",
|
|
176
|
+
"rules": [
|
|
177
|
+
{
|
|
178
|
+
"daysBeforeArrival": 14,
|
|
179
|
+
"refundPercentage": "80%"
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Select a policy by id:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
const selected = await sdk.live.quote.selectCancellationPolicy({
|
|
189
|
+
quote,
|
|
190
|
+
id: 'alternative',
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
if (selected.ok) quote = selected.quote
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
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.
|
|
197
|
+
|
|
198
|
+
## Insurance
|
|
199
|
+
|
|
200
|
+
Insurance information is exposed on `quote.insurance` when available. The `options` array contains either a `none` option or selectable insurance products.
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"options": [
|
|
205
|
+
{
|
|
206
|
+
"kind": "insurance",
|
|
207
|
+
"id": "ergo",
|
|
208
|
+
"formattedPrice": "49.00 EUR",
|
|
209
|
+
"label": "Travel cancellation insurance",
|
|
210
|
+
"requiredInformation": {
|
|
211
|
+
"kind": "travelers"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
"selected": {
|
|
216
|
+
"kind": "none"
|
|
217
|
+
},
|
|
218
|
+
"preContract": {
|
|
219
|
+
"kind": "none_selected"
|
|
220
|
+
},
|
|
221
|
+
"paymentOptions": []
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Use `selectInsurance` to choose no insurance or a product:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
quote = await sdk.live.quote.selectInsurance({
|
|
229
|
+
quote,
|
|
230
|
+
selection: {
|
|
231
|
+
kind: 'insurance',
|
|
232
|
+
id: 'ergo',
|
|
233
|
+
travelers: [
|
|
234
|
+
{
|
|
235
|
+
salutation: 'Ms',
|
|
236
|
+
forename: 'Jane',
|
|
237
|
+
surname: 'Doe',
|
|
238
|
+
birthday: '1990-01-01',
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
})
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
For insurance products that require a pre-contract, provide customer information:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
quote = await sdk.live.quote.createInsurancePreContract({
|
|
249
|
+
quote,
|
|
250
|
+
customerInformation: {
|
|
251
|
+
destinationCountryCode: 'DE',
|
|
252
|
+
address: {
|
|
253
|
+
street: 'Main Street',
|
|
254
|
+
housenumber: '1',
|
|
255
|
+
postalcode: '12345',
|
|
256
|
+
city: 'Berlin',
|
|
257
|
+
countryCode: 'DE',
|
|
258
|
+
},
|
|
259
|
+
email: 'jane@example.com',
|
|
260
|
+
mobile: '+49123456789',
|
|
261
|
+
},
|
|
262
|
+
})
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Select an insurance payment method before booking insurance:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
quote = await sdk.live.quote.selectInsurancePayment({
|
|
269
|
+
quote,
|
|
270
|
+
paymentInformation: {
|
|
271
|
+
kind: 'sepa_debit',
|
|
272
|
+
iban: 'DE02120300000000202051',
|
|
273
|
+
},
|
|
274
|
+
})
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
After the rental booking is created, complete insurance booking with the booking number and guest token:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
const insuranceBooking = await sdk.live.quote.bookInsurance({
|
|
281
|
+
quote,
|
|
282
|
+
bookingNumber: booking.bookingNumber,
|
|
283
|
+
guestToken: booking.guestToken,
|
|
284
|
+
})
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
`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.
|
|
288
|
+
|
|
289
|
+
## Configuration
|
|
290
|
+
|
|
291
|
+
Quote requests are rate-limited to one backend request per second with a queue size of five. `v9` supports insurance option refresh and insurance actions; `v10` currently returns a no-insurance placeholder and insurance actions resolve as not required.
|
|
292
|
+
|
|
293
|
+
## CLI Usage
|
|
294
|
+
|
|
295
|
+
Create `quote-input.json` with a `QuoteQuoteInput` object, then run:
|
|
296
|
+
|
|
297
|
+
```sh
|
|
298
|
+
website-sdk --backend v10 quote --input ./quote-input.json
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Use files instead of environment variables:
|
|
302
|
+
|
|
303
|
+
```sh
|
|
304
|
+
website-sdk --backend v9 --config ./website-sdk-config.json quote --input ./quote-input.json
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Output defaults to JSON. Use `--output pretty` for inspected terminal output:
|
|
308
|
+
|
|
309
|
+
```sh
|
|
310
|
+
website-sdk --backend v10 quote --input ./quote-input.json --output pretty
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The CLI only creates the initial quote. Additional service, cancellation policy, and insurance selections are SDK-only operations.
|
|
314
|
+
|
|
315
|
+
Environment variables:
|
|
316
|
+
|
|
317
|
+
- `v9`: `HUB_GRAPHQL_URL`, `HUB_V1_API_BASE_URL`, optional `HUB_V0_API_BASE_URL`, `HUB_API_KEY`, `IMAGE_PROXY_BASE_URL`.
|
|
318
|
+
- `v10`: `VOFFICE_API_ENDPOINT`, `VOFFICE_LOCAL_DEV_ACCESS_TOKEN`, `VOFFICE_IMAGE_BASE_URL`.
|