@voyantjs/storefront 0.74.1 → 0.75.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 CHANGED
@@ -78,6 +78,37 @@ Accepted intake emits `customer.signal.created` on the app event bus with
78
78
  signal came from `lead` or `newsletter` intake. Notification adapters can
79
79
  subscribe to that event to send CRM email, Slack, or other operator alerts.
80
80
 
81
+ ## Guest Booking Lookup
82
+
83
+ Use the bookings public guest lookup endpoint before rendering booking overview
84
+ or payment pages for guests:
85
+
86
+ - `POST /v1/public/bookings/guest-lookup` with `bookingCode` and `email`
87
+ - `GET /v1/public/bookings/overview?bookingCode=...` with the issued guest
88
+ access cookie or `X-Voyant-Guest-Booking-Access` header
89
+
90
+ The lookup endpoint verifies the email against booking participants, issues a
91
+ short-lived `voyant_guest_booking` HttpOnly cookie, and returns the same scoped
92
+ token for non-browser clients. When `RATE_LIMIT` KV is bound, lookups are
93
+ throttled per client IP and booking code.
94
+
95
+ ```ts
96
+ import { createGuestBookingGuard } from "@voyantjs/storefront"
97
+
98
+ const guestBooking = createGuestBookingGuard()
99
+
100
+ if (!guestBooking.hasAccess(request)) {
101
+ return fetch(guestBooking.lookupPath, guestBooking.createLookupRequest({
102
+ bookingCode: form.bookingCode,
103
+ email: form.email,
104
+ }))
105
+ }
106
+
107
+ return fetch(guestBooking.overviewUrl(form.bookingCode), {
108
+ headers: { Cookie: request.headers.get("Cookie") ?? "" },
109
+ })
110
+ ```
111
+
81
112
  ## Transport Eligibility
82
113
 
83
114
  Storefronts can check whether traveler document facts satisfy departure-level
