@v-office/website-headless 0.1.1 → 0.2.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 +8 -7
- package/dist/enhance/index.d.mts +8 -8
- package/dist/index.d.mts +135 -131
- package/dist/index.mjs +15 -11
- package/instructions/CHANGELOG.md +8 -0
- package/instructions/MIGRATION.md +8 -0
- package/instructions/versions/0.1.1/CHANGELOG.md +7 -0
- package/instructions/versions/0.1.1/MIGRATION.md +4 -0
- package/instructions/versions/0.1.1/release.json +3 -0
- package/instructions/versions/0.2.0/CHANGELOG.md +17 -0
- package/instructions/versions/0.2.0/MIGRATION.md +16 -0
- package/instructions/versions/0.2.0/release.json +3 -0
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -64,10 +64,10 @@ parameters — the rules live here, the words live in the site.
|
|
|
64
64
|
## Development
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
pnpm install
|
|
67
|
+
pnpm install # at the repository root; website-sdk is a workspace link
|
|
68
68
|
pnpm build # tsdown → dist/ (index, enhance; .mjs + .d.mts)
|
|
69
69
|
pnpm check # tsc · oxlint · oxfmt --check
|
|
70
|
-
pnpm test # vitest, jsdom environment
|
|
70
|
+
pnpm test # vitest, jsdom environment; then test/dist.node.mjs imports the build by name
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
The tests cover the pure rules (validation, insurance gate, stay helpers,
|
|
@@ -78,8 +78,9 @@ DOM (jsdom); the SDKs use `node --test` because they do not.
|
|
|
78
78
|
|
|
79
79
|
## Publishing
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
See [docs/internal/releasing/overview.md](../../docs/internal/releasing/overview.md). `node .github/release/cli.mts
|
|
82
|
+
prepare website-headless <bump>` sets the version and scaffolds
|
|
83
|
+
`instructions/versions/<version>/` with the notes and the `release.json`
|
|
84
|
+
release facts; the `Release packages` workflow publishes what is on `main`
|
|
85
|
+
after build, check and tests pass. Consumers pin the exact version and receive
|
|
86
|
+
updates through fleet rollouts (docs/website-platform/process/06-package-rollout.md).
|
package/dist/enhance/index.d.mts
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* `{current}` shown) — the component renders the template from its copy, so
|
|
21
21
|
* the enhancer carries no language of its own.
|
|
22
22
|
*/
|
|
23
|
-
declare function initImageCarousels(selector?: string): void;
|
|
24
|
-
declare function initRentalCarousel(viewport: HTMLElement): void;
|
|
23
|
+
export declare function initImageCarousels(selector?: string): void;
|
|
24
|
+
export declare function initRentalCarousel(viewport: HTMLElement): void;
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/enhance/overlay.d.ts
|
|
27
27
|
/**
|
|
@@ -66,11 +66,11 @@ declare function initRentalCarousel(viewport: HTMLElement): void;
|
|
|
66
66
|
*/
|
|
67
67
|
/** Run `mutate` inside a view transition where the browser has one and the
|
|
68
68
|
* visitor has not asked for less motion; run it directly otherwise. */
|
|
69
|
-
declare function withViewTransition(mutate: () => void): void;
|
|
69
|
+
export declare function withViewTransition(mutate: () => void): void;
|
|
70
70
|
/** Install the page's single pair of modality listeners. Safe to call often. */
|
|
71
|
-
declare function trackInputModality(): void;
|
|
71
|
+
export declare function trackInputModality(): void;
|
|
72
72
|
/** Focus `el` only when the last real input was a keyboard one. */
|
|
73
|
-
declare function focusForKeyboard(el: HTMLElement | null): void;
|
|
73
|
+
export declare function focusForKeyboard(el: HTMLElement | null): void;
|
|
74
74
|
/** Every selector the controller needs, stated by the caller. Each is scoped to
|
|
75
75
|
* `root`, so two overlays on one page cannot reach into each other. */
|
|
76
76
|
interface HistoryOverlayOptions {
|
|
@@ -93,7 +93,7 @@ interface HistoryOverlayOptions {
|
|
|
93
93
|
}
|
|
94
94
|
/** Bind one overlay. Returns silently when the markup is not on this page, so
|
|
95
95
|
* a component whose overlay self-hides costs nothing. */
|
|
96
|
-
declare function initHistoryOverlay(options: HistoryOverlayOptions): void;
|
|
96
|
+
export declare function initHistoryOverlay(options: HistoryOverlayOptions): void;
|
|
97
97
|
//#endregion
|
|
98
98
|
//#region src/enhance/gallery.d.ts
|
|
99
99
|
/**
|
|
@@ -179,6 +179,6 @@ interface GalleryOptions {
|
|
|
179
179
|
layers: GalleryLayer[];
|
|
180
180
|
}
|
|
181
181
|
/** Bind one gallery. Returns silently when its root is not on this page. */
|
|
182
|
-
declare function initGallery(options: GalleryOptions): void;
|
|
182
|
+
export declare function initGallery(options: GalleryOptions): void;
|
|
183
183
|
//#endregion
|
|
184
|
-
export {
|
|
184
|
+
export type { GalleryLayer, GalleryOptions, HistoryOverlayOptions };
|
package/dist/index.d.mts
CHANGED
|
@@ -8,31 +8,31 @@ import { BookingPaymentOption, BookingPaymentScheduleKind, GuestQuote, GuestQuot
|
|
|
8
8
|
* package never depends on a framework; the adapters live in ./react and
|
|
9
9
|
* friends.
|
|
10
10
|
*/
|
|
11
|
-
type Listener<S> = (state: S) => void;
|
|
12
|
-
type Unsubscribe = () => void;
|
|
13
|
-
interface Store<S> {
|
|
11
|
+
export type Listener<S> = (state: S) => void;
|
|
12
|
+
export type Unsubscribe = () => void;
|
|
13
|
+
export interface Store<S> {
|
|
14
14
|
getState(): S;
|
|
15
15
|
subscribe(listener: Listener<S>): Unsubscribe;
|
|
16
16
|
}
|
|
17
|
-
interface WritableStore<S> extends Store<S> {
|
|
17
|
+
export interface WritableStore<S> extends Store<S> {
|
|
18
18
|
/** Replaces the state and notifies every listener. Same reference = no-op. */
|
|
19
19
|
setState(next: S): void;
|
|
20
20
|
}
|
|
21
|
-
declare function createStore<S>(initial: S): WritableStore<S>;
|
|
21
|
+
export declare function createStore<S>(initial: S): WritableStore<S>;
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region src/sdk.d.ts
|
|
24
|
-
type WebsiteSdk = ReturnType<typeof createWebsiteSDK>;
|
|
24
|
+
export type WebsiteSdk = ReturnType<typeof createWebsiteSDK>;
|
|
25
25
|
/** Deployment stage: selects the public endpoint set below. */
|
|
26
|
-
declare const STAGES: readonly ["development", "production"];
|
|
27
|
-
type Stage = (typeof STAGES)[number];
|
|
26
|
+
export declare const STAGES: readonly ["development", "production"];
|
|
27
|
+
export type Stage = (typeof STAGES)[number];
|
|
28
28
|
/** Public endpoints of the v10 backend per stage. */
|
|
29
|
-
declare const VOFFICE_ENDPOINTS: Record<Stage, {
|
|
29
|
+
export declare const VOFFICE_ENDPOINTS: Record<Stage, {
|
|
30
30
|
apiEndpoint: string;
|
|
31
31
|
imageBaseUrl: string;
|
|
32
32
|
searchEndpoint: string;
|
|
33
33
|
}>;
|
|
34
34
|
/** Public endpoints of the v9 backend per stage; API URLs derive from `apiBaseUrl`. */
|
|
35
|
-
declare const HUB_ENDPOINTS: Record<Stage, {
|
|
35
|
+
export declare const HUB_ENDPOINTS: Record<Stage, {
|
|
36
36
|
apiBaseUrl: string;
|
|
37
37
|
imageProxyBaseUrl: string;
|
|
38
38
|
}>;
|
|
@@ -40,7 +40,7 @@ declare const HUB_ENDPOINTS: Record<Stage, {
|
|
|
40
40
|
* secret to protect. Serializable on purpose: an Astro island receives it as a
|
|
41
41
|
* prop, so the site reads its env once (in .astro / a loader) and never inside
|
|
42
42
|
* a component. */
|
|
43
|
-
type SdkConfig = {
|
|
43
|
+
export type SdkConfig = {
|
|
44
44
|
backend: "v9";
|
|
45
45
|
imageProxyBaseUrl: string;
|
|
46
46
|
v0ApiBaseUrl: string;
|
|
@@ -56,7 +56,7 @@ type SdkConfig = {
|
|
|
56
56
|
};
|
|
57
57
|
/** The three values a site actually decides — backend, stage, its token — as
|
|
58
58
|
* a full `SdkConfig`, with the endpoints the platform owns. */
|
|
59
|
-
declare function sdkConfigFor({ backend, stage, token }: {
|
|
59
|
+
export declare function sdkConfigFor({ backend, stage, token }: {
|
|
60
60
|
backend: SdkConfig["backend"];
|
|
61
61
|
stage: Stage;
|
|
62
62
|
token: string;
|
|
@@ -65,7 +65,7 @@ declare function sdkConfigFor({ backend, stage, token }: {
|
|
|
65
65
|
* overrides, custom attributes, highlight prioritization). The caller owns the
|
|
66
66
|
* lifecycle and calls `await sdk.dispose()` when done. The API is rate-limited
|
|
67
67
|
* (1/s), so a browser surface keeps ONE instance for its lifetime. */
|
|
68
|
-
declare function createSdk(config: SdkConfig, options?: WebsiteSDKOptions): WebsiteSdk;
|
|
68
|
+
export declare function createSdk(config: SdkConfig, options?: WebsiteSDKOptions): WebsiteSdk;
|
|
69
69
|
/**
|
|
70
70
|
* Render `error` and its whole cause chain as indented JSON.
|
|
71
71
|
*
|
|
@@ -84,7 +84,7 @@ declare function createSdk(config: SdkConfig, options?: WebsiteSDKOptions): Webs
|
|
|
84
84
|
* `CoreSDKError` logged as the five bland fields above with the sentence that
|
|
85
85
|
* names the fault dropped.
|
|
86
86
|
*/
|
|
87
|
-
declare function describeSdkError(error: unknown): string;
|
|
87
|
+
export declare function describeSdkError(error: unknown): string;
|
|
88
88
|
/**
|
|
89
89
|
* Log a failed SDK call with the backend's reason, tagged by `scope`.
|
|
90
90
|
*
|
|
@@ -97,7 +97,7 @@ declare function describeSdkError(error: unknown): string;
|
|
|
97
97
|
* log it separately for a clickable stack; doubling it here would print every
|
|
98
98
|
* failure twice on the surfaces that already do.
|
|
99
99
|
*/
|
|
100
|
-
declare function logSdkFailure(scope: string, error: unknown): void;
|
|
100
|
+
export declare function logSdkFailure(scope: string, error: unknown): void;
|
|
101
101
|
//#endregion
|
|
102
102
|
//#region src/quote.d.ts
|
|
103
103
|
/** One row of the price breakdown. `label`/`amount` are the SDK's own
|
|
@@ -108,13 +108,13 @@ declare function logSdkFailure(scope: string, error: unknown): void;
|
|
|
108
108
|
* from a charge line — see `adaptGuestQuote` for why those rows exist. Its
|
|
109
109
|
* `amount` is the modifier's own signed string ("-140,00 €"), so the row is a
|
|
110
110
|
* deduction from the running total, not another charge. */
|
|
111
|
-
interface QuoteLine {
|
|
111
|
+
export interface QuoteLine {
|
|
112
112
|
label: string;
|
|
113
113
|
amount: string;
|
|
114
114
|
nested: boolean;
|
|
115
115
|
discount: boolean;
|
|
116
116
|
}
|
|
117
|
-
interface PriceQuote {
|
|
117
|
+
export interface PriceQuote {
|
|
118
118
|
/** Section/line breakdown flattened in SDK order (sub-items follow their
|
|
119
119
|
* parent line, flagged `nested`). */
|
|
120
120
|
lines: QuoteLine[];
|
|
@@ -122,7 +122,7 @@ interface PriceQuote {
|
|
|
122
122
|
total: string;
|
|
123
123
|
}
|
|
124
124
|
/** Bookable add-on from `quote.additionalServices`, verbatim fields. */
|
|
125
|
-
interface QuoteAddonService {
|
|
125
|
+
export interface QuoteAddonService {
|
|
126
126
|
id: string;
|
|
127
127
|
label: string;
|
|
128
128
|
/** SDK charge string as-is (e.g. "25,00 €" — the PMS's own formatting). */
|
|
@@ -160,13 +160,13 @@ interface QuoteAddonService {
|
|
|
160
160
|
* the feed omits it. */
|
|
161
161
|
unavailableReason?: string | undefined;
|
|
162
162
|
}
|
|
163
|
-
interface QuotePolicyRule {
|
|
163
|
+
export interface QuotePolicyRule {
|
|
164
164
|
daysBeforeArrival: number;
|
|
165
165
|
/** SDK's formatted percentage string, verbatim. */
|
|
166
166
|
refundPercentage: string;
|
|
167
167
|
}
|
|
168
168
|
/** Selectable cancellation policy from `quote.cancellationPolicies`. */
|
|
169
|
-
interface QuoteCancellationPolicy {
|
|
169
|
+
export interface QuoteCancellationPolicy {
|
|
170
170
|
id: string;
|
|
171
171
|
label: string;
|
|
172
172
|
selected: boolean;
|
|
@@ -184,7 +184,7 @@ interface QuoteCancellationPolicy {
|
|
|
184
184
|
/** Voucher status echoed back on a re-priced quote (`quote.voucher`). On v10
|
|
185
185
|
* the SDK authoritatively reports whether the code applied a modifier; v9
|
|
186
186
|
* reports `"unknown"`. `message` is the PMS's own note, verbatim. */
|
|
187
|
-
interface QuoteVoucher {
|
|
187
|
+
export interface QuoteVoucher {
|
|
188
188
|
code: string;
|
|
189
189
|
status: "applied" | "not_applied" | "unknown";
|
|
190
190
|
message?: string | undefined;
|
|
@@ -194,7 +194,7 @@ interface QuoteVoucher {
|
|
|
194
194
|
* whichever insurer the hub setup configures, and only when that setup enables
|
|
195
195
|
* insurance at all — otherwise the SDK returns the "none" option alone and the
|
|
196
196
|
* adapter yields no `QuoteInsurance`. */
|
|
197
|
-
interface QuoteInsuranceOption {
|
|
197
|
+
export interface QuoteInsuranceOption {
|
|
198
198
|
id: string;
|
|
199
199
|
label: string;
|
|
200
200
|
/** SDK's own locale-formatted premium (e.g. "14,00 €"). There is no numeric
|
|
@@ -228,7 +228,7 @@ interface QuoteInsuranceOption {
|
|
|
228
228
|
* policy separately, so a UI that shows both must show them as two figures.
|
|
229
229
|
* Adding them would mean parsing the PMS's formatted strings, which this file
|
|
230
230
|
* does not do for any other charge either. */
|
|
231
|
-
interface QuoteInsurance {
|
|
231
|
+
export interface QuoteInsurance {
|
|
232
232
|
/** The SDK's own "no insurance" label, verbatim. */
|
|
233
233
|
noneLabel: string;
|
|
234
234
|
options: QuoteInsuranceOption[];
|
|
@@ -236,7 +236,7 @@ interface QuoteInsurance {
|
|
|
236
236
|
selectedId: string | null;
|
|
237
237
|
}
|
|
238
238
|
/** The renderable view of a live GuestQuote — card + selectable options. */
|
|
239
|
-
interface QuoteView {
|
|
239
|
+
export interface QuoteView {
|
|
240
240
|
card: PriceQuote;
|
|
241
241
|
services: QuoteAddonService[];
|
|
242
242
|
policies: QuoteCancellationPolicy[];
|
|
@@ -246,7 +246,7 @@ interface QuoteView {
|
|
|
246
246
|
/** Selectable travel insurance — absent when the feed offers no product. */
|
|
247
247
|
insurance?: QuoteInsurance | undefined;
|
|
248
248
|
}
|
|
249
|
-
type QuoteResult = {
|
|
249
|
+
export type QuoteResult = {
|
|
250
250
|
status: "available";
|
|
251
251
|
/** Flattened price card (back-compat: the widget renders this). */
|
|
252
252
|
quote: PriceQuote;
|
|
@@ -271,7 +271,7 @@ type QuoteResult = {
|
|
|
271
271
|
* `@v-office/website-sdk` does not re-export it and sdk-core is a transitive
|
|
272
272
|
* dependency an adopting project does not declare — so `Extract` off the
|
|
273
273
|
* result type is the reachable spelling. */
|
|
274
|
-
type QuoteUnavailableCode = Extract<GuestQuoteResult, {
|
|
274
|
+
export type QuoteUnavailableCode = Extract<GuestQuoteResult, {
|
|
275
275
|
status: "unavailable";
|
|
276
276
|
}>["code"];
|
|
277
277
|
/** The two codes that mean "the stay WAS priced, but the rental's rate setup
|
|
@@ -289,13 +289,13 @@ type QuoteUnavailableCode = Extract<GuestQuoteResult, {
|
|
|
289
289
|
* unbookable until the surplus rows are removed in the PMS. What the site owes
|
|
290
290
|
* the guest is honest copy — never the generic "not available", which asserts
|
|
291
291
|
* a booking conflict that does not exist. */
|
|
292
|
-
declare const MULTI_RATE_CODES: readonly ["AmbiguousMultiRate", "UnresolvableMultiRate"];
|
|
292
|
+
export declare const MULTI_RATE_CODES: readonly ["AmbiguousMultiRate", "UnresolvableMultiRate"];
|
|
293
293
|
/** True when an unavailable quote is a rate-configuration fault rather than a
|
|
294
294
|
* genuinely unbookable stay. Callers branch the MESSAGE on this and must keep
|
|
295
295
|
* booking disabled either way (SDK 2.16.0 MIGRATION, "Required Consumer
|
|
296
296
|
* Work"). */
|
|
297
|
-
declare function isRateConfigurationFault(code: QuoteUnavailableCode | undefined): boolean;
|
|
298
|
-
interface QuoteOccupancy {
|
|
297
|
+
export declare function isRateConfigurationFault(code: QuoteUnavailableCode | undefined): boolean;
|
|
298
|
+
export interface QuoteOccupancy {
|
|
299
299
|
adults: number;
|
|
300
300
|
children: number;
|
|
301
301
|
childrenAges?: number[] | undefined;
|
|
@@ -325,23 +325,23 @@ interface QuoteOccupancy {
|
|
|
325
325
|
* checked by adding, and as a price claim the customer would have to stand
|
|
326
326
|
* behind. The total stays the single net number.
|
|
327
327
|
*/
|
|
328
|
-
declare function adaptGuestQuote(quote: GuestQuote): QuoteView;
|
|
328
|
+
export declare function adaptGuestQuote(quote: GuestQuote): QuoteView;
|
|
329
329
|
/** Price a stay for `rentalId`. The caller owns the SDK instance and its
|
|
330
330
|
* lifecycle — pass a shared one to reuse its queue + cache across the caller's
|
|
331
331
|
* lifetime. `voucher` re-prices with a code (the PMS decides what it's worth). */
|
|
332
|
-
declare function fetchQuote(rentalId: string, period: {
|
|
332
|
+
export declare function fetchQuote(rentalId: string, period: {
|
|
333
333
|
start: string;
|
|
334
334
|
end: string;
|
|
335
335
|
}, occupancy: QuoteOccupancy, sdk: WebsiteSdk, locale: Locale, voucher?: string): Promise<QuoteResult>;
|
|
336
|
-
type QuoteSelectionResult = {
|
|
336
|
+
export type QuoteSelectionResult = {
|
|
337
337
|
ok: true;
|
|
338
338
|
quote: GuestQuote;
|
|
339
339
|
} | {
|
|
340
340
|
ok: false;
|
|
341
341
|
reason?: string | undefined;
|
|
342
342
|
};
|
|
343
|
-
declare function addQuoteService(quote: GuestQuote, id: string, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
344
|
-
declare function removeQuoteService(quote: GuestQuote, id: string, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
343
|
+
export declare function addQuoteService(quote: GuestQuote, id: string, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
344
|
+
export declare function removeQuoteService(quote: GuestQuote, id: string, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
345
345
|
/** Drop every additional-service selection from `quote`.
|
|
346
346
|
*
|
|
347
347
|
* A fresh quote's selection state is not knowable from the service list. It is
|
|
@@ -351,8 +351,8 @@ declare function removeQuoteService(quote: GuestQuote, id: string, sdk: WebsiteS
|
|
|
351
351
|
* (`GuestQuote.selections` is behind an unexported symbol). Rather than branch
|
|
352
352
|
* on something invisible, a caller that needs a known starting point clears
|
|
353
353
|
* first and steps up from zero with `addQuoteService`. */
|
|
354
|
-
declare function clearQuoteServices(quote: GuestQuote, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
355
|
-
declare function selectQuotePolicy(quote: GuestQuote, id: string, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
354
|
+
export declare function clearQuoteServices(quote: GuestQuote, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
355
|
+
export declare function selectQuotePolicy(quote: GuestQuote, id: string, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
356
356
|
/** Select a travel-insurance product (`id`) or none (`null`). Unlike the
|
|
357
357
|
* service/policy calls the SDK returns the new GuestQuote directly and throws
|
|
358
358
|
* on failure (unknown id) — normalized here to the same QuoteSelectionResult
|
|
@@ -364,7 +364,7 @@ declare function selectQuotePolicy(quote: GuestQuote, id: string, sdk: WebsiteSd
|
|
|
364
364
|
* off the quote. A product with `requiresTravelers` needs the pre-contract /
|
|
365
365
|
* payment / `bookInsurance` steps on top, which the checkout does not
|
|
366
366
|
* implement — it offers only the products it can complete. */
|
|
367
|
-
declare function selectQuoteInsurance(quote: GuestQuote, id: string | null, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
367
|
+
export declare function selectQuoteInsurance(quote: GuestQuote, id: string | null, sdk: WebsiteSdk): Promise<QuoteSelectionResult>;
|
|
368
368
|
/**
|
|
369
369
|
* The concrete "free cancellation until" date for ONE policy — DERIVED, not
|
|
370
370
|
* fabricated: the PMS states its rules relatively (`daysBeforeArrival` +
|
|
@@ -380,16 +380,16 @@ declare function selectQuoteInsurance(quote: GuestQuote, id: string | null, sdk:
|
|
|
380
380
|
* own formatted string ("100%"), so this reads it rather than comparing a
|
|
381
381
|
* number — the one place that pattern is written, because both the derived
|
|
382
382
|
* deadline and the "is this a refundable rate at all" question depend on it. */
|
|
383
|
-
declare function fullRefundRule(policy: QuoteCancellationPolicy | undefined): QuotePolicyRule | undefined;
|
|
384
|
-
declare function policyFreeCancellationUntil(policy: QuoteCancellationPolicy | undefined, arrival: Date): Date | null;
|
|
383
|
+
export declare function fullRefundRule(policy: QuoteCancellationPolicy | undefined): QuotePolicyRule | undefined;
|
|
384
|
+
export declare function policyFreeCancellationUntil(policy: QuoteCancellationPolicy | undefined, arrival: Date): Date | null;
|
|
385
385
|
/** The deadline for the stay as it stands — i.e. of the SELECTED policy.
|
|
386
386
|
* Kept as its own name because that is what a summary line means: not "some
|
|
387
387
|
* policy allows this" but "what you have chosen allows this". */
|
|
388
|
-
declare function freeCancellationUntil(policies: QuoteCancellationPolicy[], arrival: Date): Date | null;
|
|
388
|
+
export declare function freeCancellationUntil(policies: QuoteCancellationPolicy[], arrival: Date): Date | null;
|
|
389
389
|
/** The same stay priced under ONE cancellation policy. `quote` is a real
|
|
390
390
|
* GuestQuote branched off the base, so the UI can show its card, and hand the
|
|
391
391
|
* branch on to a later step, without re-quoting the stay. */
|
|
392
|
-
interface PolicyBranch {
|
|
392
|
+
export interface PolicyBranch {
|
|
393
393
|
id: string;
|
|
394
394
|
/** The branch quote — the base itself for the already-selected policy. */
|
|
395
395
|
quote: GuestQuote;
|
|
@@ -420,15 +420,15 @@ interface PolicyBranch {
|
|
|
420
420
|
* budget delays the ones that can succeed. It simply gets no branch, and the UI
|
|
421
421
|
* renders it as the unselectable row it already is.
|
|
422
422
|
*/
|
|
423
|
-
declare function pricePolicyBranches(base: GuestQuote, sdk: WebsiteSdk): Promise<PolicyBranch[]>;
|
|
423
|
+
export declare function pricePolicyBranches(base: GuestQuote, sdk: WebsiteSdk): Promise<PolicyBranch[]>;
|
|
424
424
|
//#endregion
|
|
425
425
|
//#region src/booking.d.ts
|
|
426
426
|
/** Where the payment provider sends the guest back after an online payment
|
|
427
427
|
* (relative — the SDK/PSP resolves it against the site origin). */
|
|
428
|
-
declare const CHECKOUT_RETURN_PATH = "/buchen/bestaetigung";
|
|
428
|
+
export declare const CHECKOUT_RETURN_PATH = "/buchen/bestaetigung";
|
|
429
429
|
/** The checkout form's flat contact fields (the UI shape). `toBookingContact`
|
|
430
430
|
* folds them into the SDK's nested BookingContact. */
|
|
431
|
-
interface BookingContactForm {
|
|
431
|
+
export interface BookingContactForm {
|
|
432
432
|
forename: string;
|
|
433
433
|
surname: string;
|
|
434
434
|
/** Anrede ("Frau" / "Herr"); omitted when the guest picks none. */
|
|
@@ -443,13 +443,13 @@ interface BookingContactForm {
|
|
|
443
443
|
phone?: string | undefined;
|
|
444
444
|
note?: string | undefined;
|
|
445
445
|
}
|
|
446
|
-
interface PaymentLine {
|
|
446
|
+
export interface PaymentLine {
|
|
447
447
|
label: string;
|
|
448
448
|
amount: string;
|
|
449
449
|
}
|
|
450
450
|
/** One payment entry, verbatim — a contractual step (Anzahlung / Restzahlung /
|
|
451
451
|
* Rate / Kaution) or a way to settle the whole outstanding balance. */
|
|
452
|
-
interface PaymentScheduleView {
|
|
452
|
+
export interface PaymentScheduleView {
|
|
453
453
|
/** SDK's stable kind, for programmatic behaviour ONLY. Everything the guest
|
|
454
454
|
* reads comes from `label`: the SDK translates it, and a v10 installment is
|
|
455
455
|
* not automatically a v9 prepayment. */
|
|
@@ -476,12 +476,12 @@ interface PaymentScheduleView {
|
|
|
476
476
|
* a `PaymentScheduleView`: those are the PMS's own steps, owed to the site's
|
|
477
477
|
* operator and payable through the SDK. This one is a different contract with
|
|
478
478
|
* a different recipient, and it leaves the site entirely. */
|
|
479
|
-
interface InsurancePaymentLink {
|
|
479
|
+
export interface InsurancePaymentLink {
|
|
480
480
|
label: string;
|
|
481
481
|
url: string;
|
|
482
482
|
description?: string | undefined;
|
|
483
483
|
}
|
|
484
|
-
interface BookingConfirmation {
|
|
484
|
+
export interface BookingConfirmation {
|
|
485
485
|
bookingNumber: string;
|
|
486
486
|
/** The contractual steps, in backend order — what the guest owes and when. */
|
|
487
487
|
schedules: PaymentScheduleView[];
|
|
@@ -503,10 +503,10 @@ interface BookingConfirmation {
|
|
|
503
503
|
* real. Throws on transport/backend errors (the caller renders an honest
|
|
504
504
|
* retry message; nothing was necessarily booked when it throws).
|
|
505
505
|
*/
|
|
506
|
-
declare function submitBooking(quote: GuestQuote, contact: BookingContactForm, sdk: WebsiteSdk, returnPath?: string): Promise<BookingConfirmation>;
|
|
506
|
+
export declare function submitBooking(quote: GuestQuote, contact: BookingContactForm, sdk: WebsiteSdk, returnPath?: string): Promise<BookingConfirmation>;
|
|
507
507
|
/** True for the option kinds `submitPaymentOption` can perform in-browser
|
|
508
508
|
* (redirect / form_post / stripe_checkout). Bank transfer is display-only. */
|
|
509
|
-
declare function isSubmittableOption(option: BookingPaymentOption): option is SubmittableBookingPaymentOption;
|
|
509
|
+
export declare function isSubmittableOption(option: BookingPaymentOption): option is SubmittableBookingPaymentOption;
|
|
510
510
|
/** Perform an online payment option (redirects the browser to the PSP).
|
|
511
511
|
* USER-initiated only.
|
|
512
512
|
*
|
|
@@ -516,31 +516,31 @@ declare function isSubmittableOption(option: BookingPaymentOption): option is Su
|
|
|
516
516
|
* booking, not a failed one. The checkout's catch discards the error entirely
|
|
517
517
|
* — `.catch(() => setPayError(true))` — so without this a guest who cannot
|
|
518
518
|
* pay leaves no trace at all, on a booking someone now has to chase. */
|
|
519
|
-
declare function payWithOption(option: SubmittableBookingPaymentOption, sdk: WebsiteSdk): Promise<void>;
|
|
519
|
+
export declare function payWithOption(option: SubmittableBookingPaymentOption, sdk: WebsiteSdk): Promise<void>;
|
|
520
520
|
//#endregion
|
|
521
521
|
//#region src/booking-snapshot.d.ts
|
|
522
522
|
/** Rental identity, parked by the checkout page (which has it from SSR) and
|
|
523
523
|
* folded into the snapshot at book time — the SDK seam that writes the
|
|
524
524
|
* snapshot never sees a rental name or a link. */
|
|
525
|
-
declare const CHECKOUT_CONTEXT_KEY = "voffice:checkout-context";
|
|
525
|
+
export declare const CHECKOUT_CONTEXT_KEY = "voffice:checkout-context";
|
|
526
526
|
/** The finished record `/buchen/bestaetigung` reads. */
|
|
527
|
-
declare const BOOKING_SNAPSHOT_KEY = "voffice:booking-return";
|
|
527
|
+
export declare const BOOKING_SNAPSHOT_KEY = "voffice:booking-return";
|
|
528
528
|
/** One gallery image, in the SDK's own shape (`RentalGalleryImage` minus the
|
|
529
529
|
* fields this page does not render). Stored so the confirmation can show the
|
|
530
530
|
* unit rather than describe it — the guest booked a place, not a table. */
|
|
531
|
-
interface SnapshotImage {
|
|
531
|
+
export interface SnapshotImage {
|
|
532
532
|
src: string;
|
|
533
533
|
srcset?: string | undefined;
|
|
534
534
|
alt: string;
|
|
535
535
|
}
|
|
536
|
-
interface CheckoutContext {
|
|
536
|
+
export interface CheckoutContext {
|
|
537
537
|
rentalName: string;
|
|
538
538
|
location?: string | undefined;
|
|
539
539
|
href?: string | undefined;
|
|
540
540
|
/** Capped at the same five the checkout's own summary strip shows. */
|
|
541
541
|
images?: SnapshotImage[] | undefined;
|
|
542
542
|
}
|
|
543
|
-
interface BookingSnapshotGuests {
|
|
543
|
+
export interface BookingSnapshotGuests {
|
|
544
544
|
adults: number;
|
|
545
545
|
children: number;
|
|
546
546
|
babies: number;
|
|
@@ -549,7 +549,7 @@ interface BookingSnapshotGuests {
|
|
|
549
549
|
/** Every field but `bookingNumber` self-hides when absent — the return page
|
|
550
550
|
* renders a row only for what it actually has, never an empty shell
|
|
551
551
|
* (`DATA_SCHEMA.md`: "Optional field gates optional UI"). */
|
|
552
|
-
interface BookingSnapshot {
|
|
552
|
+
export interface BookingSnapshot {
|
|
553
553
|
bookingNumber: string;
|
|
554
554
|
rentalName?: string | undefined;
|
|
555
555
|
location?: string | undefined;
|
|
@@ -564,7 +564,7 @@ interface BookingSnapshot {
|
|
|
564
564
|
}
|
|
565
565
|
/** Park the rental's identity for the return page. Called by the checkout page
|
|
566
566
|
* on load — it is the last place in the flow that knows the rental by name. */
|
|
567
|
-
declare function saveCheckoutContext(context: CheckoutContext): void;
|
|
567
|
+
export declare function saveCheckoutContext(context: CheckoutContext): void;
|
|
568
568
|
/**
|
|
569
569
|
* Write the return page's record. Called by `submitBooking` the moment the
|
|
570
570
|
* reservation exists — EARLIER than the SDK's "before submitting a payment
|
|
@@ -573,14 +573,14 @@ declare function saveCheckoutContext(context: CheckoutContext): void;
|
|
|
573
573
|
*
|
|
574
574
|
* Never throws. The snapshot is a nicety; the booking is not.
|
|
575
575
|
*/
|
|
576
|
-
declare function saveBookingSnapshot(bookingNumber: string, quote: GuestQuote): void;
|
|
576
|
+
export declare function saveBookingSnapshot(bookingNumber: string, quote: GuestQuote): void;
|
|
577
577
|
//#endregion
|
|
578
578
|
//#region src/checkout/insurance.d.ts
|
|
579
579
|
/** The plan's documents as the checkout treats them: what it lists, what the
|
|
580
580
|
* guest must open, and what makes a plan sellable at all read the SAME list,
|
|
581
581
|
* so a hidden document can never end up required-but-unlisted (which would be
|
|
582
582
|
* a gate the guest cannot close). */
|
|
583
|
-
declare function shownInsuranceResources(option: QuoteInsuranceOption): {
|
|
583
|
+
export declare function shownInsuranceResources(option: QuoteInsuranceOption): {
|
|
584
584
|
label: string;
|
|
585
585
|
url: string;
|
|
586
586
|
}[];
|
|
@@ -599,10 +599,10 @@ declare function shownInsuranceResources(option: QuoteInsuranceOption): {
|
|
|
599
599
|
* them cannot be concluded lawfully here, so it self-hides rather than
|
|
600
600
|
* being sold undocumented — the same rule as (1), applied to a legal
|
|
601
601
|
* precondition instead of a technical one. */
|
|
602
|
-
declare function selectableInsuranceOptions(insurance: QuoteInsurance): QuoteInsuranceOption[];
|
|
602
|
+
export declare function selectableInsuranceOptions(insurance: QuoteInsurance): QuoteInsuranceOption[];
|
|
603
603
|
/** The selected plan, but only when it is one the guest could actually pick
|
|
604
604
|
* here — so no price row can name a product the section above never showed. */
|
|
605
|
-
declare function selectedInsuranceOption(insurance: QuoteInsurance | undefined): QuoteInsuranceOption | undefined;
|
|
605
|
+
export declare function selectedInsuranceOption(insurance: QuoteInsurance | undefined): QuoteInsuranceOption | undefined;
|
|
606
606
|
/** The identity of an insurance PRODUCT, as opposed to the id of one priced
|
|
607
607
|
* variant of it.
|
|
608
608
|
*
|
|
@@ -617,7 +617,7 @@ declare function selectedInsuranceOption(insurance: QuoteInsurance | undefined):
|
|
|
617
617
|
*
|
|
618
618
|
* The label is what survives that: the same string in every band, and the name
|
|
619
619
|
* the guest actually chose, since it is what the radio shows. */
|
|
620
|
-
declare function insuranceProductKey(option: QuoteInsuranceOption): string;
|
|
620
|
+
export declare function insuranceProductKey(option: QuoteInsuranceOption): string;
|
|
621
621
|
/** The plan id to re-apply onto a re-priced quote, or null when there is
|
|
622
622
|
* nothing to do — no choice, already applied, or a product this feed no longer
|
|
623
623
|
* offers as a selectable one. The last case is why the feed is checked rather
|
|
@@ -640,7 +640,7 @@ declare function insuranceProductKey(option: QuoteInsuranceOption): string;
|
|
|
640
640
|
* the section no longer shows, so re-applying it would leave the quote
|
|
641
641
|
* carrying an insurance the page neither displays nor can take a document
|
|
642
642
|
* confirmation for. */
|
|
643
|
-
declare function insuranceIdToReapply(fresh: QuoteView, wanted: QuoteInsuranceOption | undefined): string | null;
|
|
643
|
+
export declare function insuranceIdToReapply(fresh: QuoteView, wanted: QuoteInsuranceOption | undefined): string | null;
|
|
644
644
|
/** Progress through the document step. Held by the orchestration hook because
|
|
645
645
|
* the submit button, a card away, is gated on it. */
|
|
646
646
|
interface InsuranceDocsState {
|
|
@@ -659,11 +659,11 @@ interface InsuranceDocsState {
|
|
|
659
659
|
* total — would be friction with nothing behind it. */
|
|
660
660
|
confirmedProduct: string | null;
|
|
661
661
|
}
|
|
662
|
-
declare const NO_INSURANCE_DOCS: InsuranceDocsState;
|
|
662
|
+
export declare const NO_INSURANCE_DOCS: InsuranceDocsState;
|
|
663
663
|
/** True while a chosen plan's document step is unfinished. No plan chosen (or
|
|
664
664
|
* "keine Versicherung") is never blocking — the duty attaches to the insurance
|
|
665
665
|
* contract, not to the stay. */
|
|
666
|
-
declare function insuranceDocsPending(option: QuoteInsuranceOption | undefined, docs: InsuranceDocsState): boolean;
|
|
666
|
+
export declare function insuranceDocsPending(option: QuoteInsuranceOption | undefined, docs: InsuranceDocsState): boolean;
|
|
667
667
|
//#endregion
|
|
668
668
|
//#region src/checkout/stay.d.ts
|
|
669
669
|
interface Stay {
|
|
@@ -679,14 +679,14 @@ interface Stay {
|
|
|
679
679
|
* SDK both use. Local on purpose (matches date-fns `format(date,
|
|
680
680
|
* "yyyy-MM-dd")`, which the sites' own lib/dates.ts uses): a calendar day
|
|
681
681
|
* picked in the browser must not shift across midnight UTC. */
|
|
682
|
-
declare function isoDate(date: Date): string;
|
|
683
|
-
declare function occupancyOf(stay: Stay): QuoteOccupancy;
|
|
682
|
+
export declare function isoDate(date: Date): string;
|
|
683
|
+
export declare function occupancyOf(stay: Stay): QuoteOccupancy;
|
|
684
684
|
/** The identity of a stay for "is the shown price still the shown stay"
|
|
685
685
|
* comparisons — every field that changes the quote, in one string. */
|
|
686
|
-
declare function stayKeyOf(stay: Stay): string;
|
|
686
|
+
export declare function stayKeyOf(stay: Stay): string;
|
|
687
687
|
/** The stay as URL search params (`start`/`end`/`adults`/… — the same
|
|
688
688
|
* vocabulary the rental page reads + writes). */
|
|
689
|
-
declare function stayParams(stay: Stay): string;
|
|
689
|
+
export declare function stayParams(stay: Stay): string;
|
|
690
690
|
//#endregion
|
|
691
691
|
//#region src/checkout/createCheckoutFlow.d.ts
|
|
692
692
|
/**
|
|
@@ -836,10 +836,10 @@ interface CheckoutFlow extends Store<CheckoutFlowState>, CheckoutFlowActions {
|
|
|
836
836
|
}
|
|
837
837
|
/** What a UI binding hands to the rendering code: the state plus the actions. */
|
|
838
838
|
type CheckoutFlowApi = CheckoutFlowState & CheckoutFlowActions;
|
|
839
|
-
declare function createCheckoutFlow(initialOptions: CheckoutFlowOptions): CheckoutFlow;
|
|
839
|
+
export declare function createCheckoutFlow(initialOptions: CheckoutFlowOptions): CheckoutFlow;
|
|
840
840
|
//#endregion
|
|
841
841
|
//#region src/checkout/card-order.d.ts
|
|
842
|
-
declare function stabilizeCardOrder(view: QuoteView, order: Map<string, number>): QuoteView;
|
|
842
|
+
export declare function stabilizeCardOrder(view: QuoteView, order: Map<string, number>): QuoteView;
|
|
843
843
|
//#endregion
|
|
844
844
|
//#region src/checkout/validation.d.ts
|
|
845
845
|
/**
|
|
@@ -869,19 +869,19 @@ interface ValidationMessages {
|
|
|
869
869
|
postalcodeInvalidCH: string;
|
|
870
870
|
streetHouseNumberWarning: string;
|
|
871
871
|
}
|
|
872
|
-
declare function normalizePhone(raw: string, dial: string | undefined): string;
|
|
873
|
-
declare function phoneError(raw: string, dial: string | undefined, c: ValidationMessages): string | undefined;
|
|
874
|
-
declare function emailError(raw: string, c: ValidationMessages): string | undefined;
|
|
875
|
-
declare function postalcodeError(raw: string, country: string, c: ValidationMessages): string | undefined;
|
|
876
|
-
declare function streetWarning(raw: string, c: ValidationMessages): string | undefined;
|
|
877
|
-
declare const VALIDATED_FIELDS: readonly ["forename", "surname", "email", "phone", "street", "postalcode", "city"];
|
|
872
|
+
export declare function normalizePhone(raw: string, dial: string | undefined): string;
|
|
873
|
+
export declare function phoneError(raw: string, dial: string | undefined, c: ValidationMessages): string | undefined;
|
|
874
|
+
export declare function emailError(raw: string, c: ValidationMessages): string | undefined;
|
|
875
|
+
export declare function postalcodeError(raw: string, country: string, c: ValidationMessages): string | undefined;
|
|
876
|
+
export declare function streetWarning(raw: string, c: ValidationMessages): string | undefined;
|
|
877
|
+
export declare const VALIDATED_FIELDS: readonly ["forename", "surname", "email", "phone", "street", "postalcode", "city"];
|
|
878
878
|
/** Validate one named field. Takes the selected COUNTRY plus its calling code
|
|
879
879
|
* (`dial`, undefined when the register has none for it): two validators depend
|
|
880
880
|
* on the country — the phone via the dial code, the PLZ via its format rule.
|
|
881
881
|
* The dial code is passed in rather than looked up because the ISO→dial
|
|
882
882
|
* mapping lives with the site's country register (its localized "Land"
|
|
883
883
|
* options), not here. */
|
|
884
|
-
declare function fieldError(name: string, value: string, country: string, dial: string | undefined, c: ValidationMessages): string | undefined;
|
|
884
|
+
export declare function fieldError(name: string, value: string, country: string, dial: string | undefined, c: ValidationMessages): string | undefined;
|
|
885
885
|
/** Country options in the shape the site's country register provides —
|
|
886
886
|
* `[code, label]` pairs, a featured group plus the full ISO register. Kept
|
|
887
887
|
* structural so the site's own `CountryGroups` type satisfies it. */
|
|
@@ -889,7 +889,7 @@ interface CountryGroupsLike {
|
|
|
889
889
|
featured: ReadonlyArray<readonly [string, string]>;
|
|
890
890
|
all: ReadonlyArray<readonly [string, string]>;
|
|
891
891
|
}
|
|
892
|
-
declare function detectCountry(countries: CountryGroupsLike): string;
|
|
892
|
+
export declare function detectCountry(countries: CountryGroupsLike): string;
|
|
893
893
|
//#endregion
|
|
894
894
|
//#region src/checkout/structure.d.ts
|
|
895
895
|
/**
|
|
@@ -901,20 +901,22 @@ declare function detectCountry(countries: CountryGroupsLike): string;
|
|
|
901
901
|
* checkout UI can silently drop a legal obligation — the § 312j BGB
|
|
902
902
|
* Button-Lösung wording, the insurance documents listed before the guest's
|
|
903
903
|
* confirmation, the price stated directly above the order button — and every
|
|
904
|
-
* unit test still passes. This module is a contract over the RENDERED result
|
|
905
|
-
*
|
|
906
|
-
*
|
|
904
|
+
* unit test still passes. This module is a contract over the RENDERED result.
|
|
905
|
+
* The imported `Booking` component satisfies it by construction; a site's own
|
|
906
|
+
* checkout is a developer's review item when it changes. The platform does
|
|
907
|
+
* NOT run this assertion at publish time (decided 2026-09-11,
|
|
908
|
+
* docs/website-platform/process/10-dist-checks.md "Custom checkouts").
|
|
907
909
|
*
|
|
908
910
|
* Two halves:
|
|
909
911
|
* - `CHECKOUT_PARTS`: the `data-part` vocabulary. Imported components carry
|
|
910
|
-
* these attributes; a site's own markup must keep them so
|
|
911
|
-
* a site's own CSS) can find the elements.
|
|
912
|
+
* these attributes; a site's own markup must keep them so this check
|
|
913
|
+
* (and a site's own CSS) can find the elements.
|
|
912
914
|
* - `CHECKOUT_STRUCTURE` + `assertCheckoutStructure(root)`: the requirements
|
|
913
|
-
* and a pure DOM check
|
|
914
|
-
*
|
|
915
|
+
* and a pure DOM check over a rendered checkout (a browser page or a
|
|
916
|
+
* jsdom document in a test). Every requirement names the legal
|
|
915
917
|
* basis it exists for, so a failure message tells the reader WHY.
|
|
916
918
|
*/
|
|
917
|
-
declare const CHECKOUT_PARTS: {
|
|
919
|
+
export declare const CHECKOUT_PARTS: {
|
|
918
920
|
/** The one place the guest is told the price they are about to owe. */
|
|
919
921
|
readonly priceTotal: "checkout-price-total";
|
|
920
922
|
/** The § 312j order button. */
|
|
@@ -930,8 +932,8 @@ type CheckoutPart = (typeof CHECKOUT_PARTS)[keyof typeof CHECKOUT_PARTS];
|
|
|
930
932
|
/** German "kostenpflichtig bestellen"-class labels the courts have accepted
|
|
931
933
|
* for § 312j Abs. 3 BGB. The check is on the RENDERED button text, so a site
|
|
932
934
|
* may re-voice the label — but only within this class. */
|
|
933
|
-
declare const BUTTON_SOLUTION_PATTERN: RegExp;
|
|
934
|
-
declare const CHECKOUT_STRUCTURE: {
|
|
935
|
+
export declare const BUTTON_SOLUTION_PATTERN: RegExp;
|
|
936
|
+
export declare const CHECKOUT_STRUCTURE: {
|
|
935
937
|
readonly "submit-present": {
|
|
936
938
|
readonly basis: "§ 312j Abs. 3 BGB (Button-Lösung)";
|
|
937
939
|
readonly description: "exactly one order button carries data-part=checkout-submit";
|
|
@@ -959,20 +961,20 @@ interface StructureViolation {
|
|
|
959
961
|
basis: string;
|
|
960
962
|
detail: string;
|
|
961
963
|
}
|
|
962
|
-
declare function assertCheckoutStructure(root: ParentNode): StructureViolation[];
|
|
964
|
+
export declare function assertCheckoutStructure(root: ParentNode): StructureViolation[];
|
|
963
965
|
//#endregion
|
|
964
966
|
//#region src/dates.d.ts
|
|
965
|
-
declare function parseParam(value: string | null | undefined): Date | undefined;
|
|
966
|
-
declare function parseGermanParam(value: string | null | undefined): Date | undefined;
|
|
967
|
+
export declare function parseParam(value: string | null | undefined): Date | undefined;
|
|
968
|
+
export declare function parseGermanParam(value: string | null | undefined): Date | undefined;
|
|
967
969
|
/** A flexible-length stay ("3–5 Nächte") as the URL carries it. Off until the
|
|
968
970
|
* search UI offers it; the keys are reserved so a site can enable it. */
|
|
969
|
-
declare const NIGHT_RANGE_ENABLED = false;
|
|
970
|
-
interface NightRange {
|
|
971
|
+
export declare const NIGHT_RANGE_ENABLED = false;
|
|
972
|
+
export interface NightRange {
|
|
971
973
|
min: number;
|
|
972
974
|
max: number;
|
|
973
975
|
}
|
|
974
|
-
declare const NIGHT_RANGE_KEYS: readonly ["minNights", "maxNights", "nights_min", "nights_max"];
|
|
975
|
-
declare function parseNightRange(params: URLSearchParams): NightRange | null;
|
|
976
|
+
export declare const NIGHT_RANGE_KEYS: readonly ["minNights", "maxNights", "nights_min", "nights_max"];
|
|
977
|
+
export declare function parseNightRange(params: URLSearchParams): NightRange | null;
|
|
976
978
|
//#endregion
|
|
977
979
|
//#region src/format.d.ts
|
|
978
980
|
/**
|
|
@@ -981,7 +983,7 @@ declare function parseNightRange(params: URLSearchParams): NightRange | null;
|
|
|
981
983
|
* when it is the zero-cents group at the end, so real cents ("1.234,50 €") stay.
|
|
982
984
|
* A real value formatted for display, nothing fabricated; other formats pass.
|
|
983
985
|
*/
|
|
984
|
-
declare function tidyPrice(formatted: string): string;
|
|
986
|
+
export declare function tidyPrice(formatted: string): string;
|
|
985
987
|
//#endregion
|
|
986
988
|
//#region src/availability.d.ts
|
|
987
989
|
/**
|
|
@@ -1009,9 +1011,9 @@ declare function tidyPrice(formatted: string): string;
|
|
|
1009
1011
|
* every calendar fed from this map agrees: the widget's picker and the
|
|
1010
1012
|
* checkout's copy, which reads the same shape.
|
|
1011
1013
|
*/
|
|
1012
|
-
declare function nightlyPrice(formatted: string, locale?: Locale): string;
|
|
1014
|
+
export declare function nightlyPrice(formatted: string, locale?: Locale): string;
|
|
1013
1015
|
type VofficeSdk$1 = WebsiteSdk;
|
|
1014
|
-
interface InitialAvailability {
|
|
1016
|
+
export interface InitialAvailability {
|
|
1015
1017
|
/** ISO dates (`YYYY-MM-DD`) the SDK flags as a valid check-in/arrival day. */
|
|
1016
1018
|
canStart: Set<string>;
|
|
1017
1019
|
/** ISO dates the rental is genuinely unbookable on (booked / closed / past the
|
|
@@ -1032,8 +1034,10 @@ interface InitialAvailability {
|
|
|
1032
1034
|
* arbiter of a bookable party), so `minPersons` isn't surfaced here. */
|
|
1033
1035
|
maxPersons: number | null;
|
|
1034
1036
|
maxAdults: number | null;
|
|
1037
|
+
childrenAllowed: boolean | null;
|
|
1038
|
+
maxPets: number | null;
|
|
1035
1039
|
}
|
|
1036
|
-
interface EndAvailability {
|
|
1040
|
+
export interface EndAvailability {
|
|
1037
1041
|
/** ISO dates the SDK flags as a valid check-out/departure for the chosen
|
|
1038
1042
|
* start (min-stay + checkout rules already applied by the SDK). */
|
|
1039
1043
|
canEnd: Set<string>;
|
|
@@ -1049,13 +1053,13 @@ interface EndAvailability {
|
|
|
1049
1053
|
/** Possible check-in days + occupancy caps for `rentalId` across the window.
|
|
1050
1054
|
* The caller's SDK instance is reused so its 30s per-rental cache spans the
|
|
1051
1055
|
* picker's lifetime. */
|
|
1052
|
-
declare function fetchInitialAvailability(sdk: VofficeSdk$1, rentalId: string, calculateFromDate: string, calculateThroughDate: string, locale: Locale): Promise<InitialAvailability>;
|
|
1056
|
+
export declare function fetchInitialAvailability(sdk: VofficeSdk$1, rentalId: string, calculateFromDate: string, calculateThroughDate: string, locale: Locale): Promise<InitialAvailability>;
|
|
1053
1057
|
/** Possible check-out days for a chosen `selectedStartDate`. */
|
|
1054
|
-
declare function fetchEndAvailability(sdk: VofficeSdk$1, rentalId: string, calculateFromDate: string, calculateThroughDate: string, selectedStartDate: string, locale: Locale): Promise<EndAvailability>;
|
|
1058
|
+
export declare function fetchEndAvailability(sdk: VofficeSdk$1, rentalId: string, calculateFromDate: string, calculateThroughDate: string, selectedStartDate: string, locale: Locale): Promise<EndAvailability>;
|
|
1055
1059
|
//#endregion
|
|
1056
1060
|
//#region src/search.d.ts
|
|
1057
1061
|
type VofficeSdk = WebsiteSdk;
|
|
1058
|
-
interface SearchImage {
|
|
1062
|
+
export interface SearchImage {
|
|
1059
1063
|
src: string;
|
|
1060
1064
|
srcset?: string | undefined;
|
|
1061
1065
|
alt: string;
|
|
@@ -1070,7 +1074,7 @@ interface SearchImage {
|
|
|
1070
1074
|
* for the single window it used to render. A window whose dates the feed omits
|
|
1071
1075
|
* has no label and never reaches this list; one the feed does not price shows
|
|
1072
1076
|
* no price rather than a placeholder. */
|
|
1073
|
-
interface AlternativePeriod {
|
|
1077
|
+
export interface AlternativePeriod {
|
|
1074
1078
|
/** „31. Aug - 4. Sep", composed from this window's own start and end. */
|
|
1075
1079
|
label: string;
|
|
1076
1080
|
/** The detail-page link carrying THIS window's dates, so the rental opens on
|
|
@@ -1094,7 +1098,7 @@ interface AlternativePeriod {
|
|
|
1094
1098
|
amount: string | null;
|
|
1095
1099
|
}[];
|
|
1096
1100
|
}
|
|
1097
|
-
interface SearchResultItem {
|
|
1101
|
+
export interface SearchResultItem {
|
|
1098
1102
|
/** PMS id — shared by the result card and its map marker. */
|
|
1099
1103
|
id: string;
|
|
1100
1104
|
/** `nameOrLabel`, verbatim. */
|
|
@@ -1208,7 +1212,7 @@ interface SearchResultItem {
|
|
|
1208
1212
|
lng: number;
|
|
1209
1213
|
} | null;
|
|
1210
1214
|
}
|
|
1211
|
-
interface SearchPayload {
|
|
1215
|
+
export interface SearchPayload {
|
|
1212
1216
|
items: SearchResultItem[];
|
|
1213
1217
|
/** Stay length from the user's start/end query, or null when undated. */
|
|
1214
1218
|
nights: number | null;
|
|
@@ -1220,7 +1224,7 @@ interface SearchPayload {
|
|
|
1220
1224
|
/** `pageInfo.hasNextPage`, verbatim. */
|
|
1221
1225
|
hasNextPage: boolean;
|
|
1222
1226
|
}
|
|
1223
|
-
interface LiveSearchOptions {
|
|
1227
|
+
export interface LiveSearchOptions {
|
|
1224
1228
|
/** Path of the site's rental detail pages, prefixed to every result `href`
|
|
1225
1229
|
* before the slug (e.g. `/de/unterkuenfte`). A trailing slash is tolerated.
|
|
1226
1230
|
* Default: `DEFAULT_RENTALS_PATH`. */
|
|
@@ -1229,7 +1233,7 @@ interface LiveSearchOptions {
|
|
|
1229
1233
|
/** The rental detail pages' path when the caller names none — the site
|
|
1230
1234
|
* starter's German route. A site whose pages live elsewhere (a locale prefix,
|
|
1231
1235
|
* another segment) passes its own `rentalsPath` to `runLiveSearch`. */
|
|
1232
|
-
declare const DEFAULT_RENTALS_PATH = "/unterkuenfte";
|
|
1236
|
+
export declare const DEFAULT_RENTALS_PATH = "/unterkuenfte";
|
|
1233
1237
|
/**
|
|
1234
1238
|
* Run a live search for the given URL query string (e.g.
|
|
1235
1239
|
* `window.location.search`). Builds the SDK query from the picker params,
|
|
@@ -1247,27 +1251,27 @@ declare const DEFAULT_RENTALS_PATH = "/unterkuenfte";
|
|
|
1247
1251
|
* so it arrives as an option the way `SearchBar.action` and `Quote.checkoutPath`
|
|
1248
1252
|
* do; `locale` never implies it. Defaults to `DEFAULT_RENTALS_PATH`.
|
|
1249
1253
|
*/
|
|
1250
|
-
declare function runLiveSearch(sdk: VofficeSdk, searchString: string, locale: Locale, cursor?: string | null, options?: LiveSearchOptions): Promise<SearchPayload>;
|
|
1254
|
+
export declare function runLiveSearch(sdk: VofficeSdk, searchString: string, locale: Locale, cursor?: string | null, options?: LiveSearchOptions): Promise<SearchPayload>;
|
|
1251
1255
|
//#endregion
|
|
1252
1256
|
//#region src/sort.d.ts
|
|
1253
1257
|
/** URL param. A client-side scope like `property`/`region`, NOT an SDK query
|
|
1254
1258
|
* key — it is dropped from the SDK query string in search.ts's DROP_KEYS and
|
|
1255
1259
|
* travels as the separate `sort` input instead. */
|
|
1256
|
-
declare const SORT_PARAM = "sort";
|
|
1257
|
-
type SortValue = "empfohlen" | "preis-auf" | "preis-ab";
|
|
1260
|
+
export declare const SORT_PARAM = "sort";
|
|
1261
|
+
export type SortValue = "empfohlen" | "preis-auf" | "preis-ab";
|
|
1258
1262
|
/** The backend's own order. Emits no `sort` at all, so it is exactly the
|
|
1259
1263
|
* ordering the page has always shown. Typed as the literal (not `SortValue`)
|
|
1260
1264
|
* so `value === DEFAULT_SORT` narrows the rest away for `SDK_SORT`. */
|
|
1261
|
-
declare const DEFAULT_SORT: "empfohlen";
|
|
1262
|
-
interface SortOption {
|
|
1265
|
+
export declare const DEFAULT_SORT: "empfohlen";
|
|
1266
|
+
export interface SortOption {
|
|
1263
1267
|
value: SortValue;
|
|
1264
1268
|
label: string;
|
|
1265
1269
|
/** Needs a period + occupancy, or the SDK rejects it before transport. */
|
|
1266
1270
|
pricedOnly?: boolean;
|
|
1267
1271
|
}
|
|
1268
|
-
declare const SORT_OPTIONS: readonly SortOption[];
|
|
1272
|
+
export declare const SORT_OPTIONS: readonly SortOption[];
|
|
1269
1273
|
/** The sort in the URL, or the default when absent/unknown. */
|
|
1270
|
-
declare function activeSort(search: string): SortValue;
|
|
1274
|
+
export declare function activeSort(search: string): SortValue;
|
|
1271
1275
|
/**
|
|
1272
1276
|
* Can this query be priced? Mirrors the SDK's own precondition: a fixed period
|
|
1273
1277
|
* (`start`+`end`) or a flexible window (`dates`/`month`/`weekend`), AND
|
|
@@ -1279,15 +1283,15 @@ declare function activeSort(search: string): SortValue;
|
|
|
1279
1283
|
* gate and still reach the SDK undated. `weekend` is the exception — it is a
|
|
1280
1284
|
* presence-only flag on both sides.
|
|
1281
1285
|
*/
|
|
1282
|
-
declare function isPricedQuery(search: string): boolean;
|
|
1286
|
+
export declare function isPricedQuery(search: string): boolean;
|
|
1283
1287
|
/** Is this option selectable for the current query? */
|
|
1284
|
-
declare function isSortAvailable(option: SortOption, search: string): boolean;
|
|
1288
|
+
export declare function isSortAvailable(option: SortOption, search: string): boolean;
|
|
1285
1289
|
/**
|
|
1286
1290
|
* The `sort` to hand the SDK for this URL, or `undefined` for the backend's
|
|
1287
1291
|
* own order. Falls back to `undefined` (rather than throwing) when a price
|
|
1288
1292
|
* sort survives in the URL after the dates were cleared.
|
|
1289
1293
|
*/
|
|
1290
|
-
declare function resolveSdkSort(search: string): SearchSearchSort | undefined;
|
|
1294
|
+
export declare function resolveSdkSort(search: string): SearchSearchSort | undefined;
|
|
1291
1295
|
//#endregion
|
|
1292
1296
|
//#region src/filters.d.ts
|
|
1293
1297
|
/**
|
|
@@ -1296,8 +1300,8 @@ declare function resolveSdkSort(search: string): SearchSearchSort | undefined;
|
|
|
1296
1300
|
* into `FilterDef[]` (which keys, in which order) and hands the list to the
|
|
1297
1301
|
* results surface. Boolean filters toggle, integer filters are a lower bound.
|
|
1298
1302
|
*/
|
|
1299
|
-
type FilterType = "boolean" | "int";
|
|
1300
|
-
interface FilterDef {
|
|
1303
|
+
export type FilterType = "boolean" | "int";
|
|
1304
|
+
export interface FilterDef {
|
|
1301
1305
|
/** The URL query key, which is also the SDK's search parameter key. */
|
|
1302
1306
|
key: string;
|
|
1303
1307
|
label: string;
|
|
@@ -1306,23 +1310,23 @@ interface FilterDef {
|
|
|
1306
1310
|
min: number;
|
|
1307
1311
|
max: number;
|
|
1308
1312
|
}
|
|
1309
|
-
interface ActiveFilter {
|
|
1313
|
+
export interface ActiveFilter {
|
|
1310
1314
|
key: string;
|
|
1311
1315
|
label: string;
|
|
1312
1316
|
}
|
|
1313
1317
|
/** A boolean filter is active when its param is present and truthy. */
|
|
1314
|
-
declare const isBooleanFilterActive: (value: string) => boolean;
|
|
1318
|
+
export declare const isBooleanFilterActive: (value: string) => boolean;
|
|
1315
1319
|
/**
|
|
1316
1320
|
* The filters currently applied in the query, in the order the defs are
|
|
1317
1321
|
* declared — the removable chips. An `int` label is prefixed with the localized
|
|
1318
1322
|
* "minimum" wording, because its value is a lower bound.
|
|
1319
1323
|
*/
|
|
1320
|
-
declare function activeFiltersFromQuery(searchParams: URLSearchParams, defs: readonly FilterDef[], minimumPrefix: string): ActiveFilter[];
|
|
1324
|
+
export declare function activeFiltersFromQuery(searchParams: URLSearchParams, defs: readonly FilterDef[], minimumPrefix: string): ActiveFilter[];
|
|
1321
1325
|
/** The dog-friendly search as the URL carries it: `pets=true` (or a count) and,
|
|
1322
1326
|
* from an older vocabulary, `petsCount=N`. Read by the live search. */
|
|
1323
|
-
declare const PETS_PARAM = "pets";
|
|
1324
|
-
declare const PETS_COUNT_PARAM = "petsCount";
|
|
1325
|
-
declare function petsCountInQuery(search: string): number;
|
|
1327
|
+
export declare const PETS_PARAM = "pets";
|
|
1328
|
+
export declare const PETS_COUNT_PARAM = "petsCount";
|
|
1329
|
+
export declare function petsCountInQuery(search: string): number;
|
|
1326
1330
|
//#endregion
|
|
1327
1331
|
//#region src/regions.d.ts
|
|
1328
1332
|
/**
|
|
@@ -1340,18 +1344,18 @@ declare function petsCountInQuery(search: string): number;
|
|
|
1340
1344
|
*/
|
|
1341
1345
|
/** URL query key carrying the active region scope. Repeatable: several
|
|
1342
1346
|
* `region=<name>` values OR together (show rentals in ANY selected region). */
|
|
1343
|
-
declare const REGION_PARAM = "region";
|
|
1347
|
+
export declare const REGION_PARAM = "region";
|
|
1344
1348
|
/** The regions active in a URL query string: the `region` values, trimmed,
|
|
1345
1349
|
* de-duplicated, order preserved. Absent or empty → `[]`. */
|
|
1346
|
-
declare function activeRegions(search: string): string[];
|
|
1350
|
+
export declare function activeRegions(search: string): string[];
|
|
1347
1351
|
/**
|
|
1348
1352
|
* The results inside the region scope. A rental may carry several regions
|
|
1349
1353
|
* (MULTI_SELECT) and matches when any of them is selected; with no active
|
|
1350
1354
|
* region every result stays. A rental the map does not know is outside every
|
|
1351
1355
|
* region, so it drops out of a scoped search rather than passing unseen.
|
|
1352
1356
|
*/
|
|
1353
|
-
declare function scopeToRegions<T extends {
|
|
1357
|
+
export declare function scopeToRegions<T extends {
|
|
1354
1358
|
id: string;
|
|
1355
1359
|
}>(items: readonly T[], active: readonly string[], regionsByRentalId: (id: string) => readonly string[] | undefined): T[];
|
|
1356
1360
|
//#endregion
|
|
1357
|
-
export {
|
|
1361
|
+
export type { CheckoutFlow, CheckoutFlowActions, CheckoutFlowApi, CheckoutFlowMessages, CheckoutFlowOptions, CheckoutFlowState, CheckoutIssue, CheckoutPart, CheckoutPhase, CountryGroupsLike, InsuranceDocsState, Locale, Stay, StructureViolation, ValidationMessages };
|
package/dist/index.mjs
CHANGED
|
@@ -1384,17 +1384,19 @@ function detectCountry(countries) {
|
|
|
1384
1384
|
* checkout UI can silently drop a legal obligation — the § 312j BGB
|
|
1385
1385
|
* Button-Lösung wording, the insurance documents listed before the guest's
|
|
1386
1386
|
* confirmation, the price stated directly above the order button — and every
|
|
1387
|
-
* unit test still passes. This module is a contract over the RENDERED result
|
|
1388
|
-
*
|
|
1389
|
-
*
|
|
1387
|
+
* unit test still passes. This module is a contract over the RENDERED result.
|
|
1388
|
+
* The imported `Booking` component satisfies it by construction; a site's own
|
|
1389
|
+
* checkout is a developer's review item when it changes. The platform does
|
|
1390
|
+
* NOT run this assertion at publish time (decided 2026-09-11,
|
|
1391
|
+
* docs/website-platform/process/10-dist-checks.md "Custom checkouts").
|
|
1390
1392
|
*
|
|
1391
1393
|
* Two halves:
|
|
1392
1394
|
* - `CHECKOUT_PARTS`: the `data-part` vocabulary. Imported components carry
|
|
1393
|
-
* these attributes; a site's own markup must keep them so
|
|
1394
|
-
* a site's own CSS) can find the elements.
|
|
1395
|
+
* these attributes; a site's own markup must keep them so this check
|
|
1396
|
+
* (and a site's own CSS) can find the elements.
|
|
1395
1397
|
* - `CHECKOUT_STRUCTURE` + `assertCheckoutStructure(root)`: the requirements
|
|
1396
|
-
* and a pure DOM check
|
|
1397
|
-
*
|
|
1398
|
+
* and a pure DOM check over a rendered checkout (a browser page or a
|
|
1399
|
+
* jsdom document in a test). Every requirement names the legal
|
|
1398
1400
|
* basis it exists for, so a failure message tells the reader WHY.
|
|
1399
1401
|
*/
|
|
1400
1402
|
const CHECKOUT_PARTS = {
|
|
@@ -1442,8 +1444,8 @@ function precedes(a, b) {
|
|
|
1442
1444
|
return (a.compareDocumentPosition(b) & 4) === 4;
|
|
1443
1445
|
}
|
|
1444
1446
|
/**
|
|
1445
|
-
* Check a rendered checkout. `root` is `document` in
|
|
1446
|
-
*
|
|
1447
|
+
* Check a rendered checkout. `root` is `document` in a browser page, or a
|
|
1448
|
+
* jsdom document in tests. Returns every violation found (empty =
|
|
1447
1449
|
* compliant). The insurance rule is conditional on purpose: the duty attaches
|
|
1448
1450
|
* to concluding an insurance contract, so a checkout that renders no
|
|
1449
1451
|
* confirmation control has nothing to gate.
|
|
@@ -1451,7 +1453,7 @@ function precedes(a, b) {
|
|
|
1451
1453
|
/** The text a sighted guest sees: descendants hidden by the `hidden` attribute,
|
|
1452
1454
|
* `aria-hidden` or an inline display/visibility rule are excluded, so a legal
|
|
1453
1455
|
* phrase in a hidden span cannot satisfy the wording rule. Stylesheet-based
|
|
1454
|
-
* hiding needs layout and
|
|
1456
|
+
* hiding needs layout and only a browser run can catch it. */
|
|
1455
1457
|
function visibleText(el) {
|
|
1456
1458
|
let text = "";
|
|
1457
1459
|
for (const node of el.childNodes) if (node.nodeType === 3) text += node.textContent ?? "";
|
|
@@ -1598,7 +1600,9 @@ async function fetchInitialAvailability(sdk, rentalId, calculateFromDate, calcul
|
|
|
1598
1600
|
priceByDay,
|
|
1599
1601
|
tooltipByDay,
|
|
1600
1602
|
maxPersons: out.maxPersons ?? null,
|
|
1601
|
-
maxAdults: out.maxAdults ?? null
|
|
1603
|
+
maxAdults: out.maxAdults ?? null,
|
|
1604
|
+
childrenAllowed: out.childrenAllowed ?? null,
|
|
1605
|
+
maxPets: out.maxPets ?? null
|
|
1602
1606
|
};
|
|
1603
1607
|
}
|
|
1604
1608
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
<!-- generated by `node .github/release/cli.mts index`; do not edit by hand -->
|
|
4
|
+
|
|
5
|
+
Release notes of `@v-office/website-headless`, newest first. Each version has its own directory.
|
|
6
|
+
|
|
7
|
+
- `versions/0.2.0/CHANGELOG.md`: release notes for 0.2.0
|
|
8
|
+
- `versions/0.1.1/CHANGELOG.md`: release notes for 0.1.1
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Migration
|
|
2
|
+
|
|
3
|
+
<!-- generated by `node .github/release/cli.mts index`; do not edit by hand -->
|
|
4
|
+
|
|
5
|
+
Migration guides of `@v-office/website-headless`, newest first. Apply them in order when skipping versions.
|
|
6
|
+
|
|
7
|
+
- `versions/0.2.0/MIGRATION.md`: Migration: 0.1.1 to 0.2.0
|
|
8
|
+
- `versions/0.1.1/MIGRATION.md`: Migration to 0.1.1
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Changelog: 0.1.1
|
|
2
|
+
|
|
3
|
+
Baseline of the shipped release notes for `@v-office/website-headless`. The package is the framework-free behavior layer of the website platform: the checkout flow as a store, validation and insurance rules, the checkout's structural requirements and the progressive-enhancement engines.
|
|
4
|
+
|
|
5
|
+
Changes before 0.1.1 are recorded in this repository's git history only. From
|
|
6
|
+
this version on, every release carries its own `CHANGELOG.md` and
|
|
7
|
+
`MIGRATION.md` in `instructions/versions/<version>/`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog: 0.2.0
|
|
2
|
+
|
|
3
|
+
The initial availability of the booking date picker now carries the v9 rules for children and
|
|
4
|
+
pets, so a guest selector can stop offering a party the quote would refuse.
|
|
5
|
+
|
|
6
|
+
## Added
|
|
7
|
+
|
|
8
|
+
- `fetchInitialAvailability` returns `childrenAllowed` and `maxPets` in its
|
|
9
|
+
`InitialAvailability`. On v9 with `@v-office/website-sdk` 2.28.0 or later,
|
|
10
|
+
`childrenAllowed` is `false` when the rental takes no children, babies included, and
|
|
11
|
+
`maxPets` is the most pets the quote accepts, `0` for none. Both are `null` on v10, with an
|
|
12
|
+
older SDK and when the rental states no rule; `null` means no limit.
|
|
13
|
+
|
|
14
|
+
## Unchanged
|
|
15
|
+
|
|
16
|
+
- `maxPersons` and `maxAdults` keep their meaning. On v9 they carry the rental's limits from
|
|
17
|
+
`@v-office/website-sdk` 2.28.0 on, where they were `null` before.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Migration: 0.1.1 to 0.2.0
|
|
2
|
+
|
|
3
|
+
## 1. Upgrade
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
pnpm add @v-office/website-headless@0.2.0
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
No changes are required for code that reads `fetchInitialAvailability`. Code that builds an
|
|
10
|
+
`InitialAvailability` itself, such as a test fixture, adds `childrenAllowed: null` and
|
|
11
|
+
`maxPets: null`.
|
|
12
|
+
|
|
13
|
+
A site with its own guest selector can use the two fields: offer neither children nor babies
|
|
14
|
+
when `childrenAllowed` is `false`, and cap pets at `maxPets`, hiding them at `0`. Keep a
|
|
15
|
+
selection the guest arrived with visible until they remove it, so a party the quote refuses
|
|
16
|
+
can still be corrected.
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-office/website-headless",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
7
|
-
"README.md"
|
|
7
|
+
"README.md",
|
|
8
|
+
"instructions"
|
|
8
9
|
],
|
|
9
10
|
"type": "module",
|
|
10
11
|
"sideEffects": false,
|
|
@@ -18,14 +19,14 @@
|
|
|
18
19
|
"access": "public"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@types/node": "26.1
|
|
22
|
-
"@v-office/website-sdk": "2.
|
|
22
|
+
"@types/node": "26.5.1",
|
|
23
|
+
"@v-office/website-sdk": "2.28.0",
|
|
23
24
|
"jsdom": "^30.0.1",
|
|
24
|
-
"oxfmt": "0.
|
|
25
|
-
"oxlint": "1.
|
|
26
|
-
"tsdown": "0.
|
|
25
|
+
"oxfmt": "0.67.0",
|
|
26
|
+
"oxlint": "1.82.0",
|
|
27
|
+
"tsdown": "0.23.0",
|
|
27
28
|
"typescript": "7.0.2",
|
|
28
|
-
"vitest": "^
|
|
29
|
+
"vitest": "^5.0.0"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
31
32
|
"@v-office/website-sdk": ">=2.13.0 <3"
|
|
@@ -42,6 +43,6 @@
|
|
|
42
43
|
"fmt": "oxfmt",
|
|
43
44
|
"fmt:check": "oxfmt --check",
|
|
44
45
|
"check": "pnpm run typecheck && pnpm run lint && pnpm run fmt:check",
|
|
45
|
-
"test": "vitest run"
|
|
46
|
+
"test": "vitest run && node --test test/dist.node.mjs"
|
|
46
47
|
}
|
|
47
48
|
}
|