@voyantjs/storefront 0.23.0 → 0.24.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/storefront",
3
- "version": "0.23.0",
3
+ "version": "0.24.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -29,18 +29,18 @@
29
29
  "drizzle-orm": "^0.45.2",
30
30
  "hono": "^4.12.10",
31
31
  "zod": "^4.3.6",
32
- "@voyantjs/availability": "0.23.0",
33
- "@voyantjs/core": "0.23.0",
34
- "@voyantjs/extras": "0.23.0",
35
- "@voyantjs/hono": "0.23.0",
36
- "@voyantjs/pricing": "0.23.0",
37
- "@voyantjs/products": "0.23.0",
38
- "@voyantjs/sellability": "0.23.0"
32
+ "@voyantjs/availability": "0.24.1",
33
+ "@voyantjs/core": "0.24.1",
34
+ "@voyantjs/extras": "0.24.1",
35
+ "@voyantjs/hono": "0.24.1",
36
+ "@voyantjs/pricing": "0.24.1",
37
+ "@voyantjs/products": "0.24.1",
38
+ "@voyantjs/sellability": "0.24.1"
39
39
  },
40
40
  "devDependencies": {
41
41
  "typescript": "^6.0.2",
42
42
  "vitest": "^4.1.2",
43
- "@voyantjs/db": "0.23.0",
43
+ "@voyantjs/db": "0.24.1",
44
44
  "@voyantjs/voyant-typescript-config": "0.1.0"
45
45
  },