@@ -0,0 +1,24 @@
1
+ export interface GuestBookingGuardRequest {
2
+ headers: Headers | Record<string, string | undefined>;
3
+ }
4
+ export interface GuestBookingLookupInput {
5
+ bookingCode: string;
6
+ email: string;
7
+ }
8
+ export interface GuestBookingGuardOptions {
9
+ cookieName?: string;
10
+ headerName?: string;
11
+ lookupPath?: string;
12
+ overviewPath?: string;
13
+ }
14
+ export declare function createGuestBookingGuard(options?: GuestBookingGuardOptions): {
15
+ cookieName: string;
16
+ headerName: string;
17
+ lookupPath: string;
18
+ overviewPath: string;
19
+ getAccessToken: (request: GuestBookingGuardRequest) => any;
20
+ hasAccess(request: GuestBookingGuardRequest): boolean;
21
+ createLookupRequest(input: GuestBookingLookupInput): RequestInit;
22
+ overviewUrl(bookingCode: string, baseUrl?: string | URL): string;
23
+ };
24
+ //# sourceMappingURL=guest-booking-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guest-booking-guard.d.ts","sourceRoot":"","sources":["../src/guest-booking-guard.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CACtD;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AA4BD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,wBAA6B;;;;;8BAM3C,wBAAwB;uBAapC,wBAAwB;+BAGhB,uBAAuB,GAAG,WAAW;6BAOvC,MAAM,YAAY,MAAM,GAAG,GAAG;EAM1D"}
@@ -0,0 +1,55 @@
1
+ import { GUEST_BOOKING_ACCESS_COOKIE, GUEST_BOOKING_ACCESS_HEADER, } from "@voyantjs/bookings/checkout-capability";
2
+ function headerValue(headers, name) {
3
+ if (typeof Headers !== "undefined" && headers instanceof Headers) {
4
+ return headers.get(name);
5
+ }
6
+ const lowerName = name.toLowerCase();
7
+ for (const [key, value] of Object.entries(headers)) {
8
+ if (key.toLowerCase() === lowerName)
9
+ return value ?? null;
10
+ }
11
+ return null;
12
+ }
13
+ function cookieValue(cookieHeader, cookieName) {
14
+ if (!cookieHeader)
15
+ return null;
16
+ for (const part of cookieHeader.split(";")) {
17
+ const [rawName, ...rawValueParts] = part.trim().split("=");
18
+ if (rawName === cookieName) {
19
+ return decodeURIComponent(rawValueParts.join("="));
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+ export function createGuestBookingGuard(options = {}) {
25
+ const cookieName = options.cookieName ?? GUEST_BOOKING_ACCESS_COOKIE;
26
+ const headerName = options.headerName ?? GUEST_BOOKING_ACCESS_HEADER;
27
+ const lookupPath = options.lookupPath ?? "/v1/public/bookings/guest-lookup";
28
+ const overviewPath = options.overviewPath ?? "/v1/public/bookings/overview";
29
+ function getAccessToken(request) {
30
+ return (headerValue(request.headers, headerName) ??
31
+ cookieValue(headerValue(request.headers, "Cookie"), cookieName));
32
+ }
33
+ return {
34
+ cookieName,
35
+ headerName,
36
+ lookupPath,
37
+ overviewPath,
38
+ getAccessToken,
39
+ hasAccess(request) {
40
+ return Boolean(getAccessToken(request));
41
+ },
42
+ createLookupRequest(input) {
43
+ return {
44
+ method: "POST",
45
+ headers: { "Content-Type": "application/json" },
46
+ body: JSON.stringify(input),
47
+ };
48
+ },
49
+ overviewUrl(bookingCode, baseUrl) {
50
+ const url = new URL(overviewPath, baseUrl ?? "https://voyant.local");
51
+ url.searchParams.set("bookingCode", bookingCode);
52
+ return baseUrl ? url.toString() : `${url.pathname}${url.search}`;
53
+ },
54
+ };
55
+ }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { Module } from "@voyantjs/core";
2
2
  import type { HonoModule } from "@voyantjs/hono/module";
3
3
  import { createStorefrontPublicRoutes } from "./routes-public.js";
4
+ export type { GuestBookingGuardOptions, GuestBookingGuardRequest, GuestBookingLookupInput, } from "./guest-booking-guard.js";
5
+ export { createGuestBookingGuard } from "./guest-booking-guard.js";
4
6
  export type { StorefrontAdminRoutes } from "./routes-admin.js";
5
7
  export { createStorefrontAdminRoutes } from "./routes-admin.js";
6
8
  export type { StorefrontPublicRoutes } from "./routes-public.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createStorefrontAdminRoutes } from "./routes-admin.js";
2
2
  import { createStorefrontPublicRoutes } from "./routes-public.js";
3
+ export { createGuestBookingGuard } from "./guest-booking-guard.js";
3
4
  export { createStorefrontAdminRoutes } from "./routes-admin.js";
4
5
  export { createStorefrontPublicRoutes } from "./routes-public.js";
5
6
  export { createStorefrontService, mergeStorefrontSettingsPatch, resolveStorefrontSettings, } from "./service.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/storefront",
3
- "version": "0.74.1",
3
+ "version": "0.75.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -39,21 +39,21 @@
39
39
  "drizzle-orm": "^0.45.2",
40
40
  "hono": "^4.12.10",
41
41
  "zod": "^4.3.6",
42
- "@voyantjs/availability": "0.74.1",
43
- "@voyantjs/crm": "0.74.1",
44
- "@voyantjs/core": "0.74.1",
45
- "@voyantjs/extras": "0.74.1",
46
- "@voyantjs/bookings": "0.74.1",
47
- "@voyantjs/finance": "0.74.1",
48
- "@voyantjs/hono": "0.74.1",
49
- "@voyantjs/pricing": "0.74.1",
50
- "@voyantjs/sellability": "0.74.1",
51
- "@voyantjs/products": "0.74.1"
42
+ "@voyantjs/availability": "0.75.0",
43
+ "@voyantjs/core": "0.75.0",
44
+ "@voyantjs/bookings": "0.75.0",
45
+ "@voyantjs/crm": "0.75.0",
46
+ "@voyantjs/extras": "0.75.0",
47
+ "@voyantjs/finance": "0.75.0",
48
+ "@voyantjs/hono": "0.75.0",
49
+ "@voyantjs/pricing": "0.75.0",
50
+ "@voyantjs/products": "0.75.0",
51
+ "@voyantjs/sellability": "0.75.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "typescript": "^6.0.2",
55
55
  "vitest": "^4.1.2",
56
- "@voyantjs/db": "0.74.1",
56
+ "@voyantjs/db": "0.75.0",
57
57
  "@voyantjs/voyant-typescript-config": "0.1.0"
58
58
  },
59
59
  "files": [