@voyantjs/storefront 0.46.0 → 0.49.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
@@ -3,6 +3,45 @@
3
3
  Public storefront routes and service helpers for checkout-adjacent product, departure,
4
4
  offer, and eligibility flows.
5
5
 
6
+ ## Public Intake
7
+
8
+ Storefront can accept public CRM intake at the public root:
9
+
10
+ - `POST /leads`
11
+ - `POST /newsletter/subscribe`
12
+
13
+ When mounted through `createStorefrontHonoModule`, these become
14
+ `/v1/public/leads` and `/v1/public/newsletter/subscribe`.
15
+
16
+ Both routes create a CRM person and a CRM customer signal. Lead intake accepts
17
+ the CRM signal `kind`, `source`, product/option references, bounded payload
18
+ metadata, and consent metadata. Newsletter intake records a `notify` signal and
19
+ uses `sourceSubmissionId` for idempotency; when omitted, the email address is
20
+ used to derive a stable newsletter submission key.
21
+
22
+ ```ts
23
+ import { createStorefrontHonoModule } from "@voyantjs/storefront"
24
+
25
+ createStorefrontHonoModule({
26
+ intake: {
27
+ guard({ body, context }) {
28
+ // Install host-owned rate-limit, captcha, signature, or abuse checks.
29
+ if (!isCaptchaValid(body, context)) {
30
+ return { allowed: false, status: 429, error: "Captcha required" }
31
+ }
32
+ },
33
+ async requestNewsletterDoubleOptIn({ email, signalId }) {
34
+ await sendDoubleOptInEmail(email, { signalId })
35
+ },
36
+ },
37
+ })
38
+ ```
39
+
40
+ Accepted intake emits `customer.signal.created` on the app event bus with
41
+ `metadata.category: "domain"` and an `intake` payload describing whether the
42
+ signal came from `lead` or `newsletter` intake. Notification adapters can
43
+ subscribe to that event to send CRM email, Slack, or other operator alerts.
44
+
6
45
  ## Transport Eligibility
7
46
 
8
47
  Storefronts can check whether traveler document facts satisfy departure-level
package/dist/index.d.ts CHANGED
@@ -5,9 +5,11 @@ export type { StorefrontPublicRoutes } from "./routes-public.js";
5
5
  export { createStorefrontPublicRoutes } from "./routes-public.js";
6
6
  export type { StorefrontOfferResolvers, StorefrontRequestContext, StorefrontServiceOptions, } from "./service.js";
7
7
  export { createStorefrontService, resolveStorefrontSettings } from "./service.js";
8
+ export type { StorefrontIntakeGuard, StorefrontIntakeGuardDecision, StorefrontIntakeOptions, StorefrontNewsletterDoubleOptInHook, } from "./service-intake.js";
9
+ export { CUSTOMER_SIGNAL_CREATED_EVENT } from "./service-intake.js";
8
10
  export { evaluateStorefrontTransportEligibility } from "./service-transport-eligibility.js";
