@v-office/website-sdk 1.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.
Files changed (39) hide show
  1. package/README.md +263 -0
  2. package/dist/cli.d.mts +1 -0
  3. package/dist/cli.mjs +337 -0
  4. package/dist/client-BbAfk-qa.mjs +33672 -0
  5. package/dist/custom-attribute-ChCbJKf_.mjs +54 -0
  6. package/dist/errors-2cuUGSvi.mjs +5 -0
  7. package/dist/index.d.mts +16130 -0
  8. package/dist/index.mjs +3 -0
  9. package/dist/operations-BanW36PK.mjs +12616 -0
  10. package/dist/operations-CHxEQ3jG.mjs +904 -0
  11. package/dist/parser-D6UAf8Ld.mjs +65 -0
  12. package/dist/quote-C3HZsFua.mjs +313 -0
  13. package/dist/quote-Vl6Nutaa.mjs +513 -0
  14. package/dist/rentals-BFmmp26v.mjs +323 -0
  15. package/dist/rentals-cQAg5TTW.mjs +403 -0
  16. package/dist/search-JqA3v_Fx.mjs +342 -0
  17. package/dist/search-filter-metadata-DZP0-Udc.mjs +4294 -0
  18. package/dist/to-rental-highlights-BcRa9Odv.mjs +402 -0
  19. package/dist/translations/shared/de-DE/availability.json +15 -0
  20. package/dist/translations/shared/de-DE/booking.json +15 -0
  21. package/dist/translations/shared/de-DE/insurance.json +18 -0
  22. package/dist/translations/shared/de-DE/quote.json +8 -0
  23. package/dist/translations/shared/de-DE/reviews.json +11 -0
  24. package/dist/translations/shared/en-US/availability.json +15 -0
  25. package/dist/translations/shared/en-US/booking.json +15 -0
  26. package/dist/translations/shared/en-US/insurance.json +18 -0
  27. package/dist/translations/shared/en-US/quote.json +8 -0
  28. package/dist/translations/shared/en-US/reviews.json +11 -0
  29. package/dist/translations/v10/de-DE/core.json +7027 -0
  30. package/dist/translations/v10/en-US/core.json +7027 -0
  31. package/dist/translations/v9/de-DE/core.json +4 -0
  32. package/dist/translations/v9/de-DE/filter.json +25 -0
  33. package/dist/translations/v9/de-DE/rental-attribute-categories.json +19 -0
  34. package/dist/translations/v9/de-DE/rental-attributes.json +451 -0
  35. package/dist/translations/v9/en-US/core.json +4 -0
  36. package/dist/translations/v9/en-US/filter.json +25 -0
  37. package/dist/translations/v9/en-US/rental-attribute-categories.json +19 -0
  38. package/dist/translations/v9/en-US/rental-attributes.json +451 -0
  39. package/package.json +90 -0
