@v-office/website-headless 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +22 -5
- package/dist/index.mjs +21 -10
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1101,9 +1101,10 @@ interface SearchResultItem {
|
|
|
1101
1101
|
name: string;
|
|
1102
1102
|
/** `address.city`, verbatim (empty when the feed omits it). */
|
|
1103
1103
|
location: string;
|
|
1104
|
-
/** Internal detail link
|
|
1105
|
-
*
|
|
1106
|
-
*
|
|
1104
|
+
/** Internal detail link — `rentalsPath` (see `runLiveSearch`) + the slug
|
|
1105
|
+
* derived from the name (URL generation), with the user's booking context
|
|
1106
|
+
* (dates + party size) appended as a query so the search selection carries
|
|
1107
|
+
* into the rental page. */
|
|
1107
1108
|
href: string;
|
|
1108
1109
|
images: SearchImage[];
|
|
1109
1110
|
/** Parsed out of the SDK highlights; 0 when the highlight is absent. */
|
|
@@ -1219,6 +1220,16 @@ interface SearchPayload {
|
|
|
1219
1220
|
/** `pageInfo.hasNextPage`, verbatim. */
|
|
1220
1221
|
hasNextPage: boolean;
|
|
1221
1222
|
}
|
|
1223
|
+
interface LiveSearchOptions {
|
|
1224
|
+
/** Path of the site's rental detail pages, prefixed to every result `href`
|
|
1225
|
+
* before the slug (e.g. `/de/unterkuenfte`). A trailing slash is tolerated.
|
|
1226
|
+
* Default: `DEFAULT_RENTALS_PATH`. */
|
|
1227
|
+
rentalsPath?: string | undefined;
|
|
1228
|
+
}
|
|
1229
|
+
/** The rental detail pages' path when the caller names none — the site
|
|
1230
|
+
* starter's German route. A site whose pages live elsewhere (a locale prefix,
|
|
1231
|
+
* another segment) passes its own `rentalsPath` to `runLiveSearch`. */
|
|
1232
|
+
declare const DEFAULT_RENTALS_PATH = "/unterkuenfte";
|
|
1222
1233
|
/**
|
|
1223
1234
|
* Run a live search for the given URL query string (e.g.
|
|
1224
1235
|
* `window.location.search`). Builds the SDK query from the picker params,
|
|
@@ -1229,8 +1240,14 @@ interface SearchPayload {
|
|
|
1229
1240
|
* Pass `cursor` (the previous page's `pageInfo.nextCursor`, treated as
|
|
1230
1241
|
* opaque) to fetch the next page. The returned `cursor`/`hasNextPage` are
|
|
1231
1242
|
* the SDK's `pageInfo` straight through, so the caller can keep paging.
|
|
1243
|
+
*
|
|
1244
|
+
* `options.rentalsPath` is the path the site serves its rental detail pages
|
|
1245
|
+
* under — the part of every result `href` before the slug. Routing is the
|
|
1246
|
+
* site's decision (a locale prefix like `/de/unterkuenfte`, another segment),
|
|
1247
|
+
* so it arrives as an option the way `SearchBar.action` and `Quote.checkoutPath`
|
|
1248
|
+
* do; `locale` never implies it. Defaults to `DEFAULT_RENTALS_PATH`.
|
|
1232
1249
|
*/
|
|
1233
|
-
declare function runLiveSearch(sdk: VofficeSdk, searchString: string, locale: Locale, cursor?: string | null): Promise<SearchPayload>;
|
|
1250
|
+
declare function runLiveSearch(sdk: VofficeSdk, searchString: string, locale: Locale, cursor?: string | null, options?: LiveSearchOptions): Promise<SearchPayload>;
|
|
1234
1251
|
//#endregion
|
|
1235
1252
|
//#region src/sort.d.ts
|
|
1236
1253
|
/** URL param. A client-side scope like `property`/`region`, NOT an SDK query
|
|
@@ -1337,4 +1354,4 @@ declare function scopeToRegions<T extends {
|
|
|
1337
1354
|
id: string;
|
|
1338
1355
|
}>(items: readonly T[], active: readonly string[], regionsByRentalId: (id: string) => readonly string[] | undefined): T[];
|
|
1339
1356
|
//#endregion
|
|
1340
|
-
export { ActiveFilter, AlternativePeriod, BOOKING_SNAPSHOT_KEY, BUTTON_SOLUTION_PATTERN, BookingConfirmation, BookingContactForm, BookingSnapshot, BookingSnapshotGuests, CHECKOUT_CONTEXT_KEY, CHECKOUT_PARTS, CHECKOUT_RETURN_PATH, CHECKOUT_STRUCTURE, CheckoutContext, type CheckoutFlow, type CheckoutFlowActions, type CheckoutFlowApi, type CheckoutFlowMessages, type CheckoutFlowOptions, type CheckoutFlowState, type CheckoutIssue, type CheckoutPart, type CheckoutPhase, type CountryGroupsLike, DEFAULT_SORT, EndAvailability, FilterDef, FilterType, HUB_ENDPOINTS, InitialAvailability, type InsuranceDocsState, InsurancePaymentLink, Listener, type Locale, MULTI_RATE_CODES, NIGHT_RANGE_ENABLED, NIGHT_RANGE_KEYS, NO_INSURANCE_DOCS, NightRange, PETS_COUNT_PARAM, PETS_PARAM, PaymentLine, PaymentScheduleView, PolicyBranch, PriceQuote, QuoteAddonService, QuoteCancellationPolicy, QuoteInsurance, QuoteInsuranceOption, QuoteLine, QuoteOccupancy, QuotePolicyRule, QuoteResult, QuoteSelectionResult, QuoteUnavailableCode, QuoteView, QuoteVoucher, REGION_PARAM, SORT_OPTIONS, SORT_PARAM, STAGES, SdkConfig, SearchImage, SearchPayload, SearchResultItem, SnapshotImage, SortOption, SortValue, Stage, type Stay, Store, type StructureViolation, Unsubscribe, VALIDATED_FIELDS, VOFFICE_ENDPOINTS, type ValidationMessages, WebsiteSdk, WritableStore, activeFiltersFromQuery, activeRegions, activeSort, adaptGuestQuote, addQuoteService, assertCheckoutStructure, clearQuoteServices, createCheckoutFlow, createSdk, createStore, describeSdkError, detectCountry, emailError, fetchEndAvailability, fetchInitialAvailability, fetchQuote, fieldError, freeCancellationUntil, fullRefundRule, insuranceDocsPending, insuranceIdToReapply, insuranceProductKey, isBooleanFilterActive, isPricedQuery, isRateConfigurationFault, isSortAvailable, isSubmittableOption, isoDate, logSdkFailure, nightlyPrice, normalizePhone, occupancyOf, parseGermanParam, parseNightRange, parseParam, payWithOption, petsCountInQuery, phoneError, policyFreeCancellationUntil, postalcodeError, pricePolicyBranches, removeQuoteService, resolveSdkSort, runLiveSearch, saveBookingSnapshot, saveCheckoutContext, scopeToRegions, sdkConfigFor, selectQuoteInsurance, selectQuotePolicy, selectableInsuranceOptions, selectedInsuranceOption, shownInsuranceResources, stabilizeCardOrder, stayKeyOf, stayParams, streetWarning, submitBooking, tidyPrice };
|
|
1357
|
+
export { ActiveFilter, AlternativePeriod, BOOKING_SNAPSHOT_KEY, BUTTON_SOLUTION_PATTERN, BookingConfirmation, BookingContactForm, BookingSnapshot, BookingSnapshotGuests, CHECKOUT_CONTEXT_KEY, CHECKOUT_PARTS, CHECKOUT_RETURN_PATH, CHECKOUT_STRUCTURE, CheckoutContext, type CheckoutFlow, type CheckoutFlowActions, type CheckoutFlowApi, type CheckoutFlowMessages, type CheckoutFlowOptions, type CheckoutFlowState, type CheckoutIssue, type CheckoutPart, type CheckoutPhase, type CountryGroupsLike, DEFAULT_RENTALS_PATH, DEFAULT_SORT, EndAvailability, FilterDef, FilterType, HUB_ENDPOINTS, InitialAvailability, type InsuranceDocsState, InsurancePaymentLink, Listener, LiveSearchOptions, type Locale, MULTI_RATE_CODES, NIGHT_RANGE_ENABLED, NIGHT_RANGE_KEYS, NO_INSURANCE_DOCS, NightRange, PETS_COUNT_PARAM, PETS_PARAM, PaymentLine, PaymentScheduleView, PolicyBranch, PriceQuote, QuoteAddonService, QuoteCancellationPolicy, QuoteInsurance, QuoteInsuranceOption, QuoteLine, QuoteOccupancy, QuotePolicyRule, QuoteResult, QuoteSelectionResult, QuoteUnavailableCode, QuoteView, QuoteVoucher, REGION_PARAM, SORT_OPTIONS, SORT_PARAM, STAGES, SdkConfig, SearchImage, SearchPayload, SearchResultItem, SnapshotImage, SortOption, SortValue, Stage, type Stay, Store, type StructureViolation, Unsubscribe, VALIDATED_FIELDS, VOFFICE_ENDPOINTS, type ValidationMessages, WebsiteSdk, WritableStore, activeFiltersFromQuery, activeRegions, activeSort, adaptGuestQuote, addQuoteService, assertCheckoutStructure, clearQuoteServices, createCheckoutFlow, createSdk, createStore, describeSdkError, detectCountry, emailError, fetchEndAvailability, fetchInitialAvailability, fetchQuote, fieldError, freeCancellationUntil, fullRefundRule, insuranceDocsPending, insuranceIdToReapply, insuranceProductKey, isBooleanFilterActive, isPricedQuery, isRateConfigurationFault, isSortAvailable, isSubmittableOption, isoDate, logSdkFailure, nightlyPrice, normalizePhone, occupancyOf, parseGermanParam, parseNightRange, parseParam, payWithOption, petsCountInQuery, phoneError, policyFreeCancellationUntil, postalcodeError, pricePolicyBranches, removeQuoteService, resolveSdkSort, runLiveSearch, saveBookingSnapshot, saveCheckoutContext, scopeToRegions, sdkConfigFor, selectQuoteInsurance, selectQuotePolicy, selectableInsuranceOptions, selectedInsuranceOption, shownInsuranceResources, stabilizeCardOrder, stayKeyOf, stayParams, streetWarning, submitBooking, tidyPrice };
|
package/dist/index.mjs
CHANGED
|
@@ -1889,14 +1889,18 @@ function buildHandover(params, dates) {
|
|
|
1889
1889
|
const suffix = out.toString();
|
|
1890
1890
|
return suffix ? `?${suffix}` : "";
|
|
1891
1891
|
}
|
|
1892
|
-
|
|
1892
|
+
/** The rental detail pages' path when the caller names none — the site
|
|
1893
|
+
* starter's German route. A site whose pages live elsewhere (a locale prefix,
|
|
1894
|
+
* another segment) passes its own `rentalsPath` to `runLiveSearch`. */
|
|
1895
|
+
const DEFAULT_RENTALS_PATH = "/unterkuenfte";
|
|
1896
|
+
function mapBase(item, rentalsPath) {
|
|
1893
1897
|
const name = item.nameOrLabel.trim();
|
|
1894
1898
|
const highlights = item.highlights ?? [];
|
|
1895
1899
|
return {
|
|
1896
1900
|
id: item.id,
|
|
1897
1901
|
name,
|
|
1898
1902
|
location: item.address?.city?.trim() ?? "",
|
|
1899
|
-
href:
|
|
1903
|
+
href: `${rentalsPath.replace(/\/+$/, "")}/${slugify(name)}`,
|
|
1900
1904
|
images: (item.images ?? []).map((img) => ({
|
|
1901
1905
|
src: img.src,
|
|
1902
1906
|
srcset: img.srcset?.trim() || void 0,
|
|
@@ -1946,11 +1950,11 @@ function mapDiscount(discount) {
|
|
|
1946
1950
|
})
|
|
1947
1951
|
};
|
|
1948
1952
|
}
|
|
1949
|
-
function mapItem(item, params, locale) {
|
|
1953
|
+
function mapItem(item, params, locale, rentalsPath) {
|
|
1950
1954
|
const scopeType = typeof item.scope === "string" ? item.scope : item.scope?.type;
|
|
1951
1955
|
const alternativePeriodLabel = formatPeriodLabel(item.alternativePeriod ?? (typeof item.scope === "object" ? item.scope.alternativePeriod : void 0), locale);
|
|
1952
1956
|
const isAlternativePeriod = alternativePeriodLabel != null || scopeType === "alternativePeriod" || scopeType === "alternative-period";
|
|
1953
|
-
const base = mapBase(item);
|
|
1957
|
+
const base = mapBase(item, rentalsPath);
|
|
1954
1958
|
return {
|
|
1955
1959
|
...base,
|
|
1956
1960
|
href: `${base.href}${buildHandover(params)}`,
|
|
@@ -1967,8 +1971,8 @@ function mapItem(item, params, locale) {
|
|
|
1967
1971
|
* label come from the first candidate period (the SDK returns them best-first,
|
|
1968
1972
|
* `boost`-ordered). Always flagged as an alternative so the card shows the
|
|
1969
1973
|
* period pill instead of treating it as an exact total. */
|
|
1970
|
-
function mapAlternativeEntry(entry, params, locale) {
|
|
1971
|
-
const base = mapBase(entry.item);
|
|
1974
|
+
function mapAlternativeEntry(entry, params, locale, rentalsPath) {
|
|
1975
|
+
const base = mapBase(entry.item, rentalsPath);
|
|
1972
1976
|
const periods = (entry.alternativePeriods ?? []).flatMap((candidate) => {
|
|
1973
1977
|
const label = formatPeriodLabel({
|
|
1974
1978
|
start: candidate.start,
|
|
@@ -2016,8 +2020,15 @@ function mapAlternativeEntry(entry, params, locale) {
|
|
|
2016
2020
|
* Pass `cursor` (the previous page's `pageInfo.nextCursor`, treated as
|
|
2017
2021
|
* opaque) to fetch the next page. The returned `cursor`/`hasNextPage` are
|
|
2018
2022
|
* the SDK's `pageInfo` straight through, so the caller can keep paging.
|
|
2023
|
+
*
|
|
2024
|
+
* `options.rentalsPath` is the path the site serves its rental detail pages
|
|
2025
|
+
* under — the part of every result `href` before the slug. Routing is the
|
|
2026
|
+
* site's decision (a locale prefix like `/de/unterkuenfte`, another segment),
|
|
2027
|
+
* so it arrives as an option the way `SearchBar.action` and `Quote.checkoutPath`
|
|
2028
|
+
* do; `locale` never implies it. Defaults to `DEFAULT_RENTALS_PATH`.
|
|
2019
2029
|
*/
|
|
2020
|
-
async function runLiveSearch(sdk, searchString, locale, cursor) {
|
|
2030
|
+
async function runLiveSearch(sdk, searchString, locale, cursor, options = {}) {
|
|
2031
|
+
const rentalsPath = options.rentalsPath ?? "/unterkuenfte";
|
|
2021
2032
|
const params = new URLSearchParams(searchString);
|
|
2022
2033
|
const nights = computeNights(params);
|
|
2023
2034
|
const sort = resolveSdkSort(searchString);
|
|
@@ -2030,9 +2041,9 @@ async function runLiveSearch(sdk, searchString, locale, cursor) {
|
|
|
2030
2041
|
...sort ? { sort } : {},
|
|
2031
2042
|
...cursor ? { cursor } : {}
|
|
2032
2043
|
});
|
|
2033
|
-
const exact = result.items.map((item) => mapItem(item, params, locale));
|
|
2044
|
+
const exact = result.items.map((item) => mapItem(item, params, locale, rentalsPath));
|
|
2034
2045
|
const exactIds = new Set(exact.map((item) => item.id));
|
|
2035
|
-
const alternatives = (result.alternatives ?? []).filter((entry) => entry?.item?.id && !exactIds.has(entry.item.id)).map((entry) => mapAlternativeEntry(entry, params, locale));
|
|
2046
|
+
const alternatives = (result.alternatives ?? []).filter((entry) => entry?.item?.id && !exactIds.has(entry.item.id)).map((entry) => mapAlternativeEntry(entry, params, locale, rentalsPath));
|
|
2036
2047
|
const items = exact.concat(alternatives);
|
|
2037
2048
|
return {
|
|
2038
2049
|
items,
|
|
@@ -2082,4 +2093,4 @@ function scopeToRegions(items, active, regionsByRentalId) {
|
|
|
2082
2093
|
return items.filter((item) => regionsByRentalId(item.id)?.some((r) => active.includes(r)));
|
|
2083
2094
|
}
|
|
2084
2095
|
//#endregion
|
|
2085
|
-
export { BOOKING_SNAPSHOT_KEY, BUTTON_SOLUTION_PATTERN, CHECKOUT_CONTEXT_KEY, CHECKOUT_PARTS, CHECKOUT_RETURN_PATH, CHECKOUT_STRUCTURE, DEFAULT_SORT, HUB_ENDPOINTS, MULTI_RATE_CODES, NIGHT_RANGE_ENABLED, NIGHT_RANGE_KEYS, NO_INSURANCE_DOCS, PETS_COUNT_PARAM, PETS_PARAM, REGION_PARAM, SORT_OPTIONS, SORT_PARAM, STAGES, VALIDATED_FIELDS, VOFFICE_ENDPOINTS, activeFiltersFromQuery, activeRegions, activeSort, adaptGuestQuote, addQuoteService, assertCheckoutStructure, clearQuoteServices, createCheckoutFlow, createSdk, createStore, describeSdkError, detectCountry, emailError, fetchEndAvailability, fetchInitialAvailability, fetchQuote, fieldError, freeCancellationUntil, fullRefundRule, insuranceDocsPending, insuranceIdToReapply, insuranceProductKey, isBooleanFilterActive, isPricedQuery, isRateConfigurationFault, isSortAvailable, isSubmittableOption, isoDate, logSdkFailure, nightlyPrice, normalizePhone, occupancyOf, parseGermanParam, parseNightRange, parseParam, payWithOption, petsCountInQuery, phoneError, policyFreeCancellationUntil, postalcodeError, pricePolicyBranches, removeQuoteService, resolveSdkSort, runLiveSearch, saveBookingSnapshot, saveCheckoutContext, scopeToRegions, sdkConfigFor, selectQuoteInsurance, selectQuotePolicy, selectableInsuranceOptions, selectedInsuranceOption, shownInsuranceResources, stabilizeCardOrder, stayKeyOf, stayParams, streetWarning, submitBooking, tidyPrice };
|
|
2096
|
+
export { BOOKING_SNAPSHOT_KEY, BUTTON_SOLUTION_PATTERN, CHECKOUT_CONTEXT_KEY, CHECKOUT_PARTS, CHECKOUT_RETURN_PATH, CHECKOUT_STRUCTURE, DEFAULT_RENTALS_PATH, DEFAULT_SORT, HUB_ENDPOINTS, MULTI_RATE_CODES, NIGHT_RANGE_ENABLED, NIGHT_RANGE_KEYS, NO_INSURANCE_DOCS, PETS_COUNT_PARAM, PETS_PARAM, REGION_PARAM, SORT_OPTIONS, SORT_PARAM, STAGES, VALIDATED_FIELDS, VOFFICE_ENDPOINTS, activeFiltersFromQuery, activeRegions, activeSort, adaptGuestQuote, addQuoteService, assertCheckoutStructure, clearQuoteServices, createCheckoutFlow, createSdk, createStore, describeSdkError, detectCountry, emailError, fetchEndAvailability, fetchInitialAvailability, fetchQuote, fieldError, freeCancellationUntil, fullRefundRule, insuranceDocsPending, insuranceIdToReapply, insuranceProductKey, isBooleanFilterActive, isPricedQuery, isRateConfigurationFault, isSortAvailable, isSubmittableOption, isoDate, logSdkFailure, nightlyPrice, normalizePhone, occupancyOf, parseGermanParam, parseNightRange, parseParam, payWithOption, petsCountInQuery, phoneError, policyFreeCancellationUntil, postalcodeError, pricePolicyBranches, removeQuoteService, resolveSdkSort, runLiveSearch, saveBookingSnapshot, saveCheckoutContext, scopeToRegions, sdkConfigFor, selectQuoteInsurance, selectQuotePolicy, selectableInsuranceOptions, selectedInsuranceOption, shownInsuranceResources, stabilizeCardOrder, stayKeyOf, stayParams, streetWarning, submitBooking, tidyPrice };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-office/website-headless",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Framework-free behavior layer for v-office websites, never UI: the checkout flow as a subscribable store (createCheckoutFlow), validation and insurance rules, the checkout's structural requirements, the live search, availability and quote runners over a caller-owned SDK, and progressive-enhancement engines for server-rendered markup",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|