@voyant-travel/cruises 0.118.2
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 +50 -0
- package/dist/adapters/connect-compat.d.ts +20 -0
- package/dist/adapters/connect-compat.d.ts.map +1 -0
- package/dist/adapters/connect-compat.js +71 -0
- package/dist/adapters/contract-fixture.d.ts +32 -0
- package/dist/adapters/contract-fixture.d.ts.map +1 -0
- package/dist/adapters/contract-fixture.js +152 -0
- package/dist/adapters/index.d.ts +331 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +16 -0
- package/dist/adapters/memoize.d.ts +28 -0
- package/dist/adapters/memoize.d.ts.map +1 -0
- package/dist/adapters/memoize.js +131 -0
- package/dist/adapters/mock.d.ts +44 -0
- package/dist/adapters/mock.d.ts.map +1 -0
- package/dist/adapters/mock.js +192 -0
- package/dist/adapters/registry.d.ts +26 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +42 -0
- package/dist/adapters/source-adapter-shim.d.ts +80 -0
- package/dist/adapters/source-adapter-shim.d.ts.map +1 -0
- package/dist/adapters/source-adapter-shim.js +390 -0
- package/dist/booking-engine/handler.d.ts +108 -0
- package/dist/booking-engine/handler.d.ts.map +1 -0
- package/dist/booking-engine/handler.js +225 -0
- package/dist/booking-engine/index.d.ts +9 -0
- package/dist/booking-engine/index.d.ts.map +1 -0
- package/dist/booking-engine/index.js +8 -0
- package/dist/booking-extension.d.ts +1179 -0
- package/dist/booking-extension.d.ts.map +1 -0
- package/dist/booking-extension.js +342 -0
- package/dist/cabin-features.d.ts +8 -0
- package/dist/cabin-features.d.ts.map +1 -0
- package/dist/cabin-features.js +7 -0
- package/dist/catalog-policy-cabins.d.ts +18 -0
- package/dist/catalog-policy-cabins.d.ts.map +1 -0
- package/dist/catalog-policy-cabins.js +96 -0
- package/dist/catalog-policy-core.d.ts +3 -0
- package/dist/catalog-policy-core.d.ts.map +1 -0
- package/dist/catalog-policy-core.js +247 -0
- package/dist/catalog-policy-structure.d.ts +3 -0
- package/dist/catalog-policy-structure.d.ts.map +1 -0
- package/dist/catalog-policy-structure.js +387 -0
- package/dist/catalog-policy.d.ts +15 -0
- package/dist/catalog-policy.d.ts.map +1 -0
- package/dist/catalog-policy.js +19 -0
- package/dist/content-shape.d.ts +5 -0
- package/dist/content-shape.d.ts.map +1 -0
- package/dist/content-shape.js +13 -0
- package/dist/draft-shape.d.ts +59 -0
- package/dist/draft-shape.d.ts.map +1 -0
- package/dist/draft-shape.js +98 -0
- package/dist/events.d.ts +21 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +21 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/lib/key.d.ts +41 -0
- package/dist/lib/key.d.ts.map +1 -0
- package/dist/lib/key.js +100 -0
- package/dist/routes-booking-payloads.d.ts +133 -0
- package/dist/routes-booking-payloads.d.ts.map +1 -0
- package/dist/routes-booking-payloads.js +142 -0
- package/dist/routes-content.d.ts +53 -0
- package/dist/routes-content.d.ts.map +1 -0
- package/dist/routes-content.js +158 -0
- package/dist/routes-core.d.ts +4 -0
- package/dist/routes-core.d.ts.map +1 -0
- package/dist/routes-core.js +68 -0
- package/dist/routes-detail.d.ts +4 -0
- package/dist/routes-detail.d.ts.map +1 -0
- package/dist/routes-detail.js +261 -0
- package/dist/routes-env.d.ts +13 -0
- package/dist/routes-env.d.ts.map +1 -0
- package/dist/routes-env.js +1 -0
- package/dist/routes-keying.d.ts +28 -0
- package/dist/routes-keying.d.ts.map +1 -0
- package/dist/routes-keying.js +70 -0
- package/dist/routes-public.d.ts +911 -0
- package/dist/routes-public.d.ts.map +1 -0
- package/dist/routes-public.js +252 -0
- package/dist/routes-sailings-prices.d.ts +4 -0
- package/dist/routes-sailings-prices.d.ts.map +1 -0
- package/dist/routes-sailings-prices.js +278 -0
- package/dist/routes-search-index.d.ts +4 -0
- package/dist/routes-search-index.d.ts.map +1 -0
- package/dist/routes-search-index.js +25 -0
- package/dist/routes-ships.d.ts +4 -0
- package/dist/routes-ships.d.ts.map +1 -0
- package/dist/routes-ships.js +147 -0
- package/dist/routes-voyage-groups.d.ts +4 -0
- package/dist/routes-voyage-groups.d.ts.map +1 -0
- package/dist/routes-voyage-groups.js +85 -0
- package/dist/routes.d.ts +5 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +14 -0
- package/dist/schema-cabins.d.ts +1098 -0
- package/dist/schema-cabins.d.ts.map +1 -0
- package/dist/schema-cabins.js +105 -0
- package/dist/schema-content.d.ts +577 -0
- package/dist/schema-content.d.ts.map +1 -0
- package/dist/schema-content.js +63 -0
- package/dist/schema-core.d.ts +1790 -0
- package/dist/schema-core.d.ts.map +1 -0
- package/dist/schema-core.js +171 -0
- package/dist/schema-itinerary.d.ts +556 -0
- package/dist/schema-itinerary.d.ts.map +1 -0
- package/dist/schema-itinerary.js +50 -0
- package/dist/schema-pricing.d.ts +633 -0
- package/dist/schema-pricing.d.ts.map +1 -0
- package/dist/schema-pricing.js +73 -0
- package/dist/schema-search.d.ts +611 -0
- package/dist/schema-search.d.ts.map +1 -0
- package/dist/schema-search.js +64 -0
- package/dist/schema-shared.d.ts +23 -0
- package/dist/schema-shared.d.ts.map +1 -0
- package/dist/schema-shared.js +107 -0
- package/dist/schema-sourced-content.d.ts +247 -0
- package/dist/schema-sourced-content.d.ts.map +1 -0
- package/dist/schema-sourced-content.js +38 -0
- package/dist/schema.d.ts +10 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +9 -0
- package/dist/service-booking-helpers.d.ts +12 -0
- package/dist/service-booking-helpers.d.ts.map +1 -0
- package/dist/service-booking-helpers.js +94 -0
- package/dist/service-booking-types.d.ts +101 -0
- package/dist/service-booking-types.d.ts.map +1 -0
- package/dist/service-booking-types.js +1 -0
- package/dist/service-bookings.d.ts +46 -0
- package/dist/service-bookings.d.ts.map +1 -0
- package/dist/service-bookings.js +420 -0
- package/dist/service-catalog-plane-cabins.d.ts +24 -0
- package/dist/service-catalog-plane-cabins.d.ts.map +1 -0
- package/dist/service-catalog-plane-cabins.js +90 -0
- package/dist/service-catalog-plane.d.ts +74 -0
- package/dist/service-catalog-plane.d.ts.map +1 -0
- package/dist/service-catalog-plane.js +194 -0
- package/dist/service-content-synthesizer.d.ts +42 -0
- package/dist/service-content-synthesizer.d.ts.map +1 -0
- package/dist/service-content-synthesizer.js +144 -0
- package/dist/service-content.d.ts +74 -0
- package/dist/service-content.d.ts.map +1 -0
- package/dist/service-content.js +315 -0
- package/dist/service-core.d.ts +134 -0
- package/dist/service-core.d.ts.map +1 -0
- package/dist/service-core.js +257 -0
- package/dist/service-detach.d.ts +18 -0
- package/dist/service-detach.d.ts.map +1 -0
- package/dist/service-detach.js +199 -0
- package/dist/service-enrichment.d.ts +11 -0
- package/dist/service-enrichment.d.ts.map +1 -0
- package/dist/service-enrichment.js +47 -0
- package/dist/service-external-refresh.d.ts +39 -0
- package/dist/service-external-refresh.d.ts.map +1 -0
- package/dist/service-external-refresh.js +47 -0
- package/dist/service-itinerary.d.ts +22 -0
- package/dist/service-itinerary.d.ts.map +1 -0
- package/dist/service-itinerary.js +34 -0
- package/dist/service-prices.d.ts +46 -0
- package/dist/service-prices.d.ts.map +1 -0
- package/dist/service-prices.js +89 -0
- package/dist/service-pricing.d.ts +97 -0
- package/dist/service-pricing.d.ts.map +1 -0
- package/dist/service-pricing.js +198 -0
- package/dist/service-sailings.d.ts +48 -0
- package/dist/service-sailings.d.ts.map +1 -0
- package/dist/service-sailings.js +145 -0
- package/dist/service-search-types.d.ts +54 -0
- package/dist/service-search-types.d.ts.map +1 -0
- package/dist/service-search-types.js +1 -0
- package/dist/service-search.d.ts +65 -0
- package/dist/service-search.d.ts.map +1 -0
- package/dist/service-search.js +467 -0
- package/dist/service-shared.d.ts +22 -0
- package/dist/service-shared.d.ts.map +1 -0
- package/dist/service-shared.js +22 -0
- package/dist/service-ships.d.ts +47 -0
- package/dist/service-ships.d.ts.map +1 -0
- package/dist/service-ships.js +156 -0
- package/dist/service.d.ts +255 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +12 -0
- package/dist/validation-cabins.d.ts +267 -0
- package/dist/validation-cabins.d.ts.map +1 -0
- package/dist/validation-cabins.js +77 -0
- package/dist/validation-content.d.ts +123 -0
- package/dist/validation-content.d.ts.map +1 -0
- package/dist/validation-content.js +40 -0
- package/dist/validation-core.d.ts +393 -0
- package/dist/validation-core.d.ts.map +1 -0
- package/dist/validation-core.js +162 -0
- package/dist/validation-itinerary.d.ts +123 -0
- package/dist/validation-itinerary.d.ts.map +1 -0
- package/dist/validation-itinerary.js +47 -0
- package/dist/validation-pricing.d.ts +137 -0
- package/dist/validation-pricing.d.ts.map +1 -0
- package/dist/validation-pricing.js +49 -0
- package/dist/validation-search.d.ts +118 -0
- package/dist/validation-search.d.ts.map +1 -0
- package/dist/validation-search.js +60 -0
- package/dist/validation-shared.d.ts +123 -0
- package/dist/validation-shared.d.ts.map +1 -0
- package/dist/validation-shared.js +103 -0
- package/dist/validation.d.ts +8 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +7 -0
- package/package.json +146 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { and, asc, count, eq, gte, inArray, lte } from "drizzle-orm";
|
|
2
|
+
import { cruiseSailings } from "./schema-core.js";
|
|
3
|
+
import { cruiseDays, cruiseSailingDays } from "./schema-itinerary.js";
|
|
4
|
+
import { cruisePriceComponents, cruisePrices } from "./schema-pricing.js";
|
|
5
|
+
import { mergeDay } from "./service-itinerary.js";
|
|
6
|
+
import { paginate, reprojectIfPossible, setUpdated } from "./service-shared.js";
|
|
7
|
+
export const cruiseSailingsService = {
|
|
8
|
+
async listSailings(db, query) {
|
|
9
|
+
const conditions = [];
|
|
10
|
+
if (query.cruiseId)
|
|
11
|
+
conditions.push(eq(cruiseSailings.cruiseId, query.cruiseId));
|
|
12
|
+
if (query.shipId)
|
|
13
|
+
conditions.push(eq(cruiseSailings.shipId, query.shipId));
|
|
14
|
+
if (query.salesStatus)
|
|
15
|
+
conditions.push(eq(cruiseSailings.salesStatus, query.salesStatus));
|
|
16
|
+
if (query.dateFrom)
|
|
17
|
+
conditions.push(gte(cruiseSailings.departureDate, query.dateFrom));
|
|
18
|
+
if (query.dateTo)
|
|
19
|
+
conditions.push(lte(cruiseSailings.departureDate, query.dateTo));
|
|
20
|
+
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
|
21
|
+
const { limit, offset } = paginate(query);
|
|
22
|
+
const [rows, totalRows] = await Promise.all([
|
|
23
|
+
db
|
|
24
|
+
.select()
|
|
25
|
+
.from(cruiseSailings)
|
|
26
|
+
.where(where)
|
|
27
|
+
.orderBy(asc(cruiseSailings.departureDate))
|
|
28
|
+
.limit(limit)
|
|
29
|
+
.offset(offset),
|
|
30
|
+
db.select({ value: count() }).from(cruiseSailings).where(where),
|
|
31
|
+
]);
|
|
32
|
+
return { data: rows, total: totalRows[0]?.value ?? 0, limit, offset };
|
|
33
|
+
},
|
|
34
|
+
async getSailingById(db, id, options = {}) {
|
|
35
|
+
const [row] = await db.select().from(cruiseSailings).where(eq(cruiseSailings.id, id)).limit(1);
|
|
36
|
+
if (!row)
|
|
37
|
+
return null;
|
|
38
|
+
const out = { ...row };
|
|
39
|
+
if (options.withPricing) {
|
|
40
|
+
const prices = await db
|
|
41
|
+
.select()
|
|
42
|
+
.from(cruisePrices)
|
|
43
|
+
.where(eq(cruisePrices.sailingId, id))
|
|
44
|
+
.orderBy(asc(cruisePrices.cabinCategoryId), asc(cruisePrices.occupancy));
|
|
45
|
+
out.prices = prices;
|
|
46
|
+
if (prices.length > 0) {
|
|
47
|
+
const priceIds = prices.map((p) => p.id);
|
|
48
|
+
out.priceComponents = await db
|
|
49
|
+
.select()
|
|
50
|
+
.from(cruisePriceComponents)
|
|
51
|
+
.where(inArray(cruisePriceComponents.priceId, priceIds));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
out.priceComponents = [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (options.withItinerary) {
|
|
58
|
+
out.effectiveDays = await this.getEffectiveItinerary(db, id);
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
},
|
|
62
|
+
async upsertSailing(db, data) {
|
|
63
|
+
const [existing] = await db
|
|
64
|
+
.select()
|
|
65
|
+
.from(cruiseSailings)
|
|
66
|
+
.where(and(eq(cruiseSailings.cruiseId, data.cruiseId), eq(cruiseSailings.departureDate, data.departureDate), eq(cruiseSailings.shipId, data.shipId)))
|
|
67
|
+
.limit(1);
|
|
68
|
+
if (existing) {
|
|
69
|
+
const [row] = await db
|
|
70
|
+
.update(cruiseSailings)
|
|
71
|
+
.set({ ...data, ...setUpdated, lastSyncedAt: new Date() })
|
|
72
|
+
.where(eq(cruiseSailings.id, existing.id))
|
|
73
|
+
.returning();
|
|
74
|
+
if (!row)
|
|
75
|
+
throw new Error("Failed to update sailing");
|
|
76
|
+
await reprojectIfPossible(db, row.cruiseId);
|
|
77
|
+
return row;
|
|
78
|
+
}
|
|
79
|
+
const [row] = await db
|
|
80
|
+
.insert(cruiseSailings)
|
|
81
|
+
.values({ ...data, lastSyncedAt: new Date() })
|
|
82
|
+
.returning();
|
|
83
|
+
if (!row)
|
|
84
|
+
throw new Error("Failed to insert sailing");
|
|
85
|
+
await reprojectIfPossible(db, row.cruiseId);
|
|
86
|
+
return row;
|
|
87
|
+
},
|
|
88
|
+
async updateSailing(db, id, data) {
|
|
89
|
+
const [row] = await db
|
|
90
|
+
.update(cruiseSailings)
|
|
91
|
+
.set({ ...data, ...setUpdated })
|
|
92
|
+
.where(eq(cruiseSailings.id, id))
|
|
93
|
+
.returning();
|
|
94
|
+
if (row)
|
|
95
|
+
await reprojectIfPossible(db, row.cruiseId);
|
|
96
|
+
return row ?? null;
|
|
97
|
+
},
|
|
98
|
+
// ---------- itinerary ----------
|
|
99
|
+
async getEffectiveItinerary(db, sailingId) {
|
|
100
|
+
const [sailing] = await db
|
|
101
|
+
.select({ cruiseId: cruiseSailings.cruiseId })
|
|
102
|
+
.from(cruiseSailings)
|
|
103
|
+
.where(eq(cruiseSailings.id, sailingId))
|
|
104
|
+
.limit(1);
|
|
105
|
+
if (!sailing)
|
|
106
|
+
return [];
|
|
107
|
+
const [baseDays, overrides] = await Promise.all([
|
|
108
|
+
db
|
|
109
|
+
.select()
|
|
110
|
+
.from(cruiseDays)
|
|
111
|
+
.where(eq(cruiseDays.cruiseId, sailing.cruiseId))
|
|
112
|
+
.orderBy(asc(cruiseDays.dayNumber)),
|
|
113
|
+
db.select().from(cruiseSailingDays).where(eq(cruiseSailingDays.sailingId, sailingId)),
|
|
114
|
+
]);
|
|
115
|
+
const overrideByDay = new Map();
|
|
116
|
+
for (const o of overrides)
|
|
117
|
+
overrideByDay.set(o.dayNumber, o);
|
|
118
|
+
return baseDays.map((day) => mergeDay(day, overrideByDay.get(day.dayNumber)));
|
|
119
|
+
},
|
|
120
|
+
async replaceCruiseDays(db, payload) {
|
|
121
|
+
return db.transaction(async (tx) => {
|
|
122
|
+
await tx.delete(cruiseDays).where(eq(cruiseDays.cruiseId, payload.cruiseId));
|
|
123
|
+
if (payload.days.length === 0)
|
|
124
|
+
return [];
|
|
125
|
+
const inserted = await tx
|
|
126
|
+
.insert(cruiseDays)
|
|
127
|
+
.values(payload.days.map((d) => ({ ...d, cruiseId: payload.cruiseId })))
|
|
128
|
+
.returning();
|
|
129
|
+
return inserted;
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
async replaceSailingDays(db, payload) {
|
|
133
|
+
return db.transaction(async (tx) => {
|
|
134
|
+
await tx.delete(cruiseSailingDays).where(eq(cruiseSailingDays.sailingId, payload.sailingId));
|
|
135
|
+
if (payload.days.length === 0)
|
|
136
|
+
return [];
|
|
137
|
+
const inserted = await tx
|
|
138
|
+
.insert(cruiseSailingDays)
|
|
139
|
+
.values(payload.days.map((d) => ({ ...d, sailingId: payload.sailingId })))
|
|
140
|
+
.returning();
|
|
141
|
+
return inserted;
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
// ---------- ships, decks, cabin categories, cabins ----------
|
|
145
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { SourceRef } from "./adapters/index.js";
|
|
2
|
+
import type { CruiseSearchIndexRow } from "./schema-search.js";
|
|
3
|
+
export type SearchIndexQueryResult = {
|
|
4
|
+
data: CruiseSearchIndexRow[];
|
|
5
|
+
total: number;
|
|
6
|
+
limit: number;
|
|
7
|
+
offset: number;
|
|
8
|
+
};
|
|
9
|
+
export type BulkSearchIndexEntry = {
|
|
10
|
+
source: "local" | "external";
|
|
11
|
+
sourceProvider?: string | null;
|
|
12
|
+
sourceRef?: SourceRef | null;
|
|
13
|
+
localCruiseId?: string | null;
|
|
14
|
+
slug: string;
|
|
15
|
+
name: string;
|
|
16
|
+
cruiseType: "ocean" | "river" | "expedition" | "coastal";
|
|
17
|
+
lineName: string;
|
|
18
|
+
shipName: string;
|
|
19
|
+
nights: number;
|
|
20
|
+
embarkPortName?: string | null;
|
|
21
|
+
embarkPortCanonicalPlaceId?: string | null;
|
|
22
|
+
disembarkPortName?: string | null;
|
|
23
|
+
disembarkPortCanonicalPlaceId?: string | null;
|
|
24
|
+
regionIds?: string[];
|
|
25
|
+
waterwayIds?: string[];
|
|
26
|
+
portIds?: string[];
|
|
27
|
+
countryIso?: string[];
|
|
28
|
+
regions?: string[];
|
|
29
|
+
waterways?: string[];
|
|
30
|
+
ports?: string[];
|
|
31
|
+
countries?: string[];
|
|
32
|
+
themes?: string[];
|
|
33
|
+
earliestDeparture?: string | null;
|
|
34
|
+
latestDeparture?: string | null;
|
|
35
|
+
departureCount?: number | null;
|
|
36
|
+
lowestPriceCents?: number | null;
|
|
37
|
+
lowestPriceCurrency?: string | null;
|
|
38
|
+
salesStatus?: string | null;
|
|
39
|
+
heroImageUrl?: string | null;
|
|
40
|
+
};
|
|
41
|
+
export type RebuildResult = {
|
|
42
|
+
localUpserted: number;
|
|
43
|
+
externalUpserted: number;
|
|
44
|
+
externalRemoved: number;
|
|
45
|
+
externalErrors: Array<{
|
|
46
|
+
adapter: string;
|
|
47
|
+
error: string;
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
export type ExternalAdapterRefreshResult = {
|
|
51
|
+
upserted: number;
|
|
52
|
+
removed: number;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=service-search-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-search-types.d.ts","sourceRoot":"","sources":["../src/service-search-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAI9D,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,oBAAoB,EAAE,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAID,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,OAAO,GAAG,UAAU,CAAA;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,6BAA6B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC1D,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search-index service for mixed local/external cruise browse rows.
|
|
3
|
+
* `cruise_search_index` is optional; storefront deployments populate it
|
|
4
|
+
* from local projection hooks and adapter `searchProjection()` streams.
|
|
5
|
+
*/
|
|
6
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
7
|
+
import type { CruiseAdapter, SourceRef } from "./adapters/index.js";
|
|
8
|
+
import { type CruiseSearchIndexRow } from "./schema-search.js";
|
|
9
|
+
import type { BulkSearchIndexEntry, ExternalAdapterRefreshResult, RebuildResult, SearchIndexQueryResult } from "./service-search-types.js";
|
|
10
|
+
import type { SearchIndexQuery } from "./validation-search.js";
|
|
11
|
+
export type { BulkSearchIndexEntry, ExternalAdapterRefreshResult, RebuildResult, SearchIndexQueryResult, } from "./service-search-types.js";
|
|
12
|
+
export declare const cruisesSearchService: {
|
|
13
|
+
query(db: PostgresJsDatabase, query: SearchIndexQuery): Promise<SearchIndexQueryResult>;
|
|
14
|
+
getBySlug(db: PostgresJsDatabase, slug: string): Promise<CruiseSearchIndexRow | null>;
|
|
15
|
+
upsertEntry(db: PostgresJsDatabase, entry: BulkSearchIndexEntry): Promise<CruiseSearchIndexRow>;
|
|
16
|
+
bulkUpsert(db: PostgresJsDatabase, entries: BulkSearchIndexEntry[]): Promise<{
|
|
17
|
+
upserted: number;
|
|
18
|
+
}>;
|
|
19
|
+
removeEntry(db: PostgresJsDatabase, id: string): Promise<boolean>;
|
|
20
|
+
removeBySource(db: PostgresJsDatabase, sourceProvider: string): Promise<{
|
|
21
|
+
removed: number;
|
|
22
|
+
}>;
|
|
23
|
+
removeExternalByIdsExcept(db: PostgresJsDatabase, sourceProvider: string, keepIds: ReadonlyArray<string>, sourceConnectionId?: string | null): Promise<{
|
|
24
|
+
removed: number;
|
|
25
|
+
}>;
|
|
26
|
+
listExternalConnectionIds(db: PostgresJsDatabase, sourceProvider: string): Promise<Array<string | null>>;
|
|
27
|
+
/**
|
|
28
|
+
* Re-project a single local cruise into the search index. Called from the
|
|
29
|
+
* cruisesService mutation hooks so the index stays fresh without a separate
|
|
30
|
+
* scheduled job. Computes the lowest available price across the cruise's
|
|
31
|
+
* sailings and the earliest/latest departure dates.
|
|
32
|
+
*
|
|
33
|
+
* If the cruise's status is 'archived' the entry is removed instead — archived
|
|
34
|
+
* cruises shouldn't appear on the storefront.
|
|
35
|
+
*/
|
|
36
|
+
projectLocalCruise(db: PostgresJsDatabase, cruiseId: string): Promise<CruiseSearchIndexRow | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Drop and rebuild every local cruise entry. Useful after schema changes
|
|
39
|
+
* or operator-triggered "rebuild storefront index" actions.
|
|
40
|
+
*/
|
|
41
|
+
rebuildLocal(db: PostgresJsDatabase): Promise<{
|
|
42
|
+
upserted: number;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Drain `searchProjection()` from a single adapter and bulk-upsert. Useful
|
|
46
|
+
* for ad-hoc "refresh from upstream" actions; production deployments
|
|
47
|
+
* typically have the adapter push deltas continuously instead.
|
|
48
|
+
*/
|
|
49
|
+
rebuildExternalForAdapter(db: PostgresJsDatabase, adapter: CruiseAdapter): Promise<{
|
|
50
|
+
upserted: number;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Drain `searchProjection()` from a single adapter and reconcile the local
|
|
54
|
+
* external search-index rows for that provider. Existing rows stay intact
|
|
55
|
+
* until the adapter stream completes; only then are missing rows removed.
|
|
56
|
+
*/
|
|
57
|
+
refreshExternalForAdapter(db: PostgresJsDatabase, adapter: CruiseAdapter): Promise<ExternalAdapterRefreshResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Full rebuild — local cruises + every registered adapter.
|
|
60
|
+
* Per-adapter errors are collected so one bad adapter doesn't block the rest.
|
|
61
|
+
*/
|
|
62
|
+
rebuildAll(db: PostgresJsDatabase): Promise<RebuildResult>;
|
|
63
|
+
};
|
|
64
|
+
export declare function sourceRefIdentityJson(sourceRef: SourceRef): string;
|
|
65
|
+
//# sourceMappingURL=service-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-search.d.ts","sourceRoot":"","sources":["../src/service-search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAKnE,OAAO,EACL,KAAK,oBAAoB,EAG1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EACV,oBAAoB,EACpB,4BAA4B,EAC5B,aAAa,EACb,sBAAsB,EACvB,MAAM,2BAA2B,CAAA;AAClC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,YAAY,EACV,oBAAoB,EACpB,4BAA4B,EAC5B,aAAa,EACb,sBAAsB,GACvB,MAAM,2BAA2B,CAAA;AAElC,eAAO,MAAM,oBAAoB;cAGf,kBAAkB,SAAS,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC;kBA4FzE,kBAAkB,QAAQ,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;oBAYrF,kBAAkB,SACf,oBAAoB,GAC1B,OAAO,CAAC,oBAAoB,CAAC;mBAoD1B,kBAAkB,WACb,oBAAoB,EAAE,GAC9B,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;oBAaV,kBAAkB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;uBASjE,kBAAkB,kBACN,MAAM,GACrB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;kCAczB,kBAAkB,kBACN,MAAM,WACb,aAAa,CAAC,MAAM,CAAC,uBACT,MAAM,GAAG,IAAI,GACjC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;kCAqBzB,kBAAkB,kBACN,MAAM,GACrB,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAmBhC;;;;;;;;OAQG;2BAEG,kBAAkB,YACZ,MAAM,GACf,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAiBvC;;;OAGG;qBACoB,kBAAkB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAezE;;;;OAIG;kCAEG,kBAAkB,WACb,aAAa,GACrB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAKhC;;;;OAIG;kCAEG,kBAAkB,WACb,aAAa,GACrB,OAAO,CAAC,4BAA4B,CAAC;IAuDxC;;;OAGG;mBACkB,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;CAqBjE,CAAA;AAwCD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAElE"}
|