@@ -0,0 +1,342 @@
1
+ import { A as toUnusedFilterKeys, C as parseChildrenAges, D as parseQueryParameters, E as collectQueryParameters, L as parseVofficeUnitData, O as expandCustomAttributeFilterCompositions, T as toQueryString, an as toStableSearchInputParameterValues, in as toStableSearchInputBackendQueryKeys, j as stable_filters_default, k as toCustomAttributeFilterLabel, nn as STABLE_SEARCH_INPUTS, on as toStableSearchInputQueryKeys, w as parseOccupancyCount } from "./client-BbAfk-qa.mjs";
2
+ import { t as CMSError } from "./errors-2cuUGSvi.mjs";
3
+ import { d as daysBetweenLocalDates, l as toIsoDateFromPeriodQueryDate } from "./parser-D6UAf8Ld.mjs";
4
+ import { n as toAddress, t as toRentalHighlights } from "./to-rental-highlights-BcRa9Odv.mjs";
5
+ import { Effect } from "effect";
6
+ //#region src/adapters/v9/parser/search/input/filter/apply-voffice-filter-derived-basic-query-inputs.ts
7
+ const hasBasicQueryInput = ({ basicQueryInputs, key }) => basicQueryInputs.some((input) => input.key === key);
8
+ const derivedBooleanFilters = [{
9
+ key: "pets",
10
+ isSelected: (filter) => (filter.petsCount ?? 0) > 0
11
+ }];
12
+ const applyVofficeFilterDerivedBasicQueryInputs = ({ appliedFilters, basicQueryInputs, filter, locale, translations }) => Effect.gen(function* () {
13
+ const nextAppliedFilters = [...appliedFilters];
14
+ const nextBasicQueryInputs = [...basicQueryInputs];
15
+ for (const derivedFilter of derivedBooleanFilters) {
16
+ if (!derivedFilter.isSelected(filter) || hasBasicQueryInput({
17
+ basicQueryInputs: nextBasicQueryInputs,
18
+ key: derivedFilter.key
19
+ })) continue;
20
+ nextBasicQueryInputs.push({
21
+ key: derivedFilter.key,
22
+ value: true
23
+ });
24
+ nextAppliedFilters.push({
25
+ key: derivedFilter.key,
26
+ label: yield* translations.translate(locale, `filter.${derivedFilter.key}.label`, derivedFilter.key)
27
+ });
28
+ }
29
+ return {
30
+ appliedFilters: nextAppliedFilters,
31
+ basicQueryInputs: nextBasicQueryInputs
32
+ };
33
+ });
34
+ //#endregion
35
+ //#region src/adapters/v9/parser/search/input/filter/filter-query-keys.ts
36
+ const FILTER_QUERY_KEYS = new Set(Object.keys(stable_filters_default));
37
+ //#endregion
38
+ //#region src/adapters/v9/parser/search/input/filter/to-basic-query-inputs.ts
39
+ const isEnabledBooleanFilter = (value) => {
40
+ const normalizedValue = value.toLowerCase();
41
+ return normalizedValue === "" || normalizedValue === "true" || normalizedValue === "1";
42
+ };
43
+ const toBasicQueryInput = ({ queryKey, value, filter }) => {
44
+ if (filter.type === "BooleanFilter") return isEnabledBooleanFilter(value) ? {
45
+ key: queryKey,
46
+ value: true
47
+ } : void 0;
48
+ if (filter.type === "InputFilter") {
49
+ const numberValue = Number(value);
50
+ if (!Number.isInteger(numberValue) || numberValue < 0) return;
51
+ return {
52
+ key: queryKey,
53
+ value: numberValue
54
+ };
55
+ }
56
+ };
57
+ const toCustomBackendFilterInput = ({ queryKey, value, filter }) => {
58
+ switch (filter.type) {
59
+ case "boolean": return isEnabledBooleanFilter(value) ? {
60
+ key: queryKey,
61
+ value: true
62
+ } : void 0;
63
+ case "int": {
64
+ const numberValue = Number(value);
65
+ return Number.isInteger(numberValue) && numberValue >= 0 ? {
66
+ key: queryKey,
67
+ value: numberValue
68
+ } : void 0;
69
+ }
70
+ case "option": return filter.options.some((option) => option.value === value) ? {
71
+ key: queryKey,
72
+ value
73
+ } : void 0;
74
+ }
75
+ };
76
+ const toBasicQueryInputs = ({ query, customAttributeFilterDefinitions, locale, translations }) => {
77
+ const appliedFilterEffects = [];
78
+ const basicQueryInputs = [];
79
+ const remainingParameters = [];
80
+ const seenScalarFilters = /* @__PURE__ */ new Set();
81
+ const customBackendFiltersByKey = new Map(customAttributeFilterDefinitions.filter((definition) => definition.source === "backendFilter" && definition.searchable).map((definition) => [definition.key, definition]));
82
+ for (const [queryKey, value] of parseQueryParameters(query)) {
83
+ const filter = stable_filters_default[queryKey];
84
+ const customBackendFilter = customBackendFiltersByKey.get(queryKey);
85
+ if ((!FILTER_QUERY_KEYS.has(queryKey) || filter == null) && customBackendFilter == null) {
86
+ remainingParameters.push([queryKey, value]);
87
+ continue;
88
+ }
89
+ if (seenScalarFilters.has(queryKey)) {
90
+ remainingParameters.push([queryKey, value]);
91
+ continue;
92
+ }
93
+ const basicQueryInput = filter == null ? customBackendFilter != null ? toCustomBackendFilterInput({
94
+ queryKey,
95
+ value,
96
+ filter: customBackendFilter
97
+ }) : void 0 : toBasicQueryInput({
98
+ queryKey,
99
+ value,
100
+ filter
101
+ });
102
+ if (basicQueryInput == null) {
103
+ remainingParameters.push([queryKey, value]);
104
+ continue;
105
+ }
106
+ seenScalarFilters.add(queryKey);
107
+ basicQueryInputs.push(basicQueryInput);
108
+ if (customBackendFilter != null) appliedFilterEffects.push(Effect.succeed({
109
+ key: queryKey,
110
+ label: toCustomAttributeFilterLabel({
111
+ definition: customBackendFilter,
112
+ locale,
113
+ value
114
+ })
115
+ }));
116
+ else appliedFilterEffects.push(translations.translate(locale, `filter.${queryKey}.label`, queryKey).pipe(Effect.map((label) => ({
117
+ key: queryKey,
118
+ label
119
+ }))));
120
+ }
121
+ return {
122
+ appliedFilters: Effect.all(appliedFilterEffects),
123
+ basicQueryInputs,
124
+ remainingQuery: toQueryString(remainingParameters)
125
+ };
126
+ };
127
+ //#endregion
128
+ //#region src/adapters/v9/parser/search/input/occupancy/occupancy-query-keys.ts
129
+ const OCCUPANCY_QUERY_KEYS = toStableSearchInputQueryKeys(STABLE_SEARCH_INPUTS.occupancy);
130
+ //#endregion
131
+ //#region src/adapters/v9/parser/search/input/occupancy/collect-occupancy-query-parameters.ts
132
+ const hasOccupancyInput = (query) => parseQueryParameters(query).some(([key]) => OCCUPANCY_QUERY_KEYS.has(key));
133
+ const collectOccupancyQueryParameters = ({ query }) => {
134
+ const { matchingParameters, remainingParameters } = collectQueryParameters({
135
+ query,
136
+ queryKeys: OCCUPANCY_QUERY_KEYS
137
+ });
138
+ return {
139
+ occupancyParameters: matchingParameters,
140
+ remainingParameters
141
+ };
142
+ };
143
+ //#endregion
144
+ //#region src/adapters/v9/parser/search/input/occupancy/to-occupancy-input.ts
145
+ const parseStableOccupancyCount = ({ key, occupancyParameters }) => Effect.gen(function* () {
146
+ const values = toStableSearchInputParameterValues({
147
+ key,
148
+ group: STABLE_SEARCH_INPUTS.occupancy,
149
+ parameters: occupancyParameters
150
+ });
151
+ if (values.length === 0) return;
152
+ return yield* parseOccupancyCount({
153
+ key,
154
+ values
155
+ });
156
+ });
157
+ const toOccupancyInput = ({ query }) => Effect.gen(function* () {
158
+ const { occupancyParameters, remainingParameters } = collectOccupancyQueryParameters({ query });
159
+ const childrenAges = yield* parseChildrenAges({ values: occupancyParameters.get("childrenAges") ?? [] });
160
+ const children = yield* parseOccupancyCount({
161
+ key: "children",
162
+ values: occupancyParameters.get("children") ?? []
163
+ });
164
+ return {
165
+ occupancyFilter: {
166
+ adults: (yield* parseOccupancyCount({
167
+ key: "adults",
168
+ values: occupancyParameters.get("adults") ?? []
169
+ })) ?? 0,
170
+ children: children ?? childrenAges?.length ?? 0,
171
+ babys: (yield* parseOccupancyCount({
172
+ key: "babies",
173
+ values: occupancyParameters.get("babies") ?? []
174
+ })) ?? 0,
175
+ petsCount: (yield* parseStableOccupancyCount({
176
+ key: "petsCount",
177
+ occupancyParameters
178
+ })) ?? 0
179
+ },
180
+ remainingQuery: toQueryString(remainingParameters)
181
+ };
182
+ });
183
+ //#endregion
184
+ //#region src/adapters/v9/parser/search/input/search-input-error.ts
185
+ const failInvalidV9SearchInput = (message) => Effect.fail(new CMSError({
186
+ backend: "v9",
187
+ operation: "search",
188
+ message
189
+ }));
190
+ //#endregion
191
+ //#region src/adapters/v9/parser/search/input/period/period-query-keys.ts
192
+ const PERIOD_QUERY_KEYS = toStableSearchInputBackendQueryKeys({
193
+ backend: "v9",
194
+ group: STABLE_SEARCH_INPUTS.period
195
+ });
196
+ //#endregion
197
+ //#region src/adapters/v9/parser/search/input/period/collect-period-query-parameters.ts
198
+ const hasPeriodInput = (query) => parseQueryParameters(query).some(([key]) => PERIOD_QUERY_KEYS.has(key));
199
+ const collectPeriodQueryParameters = ({ query }) => {
200
+ const { matchingParameters, remainingParameters } = collectQueryParameters({
201
+ query,
202
+ queryKeys: PERIOD_QUERY_KEYS
203
+ });
204
+ return {
205
+ periodParameters: matchingParameters,
206
+ remainingParameters
207
+ };
208
+ };
209
+ //#endregion
210
+ //#region src/adapters/v9/parser/search/input/period/to-period-input.ts
211
+ const parseScalarParameter = ({ key, values }) => {
212
+ if (values.length > 1) return failInvalidV9SearchInput(`Expected at most one "${key}" query parameter.`);
213
+ return Effect.succeed(values[0]);
214
+ };
215
+ const parsePositiveInt = ({ key, values }) => Effect.gen(function* () {
216
+ const value = yield* parseScalarParameter({
217
+ key,
218
+ values
219
+ });
220
+ if (value === void 0) return;
221
+ const numberValue = Number(value);
222
+ if (!Number.isInteger(numberValue) || numberValue <= 0) return yield* failInvalidV9SearchInput(`Expected "${key}" to be a positive integer.`);
223
+ return numberValue;
224
+ });
225
+ const toPeriodInput = ({ query }) => Effect.gen(function* () {
226
+ const { periodParameters, remainingParameters } = collectPeriodQueryParameters({ query });
227
+ const from = yield* parseScalarParameter({
228
+ key: "start",
229
+ values: toStableSearchInputParameterValues({
230
+ key: "start",
231
+ group: STABLE_SEARCH_INPUTS.period,
232
+ parameters: periodParameters
233
+ })
234
+ });
235
+ const till = yield* parseScalarParameter({
236
+ key: "end",
237
+ values: toStableSearchInputParameterValues({
238
+ key: "end",
239
+ group: STABLE_SEARCH_INPUTS.period,
240
+ parameters: periodParameters
241
+ })
242
+ });
243
+ const nightsMin = yield* parsePositiveInt({
244
+ key: "minNights",
245
+ values: toStableSearchInputParameterValues({
246
+ key: "minNights",
247
+ group: STABLE_SEARCH_INPUTS.period,
248
+ parameters: periodParameters
249
+ })
250
+ });
251
+ const nightsMax = yield* parsePositiveInt({
252
+ key: "maxNights",
253
+ values: toStableSearchInputParameterValues({
254
+ key: "maxNights",
255
+ group: STABLE_SEARCH_INPUTS.period,
256
+ parameters: periodParameters
257
+ })
258
+ });
259
+ if (from === void 0 || till === void 0) return yield* failInvalidV9SearchInput("Expected both \"from\" and \"till\" query parameters.");
260
+ const isoFrom = toIsoDateFromPeriodQueryDate(from);
261
+ const isoTill = toIsoDateFromPeriodQueryDate(till);
262
+ if (isoFrom === void 0 || isoTill === void 0) return yield* failInvalidV9SearchInput("Expected \"start\" and \"end\" to use DD-MM-YYYY or YYYY-MM-DD dates.");
263
+ const periodNights = daysBetweenLocalDates({
264
+ start: isoFrom,
265
+ end: isoTill
266
+ });
267
+ if (periodNights <= 0) return yield* failInvalidV9SearchInput("Expected \"end\" to be after \"start\".");
268
+ if (nightsMin === void 0 && nightsMax !== void 0 || nightsMin !== void 0 && nightsMax === void 0) return yield* failInvalidV9SearchInput("Expected both \"nights_min\" and \"nights_max\" query parameters, or neither.");
269
+ const nextNightsMin = nightsMin ?? periodNights;
270
+ const nextNightsMax = nightsMax ?? periodNights;
271
+ if (nextNightsMin > nextNightsMax) return yield* failInvalidV9SearchInput("Expected \"nights_min\" to be less than or equal to \"nights_max\".");
272
+ return {
273
+ periodFilter: {
274
+ from: isoFrom,
275
+ till: isoTill,
276
+ nights_min: nextNightsMin,
277
+ nights_max: nextNightsMax
278
+ },
279
+ remainingQuery: toQueryString(remainingParameters)
280
+ };
281
+ });
282
+ //#endregion
283
+ //#region src/adapters/v9/parser/search/input/to-query-input.ts
284
+ const toQueryInput = ({ query, customAttributeFilterDefinitions, locale, translations }) => Effect.gen(function* () {
285
+ const compositionResult = expandCustomAttributeFilterCompositions({
286
+ customAttributeFilterDefinitions,
287
+ locale,
288
+ query
289
+ });
290
+ const expandedQuery = compositionResult.query;
291
+ const periodResult = hasPeriodInput(expandedQuery) ? yield* toPeriodInput({ query: expandedQuery }) : void 0;
292
+ const queryWithoutPeriod = periodResult?.remainingQuery ?? expandedQuery;
293
+ const occupancyResult = hasOccupancyInput(queryWithoutPeriod) ? yield* toOccupancyInput({ query: queryWithoutPeriod }) : void 0;
294
+ const basicQueryResult = toBasicQueryInputs({
295
+ query: occupancyResult?.remainingQuery ?? queryWithoutPeriod,
296
+ customAttributeFilterDefinitions,
297
+ locale,
298
+ translations
299
+ });
300
+ const filter = {
301
+ ...periodResult?.periodFilter,
302
+ ...occupancyResult?.occupancyFilter
303
+ };
304
+ const { appliedFilters, basicQueryInputs } = yield* applyVofficeFilterDerivedBasicQueryInputs({
305
+ appliedFilters: yield* basicQueryResult.appliedFilters,
306
+ basicQueryInputs: basicQueryResult.basicQueryInputs,
307
+ filter,
308
+ locale,
309
+ translations
310
+ });
311
+ return {
312
+ appliedFilters: [...compositionResult.appliedFilters, ...appliedFilters],
313
+ queryInput: {
314
+ vofficeData: Object.keys(filter).length > 0 ? { filter } : void 0,
315
+ basicQueryInputs
316
+ },
317
+ unusedFilterKeys: toUnusedFilterKeys(basicQueryResult.remainingQuery)
318
+ };
319
+ });
320
+ //#endregion
321
+ //#region src/adapters/v9/parser/search/to-search-output-item.ts
322
+ const toSearchOutputItem = ({ locale, rentalHighlightPrioritization, customAttributeFilterDefinitions, rental, translations }) => Effect.gen(function* () {
323
+ const data = parseVofficeUnitData(rental.data);
324
+ const item = {
325
+ id: rental.voffice_id.toString(),
326
+ nameOrLabel: typeof data.known.name === "string" ? data.known.name : rental.voffice_id.toString(),
327
+ timeZone: "Europe/Berlin"
328
+ };
329
+ const address = toAddress(data, locale);
330
+ if (Object.keys(address).length > 0) item.address = address;
331
+ const highlights = yield* toRentalHighlights({
332
+ locale,
333
+ translations,
334
+ highlightPrioritization: rentalHighlightPrioritization,
335
+ customAttributeFilterDefinitions,
336
+ attributes: data
337
+ });
338
+ if (highlights != null) item.highlights = highlights;
339
+ return item;
340
+ });
341
+ //#endregion
342
+ export { toQueryInput, toSearchOutputItem };