46
46
  "files": [
package/dist/index.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { Module } from "@voyantjs/core";
2
- import type { HonoModule } from "@voyantjs/hono/module";
3
- import { createStorefrontPublicRoutes } from "./routes-public.js";
4
- export type { StorefrontPublicRoutes } from "./routes-public.js";
5
- export { createStorefrontPublicRoutes } from "./routes-public.js";
6
- export type { StorefrontOfferResolvers, StorefrontRequestContext, StorefrontServiceOptions, } from "./service.js";
7
- export { createStorefrontService, resolveStorefrontSettings } from "./service.js";
8
- export type { StorefrontDepartureListQuery, StorefrontFormField, StorefrontFormFieldInput, StorefrontPaymentMethod, StorefrontPaymentMethodCode, StorefrontPaymentMethodInput, StorefrontProductAvailabilitySummaryQuery, StorefrontPromotionalOffer, StorefrontSettings, StorefrontSettingsInput, } from "./validation.js";
9
- export { storefrontDepartureItinerarySchema, storefrontDepartureListQuerySchema, storefrontDepartureListResponseSchema, storefrontDeparturePricePreviewInputSchema, storefrontDeparturePricePreviewSchema, storefrontDepartureSchema, storefrontFormFieldInputSchema, storefrontFormFieldOptionSchema, storefrontFormFieldSchema, storefrontFormFieldTypeSchema, storefrontPaymentMethodCodeSchema, storefrontPaymentMethodInputSchema, storefrontPaymentMethodSchema, storefrontProductAvailabilitySlotSchema, storefrontProductAvailabilityStateSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductAvailabilitySummaryResponseSchema, storefrontProductAvailabilitySummarySchema, storefrontProductExtensionsQuerySchema, storefrontProductExtensionsResponseSchema, storefrontPromotionalOfferListQuerySchema, storefrontPromotionalOfferListResponseSchema, storefrontPromotionalOfferResponseSchema, storefrontPromotionalOfferSchema, storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
10
- export declare const storefrontModule: Module;
11
- export declare function createStorefrontHonoModule(options?: Parameters<typeof createStorefrontPublicRoutes>[0]): HonoModule;
12
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
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,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,EAC3B,4BAA4B,EAC5B,yCAAyC,EACzC,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,kCAAkC,EAClC,kCAAkC,EAClC,qCAAqC,EACrC,0CAA0C,EAC1C,qCAAqC,EACrC,yBAAyB,EACzB,8BAA8B,EAC9B,+BAA+B,EAC/B,yBAAyB,EACzB,6BAA6B,EAC7B,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;AAExB,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 DELETED
@@ -1,14 +0,0 @@
1
- import { createStorefrontPublicRoutes } from "./routes-public.js";
2
- export { createStorefrontPublicRoutes } from "./routes-public.js";
3
- export { createStorefrontService, resolveStorefrontSettings } from "./service.js";
4
- export { storefrontDepartureItinerarySchema, storefrontDepartureListQuerySchema, storefrontDepartureListResponseSchema, storefrontDeparturePricePreviewInputSchema, storefrontDeparturePricePreviewSchema, storefrontDepartureSchema, storefrontFormFieldInputSchema, storefrontFormFieldOptionSchema, storefrontFormFieldSchema, storefrontFormFieldTypeSchema, storefrontPaymentMethodCodeSchema, storefrontPaymentMethodInputSchema, storefrontPaymentMethodSchema, storefrontProductAvailabilitySlotSchema, storefrontProductAvailabilityStateSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductAvailabilitySummaryResponseSchema, storefrontProductAvailabilitySummarySchema, storefrontProductExtensionsQuerySchema, storefrontProductExtensionsResponseSchema, storefrontPromotionalOfferListQuerySchema, storefrontPromotionalOfferListResponseSchema, storefrontPromotionalOfferResponseSchema, storefrontPromotionalOfferSchema, storefrontSettingsInputSchema, storefrontSettingsSchema, } from "./validation.js";
5
- export const storefrontModule = {
6
- name: "storefront",
7
- };
8
- export function createStorefrontHonoModule(options) {
9
- return {
10
- module: storefrontModule,
11
- publicPath: "/",
12
- publicRoutes: createStorefrontPublicRoutes(options),
13
- };
14
- }
@@ -1,476 +0,0 @@
1
- import { type StorefrontServiceOptions } from "./service.js";
2
- type Env = {
3
- Variables: {
4
- db: unknown;
5
- };
6
- };
7
- export declare function createStorefrontPublicRoutes(options?: StorefrontServiceOptions): import("hono/hono-base").HonoBase<Env, {
8
- "/settings": {
9
- $get: {
10
- input: {};
11
- output: {
12
- data: {
13
- branding: {
14
- logoUrl: string | null;
15
- supportedLanguages: string[];
16
- };
17
- support: {
18
- email: string | null;
19
- phone: string | null;
20
- };
21
- legal: {
22
- termsUrl: string | null;
23
- privacyUrl: string | null;
24
- defaultContractTemplateId: string | null;
25
- };
26
- forms: {
27
- billing: {
28
- fields: {
29
- key: string;
30
- label: string;
31
- type: "date" | "select" | "email" | "text" | "country" | "tel" | "textarea" | "checkbox";
32
- required: boolean;
33
- placeholder: string | null;
34
- description: string | null;
35
- autocomplete: string | null;
36
- options: {
37
- value: string;
38
- label: string;
39
- }[];
40
- }[];
41
- };
42
- travelers: {
43
- fields: {
44
- key: string;
45
- label: string;
46
- type: "date" | "select" | "email" | "text" | "country" | "tel" | "textarea" | "checkbox";
47
- required: boolean;
48
- placeholder: string | null;
49
- description: string | null;
50
- autocomplete: string | null;
51
- options: {
52
- value: string;
53
- label: string;
54
- }[];
55
- }[];
56
- };
57
- };
58
- payment: {
59
- defaultMethod: "voucher" | "card" | "bank_transfer" | "cash" | "invoice" | null;
60
- methods: {
61
- code: "voucher" | "card" | "bank_transfer" | "cash" | "invoice";
62
- label: string;
63
- description: string | null;
64
- enabled: boolean;
65
- }[];
66
- };
67
- };
68
- };
69
- outputFormat: "json";
70
- status: import("hono/utils/http-status").ContentfulStatusCode;
71
- };
72
- };
73
- } & {
74
- "/departures/:departureId": {
75
- $get: {
76
- input: {
77
- param: {
78
- departureId: string;
79
- };
80
- };
81
- output: {
82
- data: {
83
- id: string;
84
- productId: string;
85
- itineraryId: string;
86
- optionId: string | null;
87
- dateLocal: string | null;
88
- startAt: string | null;
89
- endAt: string | null;
90
- timezone: string;
91
- startTime: {
92
- id: string;
93
- label: string | null;
94
- startTimeLocal: string;
95
- durationMinutes: number | null;
96
- } | null;
97
- meetingPoint: string | null;
98
- capacity: number | null;
99
- remaining: number | null;
100
- departureStatus: "open" | "closed" | "sold_out" | "cancelled" | "on_request";
101
- nights: number | null;
102
- days: number | null;
103
- ratePlans: {
104
- id: string;
105
- active: boolean;
106
- name: string;
107
- pricingModel: string;
108
- basePrices: {
109
- amount: number;
110
- currencyCode: string;
111
- }[];
112
- roomPrices: {
113
- amount: number;
114
- currencyCode: string;
115
- roomType: {
116
- id: string;
117
- name: string;
118
- occupancy: {
119
- adultsMin: number;
120
- adultsMax: number;
121
- childrenMax: number;
122
- };
123
- };
124
- }[];
125
- }[];
126
- };
127
- };
128
- outputFormat: "json";
129
- status: import("hono/utils/http-status").ContentfulStatusCode;
130
- } | {
131
- input: {
132
- param: {
133
- departureId: string;
134
- };
135
- };
136
- output: {
137
- error: string;
138
- };
139
- outputFormat: "json";
140
- status: 404;
141
- };
142
- };
143
- } & {
144
- "/products/:productId/departures": {
145
- $get: {
146
- input: {
147
- param: {
148
- productId: string;
149
- };
150
- };
151
- output: {
152
- data: {
153
- id: string;
154
- productId: string;
155
- itineraryId: string;
156
- optionId: string | null;
157
- dateLocal: string | null;
158
- startAt: string | null;
159
- endAt: string | null;
160
- timezone: string;
161
- startTime: {
162
- id: string;
163
- label: string | null;
164
- startTimeLocal: string;
165
- durationMinutes: number | null;
166
- } | null;
167
- meetingPoint: string | null;
168
- capacity: number | null;
169
- remaining: number | null;
170
- departureStatus: "open" | "closed" | "sold_out" | "cancelled" | "on_request";
171
- nights: number | null;
172
- days: number | null;
173
- ratePlans: {
174
- id: string;
175
- active: boolean;
176
- name: string;
177
- pricingModel: string;
178
- basePrices: {
179
- amount: number;
180
- currencyCode: string;
181
- }[];
182
- roomPrices: {
183
- amount: number;
184
- currencyCode: string;
185
- roomType: {
186
- id: string;
187
- name: string;
188
- occupancy: {
189
- adultsMin: number;
190
- adultsMax: number;
191
- childrenMax: number;
192
- };
193
- };
194
- }[];
195
- }[];
196
- }[];
197
- total: number;
198
- limit: number;
199
- offset: number;
200
- };
201
- outputFormat: "json";
202
- status: import("hono/utils/http-status").ContentfulStatusCode;
203
- };
204
- };
205
- } & {
206
- "/departures/:departureId/price": {
207
- $post: {
208
- input: {
209
- param: {
210
- departureId: string;
211
- };
212
- };
213
- output: {
214
- data: {
215
- departureId: string;
216
- productId: string;
217
- optionId: string | null;
218
- currencyCode: string;
219
- basePrice: number;
220
- taxAmount: number;
221
- total: number;
222
- notes: string | null;
223
- lineItems: {
224
- name: string;
225
- total: number;
226
- quantity: number;
227
- unitPrice: number;
228
- }[];
229
- };
230
- };
231
- outputFormat: "json";
232
- status: import("hono/utils/http-status").ContentfulStatusCode;
233
- } | {
234
- input: {
235
- param: {
236
- departureId: string;
237
- };
238
- };
239
- output: {
240
- error: string;
241
- };
242
- outputFormat: "json";
243
- status: 404;
244
- };
245
- };
246
- } & {
247
- "/products/:productId/extensions": {
248
- $get: {
249
- input: {
250
- param: {
251
- productId: string;
252
- };
253
- };
254
- output: {
255
- data: {
256
- extensions: {
257
- id: string;
258
- name: string;
259
- label: string;
260
- required: boolean;
261
- selectable: boolean;
262
- hasOptions: boolean;
263
- refProductId: string | null;
264
- thumb: string | null;
265
- pricePerPerson: number | null;
266
- currencyCode: string;
267
- pricingMode: string;
268
- defaultQuantity: number | null;
269
- minQuantity: number | null;
270
- maxQuantity: number | null;
271
- }[];
272
- items: {
273
- id: string;
274
- name: string;
275
- label: string;
276
- required: boolean;
277
- selectable: boolean;
278
- hasOptions: boolean;
279
- refProductId: string | null;
280
- thumb: string | null;
281
- pricePerPerson: number | null;
282
- currencyCode: string;
283
- pricingMode: string;
284
- defaultQuantity: number | null;
285
- minQuantity: number | null;
286
- maxQuantity: number | null;
287
- }[];
288
- details: {
289
- [x: string]: {
290
- description: string | null;
291
- media: {
292
- url: string;
293
- alt: string | null;
294
- }[];
295
- };
296
- };
297
- currencyCode: string;
298
- };
299
- };
300
- outputFormat: "json";
301
- status: import("hono/utils/http-status").ContentfulStatusCode;
302
- };
303
- };
304
- } & {
305
- "/products/:productId/availability": {
306
- $get: {
307
- input: {
308
- param: {
309
- productId: string;
310
- };
311
- };
312
- output: {
313
- data: {
314
- productId: string;
315
- availabilityState: "closed" | "sold_out" | "cancelled" | "past_cutoff" | "too_early" | "unavailable" | "on_request" | "available";
316
- counts: {
317
- total: number;
318
- open: number;
319
- closed: number;
320
- soldOut: number;
321
- cancelled: number;
322
- onRequest: number;
323
- pastCutoff: number;
324
- tooEarly: number;
325
- available: number;
326
- };
327
- departures: {
328
- id: string;
329
- productId: string;
330
- optionId: string | null;
331
- dateLocal: string | null;
332
- startAt: string | null;
333
- endAt: string | null;
334
- timezone: string;
335
- status: "open" | "closed" | "sold_out" | "cancelled" | "on_request";
336
- availabilityState: "closed" | "sold_out" | "cancelled" | "past_cutoff" | "too_early" | "unavailable" | "on_request" | "available";
337
- capacity: number | null;
338
- remaining: number | null;
339
- pastCutoff: boolean;
340
- tooEarly: boolean;
341
- }[];
342
- total: number;
343
- limit: number;
344
- offset: number;
345
- };
346
- };
347
- outputFormat: "json";
348
- status: import("hono/utils/http-status").ContentfulStatusCode;
349
- };
350
- };
351
- } & {
352
- "/products/:productId/departures/:departureId/itinerary": {
353
- $get: {
354
- input: {
355
- param: {
356
- departureId: string;
357
- } & {
358
- productId: string;
359
- };
360
- };
361
- output: {
362
- data: {
363
- id: string;
364
- days: {
365
- id: string;
366
- title: string;
367
- description: string | null;
368
- thumbnail: {
369
- url: string;
370
- } | null;
371
- segments: {
372
- id: string;
373
- title: string;
374
- description: string | null;
375
- }[];
376
- }[];
377
- };
378
- };
379
- outputFormat: "json";
380
- status: import("hono/utils/http-status").ContentfulStatusCode;
381
- } | {
382
- input: {
383
- param: {
384
- departureId: string;
385
- } & {
386
- productId: string;
387
- };
388
- };
389
- output: {
390
- error: string;
391
- };
392
- outputFormat: "json";
393
- status: 404;
394
- };
395
- };
396
- } & {
397
- "/products/:productId/offers": {
398
- $get: {
399
- input: {
400
- param: {
401
- productId: string;
402
- };
403
- };
404
- output: {
405
- data: {
406
- id: string;
407
- name: string;
408
- slug: string | null;
409
- description: string | null;
410
- discountType: "percentage" | "fixed_amount";
411
- discountValue: string;
412
- currency: string | null;
413
- applicableProductIds: string[];
414
- applicableDepartureIds: string[];
415
- validFrom: string | null;
416
- validTo: string | null;
417
- minTravelers: number | null;
418
- imageMobileUrl: string | null;
419
- imageDesktopUrl: string | null;
420
- stackable: boolean;
421
- createdAt: string;
422
- updatedAt: string;
423
- }[];
424
- };
425
- outputFormat: "json";
426
- status: import("hono/utils/http-status").ContentfulStatusCode;
427
- };
428
- };
429
- } & {
430
- "/offers/:slug": {
431
- $get: {
432
- input: {
433
- param: {
434
- slug: string;
435
- };
436
- };
437
- output: {
438
- data: {
439
- id: string;
440
- name: string;
441
- slug: string | null;
442
- description: string | null;
443
- discountType: "percentage" | "fixed_amount";
444
- discountValue: string;
445
- currency: string | null;
446
- applicableProductIds: string[];
447
- applicableDepartureIds: string[];
448
- validFrom: string | null;
449
- validTo: string | null;
450
- minTravelers: number | null;
451
- imageMobileUrl: string | null;
452
- imageDesktopUrl: string | null;
453
- stackable: boolean;
454
- createdAt: string;
455
- updatedAt: string;
456
- };
457
- };
458
- outputFormat: "json";
459
- status: import("hono/utils/http-status").ContentfulStatusCode;
460
- } | {
461
- input: {
462
- param: {
463
- slug: string;
464
- };
465
- };
466
- output: {
467
- error: string;
468
- };
469
- outputFormat: "json";
470
- status: 404;
471
- };
472
- };
473
- }, "/", "/offers/:slug">;
474
- export type StorefrontPublicRoutes = ReturnType<typeof createStorefrontPublicRoutes>;
475
- export {};
476
- //# sourceMappingURL=routes-public.d.ts.map
@@ -1 +0,0 @@
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;AASrB,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,OAAO,CAAA;KACZ,CAAA;CACF,CAAA;AAED,wBAAgB,4BAA4B,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAiG9E;AAED,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAA"}
@@ -1,73 +0,0 @@
1
- import { parseJsonBody, parseQuery } from "@voyantjs/hono";
2
- import { Hono } from "hono";
3
- import { createStorefrontService, } from "./service.js";
4
- import { storefrontDepartureListQuerySchema, storefrontDeparturePricePreviewInputSchema, storefrontProductAvailabilitySummaryQuerySchema, storefrontProductExtensionsQuerySchema, storefrontPromotionalOfferListQuerySchema, } from "./validation.js";
5
- export function createStorefrontPublicRoutes(options) {
6
- const storefrontService = createStorefrontService(options);
7
- function getRequestContext(c) {
8
- return {
9
- db: c.get("db"),
10
- env: c.env,
11
- context: c,
12
- };
13
- }
14
- return new Hono()
15
- .get("/settings", async (c) => {
16
- return c.json({ data: await storefrontService.resolveSettings(getRequestContext(c)) });
17
- })
18
- .get("/departures/:departureId", async (c) => {
19
- const departure = await storefrontService.getDeparture(c.get("db"), c.req.param("departureId"));
20
- return departure
21
- ? c.json({ data: departure })
22
- : c.json({ error: "Storefront departure not found" }, 404);
23
- })
24
- .get("/products/:productId/departures", async (c) => {
25
- return c.json(await storefrontService.listProductDepartures(c.get("db"), c.req.param("productId"), await parseQuery(c, storefrontDepartureListQuerySchema)));
26
- })
27
- .post("/departures/:departureId/price", async (c) => {
28
- const preview = await storefrontService.previewDeparturePrice(c.get("db"), c.req.param("departureId"), await parseJsonBody(c, storefrontDeparturePricePreviewInputSchema));
29
- return preview
30
- ? c.json({ data: preview })
31
- : c.json({ error: "Storefront departure not found" }, 404);
32
- })
33
- .get("/products/:productId/extensions", async (c) => {
34
- const query = await parseQuery(c, storefrontProductExtensionsQuerySchema);
35
- return c.json({
36
- data: await storefrontService.getProductExtensions(c.get("db"), c.req.param("productId"), query.optionId),
37
- });
38
- })
39
- .get("/products/:productId/availability", async (c) => {
40
- return c.json({
41
- data: await storefrontService.getProductAvailabilitySummary(c.get("db"), c.req.param("productId"), await parseQuery(c, storefrontProductAvailabilitySummaryQuerySchema)),
42
- });
43
- })
44
- .get("/products/:productId/departures/:departureId/itinerary", async (c) => {
45
- const itinerary = await storefrontService.getDepartureItinerary(c.get("db"), {
46
- departureId: c.req.param("departureId"),
47
- productId: c.req.param("productId"),
48
- });
49
- return itinerary
50
- ? c.json({ data: itinerary })
51
- : c.json({ error: "Storefront itinerary not found" }, 404);
52
- })
53
- .get("/products/:productId/offers", async (c) => {
54
- const query = await parseQuery(c, storefrontPromotionalOfferListQuerySchema);
55
- return c.json({
56
- data: await storefrontService.listApplicableOffers({
57
- productId: c.req.param("productId"),
58
- departureId: query.departureId,
59
- locale: query.locale,
60
- context: getRequestContext(c),
61
- }),
62
- });
63
- })
64
- .get("/offers/:slug", async (c) => {
65
- const query = await parseQuery(c, storefrontPromotionalOfferListQuerySchema);
66
- const offer = await storefrontService.getOfferBySlug({
67
- slug: c.req.param("slug"),
68
- locale: query.locale,
69
- context: getRequestContext(c),
70
- });
71
- return offer ? c.json({ data: offer }) : c.json({ error: "Storefront offer not found" }, 404);
72
- });
73
- }