@voyantjs/storefront 0.6.8 → 0.7.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/dist/routes-public.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export declare function createStorefrontPublicRoutes(options?: StorefrontService
|
|
|
39
39
|
}[];
|
|
40
40
|
}[];
|
|
41
41
|
};
|
|
42
|
-
|
|
42
|
+
travelers: {
|
|
43
43
|
fields: {
|
|
44
44
|
key: string;
|
|
45
45
|
label: string;
|
|
@@ -367,7 +367,7 @@ export declare function createStorefrontPublicRoutes(options?: StorefrontService
|
|
|
367
367
|
applicableDepartureIds: string[];
|
|
368
368
|
validFrom: string | null;
|
|
369
369
|
validTo: string | null;
|
|
370
|
-
|
|
370
|
+
minTravelers: number | null;
|
|
371
371
|
imageMobileUrl: string | null;
|
|
372
372
|
imageDesktopUrl: string | null;
|
|
373
373
|
stackable: boolean;
|
|
@@ -400,7 +400,7 @@ export declare function createStorefrontPublicRoutes(options?: StorefrontService
|
|
|
400
400
|
applicableDepartureIds: string[];
|
|
401
401
|
validFrom: string | null;
|
|
402
402
|
validTo: string | null;
|
|
403
|
-
|
|
403
|
+
minTravelers: number | null;
|
|
404
404
|
imageMobileUrl: string | null;
|
|
405
405
|
imageDesktopUrl: string | null;
|
|
406
406
|
stackable: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-departures.d.ts","sourceRoot":"","sources":["../src/service-departures.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"service-departures.d.ts","sourceRoot":"","sources":["../src/service-departures.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACrC,MAAM,iBAAiB,CAAA;AA00BxB,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAYvF;AAED,wBAAsB,+BAA+B,CACnD,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BpC;AAED,wBAAsB,+BAA+B,CACnD,EAAE,EAAE,kBAAkB,EACtB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,oCAAoC;;;;;;;;;;cAtKlB,MAAM;eAAS,MAAM;kBAAY,MAAM;mBAAa,MAAM;;UAqQpF;AAED,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGlB;AAED,wBAAsB,+BAA+B,CACnD,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;UAyFlD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { availabilitySlots, availabilityStartTimes } from "@voyantjs/availability/schema";
|
|
2
2
|
import { productExtras } from "@voyantjs/extras/schema";
|
|
3
3
|
import { extraPriceRules, optionPriceRules, optionUnitPriceRules, optionUnitTiers, priceCatalogs, } from "@voyantjs/pricing/schema";
|
|
4
|
-
import { optionUnits, productDayServices, productDays, productLocations, productMedia, productOptions, products, } from "@voyantjs/products/schema";
|
|
4
|
+
import { optionUnits, productDayServices, productDays, productItineraries, productLocations, productMedia, productOptions, products, } from "@voyantjs/products/schema";
|
|
5
5
|
import { sellabilityService } from "@voyantjs/sellability";
|
|
6
6
|
import { and, asc, count, desc, eq, gte, inArray, lte, ne } from "drizzle-orm";
|
|
7
7
|
function normalizeIso(value) {
|
|
@@ -93,6 +93,20 @@ async function listMeetingPointsByProductIds(db, productIds) {
|
|
|
93
93
|
}
|
|
94
94
|
return byProduct;
|
|
95
95
|
}
|
|
96
|
+
async function listDefaultItineraryIdsByProductIds(db, productIds) {
|
|
97
|
+
if (productIds.length === 0) {
|
|
98
|
+
return new Map();
|
|
99
|
+
}
|
|
100
|
+
const rows = await db
|
|
101
|
+
.select({
|
|
102
|
+
productId: productItineraries.productId,
|
|
103
|
+
itineraryId: productItineraries.id,
|
|
104
|
+
})
|
|
105
|
+
.from(productItineraries)
|
|
106
|
+
.where(and(inArray(productItineraries.productId, productIds), eq(productItineraries.isDefault, true)))
|
|
107
|
+
.orderBy(asc(productItineraries.sortOrder), asc(productItineraries.createdAt));
|
|
108
|
+
return new Map(rows.map((row) => [row.productId, row.itineraryId]));
|
|
109
|
+
}
|
|
96
110
|
async function listSlots(db, filters = {}) {
|
|
97
111
|
const conditions = [
|
|
98
112
|
eq(products.status, "active"),
|
|
@@ -124,6 +138,7 @@ async function listSlots(db, filters = {}) {
|
|
|
124
138
|
.select({
|
|
125
139
|
id: availabilitySlots.id,
|
|
126
140
|
productId: availabilitySlots.productId,
|
|
141
|
+
itineraryId: availabilitySlots.itineraryId,
|
|
127
142
|
optionId: availabilitySlots.optionId,
|
|
128
143
|
startTimeId: availabilitySlots.startTimeId,
|
|
129
144
|
dateLocal: availabilitySlots.dateLocal,
|
|
@@ -415,7 +430,7 @@ function computeFallbackLineItems(args) {
|
|
|
415
430
|
? args.context.units.find((row) => row.id === request.unitId)
|
|
416
431
|
: null;
|
|
417
432
|
lineItems.push({
|
|
418
|
-
name: unit?.name ?? args.context.option?.name ?? "
|
|
433
|
+
name: unit?.name ?? args.context.option?.name ?? "Traveler",
|
|
419
434
|
total: totalAmount,
|
|
420
435
|
quantity: request.quantity,
|
|
421
436
|
unitPrice: unitAmount,
|
|
@@ -489,12 +504,13 @@ async function applyExtraLineItems(args) {
|
|
|
489
504
|
total: Number(total.toFixed(2)),
|
|
490
505
|
};
|
|
491
506
|
}
|
|
492
|
-
async function buildDeparture(db, slot, meetingPointByProduct) {
|
|
507
|
+
async function buildDeparture(db, slot, defaultItineraryByProduct, meetingPointByProduct) {
|
|
493
508
|
const context = await resolvePricingContext(db, slot.productId, slot.optionId);
|
|
509
|
+
const itineraryId = slot.itineraryId ?? defaultItineraryByProduct.get(slot.productId) ?? null;
|
|
494
510
|
return {
|
|
495
511
|
id: slot.id,
|
|
496
512
|
productId: slot.productId,
|
|
497
|
-
itineraryId: slot.id,
|
|
513
|
+
itineraryId: itineraryId ?? slot.id,
|
|
498
514
|
optionId: slot.optionId,
|
|
499
515
|
dateLocal: normalizeLocalDate(slot.dateLocal),
|
|
500
516
|
startAt: normalizeIso(slot.startsAt),
|
|
@@ -522,8 +538,11 @@ export async function getStorefrontDeparture(db, departureId) {
|
|
|
522
538
|
if (!slot) {
|
|
523
539
|
return null;
|
|
524
540
|
}
|
|
525
|
-
const meetingPointByProduct = await
|
|
526
|
-
|
|
541
|
+
const [meetingPointByProduct, defaultItineraryByProduct] = await Promise.all([
|
|
542
|
+
listMeetingPointsByProductIds(db, [slot.productId]),
|
|
543
|
+
listDefaultItineraryIdsByProductIds(db, [slot.productId]),
|
|
544
|
+
]);
|
|
545
|
+
return buildDeparture(db, slot, defaultItineraryByProduct, meetingPointByProduct);
|
|
527
546
|
}
|
|
528
547
|
export async function listStorefrontProductDepartures(db, productId, query) {
|
|
529
548
|
const filters = {
|
|
@@ -541,8 +560,11 @@ export async function listStorefrontProductDepartures(db, productId, query) {
|
|
|
541
560
|
}),
|
|
542
561
|
countSlots(db, filters),
|
|
543
562
|
]);
|
|
544
|
-
const meetingPointByProduct = await
|
|
545
|
-
|
|
563
|
+
const [meetingPointByProduct, defaultItineraryByProduct] = await Promise.all([
|
|
564
|
+
listMeetingPointsByProductIds(db, [productId]),
|
|
565
|
+
listDefaultItineraryIdsByProductIds(db, [productId]),
|
|
566
|
+
]);
|
|
567
|
+
const data = await Promise.all(slots.map((slot) => buildDeparture(db, slot, defaultItineraryByProduct, meetingPointByProduct)));
|
|
546
568
|
return {
|
|
547
569
|
data,
|
|
548
570
|
total,
|
|
@@ -711,6 +733,16 @@ export async function getStorefrontProductExtensions(db, productId, optionId) {
|
|
|
711
733
|
};
|
|
712
734
|
}
|
|
713
735
|
export async function getStorefrontDepartureItinerary(db, input) {
|
|
736
|
+
const [slot] = await listSlots(db, {
|
|
737
|
+
productId: input.productId,
|
|
738
|
+
slotId: input.departureId,
|
|
739
|
+
limit: 1,
|
|
740
|
+
});
|
|
741
|
+
const defaultItineraryByProduct = await listDefaultItineraryIdsByProductIds(db, [input.productId]);
|
|
742
|
+
const itineraryId = slot?.itineraryId ?? defaultItineraryByProduct.get(input.productId);
|
|
743
|
+
if (!itineraryId) {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
714
746
|
const days = await db
|
|
715
747
|
.select({
|
|
716
748
|
id: productDays.id,
|
|
@@ -719,7 +751,7 @@ export async function getStorefrontDepartureItinerary(db, input) {
|
|
|
719
751
|
description: productDays.description,
|
|
720
752
|
})
|
|
721
753
|
.from(productDays)
|
|
722
|
-
.where(eq(productDays.
|
|
754
|
+
.where(eq(productDays.itineraryId, itineraryId))
|
|
723
755
|
.orderBy(asc(productDays.dayNumber));
|
|
724
756
|
if (days.length === 0) {
|
|
725
757
|
return null;
|
package/dist/service.js
CHANGED
|
@@ -47,8 +47,8 @@ export function resolveStorefrontSettings(input) {
|
|
|
47
47
|
billing: {
|
|
48
48
|
fields: (parsed.forms?.billing?.fields ?? []).map(normalizeField),
|
|
49
49
|
},
|
|
50
|
-
|
|
51
|
-
fields: (parsed.forms?.
|
|
50
|
+
travelers: {
|
|
51
|
+
fields: (parsed.forms?.travelers?.fields ?? []).map(normalizeField),
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
54
|
payment: {
|
package/dist/validation.d.ts
CHANGED
|
@@ -127,7 +127,7 @@ export declare const storefrontSettingsInputSchema: z.ZodObject<{
|
|
|
127
127
|
}, z.core.$strip>>>;
|
|
128
128
|
}, z.core.$strip>>>;
|
|
129
129
|
}, z.core.$strip>>;
|
|
130
|
-
|
|
130
|
+
travelers: z.ZodOptional<z.ZodObject<{
|
|
131
131
|
fields: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
132
132
|
key: z.ZodString;
|
|
133
133
|
label: z.ZodString;
|
|
@@ -213,7 +213,7 @@ export declare const storefrontSettingsSchema: z.ZodObject<{
|
|
|
213
213
|
}, z.core.$strip>>;
|
|
214
214
|
}, z.core.$strip>>;
|
|
215
215
|
}, z.core.$strip>;
|
|
216
|
-
|
|
216
|
+
travelers: z.ZodObject<{
|
|
217
217
|
fields: z.ZodArray<z.ZodObject<{
|
|
218
218
|
key: z.ZodString;
|
|
219
219
|
label: z.ZodString;
|
|
@@ -615,7 +615,7 @@ export declare const storefrontPromotionalOfferSchema: z.ZodObject<{
|
|
|
615
615
|
applicableDepartureIds: z.ZodArray<z.ZodString>;
|
|
616
616
|
validFrom: z.ZodNullable<z.ZodString>;
|
|
617
617
|
validTo: z.ZodNullable<z.ZodString>;
|
|
618
|
-
|
|
618
|
+
minTravelers: z.ZodNullable<z.ZodNumber>;
|
|
619
619
|
imageMobileUrl: z.ZodNullable<z.ZodString>;
|
|
620
620
|
imageDesktopUrl: z.ZodNullable<z.ZodString>;
|
|
621
621
|
stackable: z.ZodBoolean;
|
|
@@ -642,7 +642,7 @@ export declare const storefrontPromotionalOfferListResponseSchema: z.ZodObject<{
|
|
|
642
642
|
applicableDepartureIds: z.ZodArray<z.ZodString>;
|
|
643
643
|
validFrom: z.ZodNullable<z.ZodString>;
|
|
644
644
|
validTo: z.ZodNullable<z.ZodString>;
|
|
645
|
-
|
|
645
|
+
minTravelers: z.ZodNullable<z.ZodNumber>;
|
|
646
646
|
imageMobileUrl: z.ZodNullable<z.ZodString>;
|
|
647
647
|
imageDesktopUrl: z.ZodNullable<z.ZodString>;
|
|
648
648
|
stackable: z.ZodBoolean;
|
|
@@ -666,7 +666,7 @@ export declare const storefrontPromotionalOfferResponseSchema: z.ZodObject<{
|
|
|
666
666
|
applicableDepartureIds: z.ZodArray<z.ZodString>;
|
|
667
667
|
validFrom: z.ZodNullable<z.ZodString>;
|
|
668
668
|
validTo: z.ZodNullable<z.ZodString>;
|
|
669
|
-
|
|
669
|
+
minTravelers: z.ZodNullable<z.ZodNumber>;
|
|
670
670
|
imageMobileUrl: z.ZodNullable<z.ZodString>;
|
|
671
671
|
imageDesktopUrl: z.ZodNullable<z.ZodString>;
|
|
672
672
|
stackable: z.ZodBoolean;
|
package/dist/validation.js
CHANGED
|
@@ -86,7 +86,7 @@ export const storefrontSettingsInputSchema = z.object({
|
|
|
86
86
|
fields: z.array(storefrontFormFieldInputSchema).default([]),
|
|
87
87
|
})
|
|
88
88
|
.optional(),
|
|
89
|
-
|
|
89
|
+
travelers: z
|
|
90
90
|
.object({
|
|
91
91
|
fields: z.array(storefrontFormFieldInputSchema).default([]),
|
|
92
92
|
})
|
|
@@ -118,7 +118,7 @@ export const storefrontSettingsSchema = z.object({
|
|
|
118
118
|
billing: z.object({
|
|
119
119
|
fields: z.array(storefrontFormFieldSchema),
|
|
120
120
|
}),
|
|
121
|
-
|
|
121
|
+
travelers: z.object({
|
|
122
122
|
fields: z.array(storefrontFormFieldSchema),
|
|
123
123
|
}),
|
|
124
124
|
}),
|
|
@@ -302,7 +302,7 @@ export const storefrontPromotionalOfferSchema = z.object({
|
|
|
302
302
|
applicableDepartureIds: z.array(z.string()),
|
|
303
303
|
validFrom: z.string().nullable(),
|
|
304
304
|
validTo: z.string().nullable(),
|
|
305
|
-
|
|
305
|
+
minTravelers: z.number().int().nullable(),
|
|
306
306
|
imageMobileUrl: z.string().nullable(),
|
|
307
307
|
imageDesktopUrl: z.string().nullable(),
|
|
308
308
|
stackable: z.boolean(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/storefront",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"license": "FSL-1.1-Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
"drizzle-orm": "^0.45.2",
|
|
26
26
|
"hono": "^4.12.10",
|
|
27
27
|
"zod": "^4.3.6",
|
|
28
|
-
"@voyantjs/
|
|
29
|
-
"@voyantjs/
|
|
30
|
-
"@voyantjs/
|
|
31
|
-
"@voyantjs/hono": "0.
|
|
32
|
-
"@voyantjs/pricing": "0.
|
|
33
|
-
"@voyantjs/
|
|
34
|
-
"@voyantjs/
|
|
28
|
+
"@voyantjs/availability": "0.7.0",
|
|
29
|
+
"@voyantjs/core": "0.7.0",
|
|
30
|
+
"@voyantjs/extras": "0.7.0",
|
|
31
|
+
"@voyantjs/hono": "0.7.0",
|
|
32
|
+
"@voyantjs/pricing": "0.7.0",
|
|
33
|
+
"@voyantjs/products": "0.7.0",
|
|
34
|
+
"@voyantjs/sellability": "0.7.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"typescript": "^6.0.2",
|
|
38
38
|
"vitest": "^4.1.2",
|
|
39
|
-
"@voyantjs/db": "0.
|
|
39
|
+
"@voyantjs/db": "0.7.0",
|
|
40
40
|
"@voyantjs/voyant-typescript-config": "0.1.0"
|
|
41
41
|
},
|
|
42
42
|
"files": [
|