@v-office/website-sdk 2.7.0 → 2.8.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 +28 -1
- package/dist/cli.mjs +25 -4
- package/dist/{client-45_ofP_d.mjs → client-BNbBfJtO.mjs} +385 -187
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +3 -3
- package/dist/instructions/CHANGELOG.md +3 -1
- package/dist/instructions/MIGRATION.md +3 -1
- package/dist/instructions/README.md +8 -3
- package/dist/instructions/creation.md +65 -64
- package/dist/instructions/custom-attributes.md +556 -0
- package/dist/instructions/filter.md +51 -23
- package/dist/instructions/rentals.md +26 -2
- package/dist/instructions/search.md +29 -3
- package/dist/instructions/versions/2.5.0/MIGRATION.md +5 -0
- package/dist/instructions/versions/2.6.0/CHANGELOG.md +3 -25
- package/dist/instructions/versions/2.6.0/MIGRATION.md +4 -72
- package/dist/instructions/versions/2.7.0/CHANGELOG.md +44 -0
- package/dist/instructions/versions/2.7.0/MIGRATION.md +79 -0
- package/dist/instructions/versions/2.8.0/CHANGELOG.md +63 -0
- package/dist/instructions/versions/2.8.0/MIGRATION.md +252 -0
- package/dist/{rentals-Lw1qUKIj.mjs → rentals-cCejb_2d.mjs} +21 -21
- package/dist/{search-wcoZw2rt.mjs → search-Dzzra6IW.mjs} +16 -133
- package/dist/{to-rental-highlights-CxWlq76f.mjs → to-rental-highlights-OvNe9ZQS.mjs} +8 -6
- package/dist/translations/v10/de-DE/core.json +2 -0
- package/dist/translations/v10/en-US/core.json +2 -0
- package/instructions/CHANGELOG.md +3 -1
- package/instructions/MIGRATION.md +3 -1
- package/instructions/README.md +8 -3
- package/instructions/creation.md +65 -64
- package/instructions/custom-attributes.md +556 -0
- package/instructions/filter.md +51 -23
- package/instructions/rentals.md +26 -2
- package/instructions/search.md +29 -3
- package/instructions/versions/2.5.0/MIGRATION.md +5 -0
- package/instructions/versions/2.6.0/CHANGELOG.md +3 -25
- package/instructions/versions/2.6.0/MIGRATION.md +4 -72
- package/instructions/versions/2.7.0/CHANGELOG.md +44 -0
- package/instructions/versions/2.7.0/MIGRATION.md +79 -0
- package/instructions/versions/2.8.0/CHANGELOG.md +63 -0
- package/instructions/versions/2.8.0/MIGRATION.md +252 -0
- package/package.json +5 -3
package/instructions/rentals.md
CHANGED
|
@@ -147,14 +147,38 @@ Optional `WebsiteSDKOptions`:
|
|
|
147
147
|
|
|
148
148
|
```json
|
|
149
149
|
{
|
|
150
|
-
"
|
|
150
|
+
"customAttributes": {
|
|
151
|
+
"catalog": {
|
|
152
|
+
"privateSauna": {
|
|
153
|
+
"id": "GQYKYgMVh28X7VLGursbkt",
|
|
154
|
+
"type": "BOOLEAN"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"select": {
|
|
158
|
+
"privateSauna": {
|
|
159
|
+
"label": { "de-DE": "Sauna", "en-US": "Sauna" }
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"rentalHighlightPrioritization": ["bedrooms", "privateSauna", "wifi"],
|
|
151
164
|
"rentalPropertyHighlightPrioritization": ["wifi", "parking"],
|
|
152
165
|
"customAttributeFilterDefinitions": [],
|
|
153
166
|
"translationOverrides": {}
|
|
154
167
|
}
|
|
155
168
|
```
|
|
156
169
|
|
|
157
|
-
`rentalHighlightPrioritization` controls the order of rental `highlights`. `rentalPropertyHighlightPrioritization` controls property highlights for v10 property data.
|
|
170
|
+
`rentalHighlightPrioritization` controls the order of rental `highlights`. `rentalPropertyHighlightPrioritization` controls property highlights for v10 property data. Translation overrides affect localized labels.
|
|
171
|
+
|
|
172
|
+
In CLI JSON, `customAttributes` contains catalog and selection inputs; the CLI builds
|
|
173
|
+
the validated registry. Typed applications normally call `defineCustomAttributes`
|
|
174
|
+
and pass its result instead.
|
|
175
|
+
|
|
176
|
+
Custom attributes configured through `customAttributes` add values to rental output on
|
|
177
|
+
both backends. A value appears in `highlights` only when its key is listed in
|
|
178
|
+
`rentalHighlightPrioritization`, and in `attributes` under the group named by its
|
|
179
|
+
authored `category` — alongside built-in attributes of that category, not in a separate
|
|
180
|
+
bucket. Category and attribute `label`s in the output are localized strings, never
|
|
181
|
+
stable keys. See `custom-attributes.md`.
|
|
158
182
|
|
|
159
183
|
## CLI Usage
|
|
160
184
|
|
package/instructions/search.md
CHANGED
|
@@ -272,7 +272,12 @@ Sample:
|
|
|
272
272
|
"appliedFilters": [
|
|
273
273
|
{
|
|
274
274
|
"key": "wifi",
|
|
275
|
-
"label": "
|
|
275
|
+
"label": "WLAN"
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"key": "region",
|
|
279
|
+
"label": "Region: Norden",
|
|
280
|
+
"value": "north"
|
|
276
281
|
}
|
|
277
282
|
],
|
|
278
283
|
"unusedFilterKeys": [],
|
|
@@ -285,13 +290,34 @@ Sample:
|
|
|
285
290
|
|
|
286
291
|
Search items share the rental base fields and may include `scope`, `address`, `property`, `highlights`, and `formattedTotal`. Exact-period results are returned in `items`; alternative-period suggestions are returned in root-level `alternatives`.
|
|
287
292
|
|
|
293
|
+
`appliedFilters` reports what the backend actually applied, and is what a "remove
|
|
294
|
+
this filter" chip should be built from. `label` is localized presentation and can
|
|
295
|
+
repeat, so it cannot identify a filter; `key` plus `value` can. `value` is the
|
|
296
|
+
canonical applied value and is present only for filters that carry one — on/off
|
|
297
|
+
filters are identified by `key` alone. A key you sent that is **not** listed here
|
|
298
|
+
appears in `unusedFilterKeys` and had no effect on the result set. A scalar key may
|
|
299
|
+
appear in both arrays when its first value was applied but additional values were
|
|
300
|
+
rejected.
|
|
301
|
+
|
|
302
|
+
Composition filters are atomic in both metadata and the backend payload. The SDK
|
|
303
|
+
validates all configured leaves against the active backend before committing any
|
|
304
|
+
generated GraphQL or REST input. If one leaf is unsupported or malformed, no
|
|
305
|
+
composition-generated leaf restricts the result, and only the composition key is
|
|
306
|
+
reported unused. Direct filters are tracked independently and remain applied even
|
|
307
|
+
when a failed composition references the same key.
|
|
308
|
+
|
|
309
|
+
When every leaf succeeds, `appliedFilters` contains both the composition entry and
|
|
310
|
+
the expanded leaf entries. A UI may collapse those leaves under the composition for
|
|
311
|
+
display, but should keep the returned keys and canonical values when removing direct
|
|
312
|
+
filters.
|
|
313
|
+
|
|
288
314
|
## v10 Backend
|
|
289
315
|
|
|
290
316
|
v10 search runs against the dedicated REST search backend (`POST` to the configured `searchEndpoint`). Existing calls and the output type remain compatible, while the input additionally supports optional sorting. v10 results reflect the REST projection:
|
|
291
317
|
|
|
292
318
|
- At most five images per item, and no image `category`.
|
|
293
319
|
- `property` is the minimal `{ id, nameOrLabel }` shape. Hydrate `property.location`, `property.images`, or `property.address` from `sdk.static.rentals.getRentals(...)` when a card needs them.
|
|
294
|
-
- Custom-attribute search filters and highlights require
|
|
320
|
+
- Custom-attribute search filters and highlights require the `customAttributes` registry. A definition with no catalog ID cannot be executed, so its query key is left in `unusedFilterKeys`. v9 never executes a custom-attribute filter at all. See `custom-attributes.md`.
|
|
295
321
|
- Fixed-period and flexible searches are priced by the REST backend and require occupancy.
|
|
296
322
|
- Pagination uses the backend `from`/`size` window behind the same opaque `cursor`, capped at 1,000 results.
|
|
297
323
|
|
|
@@ -299,7 +325,7 @@ v10 search runs against the dedicated REST search backend (`POST` to the configu
|
|
|
299
325
|
|
|
300
326
|
Use flat `WebsiteSDKConfig` files and optional `WebsiteSDKOptions`.
|
|
301
327
|
|
|
302
|
-
For v10, config requires `searchEndpoint` (the full REST search URL) as of 2.5.0. See `creation.md` for `searchEndpoint` and the `
|
|
328
|
+
For v10, config requires `searchEndpoint` (the full REST search URL) as of 2.5.0. See `creation.md` for `searchEndpoint` and the `customAttributes` option.
|
|
303
329
|
|
|
304
330
|
Custom filter definitions can extend accepted search query keys. Search requests are rate-limited to one backend request per second with a queue size of five.
|
|
305
331
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Migration: 2.4.3 to 2.5.0
|
|
2
2
|
|
|
3
|
+
> Custom-attribute manifest guidance below is historically correct for 2.5.x but is
|
|
4
|
+
> superseded in 2.8.0. When upgrading current packages, follow
|
|
5
|
+
> `../2.8.0/MIGRATION.md` to replace `customAttributeDefinitionManifest` with
|
|
6
|
+
> `defineCustomAttributes`.
|
|
7
|
+
|
|
3
8
|
This guide covers upgrading `@v-office/website-sdk` from 2.4.3 to 2.5.0.
|
|
4
9
|
|
|
5
10
|
2.5.0 keeps `createWebsiteSDK({ config, options })`, the flat `WebsiteSDKConfig`, and existing SDK calls. v10 search now runs against the dedicated REST search backend, which requires one new config field and, for custom-attribute search, one new option. Search input also gains optional sorting, and static v10 rental loading uses the full Rental APIs internally. Existing calls and output types remain compatible.
|
|
@@ -1,28 +1,6 @@
|
|
|
1
1
|
# Changelog: 2.6.0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@v-office/website-sdk` 2.6.0 was never published. The Stripe Checkout work
|
|
4
|
+
documented under this version during development shipped as 2.7.0 on 2026-07-27.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Added
|
|
8
|
-
|
|
9
|
-
- `submitPaymentOption` and `submitPaymentOptionEffect` now complete `stripe_checkout` options that carry only `sessionId` and `accountId`. Previously these options failed with "Stripe Checkout requires a checkout session URL".
|
|
10
|
-
- Stripe.js is loaded from `https://js.stripe.com/v3/` on first use and reused for later submissions. A failed load is not kept, so the next submission retries it. An existing `window.Stripe` instance is used when the page already provides one, so no second script tag is added.
|
|
11
|
-
- The vOffice Stripe platform publishable keys are embedded in the SDK. Stripe Checkout requires no consumer configuration.
|
|
12
|
-
|
|
13
|
-
## Changed
|
|
14
|
-
|
|
15
|
-
- `stripe_checkout` submission prefers the Checkout Session `url` and only falls back to Stripe.js when it is absent. Once vOffice returns the URL, the SDK uses it without a further release.
|
|
16
|
-
- The publishable key is selected from the session id, so tenants in Stripe test mode (`cs_test_`) and live mode (`cs_live_`) both work without configuration or environment detection.
|
|
17
|
-
- Stripe sessions are created on connected accounts, so the option's `accountId` is passed to Stripe.js as `stripeAccount`.
|
|
18
|
-
- The failure raised when a `stripe_checkout` option carries neither a URL nor a session id now names both.
|
|
19
|
-
- Browser access helpers used by payment submission moved into an internal module shared by redirect, form-post, and Stripe submission. This is internal only and does not change the public API.
|
|
20
|
-
|
|
21
|
-
## Migration Impact
|
|
22
|
-
|
|
23
|
-
- Consumers that hid Stripe payment options because `url` was missing can render them again. Gate the button on the option being present rather than on `option.url`. See `versions/2.6.0/MIGRATION.md`.
|
|
24
|
-
- Sites with a Content-Security-Policy must allow `script-src https://js.stripe.com` and `frame-src https://js.stripe.com https://hooks.stripe.com`.
|
|
25
|
-
- Payment submission remains browser-only and still fails outside a browser environment.
|
|
26
|
-
- Stripe.js is fetched at submission time, so payment submission can now fail from a blocked or unavailable third-party script. Treat that as a payment failure, never as a booking failure: the reservation already exists when payment options are shown.
|
|
27
|
-
- No config, option, or output type changes. v10 Adyen `redirect` flows and all `bank_transfer` and `form_post` flows are unaffected.
|
|
28
|
-
- Stripe removed `redirectToCheckout` from its versioned Stripe.js release trains (`clover`, 2025-09-30, and later) and from the published `stripe-js` types. The method is still implemented in the unversioned `https://js.stripe.com/v3/` bundle that the SDK loads, which is why this fallback works. It is a bridge until vOffice returns the session URL and is expected to be removed afterwards. Should a future Stripe.js build drop the method entirely, submission fails with a message naming the missing session URL.
|
|
6
|
+
Use `../2.7.0/CHANGELOG.md` as the authoritative release record.
|
|
@@ -1,74 +1,6 @@
|
|
|
1
|
-
# Migration: 2.
|
|
1
|
+
# Migration: 2.6.0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@v-office/website-sdk` 2.6.0 was never published. The planned Stripe Checkout
|
|
4
|
+
change shipped in 2.7.0.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## What Changed
|
|
8
|
-
|
|
9
|
-
vOffice's `initStripePayment` action returns only `sessionId` and `accountId`, never the Checkout Session URL. Because `submitPaymentOption` redirected exclusively to a session URL, Stripe payment options could never be completed and failed with "Stripe Checkout requires a checkout session URL".
|
|
10
|
-
|
|
11
|
-
2.6.0 keeps the URL redirect as the preferred path and adds a fallback: when a `stripe_checkout` option has a `sessionId` but no `url`, the SDK loads Stripe.js and opens the Checkout Session with it. This is the same mechanism the classic non-SDK vOffice websites use.
|
|
12
|
-
|
|
13
|
-
The fallback is self-retiring. When vOffice starts returning the session URL, the option gains a `url`, the URL redirect wins, and Stripe.js is never loaded. No SDK release is needed for that transition.
|
|
14
|
-
|
|
15
|
-
## Remove Stripe Workarounds
|
|
16
|
-
|
|
17
|
-
Sites that hid the Stripe button because no URL was present should now render it. Gate on the option existing rather than on `option.url`:
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
// Before: Stripe options were unusable, so they had to be hidden
|
|
21
|
-
const payable = option.kind !== "stripe_checkout" || option.url !== undefined;
|
|
22
|
-
|
|
23
|
-
// After: every submittable option can be submitted
|
|
24
|
-
const payable = true;
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Sites that implemented their own Stripe.js bridge with a publishable key can delete it, along with the key configuration. The SDK carries the vOffice platform keys and selects between test and live based on the session id, so a tenant in Stripe test mode and a tenant in live mode both work from the same build.
|
|
28
|
-
|
|
29
|
-
## Content-Security-Policy
|
|
30
|
-
|
|
31
|
-
Stripe.js is fetched from Stripe at submission time. If your site sets a CSP, allow:
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
script-src https://js.stripe.com
|
|
35
|
-
frame-src https://js.stripe.com https://hooks.stripe.com
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Without these directives the script is blocked and Stripe submission fails. Other payment kinds are unaffected.
|
|
39
|
-
|
|
40
|
-
## Error Handling
|
|
41
|
-
|
|
42
|
-
Payment submission can now fail for new reasons: Stripe.js could not be loaded, the loaded Stripe.js build does not provide the Checkout redirect, or Stripe rejected the redirect. All surface as a `CoreSDKError` with `operation: "paymentSubmission"`, the same as existing submission failures.
|
|
43
|
-
|
|
44
|
-
Offering a retry is worthwhile for these failures. A failed Stripe.js load is not remembered, so the next submission fetches the script again and can succeed without a page reload.
|
|
45
|
-
|
|
46
|
-
The booking already exists by the time payment options are rendered, so a submission failure must never be presented as a failed booking:
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
try {
|
|
50
|
-
await sdk.live.booking.submitPaymentOption(option);
|
|
51
|
-
} catch (error) {
|
|
52
|
-
// The reservation is created. Show the booking number and offer bank transfer.
|
|
53
|
-
showPaymentFailure({ bookingNumber: booking.bookingNumber, error });
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Submission is still browser-only and fails outside a browser environment, unchanged from earlier versions.
|
|
58
|
-
|
|
59
|
-
## Payment Return
|
|
60
|
-
|
|
61
|
-
Unchanged from earlier versions, but worth confirming while testing Stripe end to end. The SDK derives the Stripe success and cancel URLs from the `relativeRedirectUrl` passed to `sdk.live.booking.book(...)` and appends `payment=stripe&success=true` or `payment=stripe&cancel=true`. That path must exist in your site and should read those query parameters.
|
|
62
|
-
|
|
63
|
-
Note that `relativeRedirectUrl` is supplied before the reservation exists, so the return URL cannot contain the booking number or guest token. Persist anything the return page needs, for example in `sessionStorage`, before submitting the payment option.
|
|
64
|
-
|
|
65
|
-
A `success=true` return means Stripe sent the browser back, not that payment has settled. Payment confirmation reaches vOffice through Stripe's webhook.
|
|
66
|
-
|
|
67
|
-
## Recommended Steps
|
|
68
|
-
|
|
69
|
-
1. Upgrade to `@v-office/website-sdk` 2.6.0.
|
|
70
|
-
2. Remove any conditional that hides Stripe payment options when `option.url` is missing.
|
|
71
|
-
3. Remove a site-level Stripe.js bridge and its publishable key configuration if you added one.
|
|
72
|
-
4. Add the Stripe CSP directives if your site sets a Content-Security-Policy.
|
|
73
|
-
5. Confirm payment submission errors are presented as payment failures with the booking number, not as booking failures.
|
|
74
|
-
6. Smoke-test one booking against a Stripe test tenant and one against a live tenant, checking that Checkout opens and that the configured return path handles both `success=true` and `cancel=true`.
|
|
6
|
+
Consumers upgrading from 2.5.x should follow `../2.7.0/MIGRATION.md`.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog: 2.7.0
|
|
2
|
+
|
|
3
|
+
Release date: 2026-07-27
|
|
4
|
+
|
|
5
|
+
This release makes v9 `stripe_checkout` payment options submittable. The vOffice
|
|
6
|
+
`initStripePayment` action returns only session metadata, so `submitPaymentOption`
|
|
7
|
+
now opens the Checkout Session with Stripe.js when the backend omits the session
|
|
8
|
+
URL. Config, service calls, and output types are unchanged.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- `submitPaymentOption` and `submitPaymentOptionEffect` now complete
|
|
13
|
+
`stripe_checkout` options that carry only `sessionId` and `accountId`.
|
|
14
|
+
- Stripe.js is loaded from `https://js.stripe.com/v3/` on first use and reused for
|
|
15
|
+
later submissions. Failed loads are not cached, and an existing `window.Stripe`
|
|
16
|
+
is reused.
|
|
17
|
+
- The SDK includes the vOffice Stripe platform publishable keys, so Stripe Checkout
|
|
18
|
+
needs no consumer key configuration.
|
|
19
|
+
|
|
20
|
+
## Changed
|
|
21
|
+
|
|
22
|
+
- `stripe_checkout` prefers a Checkout Session `url` and falls back to Stripe.js
|
|
23
|
+
only when the URL is absent.
|
|
24
|
+
- Test (`cs_test_`) and live (`cs_live_`) sessions select the corresponding
|
|
25
|
+
publishable key automatically.
|
|
26
|
+
- Connected-account sessions pass `accountId` to Stripe.js as `stripeAccount`.
|
|
27
|
+
- Missing-session failures now name both the absent URL and session ID.
|
|
28
|
+
|
|
29
|
+
## Migration Impact
|
|
30
|
+
|
|
31
|
+
- Sites that hid Stripe options because `url` was absent can render them again.
|
|
32
|
+
Gate the button on the payment option being present rather than on `option.url`.
|
|
33
|
+
- Content-Security-Policy must allow `script-src https://js.stripe.com` and
|
|
34
|
+
`frame-src https://js.stripe.com https://hooks.stripe.com`.
|
|
35
|
+
- Payment submission remains browser-only. A Stripe script or redirect failure is
|
|
36
|
+
a payment failure after the booking exists, not a booking failure.
|
|
37
|
+
- No config, service-call, or output migration is required. See
|
|
38
|
+
`versions/2.7.0/MIGRATION.md`.
|
|
39
|
+
|
|
40
|
+
## Versioning Note
|
|
41
|
+
|
|
42
|
+
The implementation was documented during development under a planned 2.6.0
|
|
43
|
+
directory, but 2.6.0 was never published. The package was released as 2.7.0; this
|
|
44
|
+
directory is the authoritative release record.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Migration: 2.5.x to 2.7.0
|
|
2
|
+
|
|
3
|
+
This guide covers upgrading `@v-office/website-sdk` from 2.5.0 or 2.5.1 to 2.7.0.
|
|
4
|
+
Version 2.6.0 was not published.
|
|
5
|
+
|
|
6
|
+
2.7.0 changes no config, service call, or output type. The runtime change is that
|
|
7
|
+
v9 `stripe_checkout` payment options can now be submitted. Sites without Stripe
|
|
8
|
+
need no migration work.
|
|
9
|
+
|
|
10
|
+
## Remove Stripe Workarounds
|
|
11
|
+
|
|
12
|
+
vOffice's `initStripePayment` action can return `sessionId` and `accountId` without
|
|
13
|
+
the Checkout Session URL. The SDK now keeps URL redirects as the preferred path and
|
|
14
|
+
uses Stripe.js when only session metadata is available.
|
|
15
|
+
|
|
16
|
+
Sites that hid Stripe options without a URL should render them:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
// Before
|
|
20
|
+
const payable = option.kind !== "stripe_checkout" || option.url !== undefined;
|
|
21
|
+
|
|
22
|
+
// 2.7.0
|
|
23
|
+
const payable = true;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Delete site-level Stripe.js bridges and publishable-key configuration added only to
|
|
27
|
+
work around the missing URL. The SDK selects the vOffice platform test or live key
|
|
28
|
+
from the session ID and passes connected-account context automatically.
|
|
29
|
+
|
|
30
|
+
## Content-Security-Policy
|
|
31
|
+
|
|
32
|
+
If the site sets a CSP, allow:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
script-src https://js.stripe.com
|
|
36
|
+
frame-src https://js.stripe.com https://hooks.stripe.com
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Without these directives, Stripe submission fails. Other payment kinds are
|
|
40
|
+
unaffected.
|
|
41
|
+
|
|
42
|
+
## Error Handling
|
|
43
|
+
|
|
44
|
+
Stripe.js loading or redirecting can fail. These failures surface as
|
|
45
|
+
`CoreSDKError` with `operation: "paymentSubmission"`. A failed script load is not
|
|
46
|
+
cached, so retrying can succeed.
|
|
47
|
+
|
|
48
|
+
The booking already exists when payment options are rendered. Present a submission
|
|
49
|
+
failure as a payment problem with the booking number, never as a failed booking:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
try {
|
|
53
|
+
await sdk.live.booking.submitPaymentOption(option);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
showPaymentFailure({ bookingNumber: booking.bookingNumber, error });
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Submission remains browser-only.
|
|
60
|
+
|
|
61
|
+
## Payment Return
|
|
62
|
+
|
|
63
|
+
The SDK derives Stripe success and cancel URLs from the `relativeRedirectUrl`
|
|
64
|
+
passed to `sdk.live.booking.book(...)`, appending
|
|
65
|
+
`payment=stripe&success=true` or `payment=stripe&cancel=true`. Persist anything the
|
|
66
|
+
return page needs before submitting the payment option because the redirect URL is
|
|
67
|
+
configured before the booking number exists.
|
|
68
|
+
|
|
69
|
+
A `success=true` return means the browser returned from Stripe, not that payment
|
|
70
|
+
settled. Stripe's webhook confirms payment to vOffice.
|
|
71
|
+
|
|
72
|
+
## Recommended Steps
|
|
73
|
+
|
|
74
|
+
1. Upgrade to `@v-office/website-sdk` 2.7.0.
|
|
75
|
+
2. Remove checks that hide Stripe options when `option.url` is missing.
|
|
76
|
+
3. Remove any site-owned Stripe.js bridge and publishable key used for this flow.
|
|
77
|
+
4. Add the Stripe CSP directives when applicable.
|
|
78
|
+
5. Present submission failures as post-booking payment failures.
|
|
79
|
+
6. Smoke-test test-mode and live-mode tenants, including success and cancel returns.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog: 2.8.0
|
|
2
|
+
|
|
3
|
+
This release replaces the loose custom-attribute manifest/configuration split with a
|
|
4
|
+
validated catalog-backed registry shared by rental display, highlights, filter
|
|
5
|
+
discovery, and search.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- `fetchCustomAttributeCatalog({ config })` reads public v10 custom-attribute
|
|
10
|
+
definition IDs, keys, types, and option identities at build time.
|
|
11
|
+
- `defineCustomAttributes(...)` joins that catalog with authored labels, exposure,
|
|
12
|
+
display, category, v9 bindings, and option labels.
|
|
13
|
+
- `defineCustomAttributesFromUnknown(...)`, `parseCustomAttributeCatalog`, and
|
|
14
|
+
`CustomAttributeCatalogSchema` support CLI/JSON and other untyped inputs.
|
|
15
|
+
- The website package exports the catalog, selection, registry, resolved-attribute,
|
|
16
|
+
category, and override types needed to author typed configuration.
|
|
17
|
+
- v10 reads public custom-attribute values for rentals and search output. v9 can
|
|
18
|
+
render the same registry through explicit `p_*` rental-data bindings and `v9Only`
|
|
19
|
+
entries.
|
|
20
|
+
- Applied value-bearing filters include a canonical `value`, allowing consumers to
|
|
21
|
+
remove one exact filter value without relying on a localized label.
|
|
22
|
+
|
|
23
|
+
## Changed
|
|
24
|
+
|
|
25
|
+
- `WebsiteSDKOptions.customAttributes` now receives the validated registry returned
|
|
26
|
+
by `defineCustomAttributes`.
|
|
27
|
+
- `customAttributeFilterDefinitions` now contains only `backendFilter` and
|
|
28
|
+
`composition` definitions. Catalog-backed custom attributes get their filter
|
|
29
|
+
policy from the registry selection.
|
|
30
|
+
- v10 custom-attribute filters are advertised only when filtering is enabled and a
|
|
31
|
+
backend definition ID exists. v9 does not advertise or execute catalog custom
|
|
32
|
+
attributes.
|
|
33
|
+
- Public/internal filter exposure and display are independent. Internal filters are
|
|
34
|
+
queryable and usable by compositions but absent from `getFilters`.
|
|
35
|
+
- Custom-attribute categories, backend-filter categories, and composition
|
|
36
|
+
categories are returned as localized display labels. Configuration continues to
|
|
37
|
+
store stable category keys.
|
|
38
|
+
- Composition discovery is backend-aware. Every configured leaf and value must be
|
|
39
|
+
executable on the active backend.
|
|
40
|
+
- Composition execution is atomic at the GraphQL/REST payload level. A failed
|
|
41
|
+
composition contributes no generated leaf and reports only its parent key unused.
|
|
42
|
+
- Nested compositions are rejected while recursive expansion remains unsupported.
|
|
43
|
+
- Query-key ownership is validated against period, occupancy, active-backend
|
|
44
|
+
built-ins, overlapping custom definitions, and repeated configured filter keys.
|
|
45
|
+
- Rental highlight prioritization remains an explicit ordered list. Custom
|
|
46
|
+
attributes render only when their resolved key is listed; registry contents do
|
|
47
|
+
not reorder built-in highlights.
|
|
48
|
+
|
|
49
|
+
## Removed
|
|
50
|
+
|
|
51
|
+
- `customAttributeDefinitionManifest`,
|
|
52
|
+
`CustomAttributeDefinitionManifest`,
|
|
53
|
+
`CustomAttributeDefinitionManifestEntry`, and related manifest helpers.
|
|
54
|
+
- `source: "customAttribute"` entries in `customAttributeFilterDefinitions`.
|
|
55
|
+
- Unsupported composition expression forms `any`, `gte`, and `lte`.
|
|
56
|
+
- `renderCustomAttributeHighlight`; use registry-backed rental/search output, or
|
|
57
|
+
`renderResolvedCustomAttribute` from `@v-office/sdk-core`.
|
|
58
|
+
|
|
59
|
+
## Migration Impact
|
|
60
|
+
|
|
61
|
+
This is a configuration and public-type migration for consumers using custom
|
|
62
|
+
attributes. Consumers that do not configure custom attributes keep the same SDK
|
|
63
|
+
construction and service calls. Follow `versions/2.8.0/MIGRATION.md`.
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Migration: 2.7.0 to 2.8.0
|
|
2
|
+
|
|
3
|
+
2.8.0 replaces `customAttributeDefinitionManifest` and
|
|
4
|
+
`source: "customAttribute"` filter definitions with one validated custom-attribute
|
|
5
|
+
registry. SDK construction and service method names are unchanged.
|
|
6
|
+
|
|
7
|
+
Consumers without custom attributes can upgrade without configuration changes.
|
|
8
|
+
|
|
9
|
+
## 1. Replace the Definition Manifest
|
|
10
|
+
|
|
11
|
+
Before:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const options = defineWebsiteSDKOptions({
|
|
15
|
+
customAttributeDefinitionManifest: {
|
|
16
|
+
byKey: {
|
|
17
|
+
region: {
|
|
18
|
+
id: "GQYKYgMVh28X7VLGursbkt",
|
|
19
|
+
key: "region",
|
|
20
|
+
type: "OPTION",
|
|
21
|
+
visibility: "PUBLIC",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
byId: {
|
|
25
|
+
GQYKYgMVh28X7VLGursbkt: {
|
|
26
|
+
id: "GQYKYgMVh28X7VLGursbkt",
|
|
27
|
+
key: "region",
|
|
28
|
+
type: "OPTION",
|
|
29
|
+
visibility: "PUBLIC",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
After:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import {
|
|
40
|
+
defineCustomAttributes,
|
|
41
|
+
defineWebsiteSDKOptions,
|
|
42
|
+
fetchCustomAttributeCatalog,
|
|
43
|
+
} from "@v-office/website-sdk";
|
|
44
|
+
|
|
45
|
+
const catalog = await fetchCustomAttributeCatalog({ config: v10Config });
|
|
46
|
+
|
|
47
|
+
const customAttributes = defineCustomAttributes({
|
|
48
|
+
catalog,
|
|
49
|
+
select: {
|
|
50
|
+
region: {
|
|
51
|
+
label: { "de-DE": "Region", "en-US": "Region" },
|
|
52
|
+
category: "OTHER",
|
|
53
|
+
filter: true,
|
|
54
|
+
optionLabels: {
|
|
55
|
+
north: { "de-DE": "Norden", "en-US": "North" },
|
|
56
|
+
south: { "de-DE": "Süden", "en-US": "South" },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const options = defineWebsiteSDKOptions({ customAttributes });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`fetchCustomAttributeCatalog` is v10-only, requires a token authorized for the
|
|
66
|
+
public-definition operation, and returns no localized labels. Fetch it in an
|
|
67
|
+
authorized build environment or pin an equivalent literal catalog.
|
|
68
|
+
`defineCustomAttributes` validates the complete catalog/selection join and reports
|
|
69
|
+
all configuration errors together.
|
|
70
|
+
|
|
71
|
+
## 2. Move Custom-Attribute Filter Policy
|
|
72
|
+
|
|
73
|
+
Remove every `source: "customAttribute"` entry from
|
|
74
|
+
`customAttributeFilterDefinitions`. Put its behavior in the matching `select`
|
|
75
|
+
entry:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
select: {
|
|
79
|
+
occupancyScore: {
|
|
80
|
+
label: { "de-DE": "Belegung", "en-US": "Occupancy" },
|
|
81
|
+
category: "ESSENTIALS",
|
|
82
|
+
filter: {
|
|
83
|
+
exposure: "public",
|
|
84
|
+
numericBounds: { min: 1, max: 12 },
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Use `filter: "internal"` or `filter: { exposure: "internal" }` for a queryable filter
|
|
91
|
+
that must not appear in `getFilters`. Omit `filter` for display only.
|
|
92
|
+
|
|
93
|
+
`customAttributeFilterDefinitions` remains the home of:
|
|
94
|
+
|
|
95
|
+
- `backendFilter`: v9 backend-native filters;
|
|
96
|
+
- `composition`: virtual Boolean filters composed from executable leaves.
|
|
97
|
+
|
|
98
|
+
## 3. Configure Display and v9 Bindings
|
|
99
|
+
|
|
100
|
+
Display is independent of filter exposure and defaults to `true`. A selected
|
|
101
|
+
catalog attribute can add a v9 rental-data binding:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
select: {
|
|
105
|
+
privateSauna: {
|
|
106
|
+
label: { "de-DE": "Sauna", "en-US": "Sauna" },
|
|
107
|
+
display: true,
|
|
108
|
+
filter: true,
|
|
109
|
+
v9: "p_14418",
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Use `v9Only` for attributes that have no v10 catalog definition:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
v9Only: {
|
|
118
|
+
thatchedRoof: {
|
|
119
|
+
v9: "p_14420",
|
|
120
|
+
type: "boolean",
|
|
121
|
+
label: { "de-DE": "Reetdach", "en-US": "Thatched roof" },
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
v9 renders bound values but does not advertise or execute catalog custom-attribute
|
|
127
|
+
filters. v10 filtering requires an enabled filter and a catalog ID.
|
|
128
|
+
|
|
129
|
+
## 4. Update Composition Expressions
|
|
130
|
+
|
|
131
|
+
Expressions now support equality leaves joined by `all`:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
expression: {
|
|
135
|
+
all: [
|
|
136
|
+
{ filter: "privateSauna", value: true },
|
|
137
|
+
{ filter: "maxPersons", value: 4 },
|
|
138
|
+
],
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Remove `operator`, `gte`, `lte`, and `any`; they never had correct runtime
|
|
143
|
+
semantics. Nested composition references are rejected.
|
|
144
|
+
|
|
145
|
+
A composition is advertised only if every leaf can execute on the active backend.
|
|
146
|
+
Execution is atomic: if one configured leaf is unknown, unsupported, malformed, or
|
|
147
|
+
conflicts with a direct value, no generated composition leaf enters the backend
|
|
148
|
+
payload and only the composition key is unused.
|
|
149
|
+
|
|
150
|
+
Successful compositions return the parent and expanded leaves in `appliedFilters`.
|
|
151
|
+
|
|
152
|
+
## 5. Rename Colliding Query Keys
|
|
153
|
+
|
|
154
|
+
Every query key must have one owner. Configuration rejects:
|
|
155
|
+
|
|
156
|
+
- period/occupancy keys such as `start`, `adults`, and `pets`;
|
|
157
|
+
- filterable custom attributes or compositions that reuse v10 built-in filter keys;
|
|
158
|
+
- configured v9 filters that reuse v9 stable filter keys;
|
|
159
|
+
- a custom attribute and custom filter definition with the same key.
|
|
160
|
+
- repeated keys within `customAttributeFilterDefinitions`.
|
|
161
|
+
|
|
162
|
+
Use the selection's `key` override when a workspace definition collides:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
select: {
|
|
166
|
+
sauna: {
|
|
167
|
+
key: "privateSauna",
|
|
168
|
+
label: { "de-DE": "Sauna", "en-US": "Sauna" },
|
|
169
|
+
filter: true,
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Update query URLs and `rentalHighlightPrioritization` to the resolved key.
|
|
175
|
+
|
|
176
|
+
## 6. Treat Categories as Display Labels
|
|
177
|
+
|
|
178
|
+
Configuration keeps stable keys such as `OUTDOORS`. `getFilters` and rental
|
|
179
|
+
attribute groups return localized labels such as `Außenbereich` or `Outdoor Area`.
|
|
180
|
+
Do not compare output categories to stable keys. Customize wording with
|
|
181
|
+
locale-nested overrides:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
translationOverrides: {
|
|
185
|
+
"de-DE": {
|
|
186
|
+
"RentalAttributesCategory.OUTDOORS.label": "Draußen",
|
|
187
|
+
},
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## 7. Update Highlight Configuration
|
|
192
|
+
|
|
193
|
+
Custom attributes appear in rental/search `highlights` only when their resolved key
|
|
194
|
+
is listed in `rentalHighlightPrioritization`:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
rentalHighlightPrioritization: ["bedrooms", customAttributes.keys.region, "bathrooms"];
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The list remains authoritative for order. Registry contents do not reorder
|
|
201
|
+
built-ins, duplicate keys render once, and a built-in metadata key shadows a
|
|
202
|
+
same-named display-only custom attribute.
|
|
203
|
+
|
|
204
|
+
## 8. Update Applied-Filter Handling
|
|
205
|
+
|
|
206
|
+
Value-bearing applied filters now include canonical `value`:
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
{ key: "region", label: "Region: North", value: "north" }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Use `key` plus `value` to remove an exact filter. Labels remain localized
|
|
213
|
+
presentation and are not identifiers. A scalar key may appear in both
|
|
214
|
+
`appliedFilters` and `unusedFilterKeys` when one value applied and another was
|
|
215
|
+
rejected.
|
|
216
|
+
|
|
217
|
+
## 9. CLI and Untyped Options
|
|
218
|
+
|
|
219
|
+
CLI JSON supplies catalog and selection **inputs**, not a finished registry:
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"customAttributes": {
|
|
224
|
+
"catalog": {
|
|
225
|
+
"privateSauna": {
|
|
226
|
+
"id": "GQYKYgMVh28X7VLGursbkt",
|
|
227
|
+
"type": "BOOLEAN"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
"select": {
|
|
231
|
+
"privateSauna": {
|
|
232
|
+
"label": { "de-DE": "Sauna", "en-US": "Sauna" },
|
|
233
|
+
"filter": true
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The CLI uses `defineCustomAttributesFromUnknown` and applies the same runtime
|
|
241
|
+
validation as typed configuration.
|
|
242
|
+
|
|
243
|
+
## Recommended Verification
|
|
244
|
+
|
|
245
|
+
1. Run `getFilters` for v9 and v10 in both locales.
|
|
246
|
+
2. Confirm internal filters are absent while public compositions using them remain
|
|
247
|
+
executable.
|
|
248
|
+
3. Inspect v9 GraphQL and v10 REST variables for one successful and one failed
|
|
249
|
+
composition.
|
|
250
|
+
4. Verify renamed custom attributes render in rentals, search highlights, URLs, and
|
|
251
|
+
applied-filter chips.
|
|
252
|
+
5. Verify `rentalHighlightPrioritization` order with and without custom attributes.
|