@voyant-travel/storefront 0.120.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +231 -0
- package/dist/booking-intents.d.ts +42 -0
- package/dist/booking-intents.d.ts.map +1 -0
- package/dist/booking-intents.js +83 -0
- package/dist/customer-portal/index.d.ts +16 -0
- package/dist/customer-portal/index.d.ts.map +1 -0
- package/dist/customer-portal/index.js +23 -0
- package/dist/customer-portal/route-runtime.d.ts +16 -0
- package/dist/customer-portal/route-runtime.d.ts.map +1 -0
- package/dist/customer-portal/route-runtime.js +27 -0
- package/dist/customer-portal/routes-public.d.ts +1936 -0
- package/dist/customer-portal/routes-public.d.ts.map +1 -0
- package/dist/customer-portal/routes-public.js +165 -0
- package/dist/customer-portal/routes.d.ts +43 -0
- package/dist/customer-portal/routes.d.ts.map +1 -0
- package/dist/customer-portal/routes.js +17 -0
- package/dist/customer-portal/service-public-impl.d.ts +138 -0
- package/dist/customer-portal/service-public-impl.d.ts.map +1 -0
- package/dist/customer-portal/service-public-impl.js +1808 -0
- package/dist/customer-portal/service-public.d.ts +2 -0
- package/dist/customer-portal/service-public.d.ts.map +1 -0
- package/dist/customer-portal/service-public.js +1 -0
- package/dist/customer-portal/validation-public/bookings.d.ts +551 -0
- package/dist/customer-portal/validation-public/bookings.d.ts.map +1 -0
- package/dist/customer-portal/validation-public/bookings.js +132 -0
- package/dist/customer-portal/validation-public/common.d.ts +162 -0
- package/dist/customer-portal/validation-public/common.d.ts.map +1 -0
- package/dist/customer-portal/validation-public/common.js +139 -0
- package/dist/customer-portal/validation-public/profile.d.ts +749 -0
- package/dist/customer-portal/validation-public/profile.d.ts.map +1 -0
- package/dist/customer-portal/validation-public/profile.js +308 -0
- package/dist/customer-portal/validation-public.d.ts +3 -0
- package/dist/customer-portal/validation-public.d.ts.map +1 -0
- package/dist/customer-portal/validation-public.js +2 -0
- package/dist/guest-booking-guard.d.ts +24 -0
- package/dist/guest-booking-guard.d.ts.map +1 -0
- package/dist/guest-booking-guard.js +55 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/product-extra-ref.d.ts +238 -0
- package/dist/product-extra-ref.d.ts.map +1 -0
- package/dist/product-extra-ref.js +22 -0
- package/dist/routes-admin.d.ts +220 -0
- package/dist/routes-admin.d.ts.map +1 -0
- package/dist/routes-admin.js +28 -0
- package/dist/routes-public.d.ts +1475 -0
- package/dist/routes-public.d.ts.map +1 -0
- package/dist/routes-public.js +362 -0
- package/dist/service-booking-session-bootstrap.d.ts +227 -0
- package/dist/service-booking-session-bootstrap.d.ts.map +1 -0
- package/dist/service-booking-session-bootstrap.js +287 -0
- package/dist/service-boundary-resource-sql.d.ts +18 -0
- package/dist/service-boundary-resource-sql.d.ts.map +1 -0
- package/dist/service-boundary-resource-sql.js +73 -0
- package/dist/service-boundary-sql.d.ts +103 -0
- package/dist/service-boundary-sql.d.ts.map +1 -0
- package/dist/service-boundary-sql.js +307 -0
- package/dist/service-departures-core.d.ts +41 -0
- package/dist/service-departures-core.d.ts.map +1 -0
- package/dist/service-departures-core.js +92 -0
- package/dist/service-departures-extensions.d.ts +46 -0
- package/dist/service-departures-extensions.d.ts.map +1 -0
- package/dist/service-departures-extensions.js +81 -0
- package/dist/service-departures-offers.d.ts +220 -0
- package/dist/service-departures-offers.d.ts.map +1 -0
- package/dist/service-departures-offers.js +177 -0
- package/dist/service-departures-price-preview.d.ts +306 -0
- package/dist/service-departures-price-preview.d.ts.map +1 -0
- package/dist/service-departures-price-preview.js +383 -0
- package/dist/service-departures-pricing-context.d.ts +115 -0
- package/dist/service-departures-pricing-context.d.ts.map +1 -0
- package/dist/service-departures-pricing-context.js +237 -0
- package/dist/service-departures-pricing.d.ts +5 -0
- package/dist/service-departures-pricing.d.ts.map +1 -0
- package/dist/service-departures-pricing.js +4 -0
- package/dist/service-departures.d.ts +192 -0
- package/dist/service-departures.d.ts.map +1 -0
- package/dist/service-departures.js +213 -0
- package/dist/service-intake.d.ts +130 -0
- package/dist/service-intake.d.ts.map +1 -0
- package/dist/service-intake.js +274 -0
- package/dist/service-transport-eligibility.d.ts +10 -0
- package/dist/service-transport-eligibility.d.ts.map +1 -0
- package/dist/service-transport-eligibility.js +198 -0
- package/dist/service.d.ts +1062 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +332 -0
- package/dist/transport-eligibility.d.ts +4 -0
- package/dist/transport-eligibility.d.ts.map +1 -0
- package/dist/transport-eligibility.js +2 -0
- package/dist/validation/departures.d.ts +1669 -0
- package/dist/validation/departures.d.ts.map +1 -0
- package/dist/validation/departures.js +397 -0
- package/dist/validation/intake.d.ts +147 -0
- package/dist/validation/intake.d.ts.map +1 -0
- package/dist/validation/intake.js +69 -0
- package/dist/validation/offers.d.ts +340 -0
- package/dist/validation/offers.d.ts.map +1 -0
- package/dist/validation/offers.js +117 -0
- package/dist/validation-settings.d.ts +609 -0
- package/dist/validation-settings.d.ts.map +1 -0
- package/dist/validation-settings.js +235 -0
- package/dist/validation-transport-eligibility.d.ts +314 -0
- package/dist/validation-transport-eligibility.d.ts.map +1 -0
- package/dist/validation-transport-eligibility.js +97 -0
- package/dist/validation.d.ts +6 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +4 -0
- package/dist/verification/index.d.ts +12 -0
- package/dist/verification/index.d.ts.map +1 -0
- package/dist/verification/index.js +18 -0
- package/dist/verification/routes-public.d.ts +121 -0
- package/dist/verification/routes-public.d.ts.map +1 -0
- package/dist/verification/routes-public.js +125 -0
- package/dist/verification/schema.d.ts +273 -0
- package/dist/verification/schema.d.ts.map +1 -0
- package/dist/verification/schema.js +50 -0
- package/dist/verification/service.d.ts +114 -0
- package/dist/verification/service.d.ts.map +1 -0
- package/dist/verification/service.js +283 -0
- package/dist/verification/validation.d.ts +98 -0
- package/dist/verification/validation.d.ts.map +1 -0
- package/dist/verification/validation.js +54 -0
- package/package.json +148 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes-public.d.ts","sourceRoot":"","sources":["../../src/customer-portal/routes-public.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAO1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAoBjE,KAAK,GAAG,GAAG;IACT,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,SAAS,CAAC,EAAE,eAAe,CAAA;QAC3B,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAoBD,MAAM,WAAW,gCAAgC;IAC/C,0BAA0B,CAAC,EAAE,CAC3B,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5C;AAED,wBAAgB,gCAAgC,CAAC,OAAO,GAAE,gCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gDAqP9F;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CAAqC,CAAA;AAE5E,MAAM,MAAM,0BAA0B,GAAG,OAAO,0BAA0B,CAAA"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { ForbiddenApiError, handleApiError, parseJsonBody, requireUserId, } from "@voyant-travel/hono";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import { buildPublicCustomerPortalRouteRuntime, CUSTOMER_PORTAL_ROUTE_RUNTIME_CONTAINER_KEY, } from "./route-runtime.js";
|
|
4
|
+
import { customerPortalRoutes } from "./routes.js";
|
|
5
|
+
import { publicCustomerPortalService } from "./service-public.js";
|
|
6
|
+
import { bootstrapCustomerPortalSchema, createCustomerPortalCompanionSchema, createCustomerPortalProfileDocumentSchema, importCustomerPortalBookingTravelersSchema, updateCustomerPortalCompanionSchema, updateCustomerPortalProfileDocumentSchema, updateCustomerPortalProfileSchema, } from "./validation-public.js";
|
|
7
|
+
function notFound(c, error) {
|
|
8
|
+
return c.json({ error }, 404);
|
|
9
|
+
}
|
|
10
|
+
function hasErrorResult(value) {
|
|
11
|
+
return "error" in value;
|
|
12
|
+
}
|
|
13
|
+
function hasBootstrapErrorResult(value) {
|
|
14
|
+
return "error" in value;
|
|
15
|
+
}
|
|
16
|
+
export function createPublicCustomerPortalRoutes(options = {}) {
|
|
17
|
+
const getRuntime = (c) => c.var.container?.resolve(CUSTOMER_PORTAL_ROUTE_RUNTIME_CONTAINER_KEY) ?? buildPublicCustomerPortalRouteRuntime(c.env, options);
|
|
18
|
+
const resolveOptionalKms = (c) => getRuntime(c).getOptionalKmsProvider();
|
|
19
|
+
const resolveDocumentDownloadUrl = (c, storageKey) => getRuntime(c).resolveDocumentDownloadUrl?.(storageKey) ?? null;
|
|
20
|
+
return new Hono()
|
|
21
|
+
.route("/", customerPortalRoutes)
|
|
22
|
+
.get("/me", async (c) => {
|
|
23
|
+
const userId = requireUserId(c);
|
|
24
|
+
const profile = await publicCustomerPortalService.getProfileWithOptions(c.get("db"), userId, {
|
|
25
|
+
kms: resolveOptionalKms(c),
|
|
26
|
+
});
|
|
27
|
+
return profile ? c.json({ data: profile }) : notFound(c, "Customer profile not found");
|
|
28
|
+
})
|
|
29
|
+
.patch("/me", async (c) => {
|
|
30
|
+
const userId = requireUserId(c);
|
|
31
|
+
const result = await publicCustomerPortalService.updateProfileWithOptions(c.get("db"), userId, await parseJsonBody(c, updateCustomerPortalProfileSchema), {
|
|
32
|
+
kms: resolveOptionalKms(c),
|
|
33
|
+
});
|
|
34
|
+
if (hasErrorResult(result)) {
|
|
35
|
+
if (result.error === "not_found") {
|
|
36
|
+
return notFound(c, "Customer profile not found");
|
|
37
|
+
}
|
|
38
|
+
return c.json({ error: "Customer record is not linked to this account" }, 409);
|
|
39
|
+
}
|
|
40
|
+
return c.json({ data: result.profile });
|
|
41
|
+
})
|
|
42
|
+
.get("/me/documents", async (c) => {
|
|
43
|
+
const userId = requireUserId(c);
|
|
44
|
+
const data = await publicCustomerPortalService.listMyDocuments(c.get("db"), userId, {
|
|
45
|
+
kms: resolveOptionalKms(c),
|
|
46
|
+
});
|
|
47
|
+
return c.json({ data });
|
|
48
|
+
})
|
|
49
|
+
.post("/me/documents", async (c) => {
|
|
50
|
+
const userId = requireUserId(c);
|
|
51
|
+
const input = await parseJsonBody(c, createCustomerPortalProfileDocumentSchema);
|
|
52
|
+
const row = await publicCustomerPortalService.createMyDocument(c.get("db"), userId, input, {
|
|
53
|
+
kms: resolveOptionalKms(c),
|
|
54
|
+
});
|
|
55
|
+
if (!row)
|
|
56
|
+
return notFound(c, "Customer profile not found");
|
|
57
|
+
return c.json({ data: row }, 201);
|
|
58
|
+
})
|
|
59
|
+
.patch("/me/documents/:id", async (c) => {
|
|
60
|
+
const userId = requireUserId(c);
|
|
61
|
+
const input = await parseJsonBody(c, updateCustomerPortalProfileDocumentSchema);
|
|
62
|
+
const row = await publicCustomerPortalService.updateMyDocument(c.get("db"), userId, c.req.param("id"), input, { kms: resolveOptionalKms(c) });
|
|
63
|
+
if (!row)
|
|
64
|
+
return notFound(c, "Document not found");
|
|
65
|
+
return c.json({ data: row });
|
|
66
|
+
})
|
|
67
|
+
.delete("/me/documents/:id", async (c) => {
|
|
68
|
+
const userId = requireUserId(c);
|
|
69
|
+
const result = await publicCustomerPortalService.deleteMyDocument(c.get("db"), userId, c.req.param("id"));
|
|
70
|
+
if (!result)
|
|
71
|
+
return notFound(c, "Document not found");
|
|
72
|
+
return c.json({ success: true });
|
|
73
|
+
})
|
|
74
|
+
.post("/me/documents/:id/set-primary", async (c) => {
|
|
75
|
+
const userId = requireUserId(c);
|
|
76
|
+
const row = await publicCustomerPortalService.setPrimaryMyDocument(c.get("db"), userId, c.req.param("id"), { kms: resolveOptionalKms(c) });
|
|
77
|
+
if (!row)
|
|
78
|
+
return notFound(c, "Document not found");
|
|
79
|
+
return c.json({ data: row });
|
|
80
|
+
})
|
|
81
|
+
.post("/bootstrap", async (c) => {
|
|
82
|
+
const userId = requireUserId(c);
|
|
83
|
+
const result = await publicCustomerPortalService.bootstrap(c.get("db"), userId, await parseJsonBody(c, bootstrapCustomerPortalSchema));
|
|
84
|
+
if (hasBootstrapErrorResult(result)) {
|
|
85
|
+
if (result.error === "not_found") {
|
|
86
|
+
return notFound(c, "Customer profile not found");
|
|
87
|
+
}
|
|
88
|
+
if (result.error === "customer_record_not_found") {
|
|
89
|
+
return notFound(c, "Customer record not found");
|
|
90
|
+
}
|
|
91
|
+
return c.json({ error: "Customer record is already linked to another account" }, 409);
|
|
92
|
+
}
|
|
93
|
+
if (result.status === "customer_selection_required") {
|
|
94
|
+
return c.json({ data: result }, 409);
|
|
95
|
+
}
|
|
96
|
+
return c.json({ data: result });
|
|
97
|
+
})
|
|
98
|
+
.get("/companions", async (c) => {
|
|
99
|
+
const userId = requireUserId(c);
|
|
100
|
+
return c.json({ data: await publicCustomerPortalService.listCompanions(c.get("db"), userId) });
|
|
101
|
+
})
|
|
102
|
+
.post("/companions", async (c) => {
|
|
103
|
+
const userId = requireUserId(c);
|
|
104
|
+
const companion = await publicCustomerPortalService.createCompanion(c.get("db"), userId, await parseJsonBody(c, createCustomerPortalCompanionSchema));
|
|
105
|
+
if (!companion) {
|
|
106
|
+
return c.json({ error: "Customer record is not linked to this account" }, 409);
|
|
107
|
+
}
|
|
108
|
+
return c.json({ data: companion }, 201);
|
|
109
|
+
})
|
|
110
|
+
.post("/companions/import-booking-travelers", async (c) => {
|
|
111
|
+
const userId = requireUserId(c);
|
|
112
|
+
const result = await publicCustomerPortalService.importBookingTravelersAsCompanions(c.get("db"), userId, await parseJsonBody(c, importCustomerPortalBookingTravelersSchema));
|
|
113
|
+
if (!result) {
|
|
114
|
+
return c.json({ error: "Customer record is not linked to this account" }, 409);
|
|
115
|
+
}
|
|
116
|
+
return c.json({ data: result });
|
|
117
|
+
})
|
|
118
|
+
.patch("/companions/:companionId", async (c) => {
|
|
119
|
+
const userId = requireUserId(c);
|
|
120
|
+
const companion = await publicCustomerPortalService.updateCompanion(c.get("db"), userId, c.req.param("companionId"), await parseJsonBody(c, updateCustomerPortalCompanionSchema));
|
|
121
|
+
if (companion === "forbidden") {
|
|
122
|
+
return handleApiError(new ForbiddenApiError("Companion does not belong to this customer"), c);
|
|
123
|
+
}
|
|
124
|
+
if (!companion) {
|
|
125
|
+
return notFound(c, "Companion not found");
|
|
126
|
+
}
|
|
127
|
+
return c.json({ data: companion });
|
|
128
|
+
})
|
|
129
|
+
.delete("/companions/:companionId", async (c) => {
|
|
130
|
+
const userId = requireUserId(c);
|
|
131
|
+
const result = await publicCustomerPortalService.deleteCompanion(c.get("db"), userId, c.req.param("companionId"));
|
|
132
|
+
if (result === "forbidden") {
|
|
133
|
+
return handleApiError(new ForbiddenApiError("Companion does not belong to this customer"), c);
|
|
134
|
+
}
|
|
135
|
+
if (result === "not_found") {
|
|
136
|
+
return notFound(c, "Companion not found");
|
|
137
|
+
}
|
|
138
|
+
return c.json({ success: true });
|
|
139
|
+
})
|
|
140
|
+
.get("/bookings", async (c) => {
|
|
141
|
+
const userId = requireUserId(c);
|
|
142
|
+
const bookings = await publicCustomerPortalService.listBookings(c.get("db"), userId);
|
|
143
|
+
return bookings ? c.json({ data: bookings }) : notFound(c, "Customer profile not found");
|
|
144
|
+
})
|
|
145
|
+
.get("/bookings/:bookingId", async (c) => {
|
|
146
|
+
const userId = requireUserId(c);
|
|
147
|
+
const booking = await publicCustomerPortalService.getBooking(c.get("db"), userId, c.req.param("bookingId"), {
|
|
148
|
+
resolveDocumentDownloadUrl: (storageKey) => resolveDocumentDownloadUrl(c, storageKey),
|
|
149
|
+
});
|
|
150
|
+
return booking ? c.json({ data: booking }) : notFound(c, "Booking not found");
|
|
151
|
+
})
|
|
152
|
+
.get("/bookings/:bookingId/documents", async (c) => {
|
|
153
|
+
const userId = requireUserId(c);
|
|
154
|
+
const documents = await publicCustomerPortalService.listBookingDocuments(c.get("db"), userId, c.req.param("bookingId"), {
|
|
155
|
+
resolveDocumentDownloadUrl: (storageKey) => resolveDocumentDownloadUrl(c, storageKey),
|
|
156
|
+
});
|
|
157
|
+
return documents ? c.json({ data: documents }) : notFound(c, "Booking not found");
|
|
158
|
+
})
|
|
159
|
+
.get("/bookings/:bookingId/billing-contact", async (c) => {
|
|
160
|
+
const userId = requireUserId(c);
|
|
161
|
+
const billingContact = await publicCustomerPortalService.getBookingBillingContact(c.get("db"), userId, c.req.param("bookingId"));
|
|
162
|
+
return billingContact ? c.json({ data: billingContact }) : notFound(c, "Booking not found");
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
export const publicCustomerPortalRoutes = createPublicCustomerPortalRoutes();
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
type Env = {
|
|
3
|
+
Variables: {
|
|
4
|
+
db: PostgresJsDatabase;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
export declare const customerPortalRoutes: import("hono/hono-base").HonoBase<Env, {
|
|
8
|
+
"/contact-exists": {
|
|
9
|
+
$get: {
|
|
10
|
+
input: {};
|
|
11
|
+
output: {
|
|
12
|
+
data: {
|
|
13
|
+
email: string;
|
|
14
|
+
authAccountExists: boolean;
|
|
15
|
+
customerRecordExists: boolean;
|
|
16
|
+
linkedCustomerRecordExists: boolean;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
outputFormat: "json";
|
|
20
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
} & {
|
|
24
|
+
"/contact-exists/phone": {
|
|
25
|
+
$get: {
|
|
26
|
+
input: {};
|
|
27
|
+
output: {
|
|
28
|
+
data: {
|
|
29
|
+
phone: string;
|
|
30
|
+
authAccountExists: boolean;
|
|
31
|
+
authAccountVerified: boolean;
|
|
32
|
+
customerRecordExists: boolean;
|
|
33
|
+
linkedCustomerRecordExists: boolean;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
outputFormat: "json";
|
|
37
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}, "/", "/contact-exists/phone">;
|
|
41
|
+
export type CustomerPortalRoutes = typeof customerPortalRoutes;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/customer-portal/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AASjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;KACvB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAe7B,CAAA;AAEJ,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { parseQuery } from "@voyant-travel/hono";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import { publicCustomerPortalService } from "./service-public.js";
|
|
4
|
+
import { customerPortalContactExistsQuerySchema, customerPortalPhoneContactExistsQuerySchema, } from "./validation-public.js";
|
|
5
|
+
export const customerPortalRoutes = new Hono()
|
|
6
|
+
.get("/contact-exists", async (c) => {
|
|
7
|
+
const query = parseQuery(c, customerPortalContactExistsQuerySchema);
|
|
8
|
+
return c.json({
|
|
9
|
+
data: await publicCustomerPortalService.contactExists(c.get("db"), query.email),
|
|
10
|
+
});
|
|
11
|
+
})
|
|
12
|
+
.get("/contact-exists/phone", async (c) => {
|
|
13
|
+
const query = parseQuery(c, customerPortalPhoneContactExistsQuerySchema);
|
|
14
|
+
return c.json({
|
|
15
|
+
data: await publicCustomerPortalService.phoneContactExists(c.get("db"), query.phone),
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { type KmsProvider } from "@voyant-travel/utils";
|
|
2
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
+
import type { BootstrapCustomerPortalInput, BootstrapCustomerPortalResult, CreateCustomerPortalCompanionInput, CustomerPortalBookingDetail, CustomerPortalBookingSummary, CustomerPortalCompanion, CustomerPortalContactExistsResult, CustomerPortalPhoneContactExistsResult, CustomerPortalProfile, ImportCustomerPortalBookingTravelersInput, ImportCustomerPortalBookingTravelersResult, UpdateCustomerPortalCompanionInput, UpdateCustomerPortalProfileInput } from "./validation-public.js";
|
|
4
|
+
interface CustomerPortalServiceOptions {
|
|
5
|
+
kms?: KmsProvider | null;
|
|
6
|
+
resolveDocumentDownloadUrl?: (storageKey: string) => Promise<string | null> | string | null;
|
|
7
|
+
}
|
|
8
|
+
type WireDocumentType = "passport" | "id_card" | "visa" | "drivers_license" | "other";
|
|
9
|
+
export declare const publicCustomerPortalService: {
|
|
10
|
+
contactExists(db: PostgresJsDatabase, email: string): Promise<CustomerPortalContactExistsResult>;
|
|
11
|
+
phoneContactExists(db: PostgresJsDatabase, phone: string): Promise<CustomerPortalPhoneContactExistsResult>;
|
|
12
|
+
getProfile(db: PostgresJsDatabase, userId: string): Promise<CustomerPortalProfile | null>;
|
|
13
|
+
getProfileWithOptions(db: PostgresJsDatabase, userId: string, options?: CustomerPortalServiceOptions): Promise<CustomerPortalProfile | null>;
|
|
14
|
+
updateProfile(db: PostgresJsDatabase, userId: string, input: UpdateCustomerPortalProfileInput): Promise<{
|
|
15
|
+
profile: CustomerPortalProfile;
|
|
16
|
+
} | {
|
|
17
|
+
error: "not_found" | "customer_record_required";
|
|
18
|
+
}>;
|
|
19
|
+
updateProfileWithOptions(db: PostgresJsDatabase, userId: string, input: UpdateCustomerPortalProfileInput, options?: CustomerPortalServiceOptions): Promise<{
|
|
20
|
+
profile: CustomerPortalProfile;
|
|
21
|
+
} | {
|
|
22
|
+
error: "not_found" | "customer_record_required";
|
|
23
|
+
}>;
|
|
24
|
+
bootstrap(db: PostgresJsDatabase, userId: string, input: BootstrapCustomerPortalInput): Promise<BootstrapCustomerPortalResult | {
|
|
25
|
+
error: "not_found" | "customer_record_not_found" | "customer_record_claimed";
|
|
26
|
+
}>;
|
|
27
|
+
listCompanions(db: PostgresJsDatabase, userId: string): Promise<CustomerPortalCompanion[]>;
|
|
28
|
+
importBookingTravelersAsCompanions(db: PostgresJsDatabase, userId: string, input: ImportCustomerPortalBookingTravelersInput): Promise<ImportCustomerPortalBookingTravelersResult | null>;
|
|
29
|
+
importBookingParticipantsAsCompanions(db: PostgresJsDatabase, userId: string, input: ImportCustomerPortalBookingTravelersInput): Promise<ImportCustomerPortalBookingTravelersResult | null>;
|
|
30
|
+
createCompanion(db: PostgresJsDatabase, userId: string, input: CreateCustomerPortalCompanionInput): Promise<CustomerPortalCompanion | null>;
|
|
31
|
+
updateCompanion(db: PostgresJsDatabase, userId: string, companionId: string, input: UpdateCustomerPortalCompanionInput): Promise<CustomerPortalCompanion | null | "forbidden">;
|
|
32
|
+
deleteCompanion(db: PostgresJsDatabase, userId: string, companionId: string): Promise<"deleted" | "not_found" | "forbidden">;
|
|
33
|
+
listBookings(db: PostgresJsDatabase, userId: string): Promise<CustomerPortalBookingSummary[] | null>;
|
|
34
|
+
getBooking(db: PostgresJsDatabase, userId: string, bookingId: string, options?: CustomerPortalServiceOptions): Promise<CustomerPortalBookingDetail | null>;
|
|
35
|
+
listBookingDocuments(db: PostgresJsDatabase, userId: string, bookingId: string, options?: CustomerPortalServiceOptions): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
source: "finance" | "legal" | "booking_document";
|
|
38
|
+
travelerId: string | null;
|
|
39
|
+
type: "visa" | "other" | "insurance" | "health" | "passport_copy" | "invoice" | "proforma" | "credit_note" | "contract";
|
|
40
|
+
fileName: string;
|
|
41
|
+
fileUrl: string;
|
|
42
|
+
mimeType: string | null;
|
|
43
|
+
reference: string | null;
|
|
44
|
+
}[] | null>;
|
|
45
|
+
getBookingBillingContact(db: PostgresJsDatabase, userId: string, bookingId: string): Promise<{
|
|
46
|
+
email: string | null;
|
|
47
|
+
phone: string | null;
|
|
48
|
+
firstName: string | null;
|
|
49
|
+
lastName: string | null;
|
|
50
|
+
country: string | null;
|
|
51
|
+
state: string | null;
|
|
52
|
+
city: string | null;
|
|
53
|
+
address1: string | null;
|
|
54
|
+
address2: string | null;
|
|
55
|
+
postal: string | null;
|
|
56
|
+
} | null>;
|
|
57
|
+
listMyDocuments(db: PostgresJsDatabase, userId: string, options?: CustomerPortalServiceOptions): Promise<{
|
|
58
|
+
id: string;
|
|
59
|
+
type: WireDocumentType;
|
|
60
|
+
number: string | null;
|
|
61
|
+
issuingAuthority: string | null;
|
|
62
|
+
issuingCountry: string | null;
|
|
63
|
+
issueDate: string | null;
|
|
64
|
+
expiryDate: string | null;
|
|
65
|
+
attachmentId: string | null;
|
|
66
|
+
isPrimary: boolean;
|
|
67
|
+
notes: string | null;
|
|
68
|
+
createdAt: string;
|
|
69
|
+
updatedAt: string;
|
|
70
|
+
}[]>;
|
|
71
|
+
createMyDocument(db: PostgresJsDatabase, userId: string, input: {
|
|
72
|
+
type: WireDocumentType;
|
|
73
|
+
number?: string | null;
|
|
74
|
+
issuingAuthority?: string | null;
|
|
75
|
+
issuingCountry?: string | null;
|
|
76
|
+
issueDate?: string | null;
|
|
77
|
+
expiryDate?: string | null;
|
|
78
|
+
attachmentId?: string | null;
|
|
79
|
+
isPrimary?: boolean;
|
|
80
|
+
notes?: string | null;
|
|
81
|
+
}, options?: CustomerPortalServiceOptions): Promise<{
|
|
82
|
+
id: string;
|
|
83
|
+
type: WireDocumentType;
|
|
84
|
+
number: string | null;
|
|
85
|
+
issuingAuthority: string | null;
|
|
86
|
+
issuingCountry: string | null;
|
|
87
|
+
issueDate: string | null;
|
|
88
|
+
expiryDate: string | null;
|
|
89
|
+
attachmentId: string | null;
|
|
90
|
+
isPrimary: boolean;
|
|
91
|
+
notes: string | null;
|
|
92
|
+
createdAt: string;
|
|
93
|
+
updatedAt: string;
|
|
94
|
+
} | null>;
|
|
95
|
+
updateMyDocument(db: PostgresJsDatabase, userId: string, documentId: string, input: {
|
|
96
|
+
type?: WireDocumentType;
|
|
97
|
+
number?: string | null;
|
|
98
|
+
issuingAuthority?: string | null;
|
|
99
|
+
issuingCountry?: string | null;
|
|
100
|
+
issueDate?: string | null;
|
|
101
|
+
expiryDate?: string | null;
|
|
102
|
+
attachmentId?: string | null;
|
|
103
|
+
isPrimary?: boolean;
|
|
104
|
+
notes?: string | null;
|
|
105
|
+
}, options?: CustomerPortalServiceOptions): Promise<{
|
|
106
|
+
id: string;
|
|
107
|
+
type: WireDocumentType;
|
|
108
|
+
number: string | null;
|
|
109
|
+
issuingAuthority: string | null;
|
|
110
|
+
issuingCountry: string | null;
|
|
111
|
+
issueDate: string | null;
|
|
112
|
+
expiryDate: string | null;
|
|
113
|
+
attachmentId: string | null;
|
|
114
|
+
isPrimary: boolean;
|
|
115
|
+
notes: string | null;
|
|
116
|
+
createdAt: string;
|
|
117
|
+
updatedAt: string;
|
|
118
|
+
} | null>;
|
|
119
|
+
deleteMyDocument(db: PostgresJsDatabase, userId: string, documentId: string): Promise<{
|
|
120
|
+
id: string;
|
|
121
|
+
} | null>;
|
|
122
|
+
setPrimaryMyDocument(db: PostgresJsDatabase, userId: string, documentId: string, options?: CustomerPortalServiceOptions): Promise<{
|
|
123
|
+
id: string;
|
|
124
|
+
type: WireDocumentType;
|
|
125
|
+
number: string | null;
|
|
126
|
+
issuingAuthority: string | null;
|
|
127
|
+
issuingCountry: string | null;
|
|
128
|
+
issueDate: string | null;
|
|
129
|
+
expiryDate: string | null;
|
|
130
|
+
attachmentId: string | null;
|
|
131
|
+
isPrimary: boolean;
|
|
132
|
+
notes: string | null;
|
|
133
|
+
createdAt: string;
|
|
134
|
+
updatedAt: string;
|
|
135
|
+
} | null>;
|
|
136
|
+
};
|
|
137
|
+
export {};
|
|
138
|
+
//# sourceMappingURL=service-public-impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-public-impl.d.ts","sourceRoot":"","sources":["../../src/customer-portal/service-public-impl.ts"],"names":[],"mappings":"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"}
|