9
- export type { StorefrontAppliedOffer, StorefrontDepartureListQuery, StorefrontFormField, StorefrontFormFieldInput, StorefrontOfferApplyInput, StorefrontOfferMutationResult, StorefrontOfferRedeemInput, StorefrontPaymentMethod, StorefrontPaymentMethodCode, StorefrontPaymentMethodInput, StorefrontProductAvailabilitySummaryQuery, StorefrontPromotionalOffer, StorefrontSettings, StorefrontSettingsInput, } from "./validation.js";
10
- export { storefrontAppliedOfferSchema, storefrontDepartureItinerarySchema, storefrontDepartureListQuerySchema, storefrontDepartureListResponseSchema, storefrontDeparturePricePreviewInputSchema, storefrontDeparturePricePreviewSchema, storefrontDepartureSchema, storefrontFormFieldInputSchema, storefrontFormFieldOptionSchema, storefrontFormFieldSchema, storefrontFormFieldTypeSchema, storefrontOfferApplyInputSchema, storefrontOfferAudienceSchema, storefrontOfferConflictSchema, storefrontOfferMutationReasonSchema, storefrontOfferMutationResponseSchema, storefrontOfferMutationResultSchema, storefrontOfferMutationStatusSchema, storefrontOfferRedeemInputSchema, storefrontPaymentMethodCodeSchema, storefrontPaymentMethodInputSchema, storefrontPaymentMethodSchema, storefrontProductAvailabilitySlotSchema, storefrontProductAvailabilityStateSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductAvailabilitySummaryResponseSchema, storefrontProductAvailabilitySummarySchema, storefrontProductExtensionsQuerySchema, storefrontProductExtensionsResponseSchema, storefrontPromotionalOfferListQuerySchema, storefrontPromotionalOfferListResponseSchema, storefrontPromotionalOfferResponseSchema, storefrontPromotionalOfferSchema, storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
11
+ export type { StorefrontAppliedOffer, StorefrontDepartureListQuery, StorefrontFormField, StorefrontFormFieldInput, StorefrontIntakeConsent, StorefrontIntakeResponse, StorefrontLeadContact, StorefrontLeadIntakeInput, StorefrontNewsletterSubscribeInput, StorefrontNewsletterSubscribeResponse, StorefrontOfferApplyInput, StorefrontOfferMutationResult, StorefrontOfferRedeemInput, StorefrontPaymentMethod, StorefrontPaymentMethodCode, StorefrontPaymentMethodInput, StorefrontProductAvailabilitySummaryQuery, StorefrontPromotionalOffer, StorefrontSettings, StorefrontSettingsInput, } from "./validation.js";
12
+ export { storefrontAppliedOfferSchema, storefrontDepartureItinerarySchema, storefrontDepartureListQuerySchema, storefrontDepartureListResponseSchema, storefrontDeparturePricePreviewInputSchema, storefrontDeparturePricePreviewSchema, storefrontDepartureSchema, storefrontFormFieldInputSchema, storefrontFormFieldOptionSchema, storefrontFormFieldSchema, storefrontFormFieldTypeSchema, storefrontIntakeConsentSchema, storefrontIntakeResponseSchema, storefrontLeadContactSchema, storefrontLeadIntakeInputSchema, storefrontNewsletterSubscribeInputSchema, storefrontNewsletterSubscribeResponseSchema, storefrontOfferApplyInputSchema, storefrontOfferAudienceSchema, storefrontOfferConflictSchema, storefrontOfferMutationReasonSchema, storefrontOfferMutationResponseSchema, storefrontOfferMutationResultSchema, storefrontOfferMutationStatusSchema, storefrontOfferRedeemInputSchema, storefrontPaymentMethodCodeSchema, storefrontPaymentMethodInputSchema, storefrontPaymentMethodSchema, storefrontProductAvailabilitySlotSchema, storefrontProductAvailabilityStateSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductAvailabilitySummaryResponseSchema, storefrontProductAvailabilitySummarySchema, storefrontProductExtensionsQuerySchema, storefrontProductExtensionsResponseSchema, storefrontPromotionalOfferListQuerySchema, storefrontPromotionalOfferListResponseSchema, storefrontPromotionalOfferResponseSchema, storefrontPromotionalOfferSchema, storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
11
13
  export type { StorefrontTransportEligibilityInput, StorefrontTransportEligibilityIssue, StorefrontTransportEligibilityResult, StorefrontTransportEligibilityRule, StorefrontTransportEligibilityRuleInput, } from "./validation-transport-eligibility.js";
12
14
  export { storefrontRequiredDocumentTypeSchema, storefrontTransportEligibilityDocumentInputSchema, storefrontTransportEligibilityInputSchema, storefrontTransportEligibilityIssueCodeSchema, storefrontTransportEligibilityIssueSchema, storefrontTransportEligibilityResultSchema, storefrontTransportEligibilityRuleSchema, storefrontTransportEligibilitySeveritySchema, storefrontTransportEligibilityTravelerInputSchema, storefrontTransportEligibilityTravelerResultSchema, storefrontTravelDocumentTypeSchema, } from "./validation-transport-eligibility.js";
13
15
  export declare const storefrontModule: Module;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AAEjE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AACjE,YAAY,EACV,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACjF,OAAO,EAAE,sCAAsC,EAAE,MAAM,oCAAoC,CAAA;AAC3F,YAAY,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,2BAA2B,EAC3B,4BAA4B,EAC5B,yCAAyC,EACzC,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,qCAAqC,EACrC,0CAA0C,EAC1C,qCAAqC,EACrC,yBAAyB,EACzB,8BAA8B,EAC9B,+BAA+B,EAC/B,yBAAyB,EACzB,6BAA6B,EAC7B,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,mCAAmC,EACnC,qCAAqC,EACrC,mCAAmC,EACnC,mCAAmC,EACnC,gCAAgC,EAChC,iCAAiC,EACjC,kCAAkC,EAClC,6BAA6B,EAC7B,uCAAuC,EACvC,wCAAwC,EACxC,+CAA+C,EAC/C,kDAAkD,EAClD,0CAA0C,EAC1C,sCAAsC,EACtC,yCAAyC,EACzC,yCAAyC,EACzC,4CAA4C,EAC5C,wCAAwC,EACxC,gCAAgC,EAChC,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,mCAAmC,EACnC,mCAAmC,EACnC,oCAAoC,EACpC,kCAAkC,EAClC,uCAAuC,GACxC,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EACL,oCAAoC,EACpC,iDAAiD,EACjD,yCAAyC,EACzC,6CAA6C,EAC7C,yCAAyC,EACzC,0CAA0C,EAC1C,wCAAwC,EACxC,4CAA4C,EAC5C,iDAAiD,EACjD,kDAAkD,EAClD,kCAAkC,GACnC,MAAM,uCAAuC,CAAA;AAE9C,eAAO,MAAM,gBAAgB,EAAE,MAE9B,CAAA;AAED,wBAAgB,0BAA0B,CACxC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAAC,CAAC,GAC3D,UAAU,CAMZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AAEjE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AACjE,YAAY,EACV,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACjF,YAAY,EACV,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,mCAAmC,GACpC,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAA;AACnE,OAAO,EAAE,sCAAsC,EAAE,MAAM,oCAAoC,CAAA;AAC3F,YAAY,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,kCAAkC,EAClC,qCAAqC,EACrC,yBAAyB,EACzB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,2BAA2B,EAC3B,4BAA4B,EAC5B,yCAAyC,EACzC,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,qCAAqC,EACrC,0CAA0C,EAC1C,qCAAqC,EACrC,yBAAyB,EACzB,8BAA8B,EAC9B,+BAA+B,EAC/B,yBAAyB,EACzB,6BAA6B,EAC7B,6BAA6B,EAC7B,8BAA8B,EAC9B,2BAA2B,EAC3B,+BAA+B,EAC/B,wCAAwC,EACxC,2CAA2C,EAC3C,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,mCAAmC,EACnC,qCAAqC,EACrC,mCAAmC,EACnC,mCAAmC,EACnC,gCAAgC,EAChC,iCAAiC,EACjC,kCAAkC,EAClC,6BAA6B,EAC7B,uCAAuC,EACvC,wCAAwC,EACxC,+CAA+C,EAC/C,kDAAkD,EAClD,0CAA0C,EAC1C,sCAAsC,EACtC,yCAAyC,EACzC,yCAAyC,EACzC,4CAA4C,EAC5C,wCAAwC,EACxC,gCAAgC,EAChC,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,mCAAmC,EACnC,mCAAmC,EACnC,oCAAoC,EACpC,kCAAkC,EAClC,uCAAuC,GACxC,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EACL,oCAAoC,EACpC,iDAAiD,EACjD,yCAAyC,EACzC,6CAA6C,EAC7C,yCAAyC,EACzC,0CAA0C,EAC1C,wCAAwC,EACxC,4CAA4C,EAC5C,iDAAiD,EACjD,kDAAkD,EAClD,kCAAkC,GACnC,MAAM,uCAAuC,CAAA;AAE9C,eAAO,MAAM,gBAAgB,EAAE,MAE9B,CAAA;AAED,wBAAgB,0BAA0B,CACxC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAAC,CAAC,GAC3D,UAAU,CAMZ"}
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { createStorefrontPublicRoutes } from "./routes-public.js";
2
2
  export { createStorefrontPublicRoutes } from "./routes-public.js";
3
3
  export { createStorefrontService, resolveStorefrontSettings } from "./service.js";
4
+ export { CUSTOMER_SIGNAL_CREATED_EVENT } from "./service-intake.js";
4
5
  export { evaluateStorefrontTransportEligibility } from "./service-transport-eligibility.js";
5
- export { storefrontAppliedOfferSchema, storefrontDepartureItinerarySchema, storefrontDepartureListQuerySchema, storefrontDepartureListResponseSchema, storefrontDeparturePricePreviewInputSchema, storefrontDeparturePricePreviewSchema, storefrontDepartureSchema, storefrontFormFieldInputSchema, storefrontFormFieldOptionSchema, storefrontFormFieldSchema, storefrontFormFieldTypeSchema, storefrontOfferApplyInputSchema, storefrontOfferAudienceSchema, storefrontOfferConflictSchema, storefrontOfferMutationReasonSchema, storefrontOfferMutationResponseSchema, storefrontOfferMutationResultSchema, storefrontOfferMutationStatusSchema, storefrontOfferRedeemInputSchema, storefrontPaymentMethodCodeSchema, storefrontPaymentMethodInputSchema, storefrontPaymentMethodSchema, storefrontProductAvailabilitySlotSchema, storefrontProductAvailabilityStateSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductAvailabilitySummaryResponseSchema, storefrontProductAvailabilitySummarySchema, storefrontProductExtensionsQuerySchema, storefrontProductExtensionsResponseSchema, storefrontPromotionalOfferListQuerySchema, storefrontPromotionalOfferListResponseSchema, storefrontPromotionalOfferResponseSchema, storefrontPromotionalOfferSchema, storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
6
+ export { storefrontAppliedOfferSchema, storefrontDepartureItinerarySchema, storefrontDepartureListQuerySchema, storefrontDepartureListResponseSchema, storefrontDeparturePricePreviewInputSchema, storefrontDeparturePricePreviewSchema, storefrontDepartureSchema, storefrontFormFieldInputSchema, storefrontFormFieldOptionSchema, storefrontFormFieldSchema, storefrontFormFieldTypeSchema, storefrontIntakeConsentSchema, storefrontIntakeResponseSchema, storefrontLeadContactSchema, storefrontLeadIntakeInputSchema, storefrontNewsletterSubscribeInputSchema, storefrontNewsletterSubscribeResponseSchema, storefrontOfferApplyInputSchema, storefrontOfferAudienceSchema, storefrontOfferConflictSchema, storefrontOfferMutationReasonSchema, storefrontOfferMutationResponseSchema, storefrontOfferMutationResultSchema, storefrontOfferMutationStatusSchema, storefrontOfferRedeemInputSchema, storefrontPaymentMethodCodeSchema, storefrontPaymentMethodInputSchema, storefrontPaymentMethodSchema, storefrontProductAvailabilitySlotSchema, storefrontProductAvailabilityStateSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductAvailabilitySummaryResponseSchema, storefrontProductAvailabilitySummarySchema, storefrontProductExtensionsQuerySchema, storefrontProductExtensionsResponseSchema, storefrontPromotionalOfferListQuerySchema, storefrontPromotionalOfferListResponseSchema, storefrontPromotionalOfferResponseSchema, storefrontPromotionalOfferSchema, storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
6
7
  export { storefrontRequiredDocumentTypeSchema, storefrontTransportEligibilityDocumentInputSchema, storefrontTransportEligibilityInputSchema, storefrontTransportEligibilityIssueCodeSchema, storefrontTransportEligibilityIssueSchema, storefrontTransportEligibilityResultSchema, storefrontTransportEligibilityRuleSchema, storefrontTransportEligibilitySeveritySchema, storefrontTransportEligibilityTravelerInputSchema, storefrontTransportEligibilityTravelerResultSchema, storefrontTravelDocumentTypeSchema, } from "./validation-transport-eligibility.js";
7
8
  export const storefrontModule = {
8
9
  name: "storefront",
@@ -1,7 +1,9 @@
1
+ import type { EventBus } from "@voyantjs/core";
1
2
  import { type StorefrontServiceOptions } from "./service.js";
2
3
  type Env = {
3
4
  Variables: {
4
5
  db: unknown;
6
+ eventBus?: EventBus;
5
7
  };
6
8
  };
7
9
  export declare function createStorefrontPublicRoutes(options?: StorefrontServiceOptions): import("hono/hono-base").HonoBase<Env, {
@@ -56,9 +58,9 @@ export declare function createStorefrontPublicRoutes(options?: StorefrontService
56
58
  };
57
59
  };
58
60
  payment: {
59
- defaultMethod: "voucher" | "card" | "bank_transfer" | "cash" | "invoice" | null;
61
+ defaultMethod: "voucher" | "bank_transfer" | "card" | "cash" | "invoice" | null;
60
62
  methods: {
61
- code: "voucher" | "card" | "bank_transfer" | "cash" | "invoice";
63
+ code: "voucher" | "bank_transfer" | "card" | "cash" | "invoice";
62
64
  label: string;
63
65
  description: string | null;
64
66
  enabled: boolean;
@@ -70,6 +72,57 @@ export declare function createStorefrontPublicRoutes(options?: StorefrontService
70
72
  status: import("hono/utils/http-status").ContentfulStatusCode;
71
73
  };
72
74
  };
75
+ } & {
76
+ "/leads": {
77
+ $post: {
78
+ input: {};
79
+ output: {
80
+ error: string;
81
+ };
82
+ outputFormat: "json";
83
+ status: 400 | 403 | 429;
84
+ } | {
85
+ input: {};
86
+ output: {
87
+ data: {
88
+ id: string;
89
+ personId: string;
90
+ kind: "wishlist" | "notify" | "inquiry" | "request_offer" | "referral";
91
+ source: "admin" | "form" | "phone" | "website" | "booking" | "abandoned_cart";
92
+ status: "expired" | "converted" | "lost" | "new" | "contacted" | "qualified";
93
+ duplicate: boolean;
94
+ };
95
+ };
96
+ outputFormat: "json";
97
+ status: 201;
98
+ };
99
+ };
100
+ } & {
101
+ "/newsletter/subscribe": {
102
+ $post: {
103
+ input: {};
104
+ output: {
105
+ error: string;
106
+ };
107
+ outputFormat: "json";
108
+ status: 400 | 403 | 429;
109
+ } | {
110
+ input: {};
111
+ output: {
112
+ data: {
113
+ id: string;
114
+ personId: string;
115
+ kind: "wishlist" | "notify" | "inquiry" | "request_offer" | "referral";
116
+ source: "admin" | "form" | "phone" | "website" | "booking" | "abandoned_cart";
117
+ status: "expired" | "converted" | "lost" | "new" | "contacted" | "qualified";
118
+ duplicate: boolean;
119
+ doubleOptIn: "not_configured" | "requested";
120
+ };
121
+ };
122
+ outputFormat: "json";
123
+ status: 202;
124
+ };
125
+ };
73
126
  } & {
74
127
  "/departures/:departureId": {
75
128
  $get: {
@@ -1 +1 @@
1
- {"version":3,"file":"routes-public.d.ts","sourceRoot":"","sources":["../src/routes-public.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,cAAc,CAAA;AAYrB,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,OAAO,CAAA;KACZ,CAAA;CACF,CAAA;AAED,wBAAgB,4BAA4B,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAyI9E;AAED,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAA"}
1
+ {"version":3,"file":"routes-public.d.ts","sourceRoot":"","sources":["../src/routes-public.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAK9C,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,cAAc,CAAA;AAgBrB,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,OAAO,CAAA;QACX,QAAQ,CAAC,EAAE,QAAQ,CAAA;KACpB,CAAA;CACF,CAAA;AAED,wBAAgB,4BAA4B,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA+L9E;AAED,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAA"}
@@ -1,20 +1,56 @@
1
1
  import { parseJsonBody, parseQuery } from "@voyantjs/hono";
2
2
  import { Hono } from "hono";
3
3
  import { createStorefrontService, } from "./service.js";
4
- import { storefrontDepartureListQuerySchema, storefrontDeparturePricePreviewInputSchema, storefrontOfferApplyInputSchema, storefrontOfferRedeemInputSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductExtensionsQuerySchema, storefrontPromotionalOfferListQuerySchema, } from "./validation.js";
4
+ import { storefrontDepartureListQuerySchema, storefrontDeparturePricePreviewInputSchema, storefrontLeadIntakeInputSchema, storefrontNewsletterSubscribeInputSchema, storefrontOfferApplyInputSchema, storefrontOfferRedeemInputSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductExtensionsQuerySchema, storefrontPromotionalOfferListQuerySchema, } from "./validation.js";
5
5
  import { storefrontTransportEligibilityInputSchema } from "./validation-transport-eligibility.js";
6
6
  export function createStorefrontPublicRoutes(options) {
7
7
  const storefrontService = createStorefrontService(options);
8
8
  function getRequestContext(c) {
9
9
  return {
10
10
  db: c.get("db"),
11
+ eventBus: c.get("eventBus"),
11
12
  env: c.env,
12
13
  context: c,
13
14
  };
14
15
  }
16
+ async function runIntakeGuard(input) {
17
+ const decision = await storefrontService.checkIntakeGuard(input);
18
+ if (!decision || decision.allowed)
19
+ return null;
20
+ return {
21
+ status: decision.status ?? 403,
22
+ error: decision.error ?? "Storefront intake rejected",
23
+ };
24
+ }
15
25
  return new Hono()
16
26
  .get("/settings", async (c) => {
17
27
  return c.json({ data: await storefrontService.resolveSettings(getRequestContext(c)) });
28
+ })
29
+ .post("/leads", async (c) => {
30
+ const context = getRequestContext(c);
31
+ const body = await parseJsonBody(c, storefrontLeadIntakeInputSchema);
32
+ const rejected = await runIntakeGuard({ kind: "lead", body, context });
33
+ if (rejected)
34
+ return c.json({ error: rejected.error }, rejected.status);
35
+ return c.json({
36
+ data: await storefrontService.createLead({
37
+ body,
38
+ context,
39
+ }),
40
+ }, 201);
41
+ })
42
+ .post("/newsletter/subscribe", async (c) => {
43
+ const context = getRequestContext(c);
44
+ const body = await parseJsonBody(c, storefrontNewsletterSubscribeInputSchema);
45
+ const rejected = await runIntakeGuard({ kind: "newsletter", body, context });
46
+ if (rejected)
47
+ return c.json({ error: rejected.error }, rejected.status);
48
+ return c.json({
49
+ data: await storefrontService.subscribeNewsletter({
50
+ body,
51
+ context,
52
+ }),
53
+ }, 202);
18
54
  })
19
55
  .get("/departures/:departureId", async (c) => {
20
56
  const departure = await storefrontService.getDeparture(c.get("db"), c.req.param("departureId"));
@@ -0,0 +1,40 @@
1
+ import { CUSTOMER_SIGNAL_CREATED_EVENT } from "@voyantjs/crm/events";
2
+ import type { StorefrontRequestContext } from "./service.js";
3
+ import type { StorefrontIntakeResponse, StorefrontLeadIntakeInput, StorefrontNewsletterSubscribeInput, StorefrontNewsletterSubscribeResponse } from "./validation.js";
4
+ export { CUSTOMER_SIGNAL_CREATED_EVENT };
5
+ export interface StorefrontIntakeGuardDecision {
6
+ allowed: boolean;
7
+ status?: 400 | 403 | 429;
8
+ error?: string;
9
+ }
10
+ export type StorefrontIntakeGuard = (input: {
11
+ kind: "lead";
12
+ body: StorefrontLeadIntakeInput;
13
+ context: StorefrontRequestContext;
14
+ } | {
15
+ kind: "newsletter";
16
+ body: StorefrontNewsletterSubscribeInput;
17
+ context: StorefrontRequestContext;
18
+ }) => Promise<StorefrontIntakeGuardDecision | undefined> | StorefrontIntakeGuardDecision | undefined;
19
+ export type StorefrontNewsletterDoubleOptInHook = (input: {
20
+ email: string;
21
+ personId: string;
22
+ signalId: string;
23
+ sourceSubmissionId: string;
24
+ body: StorefrontNewsletterSubscribeInput;
25
+ context: StorefrontRequestContext;
26
+ }) => Promise<void> | void;
27
+ export interface StorefrontIntakeOptions {
28
+ guard?: StorefrontIntakeGuard;
29
+ requestNewsletterDoubleOptIn?: StorefrontNewsletterDoubleOptInHook;
30
+ }
31
+ export declare function createStorefrontLeadSignal(input: {
32
+ body: StorefrontLeadIntakeInput;
33
+ context: StorefrontRequestContext;
34
+ }): Promise<StorefrontIntakeResponse>;
35
+ export declare function subscribeStorefrontNewsletter(input: {
36
+ body: StorefrontNewsletterSubscribeInput;
37
+ context: StorefrontRequestContext;
38
+ requestDoubleOptIn?: StorefrontNewsletterDoubleOptInHook;
39
+ }): Promise<StorefrontNewsletterSubscribeResponse>;
40
+ //# sourceMappingURL=service-intake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-intake.d.ts","sourceRoot":"","sources":["../src/service-intake.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAA6B,MAAM,sBAAsB,CAAA;AAI/F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,KAAK,EACV,wBAAwB,EAExB,yBAAyB,EACzB,kCAAkC,EAClC,qCAAqC,EACtC,MAAM,iBAAiB,CAAA;AAExB,OAAO,EAAE,6BAA6B,EAAE,CAAA;AAExC,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,qBAAqB,GAAG,CAClC,KAAK,EACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,yBAAyB,CAAA;IAC/B,OAAO,EAAE,wBAAwB,CAAA;CAClC,GACD;IACE,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,kCAAkC,CAAA;IACxC,OAAO,EAAE,wBAAwB,CAAA;CAClC,KACF,OAAO,CAAC,6BAA6B,GAAG,SAAS,CAAC,GAAG,6BAA6B,GAAG,SAAS,CAAA;AAEnG,MAAM,MAAM,mCAAmC,GAAG,CAAC,KAAK,EAAE;IACxD,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,IAAI,EAAE,kCAAkC,CAAA;IACxC,OAAO,EAAE,wBAAwB,CAAA;CAClC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAE1B,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,qBAAqB,CAAA;IAC7B,4BAA4B,CAAC,EAAE,mCAAmC,CAAA;CACnE;AA+GD,wBAAsB,0BAA0B,CAAC,KAAK,EAAE;IACtD,IAAI,EAAE,yBAAyB,CAAA;IAC/B,OAAO,EAAE,wBAAwB,CAAA;CAClC,GAAG,OAAO,CAAC,wBAAwB,CAAC,CA8DpC;AAED,wBAAsB,6BAA6B,CAAC,KAAK,EAAE;IACzD,IAAI,EAAE,kCAAkC,CAAA;IACxC,OAAO,EAAE,wBAAwB,CAAA;IACjC,kBAAkB,CAAC,EAAE,mCAAmC,CAAA;CACzD,GAAG,OAAO,CAAC,qCAAqC,CAAC,CA6FjD"}
@@ -0,0 +1,231 @@
1
+ import { crmService } from "@voyantjs/crm";
2
+ import { CUSTOMER_SIGNAL_CREATED_EVENT, emitCustomerSignalCreated } from "@voyantjs/crm/events";
3
+ import { customerSignals } from "@voyantjs/crm/schema";
4
+ import { and, eq } from "drizzle-orm";
5
+ export { CUSTOMER_SIGNAL_CREATED_EVENT };
6
+ function requireDb(context) {
7
+ if (!context.db) {
8
+ throw new Error("Storefront intake requires a request database");
9
+ }
10
+ return context.db;
11
+ }
12
+ function splitName(name) {
13
+ if (!name)
14
+ return {};
15
+ const parts = name.trim().split(/\s+/);
16
+ if (parts.length === 0)
17
+ return {};
18
+ if (parts.length === 1)
19
+ return { firstName: parts[0] };
20
+ return { firstName: parts[0], lastName: parts.slice(1).join(" ") };
21
+ }
22
+ function personNameFromContact(contact) {
23
+ const split = splitName(contact.name);
24
+ return {
25
+ firstName: contact.firstName ?? split.firstName ?? "Storefront",
26
+ lastName: contact.lastName ?? split.lastName ?? "Lead",
27
+ };
28
+ }
29
+ function personNameFromNewsletter(input) {
30
+ const split = splitName(input.name);
31
+ const emailLocalPart = input.email
32
+ .split("@")[0]
33
+ ?.replace(/[._-]+/g, " ")
34
+ .trim();
35
+ return {
36
+ firstName: input.firstName ?? split.firstName ?? emailLocalPart ?? "Newsletter",
37
+ lastName: input.lastName ?? split.lastName ?? "Subscriber",
38
+ };
39
+ }
40
+ function normalizeEmail(email) {
41
+ return email.trim().toLowerCase();
42
+ }
43
+ function defaultNewsletterSubmissionId(email) {
44
+ return `newsletter:${normalizeEmail(email)}`;
45
+ }
46
+ async function findExistingSignal(db, input) {
47
+ if (!input.sourceSubmissionId)
48
+ return null;
49
+ const [row] = await db
50
+ .select()
51
+ .from(customerSignals)
52
+ .where(and(eq(customerSignals.kind, input.kind), eq(customerSignals.sourceSubmissionId, input.sourceSubmissionId)))
53
+ .limit(1);
54
+ return row ?? null;
55
+ }
56
+ function leadResponse(signal, duplicate) {
57
+ return {
58
+ id: signal.id,
59
+ personId: signal.personId,
60
+ kind: signal.kind,
61
+ source: signal.source,
62
+ status: signal.status,
63
+ duplicate,
64
+ };
65
+ }
66
+ function newsletterDoubleOptInFromSignal(signal) {
67
+ const metadata = signal.metadata;
68
+ const newsletter = metadata && typeof metadata === "object" && "newsletter" in metadata
69
+ ? metadata.newsletter
70
+ : null;
71
+ if (!newsletter || typeof newsletter !== "object" || !("doubleOptIn" in newsletter)) {
72
+ return "not_configured";
73
+ }
74
+ return newsletter.doubleOptIn === "requested" ? "requested" : "not_configured";
75
+ }
76
+ function newsletterSignalMetadata(input) {
77
+ return {
78
+ intake: { surface: "storefront", type: "newsletter" },
79
+ newsletter: { email: input.email, doubleOptIn: input.doubleOptIn },
80
+ payload: input.body.payload,
81
+ consent: input.body.consent,
82
+ source: {
83
+ url: input.body.sourceUrl ?? null,
84
+ locale: input.body.locale ?? null,
85
+ },
86
+ };
87
+ }
88
+ export async function createStorefrontLeadSignal(input) {
89
+ const db = requireDb(input.context);
90
+ const existing = await findExistingSignal(db, {
91
+ kind: input.body.kind,
92
+ sourceSubmissionId: input.body.sourceSubmissionId,
93
+ });
94
+ if (existing)
95
+ return leadResponse(existing, true);
96
+ const { firstName, lastName } = personNameFromContact(input.body.contact);
97
+ const person = await crmService.createPerson(db, {
98
+ firstName,
99
+ lastName,
100
+ status: "active",
101
+ website: null,
102
+ email: input.body.contact.email ? normalizeEmail(input.body.contact.email) : null,
103
+ phone: input.body.contact.phone ?? null,
104
+ source: "storefront",
105
+ sourceRef: input.body.sourceSubmissionId ?? null,
106
+ tags: input.body.tags,
107
+ });
108
+ if (!person)
109
+ throw new Error("Failed to create CRM person for storefront lead");
110
+ const signal = await crmService.createCustomerSignal(db, {
111
+ personId: person.id,
112
+ productId: input.body.productId ?? null,
113
+ optionUnitId: input.body.optionUnitId ?? null,
114
+ kind: input.body.kind,
115
+ source: input.body.source,
116
+ status: "new",
117
+ priority: "normal",
118
+ notes: input.body.notes ?? null,
119
+ tags: input.body.tags,
120
+ sourceSubmissionId: input.body.sourceSubmissionId ?? null,
121
+ metadata: {
122
+ intake: { surface: "storefront", type: "lead" },
123
+ payload: input.body.payload,
124
+ consent: input.body.consent,
125
+ source: {
126
+ url: input.body.sourceUrl ?? null,
127
+ locale: input.body.locale ?? null,
128
+ },
129
+ },
130
+ });
131
+ if (!signal)
132
+ throw new Error("Failed to create CRM customer signal for storefront lead");
133
+ await emitCustomerSignalCreated(input.context.eventBus, {
134
+ id: signal.id,
135
+ personId: signal.personId,
136
+ kind: signal.kind,
137
+ source: signal.source,
138
+ status: signal.status,
139
+ productId: signal.productId,
140
+ optionUnitId: signal.optionUnitId,
141
+ sourceSubmissionId: signal.sourceSubmissionId,
142
+ intake: { surface: "storefront", type: "lead" },
143
+ }, "route");
144
+ return leadResponse(signal, false);
145
+ }
146
+ export async function subscribeStorefrontNewsletter(input) {
147
+ const db = requireDb(input.context);
148
+ const email = normalizeEmail(input.body.email);
149
+ const sourceSubmissionId = input.body.sourceSubmissionId ?? defaultNewsletterSubmissionId(input.body.email);
150
+ const existing = await findExistingSignal(db, {
151
+ kind: "notify",
152
+ sourceSubmissionId,
153
+ });
154
+ if (existing) {
155
+ return {
156
+ ...leadResponse(existing, true),
157
+ doubleOptIn: newsletterDoubleOptInFromSignal(existing),
158
+ };
159
+ }
160
+ const { firstName, lastName } = personNameFromNewsletter(input.body);
161
+ const person = await crmService.createPerson(db, {
162
+ firstName,
163
+ lastName,
164
+ status: "active",
165
+ website: null,
166
+ email,
167
+ source: "storefront-newsletter",
168
+ sourceRef: sourceSubmissionId,
169
+ tags: input.body.tags,
170
+ });
171
+ if (!person)
172
+ throw new Error("Failed to create CRM person for newsletter subscription");
173
+ const doubleOptIn = input.requestDoubleOptIn ? "requested" : "not_configured";
174
+ let signal = await crmService.createCustomerSignal(db, {
175
+ personId: person.id,
176
+ kind: "notify",
177
+ source: input.body.source,
178
+ status: "new",
179
+ priority: "normal",
180
+ notes: "Newsletter subscription",
181
+ tags: input.body.tags,
182
+ sourceSubmissionId,
183
+ metadata: newsletterSignalMetadata({
184
+ email,
185
+ doubleOptIn: "not_configured",
186
+ body: input.body,
187
+ }),
188
+ });
189
+ if (!signal)
190
+ throw new Error("Failed to create CRM customer signal for newsletter subscription");
191
+ if (input.requestDoubleOptIn) {
192
+ try {
193
+ await input.requestDoubleOptIn({
194
+ email,
195
+ personId: person.id,
196
+ signalId: signal.id,
197
+ sourceSubmissionId,
198
+ body: input.body,
199
+ context: input.context,
200
+ });
201
+ }
202
+ catch (error) {
203
+ await crmService.deleteCustomerSignal(db, signal.id).catch(() => null);
204
+ await crmService.deletePerson(db, person.id).catch(() => null);
205
+ throw error;
206
+ }
207
+ signal =
208
+ (await crmService.updateCustomerSignal(db, signal.id, {
209
+ metadata: newsletterSignalMetadata({
210
+ email,
211
+ doubleOptIn,
212
+ body: input.body,
213
+ }),
214
+ })) ?? signal;
215
+ }
216
+ await emitCustomerSignalCreated(input.context.eventBus, {
217
+ id: signal.id,
218
+ personId: signal.personId,
219
+ kind: signal.kind,
220
+ source: signal.source,
221
+ status: signal.status,
222
+ productId: signal.productId,
223
+ optionUnitId: signal.optionUnitId,
224
+ sourceSubmissionId: signal.sourceSubmissionId,
225
+ intake: { surface: "storefront", type: "newsletter", doubleOptIn },
226
+ }, "route");
227
+ return {
228
+ ...leadResponse(signal, false),
229
+ doubleOptIn,
230
+ };
231
+ }
package/dist/service.d.ts CHANGED
@@ -1,5 +1,7 @@
1
+ import type { EventBus } from "@voyantjs/core";
1
2
  import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
- import { type StorefrontDepartureListQuery, type StorefrontDeparturePricePreviewInput, type StorefrontOfferApplyInput, type StorefrontOfferMutationResult, type StorefrontOfferRedeemInput, type StorefrontProductAvailabilitySummaryQuery, type StorefrontPromotionalOffer, type StorefrontSettings, type StorefrontSettingsInput } from "./validation.js";
3
+ import { type StorefrontIntakeGuard, type StorefrontIntakeOptions } from "./service-intake.js";
4
+ import { type StorefrontDepartureListQuery, type StorefrontDeparturePricePreviewInput, type StorefrontLeadIntakeInput, type StorefrontNewsletterSubscribeInput, type StorefrontOfferApplyInput, type StorefrontOfferMutationResult, type StorefrontOfferRedeemInput, type StorefrontProductAvailabilitySummaryQuery, type StorefrontPromotionalOffer, type StorefrontSettings, type StorefrontSettingsInput } from "./validation.js";
3
5
  import type { StorefrontTransportEligibilityInput, StorefrontTransportEligibilityResult, StorefrontTransportEligibilityRuleInput } from "./validation-transport-eligibility.js";
4
6
  export interface StorefrontServiceOptions {
5
7
  settings?: StorefrontSettingsInput;
@@ -13,9 +15,11 @@ export interface StorefrontServiceOptions {
13
15
  travelStartsOn?: string | null;
14
16
  travelEndsOn?: string | null;
15
17
  } & StorefrontRequestContext) => Promise<StorefrontTransportEligibilityRuleInput[]> | StorefrontTransportEligibilityRuleInput[];
18
+ intake?: StorefrontIntakeOptions;
16
19
  }
17
20
  export interface StorefrontRequestContext {
18
21
  db?: PostgresJsDatabase;
22
+ eventBus?: EventBus;
19
23
  env?: unknown;
20
24
  context?: unknown;
21
25
  }
@@ -87,9 +91,9 @@ export declare function createStorefrontService(options?: StorefrontServiceOptio
87
91
  };
88
92
  };
89
93
  payment: {
90
- defaultMethod: "voucher" | "card" | "bank_transfer" | "cash" | "invoice" | null;
94
+ defaultMethod: "voucher" | "bank_transfer" | "card" | "cash" | "invoice" | null;
91
95
  methods: {
92
- code: "voucher" | "card" | "bank_transfer" | "cash" | "invoice";
96
+ code: "voucher" | "bank_transfer" | "card" | "cash" | "invoice";
93
97
  label: string;
94
98
  description: string | null;
95
99
  enabled: boolean;
@@ -330,5 +334,38 @@ export declare function createStorefrontService(options?: StorefrontServiceOptio
330
334
  body: StorefrontOfferRedeemInput;
331
335
  context?: StorefrontRequestContext;
332
336
  }): Promise<StorefrontOfferMutationResult | null>;
337
+ checkIntakeGuard: (input: {
338
+ kind: "lead";
339
+ body: StorefrontLeadIntakeInput;
340
+ context: StorefrontRequestContext;
341
+ } | {
342
+ kind: "newsletter";
343
+ body: StorefrontNewsletterSubscribeInput;
344
+ context: StorefrontRequestContext;
345
+ }) => Promise<import("./service-intake.js").StorefrontIntakeGuardDecision | undefined>;
346
+ createLead(input: {
347
+ body: StorefrontLeadIntakeInput;
348
+ context: StorefrontRequestContext;
349
+ }): Promise<{
350
+ id: string;
351
+ personId: string;
352
+ kind: "wishlist" | "notify" | "inquiry" | "request_offer" | "referral";
353
+ source: "admin" | "form" | "phone" | "website" | "booking" | "abandoned_cart";
354
+ status: "expired" | "converted" | "lost" | "new" | "contacted" | "qualified";
355
+ duplicate: boolean;
356
+ }>;
357
+ subscribeNewsletter(input: {
358
+ body: StorefrontNewsletterSubscribeInput;
359
+ context: StorefrontRequestContext;
360
+ }): Promise<{
361
+ id: string;
362
+ personId: string;
363
+ kind: "wishlist" | "notify" | "inquiry" | "request_offer" | "referral";
364
+ source: "admin" | "form" | "phone" | "website" | "booking" | "abandoned_cart";
365
+ status: "expired" | "converted" | "lost" | "new" | "contacted" | "qualified";
366
+ duplicate: boolean;
367
+ doubleOptIn: "not_configured" | "requested";
368
+ }>;
333
369
  };
370
+ export type { StorefrontIntakeGuard, StorefrontIntakeOptions };
334
371
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/dist/service.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getStorefrontDeparture, getStorefrontDepartureItinerary, getStorefrontProductAvailabilitySummary, getStorefrontProductExtensions, listStorefrontProductDepartures, previewStorefrontDeparturePrice, } from "./service-departures.js";
2
+ import { createStorefrontLeadSignal, subscribeStorefrontNewsletter, } from "./service-intake.js";
2
3
  import { evaluateStorefrontTransportEligibility } from "./service-transport-eligibility.js";
3
4
  import { storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
4
5
  const defaultPaymentLabels = {
@@ -74,6 +75,9 @@ export function createStorefrontService(options) {
74
75
  options?.transportEligibilityRules ??
75
76
  []);
76
77
  }
78
+ async function checkIntakeGuard(input) {
79
+ return options?.intake?.guard?.(input);
80
+ }
77
81
  return {
78
82
  getSettings() {
79
83
  return settings;
@@ -137,5 +141,15 @@ export function createStorefrontService(options) {
137
141
  const { context, ...offerInput } = input;
138
142
  return ((await resolveOffers(context)?.then((resolvers) => resolvers?.redeemOffer?.({ ...offerInput, ...(context ?? {}) }))) ?? null);
139
143
  },
144
+ checkIntakeGuard,
145
+ createLead(input) {
146
+ return createStorefrontLeadSignal(input);
147
+ },
148
+ subscribeNewsletter(input) {
149
+ return subscribeStorefrontNewsletter({
150
+ ...input,
151
+ requestDoubleOptIn: options?.intake?.requestNewsletterDoubleOptIn,
152
+ });
153
+ },
140
154
  };
141
155
  }
@@ -1,8 +1,153 @@
1
1
  import { z } from "zod";
2
+ export declare const storefrontIntakeConsentSchema: z.ZodObject<{
3
+ marketing: z.ZodDefault<z.ZodBoolean>;
4
+ newsletter: z.ZodDefault<z.ZodBoolean>;
5
+ gdpr: z.ZodDefault<z.ZodBoolean>;
6
+ scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
7
+ acceptedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
+ }, z.core.$strip>;
9
+ export declare const storefrontLeadContactSchema: z.ZodObject<{
10
+ name: z.ZodOptional<z.ZodString>;
11
+ firstName: z.ZodOptional<z.ZodString>;
12
+ lastName: z.ZodOptional<z.ZodString>;
13
+ email: z.ZodOptional<z.ZodEmail>;
14
+ phone: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ export declare const storefrontLeadIntakeInputSchema: z.ZodObject<{
17
+ kind: z.ZodDefault<z.ZodEnum<{
18
+ wishlist: "wishlist";
19
+ notify: "notify";
20
+ inquiry: "inquiry";
21
+ request_offer: "request_offer";
22
+ referral: "referral";
23
+ }>>;
24
+ source: z.ZodDefault<z.ZodEnum<{
25
+ admin: "admin";
26
+ form: "form";
27
+ phone: "phone";
28
+ website: "website";
29
+ booking: "booking";
30
+ abandoned_cart: "abandoned_cart";
31
+ }>>;
32
+ contact: z.ZodObject<{
33
+ name: z.ZodOptional<z.ZodString>;
34
+ firstName: z.ZodOptional<z.ZodString>;
35
+ lastName: z.ZodOptional<z.ZodString>;
36
+ email: z.ZodOptional<z.ZodEmail>;
37
+ phone: z.ZodOptional<z.ZodString>;
38
+ }, z.core.$strip>;
39
+ productId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
40
+ optionUnitId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
41
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
42
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
43
+ sourceSubmissionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
44
+ sourceUrl: z.ZodOptional<z.ZodNullable<z.ZodURL>>;
45
+ locale: z.ZodOptional<z.ZodString>;
46
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
47
+ consent: z.ZodDefault<z.ZodObject<{
48
+ marketing: z.ZodDefault<z.ZodBoolean>;
49
+ newsletter: z.ZodDefault<z.ZodBoolean>;
50
+ gdpr: z.ZodDefault<z.ZodBoolean>;
51
+ scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
+ acceptedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
53
+ }, z.core.$strip>>;
54
+ }, z.core.$strip>;
55
+ export declare const storefrontNewsletterSubscribeInputSchema: z.ZodObject<{
56
+ email: z.ZodEmail;
57
+ name: z.ZodOptional<z.ZodString>;
58
+ firstName: z.ZodOptional<z.ZodString>;
59
+ lastName: z.ZodOptional<z.ZodString>;
60
+ source: z.ZodDefault<z.ZodEnum<{
61
+ admin: "admin";
62
+ form: "form";
63
+ phone: "phone";
64
+ website: "website";
65
+ booking: "booking";
66
+ abandoned_cart: "abandoned_cart";
67
+ }>>;
68
+ sourceSubmissionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
69
+ sourceUrl: z.ZodOptional<z.ZodNullable<z.ZodURL>>;
70
+ locale: z.ZodOptional<z.ZodString>;
71
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
72
+ payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
73
+ consent: z.ZodObject<{
74
+ marketing: z.ZodDefault<z.ZodBoolean>;
75
+ gdpr: z.ZodDefault<z.ZodBoolean>;
76
+ scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
77
+ acceptedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
78
+ newsletter: z.ZodLiteral<true>;
79
+ }, z.core.$strip>;
80
+ }, z.core.$strip>;
81
+ export declare const storefrontIntakeResponseSchema: z.ZodObject<{
82
+ id: z.ZodString;
83
+ personId: z.ZodString;
84
+ kind: z.ZodEnum<{
85
+ wishlist: "wishlist";
86
+ notify: "notify";
87
+ inquiry: "inquiry";
88
+ request_offer: "request_offer";
89
+ referral: "referral";
90
+ }>;
91
+ source: z.ZodEnum<{
92
+ admin: "admin";
93
+ form: "form";
94
+ phone: "phone";
95
+ website: "website";
96
+ booking: "booking";
97
+ abandoned_cart: "abandoned_cart";
98
+ }>;
99
+ status: z.ZodEnum<{
100
+ expired: "expired";
101
+ converted: "converted";
102
+ lost: "lost";
103
+ new: "new";
104
+ contacted: "contacted";
105
+ qualified: "qualified";
106
+ }>;
107
+ duplicate: z.ZodBoolean;
108
+ }, z.core.$strip>;
109
+ export declare const storefrontNewsletterSubscribeResponseSchema: z.ZodObject<{
110
+ id: z.ZodString;
111
+ personId: z.ZodString;
112
+ kind: z.ZodEnum<{
113
+ wishlist: "wishlist";
114
+ notify: "notify";
115
+ inquiry: "inquiry";
116
+ request_offer: "request_offer";
117
+ referral: "referral";
118
+ }>;
119
+ source: z.ZodEnum<{
120
+ admin: "admin";
121
+ form: "form";
122
+ phone: "phone";
123
+ website: "website";
124
+ booking: "booking";
125
+ abandoned_cart: "abandoned_cart";
126
+ }>;
127
+ status: z.ZodEnum<{
128
+ expired: "expired";
129
+ converted: "converted";
130
+ lost: "lost";
131
+ new: "new";
132
+ contacted: "contacted";
133
+ qualified: "qualified";
134
+ }>;
135
+ duplicate: z.ZodBoolean;
136
+ doubleOptIn: z.ZodEnum<{
137
+ not_configured: "not_configured";
138
+ requested: "requested";
139
+ }>;
140
+ }, z.core.$strip>;
141
+ export type StorefrontIntakeConsent = z.infer<typeof storefrontIntakeConsentSchema>;
142
+ export type StorefrontLeadContact = z.infer<typeof storefrontLeadContactSchema>;
143
+ export type StorefrontLeadIntakeInput = z.infer<typeof storefrontLeadIntakeInputSchema>;
144
+ export type StorefrontNewsletterSubscribeInput = z.infer<typeof storefrontNewsletterSubscribeInputSchema>;
145
+ export type StorefrontIntakeResponse = z.infer<typeof storefrontIntakeResponseSchema>;
146
+ export type StorefrontNewsletterSubscribeResponse = z.infer<typeof storefrontNewsletterSubscribeResponseSchema>;
2
147
  export declare const storefrontPaymentMethodCodeSchema: z.ZodEnum<{
3
148
  voucher: "voucher";
4
- card: "card";
5
149
  bank_transfer: "bank_transfer";
150
+ card: "card";
6
151
  cash: "cash";
7
152
  invoice: "invoice";
8
153
  }>;
@@ -67,8 +212,8 @@ export declare const storefrontFormFieldSchema: z.ZodObject<{
67
212
  export declare const storefrontPaymentMethodInputSchema: z.ZodObject<{
68
213
  code: z.ZodEnum<{
69
214
  voucher: "voucher";
70
- card: "card";
71
215
  bank_transfer: "bank_transfer";
216
+ card: "card";
72
217
  cash: "cash";
73
218
  invoice: "invoice";
74
219
  }>;
@@ -79,8 +224,8 @@ export declare const storefrontPaymentMethodInputSchema: z.ZodObject<{
79
224
  export declare const storefrontPaymentMethodSchema: z.ZodObject<{
80
225
  code: z.ZodEnum<{
81
226
  voucher: "voucher";
82
- card: "card";
83
227
  bank_transfer: "bank_transfer";
228
+ card: "card";
84
229
  cash: "cash";
85
230
  invoice: "invoice";
86
231
  }>;
@@ -155,16 +300,16 @@ export declare const storefrontSettingsInputSchema: z.ZodObject<{
155
300
  payment: z.ZodOptional<z.ZodObject<{
156
301
  defaultMethod: z.ZodNullable<z.ZodOptional<z.ZodEnum<{
157
302
  voucher: "voucher";
158
- card: "card";
159
303
  bank_transfer: "bank_transfer";
304
+ card: "card";
160
305
  cash: "cash";
161
306
  invoice: "invoice";
162
307
  }>>>;
163
308
  methods: z.ZodOptional<z.ZodArray<z.ZodObject<{
164
309
  code: z.ZodEnum<{
165
310
  voucher: "voucher";
166
- card: "card";
167
311
  bank_transfer: "bank_transfer";
312
+ card: "card";
168
313
  cash: "cash";
169
314
  invoice: "invoice";
170
315
  }>;
@@ -241,16 +386,16 @@ export declare const storefrontSettingsSchema: z.ZodObject<{
241
386
  payment: z.ZodObject<{
242
387
  defaultMethod: z.ZodNullable<z.ZodEnum<{
243
388
  voucher: "voucher";
244
- card: "card";
245
389
  bank_transfer: "bank_transfer";
390
+ card: "card";
246
391
  cash: "cash";
247
392
  invoice: "invoice";
248
393
  }>>;
249
394
  methods: z.ZodArray<z.ZodObject<{
250
395
  code: z.ZodEnum<{
251
396
  voucher: "voucher";
252
- card: "card";
253
397
  bank_transfer: "bank_transfer";
398
+ card: "card";
254
399
  cash: "cash";
255
400
  invoice: "invoice";
256
401
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { availabilitySlotStatusSchema } from "@voyantjs/availability/validation";
2
+ import { customerSignalKindSchema, customerSignalSourceSchema, customerSignalStatusSchema, } from "@voyantjs/crm/validation";
2
3
  import { extraPricingModeSchema } from "@voyantjs/extras/validation";
3
4
  import { z } from "zod";
4
5
  const languageTagSchema = z
@@ -6,6 +7,72 @@ const languageTagSchema = z
6
7
  .trim()
7
8
  .regex(/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/);
8
9
  const urlOrNullSchema = z.url().nullable();
10
+ const boundedRecordSchema = z
11
+ .record(z.string(), z.unknown())
12
+ .refine((value) => JSON.stringify(value).length <= 8000, {
13
+ message: "Object payload must be 8KB or smaller",
14
+ });
15
+ const storefrontIntakeTagsSchema = z.array(z.string().trim().min(1).max(64)).max(20).default([]);
16
+ export const storefrontIntakeConsentSchema = z.object({
17
+ marketing: z.boolean().default(false),
18
+ newsletter: z.boolean().default(false),
19
+ gdpr: z.boolean().default(false),
20
+ scope: z.string().trim().min(1).max(120).nullable().optional(),
21
+ acceptedAt: z.string().datetime().nullable().optional(),
22
+ });
23
+ export const storefrontLeadContactSchema = z
24
+ .object({
25
+ name: z.string().trim().min(1).max(240).optional(),
26
+ firstName: z.string().trim().min(1).max(120).optional(),
27
+ lastName: z.string().trim().min(1).max(120).optional(),
28
+ email: z.email().max(320).optional(),
29
+ phone: z.string().trim().min(3).max(64).optional(),
30
+ })
31
+ .refine((value) => Boolean(value.email || value.phone), {
32
+ message: "Either contact.email or contact.phone is required",
33
+ });
34
+ export const storefrontLeadIntakeInputSchema = z.object({
35
+ kind: customerSignalKindSchema.default("inquiry"),
36
+ source: customerSignalSourceSchema.default("website"),
37
+ contact: storefrontLeadContactSchema,
38
+ productId: z.string().trim().min(1).max(160).nullable().optional(),
39
+ optionUnitId: z.string().trim().min(1).max(160).nullable().optional(),
40
+ notes: z.string().trim().max(4000).nullable().optional(),
41
+ tags: storefrontIntakeTagsSchema,
42
+ sourceSubmissionId: z.string().trim().min(1).max(160).nullable().optional(),
43
+ sourceUrl: z.url().nullable().optional(),
44
+ locale: languageTagSchema.optional(),
45
+ payload: boundedRecordSchema.default({}),
46
+ consent: storefrontIntakeConsentSchema.default({
47
+ marketing: false,
48
+ newsletter: false,
49
+ gdpr: false,
50
+ }),
51
+ });
52
+ export const storefrontNewsletterSubscribeInputSchema = z.object({
53
+ email: z.email().max(320),
54
+ name: z.string().trim().min(1).max(240).optional(),
55
+ firstName: z.string().trim().min(1).max(120).optional(),
56
+ lastName: z.string().trim().min(1).max(120).optional(),
57
+ source: customerSignalSourceSchema.default("website"),
58
+ sourceSubmissionId: z.string().trim().min(1).max(160).nullable().optional(),
59
+ sourceUrl: z.url().nullable().optional(),
60
+ locale: languageTagSchema.optional(),
61
+ tags: storefrontIntakeTagsSchema,
62
+ payload: boundedRecordSchema.default({}),
63
+ consent: storefrontIntakeConsentSchema.extend({ newsletter: z.literal(true) }),
64
+ });
65
+ export const storefrontIntakeResponseSchema = z.object({
66
+ id: z.string(),
67
+ personId: z.string(),
68
+ kind: customerSignalKindSchema,
69
+ source: customerSignalSourceSchema,
70
+ status: customerSignalStatusSchema,
71
+ duplicate: z.boolean(),
72
+ });
73
+ export const storefrontNewsletterSubscribeResponseSchema = storefrontIntakeResponseSchema.extend({
74
+ doubleOptIn: z.enum(["not_configured", "requested"]),
75
+ });
9
76
  export const storefrontPaymentMethodCodeSchema = z.enum([
10
77
  "card",
11
78
  "bank_transfer",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/storefront",
3
- "version": "0.46.0",
3
+ "version": "0.49.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -34,18 +34,19 @@
34
34
  "drizzle-orm": "^0.45.2",
35
35
  "hono": "^4.12.10",
36
36
  "zod": "^4.3.6",
37
- "@voyantjs/availability": "0.46.0",
38
- "@voyantjs/core": "0.46.0",
39
- "@voyantjs/extras": "0.46.0",
40
- "@voyantjs/hono": "0.46.0",
41
- "@voyantjs/pricing": "0.46.0",
42
- "@voyantjs/products": "0.46.0",
43
- "@voyantjs/sellability": "0.46.0"
37
+ "@voyantjs/core": "0.49.0",
38
+ "@voyantjs/crm": "0.49.0",
39
+ "@voyantjs/extras": "0.49.0",
40
+ "@voyantjs/hono": "0.49.0",
41
+ "@voyantjs/pricing": "0.49.0",
42
+ "@voyantjs/products": "0.49.0",
43
+ "@voyantjs/sellability": "0.49.0",
44
+ "@voyantjs/availability": "0.49.0"
44
45
  },
45
46
  "devDependencies": {
46
47
  "typescript": "^6.0.2",
47
48
  "vitest": "^4.1.2",
48
- "@voyantjs/db": "0.46.0",
49
+ "@voyantjs/db": "0.49.0",
49
50
  "@voyantjs/voyant-typescript-config": "0.1.0"
50
51
  },
51
52
  "files": [