@v-office/website-sdk 2.17.0 → 2.18.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.
Files changed (38) hide show
  1. package/README.md +18 -0
  2. package/dist/cli.mjs +10 -11
  3. package/dist/{client-ScO68LGg.mjs → client-BnA0oXd_.mjs} +221 -24
  4. package/dist/index.d.mts +48 -2
  5. package/dist/index.mjs +2 -2
  6. package/dist/instructions/CHANGELOG.md +2 -0
  7. package/dist/instructions/MIGRATION.md +2 -0
  8. package/dist/instructions/README.md +10 -2
  9. package/dist/instructions/availability.md +12 -11
  10. package/dist/instructions/creation.md +46 -1
  11. package/dist/instructions/custom-attributes.md +7 -0
  12. package/dist/instructions/quote.md +8 -0
  13. package/dist/instructions/rentals.md +130 -2
  14. package/dist/instructions/versions/2.17.1/CHANGELOG.md +26 -0
  15. package/dist/instructions/versions/2.17.1/MIGRATION.md +35 -0
  16. package/dist/instructions/versions/2.18.0/CHANGELOG.md +133 -0
  17. package/dist/instructions/versions/2.18.0/MIGRATION.md +364 -0
  18. package/dist/{quote-C-Bs3XTE.mjs → quote-cjFdLn0m.mjs} +1 -0
  19. package/dist/{rentals-BokBV-ze.mjs → rentals-GfJVIv7i.mjs} +205 -12
  20. package/dist/{search-zsnAfUtc.mjs → search-CR1UjnmR.mjs} +3 -2
  21. package/dist/to-rental-highlights-CJvDxSLw.mjs +3035 -0
  22. package/dist/translations/v10/de-DE/core.json +1 -1
  23. package/dist/translations/v9/de-DE/core.json +7 -1
  24. package/dist/translations/v9/en-US/core.json +7 -1
  25. package/dist/{to-rental-highlights-BAsEuxoy.mjs → v9-data-BnYxa2Ek.mjs} +21 -2435
  26. package/instructions/CHANGELOG.md +2 -0
  27. package/instructions/MIGRATION.md +2 -0
  28. package/instructions/README.md +10 -2
  29. package/instructions/availability.md +12 -11
  30. package/instructions/creation.md +46 -1
  31. package/instructions/custom-attributes.md +7 -0
  32. package/instructions/quote.md +8 -0
  33. package/instructions/rentals.md +130 -2
  34. package/instructions/versions/2.17.1/CHANGELOG.md +26 -0
  35. package/instructions/versions/2.17.1/MIGRATION.md +35 -0
  36. package/instructions/versions/2.18.0/CHANGELOG.md +133 -0
  37. package/instructions/versions/2.18.0/MIGRATION.md +364 -0
  38. package/package.json +5 -4
@@ -0,0 +1,364 @@
1
+ # Migration: 2.17.1 to 2.18.0
2
+
3
+ 2.18.0 adds an opt-in legacy-v9 facility association for tenants whose
4
+ facilities reference vOffice object groups through a custom `p_*` data
5
+ attribute. It also exposes initial-availability calendar prices on available
6
+ dates that cannot be used as a start date, and combines repeated included
7
+ rent rows when a quoted stay crosses seasonal rates.
8
+
9
+ The default facility association and the public static rental result remain
10
+ unchanged when the new config field is omitted. Public availability and quote
11
+ types are unchanged.
12
+
13
+ ## 1. Upgrade
14
+
15
+ ```sh
16
+ pnpm add @v-office/website-sdk@2.18.0
17
+ ```
18
+
19
+ ## 2. Keep the Default Relation When Available
20
+
21
+ No configuration change is required when vOffice units already carry their
22
+ native facility relation:
23
+
24
+ ```ts
25
+ const sdk = createWebsiteSDK({
26
+ config: {
27
+ backend: "v9",
28
+ graphqlUrl: "https://example.com/graphql",
29
+ apiKey: "...",
30
+ imageProxyBaseUrl: "https://images.example.com",
31
+ },
32
+ });
33
+ ```
34
+
35
+ This continues to load the nested `voffice_facility` for each unit. It does not
36
+ request top-level facilities or object-group memberships.
37
+
38
+ ## 3. Enable Object-Group Association When Required
39
+
40
+ Set the numeric suffix of the facility custom attribute that contains the
41
+ related object-group ID or IDs:
42
+
43
+ ```ts
44
+ const sdk = createWebsiteSDK({
45
+ config: {
46
+ backend: "v9",
47
+ graphqlUrl: "https://example.com/graphql",
48
+ apiKey: "...",
49
+ imageProxyBaseUrl: "https://images.example.com",
50
+ facilityObjectGroupRelationAttributeId: 18962,
51
+ },
52
+ });
53
+ ```
54
+
55
+ The SDK converts `18962` to the GraphQL facility data attribute `p_18962`.
56
+ Do not pass `"p_18962"` or another string; the config value is a positive
57
+ integer.
58
+
59
+ When enabled, `getRentals`:
60
+
61
+ 1. Loads all units with `voffice_groups { voffice_group_id }`.
62
+ 2. Loads all facilities and requests `p_18962` alongside the normal facility
63
+ attributes.
64
+ 3. Associates each unit with the facility whose configured object-group IDs
65
+ contain one of the unit's group memberships.
66
+ 4. Exposes the resolved facility through the existing `rental.property`.
67
+ 5. Applies static rental scope and then loads feedbacks for retained rentals.
68
+
69
+ ### Expanded v9 property fields
70
+
71
+ Both native and object-group v9 facility relations now populate more of the
72
+ existing `rental.property` shape when the Hub provides the source data:
73
+
74
+ - `propertyType` from `type`
75
+ - `location` from the GeoJSON `loc`
76
+ - `address` from `address`, with `regionName` used as `province`
77
+ - all existing description components from their corresponding localized
78
+ facility fields
79
+ - `attributes` for `allergic`, `childrenWelcome`, `pets`, and `youthgroups`
80
+
81
+ `HOUSE_FAC` becomes `HOLIDAY_HOME_COMPLEX` and `FLAT_FAC` becomes
82
+ `APARTMENT_COMPLEX`. `HOTEL`, `HOSTEL`, `FARM`, and `CAMPGROUND` already match
83
+ the shared values. The normalized value is localized through
84
+ `Property.propertyType.option.*` before it is returned. Unknown facility types
85
+ are omitted.
86
+
87
+ This uses the existing core `RentalPropertySchema`; no public property field or
88
+ type was added. Missing, empty, zero-valued, or malformed optional source data
89
+ remains omitted. The release does not synthesize property `vicinity` from
90
+ unrelated facility fields.
91
+
92
+ To select and order v9 property highlights, use the existing website option:
93
+
94
+ ```ts
95
+ const sdk = createWebsiteSDK({
96
+ config,
97
+ options: {
98
+ rentalPropertyHighlightPrioritization: ["childrenWelcome", "pets", "youthgroups"],
99
+ },
100
+ });
101
+ ```
102
+
103
+ The v9 renderer supports the typed facility attributes `allergic`,
104
+ `childrenWelcome`, `pets`, and `youthgroups`. It preserves the configured order,
105
+ deduplicates keys, and ignores unsupported, missing, or non-renderable values.
106
+ Rental custom attributes are not considered for property highlights.
107
+
108
+ ## 4. Add Tenant-Specific Facility Highlight Text
109
+
110
+ Use a v9 property-highlight source when a facility custom field contains
111
+ editor-authored highlight lines, such as `p_18963` ("Anlagen Highlights"):
112
+
113
+ ```ts
114
+ import {
115
+ createWebsiteSDK,
116
+ defineV9PropertyHighlightSources,
117
+ defineWebsiteSDKOptions,
118
+ } from "@v-office/website-sdk";
119
+
120
+ const v9PropertyHighlightSources = defineV9PropertyHighlightSources({
121
+ facilityHighlights: {
122
+ v9: "p_18963",
123
+ type: "line-list",
124
+ },
125
+ });
126
+
127
+ const sdk = createWebsiteSDK({
128
+ config,
129
+ options: defineWebsiteSDKOptions({
130
+ v9PropertyHighlightSources,
131
+ rentalPropertyHighlightPrioritization: [
132
+ "childrenWelcome",
133
+ v9PropertyHighlightSources.keys.facilityHighlights,
134
+ "pets",
135
+ ],
136
+ }),
137
+ });
138
+ ```
139
+
140
+ The registry gives the tenant-specific field a stable public selection key.
141
+ Defining a source alone does not request or emit it; add the generated key to
142
+ `rentalPropertyHighlightPrioritization`. The selected `p_*` field is requested
143
+ for both native and object-group facility relations.
144
+
145
+ Source keys must not reuse the built-in v9 facility keys `allergic`,
146
+ `childrenWelcome`, `pets`, or `youthgroups`; registry creation rejects those
147
+ collisions.
148
+
149
+ `line-list` resolves the localized field value, splits it at Unix or Windows
150
+ newlines, trims each line, drops empty lines, and deduplicates exact visible
151
+ values while preserving order. Each remaining line becomes one
152
+ `property.highlights` item at the source key's position. Missing and `null`
153
+ values emit nothing. Semicolons remain text; use one highlight per line in
154
+ vOffice.
155
+
156
+ For CLI JSON, provide the authored source definitions directly:
157
+
158
+ ```json
159
+ {
160
+ "v9PropertyHighlightSources": {
161
+ "facilityHighlights": {
162
+ "v9": "p_18963",
163
+ "type": "line-list"
164
+ }
165
+ },
166
+ "rentalPropertyHighlightPrioritization": ["childrenWelcome", "facilityHighlights", "pets"]
167
+ }
168
+ ```
169
+
170
+ The CLI builds and validates the registry. TypeScript consumers should use
171
+ `defineV9PropertyHighlightSources` so `keys.facilityHighlights` is inferred and
172
+ checked.
173
+
174
+ ## 5. Prepare the GraphQL Hub
175
+
176
+ Before enabling the config, verify that the same API key can query:
177
+
178
+ ```graphql
179
+ query FacilityObjectGroupRelations {
180
+ facilities: voffice_facilities(language: "de") {
181
+ id
182
+ name
183
+ data(attributes: ["p_18962", "p_18963"])
184
+ }
185
+
186
+ all(language: "de") {
187
+ voffice_id
188
+ voffice_groups {
189
+ voffice_group_id
190
+ }
191
+ }
192
+ }
193
+ ```
194
+
195
+ The Hub must return:
196
+
197
+ - the required facilities from `voffice_facilities`
198
+ - a usable relation value in the configured `p_*` attribute
199
+ - any selected facility highlight `p_*` values
200
+ - matching `voffice_group_id` values on the intended units
201
+
202
+ Do not enable the mode while those resources are only available through v0 or
203
+ v1 and have not yet synchronized to GraphQL.
204
+
205
+ ## 6. Account for Relation Validation
206
+
207
+ The relation attribute can contain positive numeric IDs as numbers, numeric
208
+ strings, localized string records, arrays, or strings separated by whitespace,
209
+ commas, or semicolons.
210
+
211
+ The static request fails rather than selecting an arbitrary property when:
212
+
213
+ - no facility has a usable configured relation value
214
+ - a non-empty relation value cannot be interpreted as positive integer IDs
215
+ - two facilities claim the same object-group ID
216
+ - one unit matches object groups belonging to different facilities
217
+
218
+ One facility may reference several groups. One unit may match several groups
219
+ when all of them resolve to the same facility.
220
+
221
+ Facilities whose relation is empty contribute no association. Rentals with no
222
+ matching relation remain in the result and omit `property`. Compatibility mode
223
+ does not fall back to the native facility relation.
224
+
225
+ ## 7. Account for Batched Catalogue Requests
226
+
227
+ Legacy-v9 static rentals now load a small ordered rental-ID list first. Complete
228
+ rental details and feedbacks are then requested sequentially in batches of 128
229
+ IDs. Object-group mode loads the facility list once.
230
+
231
+ The public result and rental order are unchanged. HTTP mocks, request counters,
232
+ and GraphQL tracing that expected one detail query and one feedback query must
233
+ allow multiple requests for catalogues larger than 128 rentals.
234
+
235
+ Do not combine the detail batches into GraphQL aliases in one HTTP request. The
236
+ separate requests are intentional because they bound the amount of data the
237
+ Laravel/PHP Hub must construct and serialize at once.
238
+
239
+ ## 8. Keep Other APIs Unchanged
240
+
241
+ The facility-association config only changes legacy-v9 static `getRentals`.
242
+ It does not change:
243
+
244
+ - v9 live search or its `falicityid` rental-scope filter
245
+ - quote inputs, booking, or contact requests
246
+ - start-date-selected availability
247
+ - shared core rental types
248
+
249
+ If an application uses both static rental scope and live search, verify both
250
+ flows separately because object-group association is intentionally limited to
251
+ the static catalogue.
252
+
253
+ ## 9. Render Prices on Available Non-Start Dates
254
+
255
+ `getInitialAvailability` can now return a non-null `formattedPrice` on
256
+ available dates whose status is `check_in_not_allowed` or
257
+ `no_valid_check_out_from_start`:
258
+
259
+ ```ts
260
+ const availability = await sdk.live.availability.getInitialAvailability(input);
261
+
262
+ for (const [date, day] of Object.entries(availability.calendarDays)) {
263
+ renderCalendarDay({
264
+ date,
265
+ status: day.status,
266
+ price: day.formattedPrice,
267
+ });
268
+ }
269
+ ```
270
+
271
+ `formattedPrice` is already localized for the input locale. Render it
272
+ directly when non-null. Do not treat a missing price as the only signal that
273
+ a date is unavailable; use `isAvailableDate` and `status`.
274
+
275
+ The field remains `null` when:
276
+
277
+ - the calendar marks the day unavailable
278
+ - the source supplies no numeric price
279
+
280
+ Start-date-selected availability still has no calendar prices. The v10 change
281
+ is delivered by `@v-office/sdk-core`. Refresh the lockfile when upgrading the
282
+ website SDK so it resolves the coordinated core version shipped for 2.18.0.
283
+
284
+ ## 10. Render Combined Seasonal Rent Lines
285
+
286
+ Included booking-card subitems that share the same localized `position` and
287
+ `appliedCharge` are now one row on both v9 and v10. A stay that crosses
288
+ seasonal rental prices therefore shows a single rent line such as `Miete` /
289
+ `Inklusive` instead of repeating that row once per rate period.
290
+
291
+ Cleaning, linen, booking fees, and other distinct included labels remain
292
+ separate. The inclusive total still sums every backend rent period; only the
293
+ repeated display rows are combined. Quote inputs and the booking-card schema
294
+ are unchanged.
295
+
296
+ Render `subItems` as returned. Do not reconstruct a seasonal breakdown from
297
+ duplicate rent labels; those duplicates are no longer emitted. The v10 change
298
+ is delivered by `@v-office/sdk-core`. Refresh the lockfile when upgrading the
299
+ website SDK so it resolves the coordinated core version shipped for 2.18.0.
300
+
301
+ ## Required Consumer Work
302
+
303
+ Consumers using the default native facility relation and selected availability
304
+ fields only need to upgrade.
305
+
306
+ Consumers enabling object-group association should:
307
+
308
+ 1. Confirm GraphQL synchronization for facilities, relation values, and groups.
309
+ 2. Add `facilityObjectGroupRelationAttributeId` to the v9 config.
310
+ 3. Confirm expected rentals contain `property`.
311
+ 4. Keep unmatched rentals without `property` valid.
312
+ 5. Update complete-output snapshots that gain associated properties.
313
+ 6. Update v9 property snapshots that gain `propertyType`, `location`, `address`,
314
+ description components, or built-in attributes.
315
+
316
+ Consumers enabling custom v9 property highlight text should:
317
+
318
+ 1. Confirm the facility `p_*` field has synchronized to GraphQL.
319
+ 2. Define it with `defineV9PropertyHighlightSources`.
320
+ 3. Select its stable key in `rentalPropertyHighlightPrioritization`.
321
+ 4. Keep missing or `null` source values valid.
322
+ 5. Update complete rental snapshots that gain property highlight lines.
323
+
324
+ Consumers that snapshot or hide calendar prices should:
325
+
326
+ 1. Render `formattedPrice` directly when non-null, including on available
327
+ dates that cannot be used as a start date.
328
+ 2. Keep `formattedPrice: null` valid for unavailable and price-less dates.
329
+ 3. Refresh the lockfile so v10 resolves the coordinated core release.
330
+ 4. Update complete initial-availability snapshots that expected `null` on
331
+ `check_in_not_allowed` or `no_valid_check_out_from_start`.
332
+
333
+ Consumers that snapshot or expand included quote rows should:
334
+
335
+ 1. Keep rendering each included `subItem` as one row.
336
+ 2. Update complete quote snapshots that expected one rent row per seasonal
337
+ rate period.
338
+ 3. Refresh the lockfile so v10 resolves the coordinated core release.
339
+
340
+ ## Recommended Verification
341
+
342
+ 1. Run `getRentals` without the config and confirm native facility associations
343
+ remain unchanged.
344
+ 2. Run it with the configured attribute ID and count rentals by `property.id`.
345
+ 3. Verify a facility that references several groups receives every intended
346
+ rental once.
347
+ 4. Verify unmatched rentals remain present without `property`.
348
+ 5. Verify the configured `rentalScope.propertyId`, when used, returns only the
349
+ resolved facility's rentals.
350
+ 6. Verify populated facility location, address, type, descriptions, and
351
+ attributes are represented in `rental.property`.
352
+ 7. Test at least one catalogue larger than 128 rentals so detail and feedback
353
+ batching are exercised.
354
+ 8. Select a configured line-list source between two built-in property keys and
355
+ confirm its non-empty lines appear at that exact position without duplicates.
356
+ 9. Confirm an unselected source is not requested or emitted.
357
+ 10. Load initial availability for a stay-through or closed-on-arrival date that
358
+ has a source price and confirm `formattedPrice` is non-null.
359
+ 11. Confirm unavailable and price-less dates retain `formattedPrice: null`.
360
+ 12. Confirm start-date-selected availability still has no calendar prices.
361
+ 13. Quote a stay that crosses a seasonal rental-price change and confirm the
362
+ included section shows one rent row.
363
+ 14. Confirm other included labels still appear as separate rows and that the
364
+ inclusive total is unchanged.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v-office/website-sdk",
3
- "version": "2.17.0",
3
+ "version": "2.18.0",
4
4
  "description": "Website-facing SDK facade backed by @v-office/sdk-core",
5
5
  "bin": {
6
6
  "website-sdk": "./dist/cli.mjs"
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@graphql-typed-document-node/core": "3.2.0",
45
- "@v-office/sdk-core": "^1.18.0",
45
+ "@v-office/sdk-core": "^1.19.0",
46
46
  "effect": "4.0.0-beta.85",
47
47
  "graphql": "17.0.2",
48
48
  "yaml": "^2.9.0"
@@ -77,8 +77,9 @@
77
77
  "fmt": "oxfmt",
78
78
  "fmt:check": "oxfmt --check",
79
79
  "check": "pnpm run typecheck && pnpm run lint && pnpm run fmt:check",
80
- "test": "pnpm run test:v9:properties && pnpm run test:v9:availability && pnpm run build && node --test test/*.test.mjs",
81
- "test:v9:properties": "node --test codegen/v9/heuristic-generation/generate/property.test.ts src/legacy-v9/parser/rentals/render-property-attribute.test.ts src/legacy-v9/parser/rentals/to-rooms.test.ts",
80
+ "test": "pnpm run test:v9:properties && pnpm run test:v9:rentals && pnpm run test:v9:availability && pnpm run build && node --test test/*.test.mjs",
81
+ "test:v9:properties": "node --test codegen/v9/heuristic-generation/generate/property.test.ts src/legacy-v9/property-highlight-sources.test.ts src/legacy-v9/parser/rentals/render-property-attribute.test.ts src/legacy-v9/parser/rentals/to-property.test.ts src/legacy-v9/parser/rentals/to-rooms.test.ts",
82
+ "test:v9:rentals": "node --test src/legacy-v9/static/associate-rentals-with-facilities-by-object-groups.test.ts",
82
83
  "test:v9:availability": "node --test src/legacy-v9/parser/availability/to-initial-availability-calendar-days.test.ts",
83
84
  "playground:custom-attributes": "pnpm run build && node --env-file=.env playground/custom-attributes.ts"
84
85
  }