@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.
Files changed (210) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +50 -0
  3. package/dist/adapters/connect-compat.d.ts +20 -0
  4. package/dist/adapters/connect-compat.d.ts.map +1 -0
  5. package/dist/adapters/connect-compat.js +71 -0
  6. package/dist/adapters/contract-fixture.d.ts +32 -0
  7. package/dist/adapters/contract-fixture.d.ts.map +1 -0
  8. package/dist/adapters/contract-fixture.js +152 -0
  9. package/dist/adapters/index.d.ts +331 -0
  10. package/dist/adapters/index.d.ts.map +1 -0
  11. package/dist/adapters/index.js +16 -0
  12. package/dist/adapters/memoize.d.ts +28 -0
  13. package/dist/adapters/memoize.d.ts.map +1 -0
  14. package/dist/adapters/memoize.js +131 -0
  15. package/dist/adapters/mock.d.ts +44 -0
  16. package/dist/adapters/mock.d.ts.map +1 -0
  17. package/dist/adapters/mock.js +192 -0
  18. package/dist/adapters/registry.d.ts +26 -0
  19. package/dist/adapters/registry.d.ts.map +1 -0
  20. package/dist/adapters/registry.js +42 -0
  21. package/dist/adapters/source-adapter-shim.d.ts +80 -0
  22. package/dist/adapters/source-adapter-shim.d.ts.map +1 -0
  23. package/dist/adapters/source-adapter-shim.js +390 -0
  24. package/dist/booking-engine/handler.d.ts +108 -0
  25. package/dist/booking-engine/handler.d.ts.map +1 -0
  26. package/dist/booking-engine/handler.js +225 -0
  27. package/dist/booking-engine/index.d.ts +9 -0
  28. package/dist/booking-engine/index.d.ts.map +1 -0
  29. package/dist/booking-engine/index.js +8 -0
  30. package/dist/booking-extension.d.ts +1179 -0
  31. package/dist/booking-extension.d.ts.map +1 -0
  32. package/dist/booking-extension.js +342 -0
  33. package/dist/cabin-features.d.ts +8 -0
  34. package/dist/cabin-features.d.ts.map +1 -0
  35. package/dist/cabin-features.js +7 -0
  36. package/dist/catalog-policy-cabins.d.ts +18 -0
  37. package/dist/catalog-policy-cabins.d.ts.map +1 -0
  38. package/dist/catalog-policy-cabins.js +96 -0
  39. package/dist/catalog-policy-core.d.ts +3 -0
  40. package/dist/catalog-policy-core.d.ts.map +1 -0
  41. package/dist/catalog-policy-core.js +247 -0
  42. package/dist/catalog-policy-structure.d.ts +3 -0
  43. package/dist/catalog-policy-structure.d.ts.map +1 -0
  44. package/dist/catalog-policy-structure.js +387 -0
  45. package/dist/catalog-policy.d.ts +15 -0
  46. package/dist/catalog-policy.d.ts.map +1 -0
  47. package/dist/catalog-policy.js +19 -0
  48. package/dist/content-shape.d.ts +5 -0
  49. package/dist/content-shape.d.ts.map +1 -0
  50. package/dist/content-shape.js +13 -0
  51. package/dist/draft-shape.d.ts +59 -0
  52. package/dist/draft-shape.d.ts.map +1 -0
  53. package/dist/draft-shape.js +98 -0
  54. package/dist/events.d.ts +21 -0
  55. package/dist/events.d.ts.map +1 -0
  56. package/dist/events.js +21 -0
  57. package/dist/index.d.ts +43 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +66 -0
  60. package/dist/lib/key.d.ts +41 -0
  61. package/dist/lib/key.d.ts.map +1 -0
  62. package/dist/lib/key.js +100 -0
  63. package/dist/routes-booking-payloads.d.ts +133 -0
  64. package/dist/routes-booking-payloads.d.ts.map +1 -0
  65. package/dist/routes-booking-payloads.js +142 -0
  66. package/dist/routes-content.d.ts +53 -0
  67. package/dist/routes-content.d.ts.map +1 -0
  68. package/dist/routes-content.js +158 -0
  69. package/dist/routes-core.d.ts +4 -0
  70. package/dist/routes-core.d.ts.map +1 -0
  71. package/dist/routes-core.js +68 -0
  72. package/dist/routes-detail.d.ts +4 -0
  73. package/dist/routes-detail.d.ts.map +1 -0
  74. package/dist/routes-detail.js +261 -0
  75. package/dist/routes-env.d.ts +13 -0
  76. package/dist/routes-env.d.ts.map +1 -0
  77. package/dist/routes-env.js +1 -0
  78. package/dist/routes-keying.d.ts +28 -0
  79. package/dist/routes-keying.d.ts.map +1 -0
  80. package/dist/routes-keying.js +70 -0
  81. package/dist/routes-public.d.ts +911 -0
  82. package/dist/routes-public.d.ts.map +1 -0
  83. package/dist/routes-public.js +252 -0
  84. package/dist/routes-sailings-prices.d.ts +4 -0
  85. package/dist/routes-sailings-prices.d.ts.map +1 -0
  86. package/dist/routes-sailings-prices.js +278 -0
  87. package/dist/routes-search-index.d.ts +4 -0
  88. package/dist/routes-search-index.d.ts.map +1 -0
  89. package/dist/routes-search-index.js +25 -0
  90. package/dist/routes-ships.d.ts +4 -0
  91. package/dist/routes-ships.d.ts.map +1 -0
  92. package/dist/routes-ships.js +147 -0
  93. package/dist/routes-voyage-groups.d.ts +4 -0
  94. package/dist/routes-voyage-groups.d.ts.map +1 -0
  95. package/dist/routes-voyage-groups.js +85 -0
  96. package/dist/routes.d.ts +5 -0
  97. package/dist/routes.d.ts.map +1 -0
  98. package/dist/routes.js +14 -0
  99. package/dist/schema-cabins.d.ts +1098 -0
  100. package/dist/schema-cabins.d.ts.map +1 -0
  101. package/dist/schema-cabins.js +105 -0
  102. package/dist/schema-content.d.ts +577 -0
  103. package/dist/schema-content.d.ts.map +1 -0
  104. package/dist/schema-content.js +63 -0
  105. package/dist/schema-core.d.ts +1790 -0
  106. package/dist/schema-core.d.ts.map +1 -0
  107. package/dist/schema-core.js +171 -0
  108. package/dist/schema-itinerary.d.ts +556 -0
  109. package/dist/schema-itinerary.d.ts.map +1 -0
  110. package/dist/schema-itinerary.js +50 -0
  111. package/dist/schema-pricing.d.ts +633 -0
  112. package/dist/schema-pricing.d.ts.map +1 -0
  113. package/dist/schema-pricing.js +73 -0
  114. package/dist/schema-search.d.ts +611 -0
  115. package/dist/schema-search.d.ts.map +1 -0
  116. package/dist/schema-search.js +64 -0
  117. package/dist/schema-shared.d.ts +23 -0
  118. package/dist/schema-shared.d.ts.map +1 -0
  119. package/dist/schema-shared.js +107 -0
  120. package/dist/schema-sourced-content.d.ts +247 -0
  121. package/dist/schema-sourced-content.d.ts.map +1 -0
  122. package/dist/schema-sourced-content.js +38 -0
  123. package/dist/schema.d.ts +10 -0
  124. package/dist/schema.d.ts.map +1 -0
  125. package/dist/schema.js +9 -0
  126. package/dist/service-booking-helpers.d.ts +12 -0
  127. package/dist/service-booking-helpers.d.ts.map +1 -0
  128. package/dist/service-booking-helpers.js +94 -0
  129. package/dist/service-booking-types.d.ts +101 -0
  130. package/dist/service-booking-types.d.ts.map +1 -0
  131. package/dist/service-booking-types.js +1 -0
  132. package/dist/service-bookings.d.ts +46 -0
  133. package/dist/service-bookings.d.ts.map +1 -0
  134. package/dist/service-bookings.js +420 -0
  135. package/dist/service-catalog-plane-cabins.d.ts +24 -0
  136. package/dist/service-catalog-plane-cabins.d.ts.map +1 -0
  137. package/dist/service-catalog-plane-cabins.js +90 -0
  138. package/dist/service-catalog-plane.d.ts +74 -0
  139. package/dist/service-catalog-plane.d.ts.map +1 -0
  140. package/dist/service-catalog-plane.js +194 -0
  141. package/dist/service-content-synthesizer.d.ts +42 -0
  142. package/dist/service-content-synthesizer.d.ts.map +1 -0
  143. package/dist/service-content-synthesizer.js +144 -0
  144. package/dist/service-content.d.ts +74 -0
  145. package/dist/service-content.d.ts.map +1 -0
  146. package/dist/service-content.js +315 -0
  147. package/dist/service-core.d.ts +134 -0
  148. package/dist/service-core.d.ts.map +1 -0
  149. package/dist/service-core.js +257 -0
  150. package/dist/service-detach.d.ts +18 -0
  151. package/dist/service-detach.d.ts.map +1 -0
  152. package/dist/service-detach.js +199 -0
  153. package/dist/service-enrichment.d.ts +11 -0
  154. package/dist/service-enrichment.d.ts.map +1 -0
  155. package/dist/service-enrichment.js +47 -0
  156. package/dist/service-external-refresh.d.ts +39 -0
  157. package/dist/service-external-refresh.d.ts.map +1 -0
  158. package/dist/service-external-refresh.js +47 -0
  159. package/dist/service-itinerary.d.ts +22 -0
  160. package/dist/service-itinerary.d.ts.map +1 -0
  161. package/dist/service-itinerary.js +34 -0
  162. package/dist/service-prices.d.ts +46 -0
  163. package/dist/service-prices.d.ts.map +1 -0
  164. package/dist/service-prices.js +89 -0
  165. package/dist/service-pricing.d.ts +97 -0
  166. package/dist/service-pricing.d.ts.map +1 -0
  167. package/dist/service-pricing.js +198 -0
  168. package/dist/service-sailings.d.ts +48 -0
  169. package/dist/service-sailings.d.ts.map +1 -0
  170. package/dist/service-sailings.js +145 -0
  171. package/dist/service-search-types.d.ts +54 -0
  172. package/dist/service-search-types.d.ts.map +1 -0
  173. package/dist/service-search-types.js +1 -0
  174. package/dist/service-search.d.ts +65 -0
  175. package/dist/service-search.d.ts.map +1 -0
  176. package/dist/service-search.js +467 -0
  177. package/dist/service-shared.d.ts +22 -0
  178. package/dist/service-shared.d.ts.map +1 -0
  179. package/dist/service-shared.js +22 -0
  180. package/dist/service-ships.d.ts +47 -0
  181. package/dist/service-ships.d.ts.map +1 -0
  182. package/dist/service-ships.js +156 -0
  183. package/dist/service.d.ts +255 -0
  184. package/dist/service.d.ts.map +1 -0
  185. package/dist/service.js +12 -0
  186. package/dist/validation-cabins.d.ts +267 -0
  187. package/dist/validation-cabins.d.ts.map +1 -0
  188. package/dist/validation-cabins.js +77 -0
  189. package/dist/validation-content.d.ts +123 -0
  190. package/dist/validation-content.d.ts.map +1 -0
  191. package/dist/validation-content.js +40 -0
  192. package/dist/validation-core.d.ts +393 -0
  193. package/dist/validation-core.d.ts.map +1 -0
  194. package/dist/validation-core.js +162 -0
  195. package/dist/validation-itinerary.d.ts +123 -0
  196. package/dist/validation-itinerary.d.ts.map +1 -0
  197. package/dist/validation-itinerary.js +47 -0
  198. package/dist/validation-pricing.d.ts +137 -0
  199. package/dist/validation-pricing.d.ts.map +1 -0
  200. package/dist/validation-pricing.js +49 -0
  201. package/dist/validation-search.d.ts +118 -0
  202. package/dist/validation-search.d.ts.map +1 -0
  203. package/dist/validation-search.js +60 -0
  204. package/dist/validation-shared.d.ts +123 -0
  205. package/dist/validation-shared.d.ts.map +1 -0
  206. package/dist/validation-shared.js +103 -0
  207. package/dist/validation.d.ts +8 -0
  208. package/dist/validation.d.ts.map +1 -0
  209. package/dist/validation.js +7 -0
  210. package/package.json +146 -0
@@ -0,0 +1,257 @@
1
+ import { and, asc, count, desc, eq, ilike, or, sql } from "drizzle-orm";
2
+ import { CRUISE_CREATED_EVENT, CRUISE_DELETED_EVENT, CRUISE_UPDATED_EVENT, emitCruiseLifecycleEvent, } from "./events.js";
3
+ import { cruiseSailings, cruises, cruiseVoyageGroupSegments, cruiseVoyageGroups, } from "./schema-core.js";
4
+ import { cruiseDays } from "./schema-itinerary.js";
5
+ import { cruisePrices } from "./schema-pricing.js";
6
+ import { paginate, reprojectIfPossible, setUpdated, } from "./service-shared.js";
7
+ export const cruiseCoreService = {
8
+ async listVoyageGroups(db, query) {
9
+ const conditions = [];
10
+ if (query.groupKind)
11
+ conditions.push(eq(cruiseVoyageGroups.groupKind, query.groupKind));
12
+ if (query.status)
13
+ conditions.push(eq(cruiseVoyageGroups.status, query.status));
14
+ if (query.lineSupplierId) {
15
+ conditions.push(eq(cruiseVoyageGroups.lineSupplierId, query.lineSupplierId));
16
+ }
17
+ if (query.region) {
18
+ conditions.push(
19
+ // agent-quality: raw-sql reviewed -- owner: cruises; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
20
+ sql `${cruiseVoyageGroups.regions} @> ${JSON.stringify([query.region])}::jsonb`);
21
+ }
22
+ if (query.search) {
23
+ const term = `%${query.search}%`;
24
+ conditions.push(or(ilike(cruiseVoyageGroups.name, term), ilike(cruiseVoyageGroups.description, term)));
25
+ }
26
+ const where = conditions.length > 0 ? and(...conditions) : undefined;
27
+ const { limit, offset } = paginate(query);
28
+ const [rows, totalRows] = await Promise.all([
29
+ db
30
+ .select()
31
+ .from(cruiseVoyageGroups)
32
+ .where(where)
33
+ .orderBy(desc(cruiseVoyageGroups.createdAt))
34
+ .limit(limit)
35
+ .offset(offset),
36
+ db.select({ value: count() }).from(cruiseVoyageGroups).where(where),
37
+ ]);
38
+ return { data: rows, total: totalRows[0]?.value ?? 0, limit, offset };
39
+ },
40
+ async getVoyageGroupById(db, id, options = {}) {
41
+ const [row] = await db
42
+ .select()
43
+ .from(cruiseVoyageGroups)
44
+ .where(eq(cruiseVoyageGroups.id, id))
45
+ .limit(1);
46
+ if (!row)
47
+ return null;
48
+ const out = { ...row };
49
+ if (options.withSegments) {
50
+ out.segments = await db
51
+ .select()
52
+ .from(cruiseVoyageGroupSegments)
53
+ .where(eq(cruiseVoyageGroupSegments.voyageGroupId, id))
54
+ .orderBy(asc(cruiseVoyageGroupSegments.sortOrder));
55
+ }
56
+ return out;
57
+ },
58
+ async createVoyageGroup(db, data) {
59
+ const [row] = await db
60
+ .insert(cruiseVoyageGroups)
61
+ .values(data)
62
+ .returning();
63
+ if (!row)
64
+ throw new Error("Failed to create voyage group");
65
+ return row;
66
+ },
67
+ async updateVoyageGroup(db, id, data) {
68
+ const [row] = await db
69
+ .update(cruiseVoyageGroups)
70
+ .set({ ...data, ...setUpdated })
71
+ .where(eq(cruiseVoyageGroups.id, id))
72
+ .returning();
73
+ return row ?? null;
74
+ },
75
+ async archiveVoyageGroup(db, id) {
76
+ const [row] = await db
77
+ .update(cruiseVoyageGroups)
78
+ .set({ status: "archived", ...setUpdated })
79
+ .where(eq(cruiseVoyageGroups.id, id))
80
+ .returning();
81
+ return row ?? null;
82
+ },
83
+ async listVoyageGroupSegments(db, query) {
84
+ const conditions = [];
85
+ if (query.voyageGroupId) {
86
+ conditions.push(eq(cruiseVoyageGroupSegments.voyageGroupId, query.voyageGroupId));
87
+ }
88
+ if (query.cruiseId)
89
+ conditions.push(eq(cruiseVoyageGroupSegments.cruiseId, query.cruiseId));
90
+ if (query.sailingId)
91
+ conditions.push(eq(cruiseVoyageGroupSegments.sailingId, query.sailingId));
92
+ if (query.segmentKind) {
93
+ conditions.push(eq(cruiseVoyageGroupSegments.segmentKind, query.segmentKind));
94
+ }
95
+ if (query.segmentRole) {
96
+ conditions.push(eq(cruiseVoyageGroupSegments.segmentRole, query.segmentRole));
97
+ }
98
+ const where = conditions.length > 0 ? and(...conditions) : undefined;
99
+ const { limit, offset } = paginate(query);
100
+ const [rows, totalRows] = await Promise.all([
101
+ db
102
+ .select()
103
+ .from(cruiseVoyageGroupSegments)
104
+ .where(where)
105
+ .orderBy(asc(cruiseVoyageGroupSegments.voyageGroupId), asc(cruiseVoyageGroupSegments.sortOrder))
106
+ .limit(limit)
107
+ .offset(offset),
108
+ db.select({ value: count() }).from(cruiseVoyageGroupSegments).where(where),
109
+ ]);
110
+ return { data: rows, total: totalRows[0]?.value ?? 0, limit, offset };
111
+ },
112
+ async createVoyageGroupSegment(db, data) {
113
+ const [row] = await db
114
+ .insert(cruiseVoyageGroupSegments)
115
+ .values(data)
116
+ .returning();
117
+ if (!row)
118
+ throw new Error("Failed to create voyage group segment");
119
+ return row;
120
+ },
121
+ async updateVoyageGroupSegment(db, id, data) {
122
+ const [row] = await db
123
+ .update(cruiseVoyageGroupSegments)
124
+ .set({ ...data, ...setUpdated })
125
+ .where(eq(cruiseVoyageGroupSegments.id, id))
126
+ .returning();
127
+ return row ?? null;
128
+ },
129
+ async deleteVoyageGroupSegment(db, id) {
130
+ const rows = await db
131
+ .delete(cruiseVoyageGroupSegments)
132
+ .where(eq(cruiseVoyageGroupSegments.id, id))
133
+ .returning({ id: cruiseVoyageGroupSegments.id });
134
+ return rows.length > 0;
135
+ },
136
+ async listCruises(db, query) {
137
+ const conditions = [];
138
+ if (query.cruiseType)
139
+ conditions.push(eq(cruises.cruiseType, query.cruiseType));
140
+ if (query.status)
141
+ conditions.push(eq(cruises.status, query.status));
142
+ if (query.lineSupplierId)
143
+ conditions.push(eq(cruises.lineSupplierId, query.lineSupplierId));
144
+ if (query.region) {
145
+ // agent-quality: raw-sql reviewed -- owner: cruises; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
146
+ conditions.push(sql `${cruises.regions} @> ${JSON.stringify([query.region])}::jsonb`);
147
+ }
148
+ if (query.search) {
149
+ const term = `%${query.search}%`;
150
+ conditions.push(or(ilike(cruises.name, term), ilike(cruises.description, term)));
151
+ }
152
+ const where = conditions.length > 0 ? and(...conditions) : undefined;
153
+ const { limit, offset } = paginate(query);
154
+ const [rows, totalRows] = await Promise.all([
155
+ db
156
+ .select()
157
+ .from(cruises)
158
+ .where(where)
159
+ .orderBy(desc(cruises.createdAt))
160
+ .limit(limit)
161
+ .offset(offset),
162
+ db.select({ value: count() }).from(cruises).where(where),
163
+ ]);
164
+ return { data: rows, total: totalRows[0]?.value ?? 0, limit, offset };
165
+ },
166
+ async getCruiseById(db, id, options = {}) {
167
+ const [row] = await db.select().from(cruises).where(eq(cruises.id, id)).limit(1);
168
+ if (!row)
169
+ return null;
170
+ const out = { ...row };
171
+ if (options.withSailings) {
172
+ out.sailings = await db
173
+ .select()
174
+ .from(cruiseSailings)
175
+ .where(eq(cruiseSailings.cruiseId, id))
176
+ .orderBy(asc(cruiseSailings.departureDate));
177
+ }
178
+ if (options.withDays) {
179
+ out.days = await db
180
+ .select()
181
+ .from(cruiseDays)
182
+ .where(eq(cruiseDays.cruiseId, id))
183
+ .orderBy(asc(cruiseDays.dayNumber));
184
+ }
185
+ return out;
186
+ },
187
+ async createCruise(db, data, runtime = {}) {
188
+ const [row] = await db
189
+ .insert(cruises)
190
+ .values(data)
191
+ .returning();
192
+ if (!row)
193
+ throw new Error("Failed to create cruise");
194
+ await reprojectIfPossible(db, row.id);
195
+ await emitCruiseLifecycleEvent(runtime.eventBus, CRUISE_CREATED_EVENT, { id: row.id });
196
+ return row;
197
+ },
198
+ async updateCruise(db, id, data, runtime = {}) {
199
+ const [row] = await db
200
+ .update(cruises)
201
+ .set({ ...data, ...setUpdated })
202
+ .where(eq(cruises.id, id))
203
+ .returning();
204
+ if (row) {
205
+ await reprojectIfPossible(db, row.id);
206
+ await emitCruiseLifecycleEvent(runtime.eventBus, CRUISE_UPDATED_EVENT, { id: row.id });
207
+ }
208
+ return row ?? null;
209
+ },
210
+ async archiveCruise(db, id, runtime = {}) {
211
+ const [row] = await db
212
+ .update(cruises)
213
+ .set({ status: "archived", ...setUpdated })
214
+ .where(eq(cruises.id, id))
215
+ .returning();
216
+ if (row) {
217
+ await reprojectIfPossible(db, row.id);
218
+ await emitCruiseLifecycleEvent(runtime.eventBus, CRUISE_DELETED_EVENT, { id: row.id });
219
+ }
220
+ return row ?? null;
221
+ },
222
+ async recomputeCruiseAggregates(db, cruiseId) {
223
+ // Lowest available price across all of this cruise's sailings × cabin categories × occupancies.
224
+ const [priceAgg] = await db
225
+ .select({
226
+ lowest: sql `MIN(${cruisePrices.pricePerPerson}::numeric)::text`,
227
+ currency: sql `(ARRAY_AGG(${cruisePrices.currency} ORDER BY ${cruisePrices.pricePerPerson}::numeric ASC))[1]`,
228
+ })
229
+ .from(cruisePrices)
230
+ .innerJoin(cruiseSailings, eq(cruisePrices.sailingId, cruiseSailings.id))
231
+ .where(
232
+ // agent-quality: raw-sql reviewed -- owner: cruises; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
233
+ and(eq(cruiseSailings.cruiseId, cruiseId), sql `${cruisePrices.availability} <> 'sold_out'`));
234
+ const [dateAgg] = await db
235
+ .select({
236
+ earliest: sql `MIN(${cruiseSailings.departureDate})`,
237
+ latest: sql `MAX(${cruiseSailings.departureDate})`,
238
+ })
239
+ .from(cruiseSailings)
240
+ .where(eq(cruiseSailings.cruiseId, cruiseId));
241
+ const [row] = await db
242
+ .update(cruises)
243
+ .set({
244
+ lowestPriceCached: priceAgg?.lowest ?? null,
245
+ lowestPriceCurrencyCached: priceAgg?.currency ?? null,
246
+ earliestDepartureCached: dateAgg?.earliest ?? null,
247
+ latestDepartureCached: dateAgg?.latest ?? null,
248
+ ...setUpdated,
249
+ })
250
+ .where(eq(cruises.id, cruiseId))
251
+ .returning();
252
+ if (row)
253
+ await reprojectIfPossible(db, row.id);
254
+ return row ?? null;
255
+ },
256
+ // ---------- sailings ----------
257
+ };
@@ -0,0 +1,18 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ import type { CruiseAdapter, SourceRef } from "./adapters/index.js";
3
+ import { type Cruise } from "./schema-core.js";
4
+ /**
5
+ * One-way conversion of an external cruise into a local cruise.
6
+ *
7
+ * Fetches the cruise + ship + cabin categories + sailings (with itineraries)
8
+ * from the adapter and inserts them as local rows in one transaction. After
9
+ * detach the operator owns the data and can edit it freely; the upstream
10
+ * link is severed (future calls to the original external key still work
11
+ * upstream-side, but the local DB has its own snapshot).
12
+ *
13
+ * Returns the newly-created local cruise row.
14
+ */
15
+ export declare function detachExternalCruise(db: PostgresJsDatabase, adapter: CruiseAdapter, sourceRef: SourceRef, options?: {
16
+ slugSuffix?: string;
17
+ }): Promise<Cruise>;
18
+ //# sourceMappingURL=service-detach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-detach.d.ts","sourceRoot":"","sources":["../src/service-detach.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAEnE,OAAO,EAAE,KAAK,MAAM,EAA2B,MAAM,kBAAkB,CAAA;AAIvE;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpC,OAAO,CAAC,MAAM,CAAC,CAsKjB"}
@@ -0,0 +1,199 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { cruiseCabinCategories, cruiseDecks, cruiseShips } from "./schema-cabins.js";
3
+ import { cruiseSailings, cruises } from "./schema-core.js";
4
+ import { cruiseSailingDays } from "./schema-itinerary.js";
5
+ import { cruisesService } from "./service.js";
6
+ /**
7
+ * One-way conversion of an external cruise into a local cruise.
8
+ *
9
+ * Fetches the cruise + ship + cabin categories + sailings (with itineraries)
10
+ * from the adapter and inserts them as local rows in one transaction. After
11
+ * detach the operator owns the data and can edit it freely; the upstream
12
+ * link is severed (future calls to the original external key still work
13
+ * upstream-side, but the local DB has its own snapshot).
14
+ *
15
+ * Returns the newly-created local cruise row.
16
+ */
17
+ export async function detachExternalCruise(db, adapter, sourceRef, options = {}) {
18
+ const externalCruise = await adapter.fetchCruise(sourceRef);
19
+ if (!externalCruise) {
20
+ throw new Error(`Adapter '${adapter.name}' returned no cruise for ref ${sourceRef.externalId}`);
21
+ }
22
+ return db.transaction(async (tx) => {
23
+ let localShipId = null;
24
+ // 1. Snapshot ship + decks + cabin categories if the cruise references a ship.
25
+ if (externalCruise.defaultShipRef) {
26
+ const externalShip = await adapter.fetchShip(externalCruise.defaultShipRef);
27
+ if (externalShip) {
28
+ const slug = await ensureUniqueShipSlug(tx, externalShip.slug, options.slugSuffix);
29
+ const [shipRow] = await tx
30
+ .insert(cruiseShips)
31
+ .values({
32
+ slug,
33
+ name: externalShip.name,
34
+ shipType: externalShip.shipType,
35
+ capacityGuests: externalShip.capacityGuests ?? null,
36
+ capacityCrew: externalShip.capacityCrew ?? null,
37
+ cabinCount: externalShip.cabinCount ?? null,
38
+ deckCount: externalShip.deckCount ?? null,
39
+ lengthMeters: externalShip.lengthMeters ?? null,
40
+ cruisingSpeedKnots: externalShip.cruisingSpeedKnots ?? null,
41
+ yearBuilt: externalShip.yearBuilt ?? null,
42
+ yearRefurbished: externalShip.yearRefurbished ?? null,
43
+ imo: externalShip.imo ?? null,
44
+ description: externalShip.description ?? null,
45
+ deckPlanUrl: externalShip.deckPlanUrl ?? null,
46
+ gallery: externalShip.gallery ?? [],
47
+ amenities: (externalShip.amenities ?? {}),
48
+ externalRefs: { [adapter.name]: externalShip.sourceRef.externalId },
49
+ isActive: true,
50
+ })
51
+ .returning();
52
+ if (!shipRow)
53
+ throw new Error("Failed to insert detached ship");
54
+ localShipId = shipRow.id;
55
+ if (externalShip.decks) {
56
+ for (const deck of externalShip.decks) {
57
+ await tx.insert(cruiseDecks).values({
58
+ shipId: shipRow.id,
59
+ name: deck.name,
60
+ level: deck.level ?? null,
61
+ planImageUrl: deck.planImageUrl ?? null,
62
+ });
63
+ }
64
+ }
65
+ if (externalShip.categories) {
66
+ for (const cat of externalShip.categories) {
67
+ await tx.insert(cruiseCabinCategories).values({
68
+ shipId: shipRow.id,
69
+ code: cat.code,
70
+ name: cat.name,
71
+ roomType: cat.roomType,
72
+ description: cat.description ?? null,
73
+ minOccupancy: cat.minOccupancy,
74
+ maxOccupancy: cat.maxOccupancy,
75
+ squareFeet: cat.squareFeet ?? null,
76
+ wheelchairAccessible: cat.wheelchairAccessible ?? false,
77
+ amenities: cat.amenities ?? [],
78
+ featureCodes: cat.featureCodes ?? [],
79
+ bedConfigurations: cat.bedConfigurations ?? [],
80
+ accessibilityFeatures: cat.accessibilityFeatures ?? [],
81
+ viewType: cat.viewType ?? null,
82
+ images: cat.images ?? [],
83
+ floorplanImages: cat.floorplanImages ?? [],
84
+ gradeCodes: cat.gradeCodes ?? [],
85
+ externalRefs: { [adapter.name]: cat.sourceRef.externalId },
86
+ });
87
+ }
88
+ }
89
+ }
90
+ }
91
+ // 2. Insert the cruise row.
92
+ const slug = await ensureUniqueCruiseSlug(tx, externalCruise.slug, options.slugSuffix);
93
+ const [cruiseRow] = await tx
94
+ .insert(cruises)
95
+ .values({
96
+ slug,
97
+ name: externalCruise.name,
98
+ cruiseType: externalCruise.cruiseType,
99
+ defaultShipId: localShipId,
100
+ nights: externalCruise.nights,
101
+ embarkPortCanonicalPlaceId: externalCruise.embarkPortCanonicalPlaceId ?? null,
102
+ disembarkPortCanonicalPlaceId: externalCruise.disembarkPortCanonicalPlaceId ?? null,
103
+ description: externalCruise.description ?? null,
104
+ shortDescription: externalCruise.shortDescription ?? null,
105
+ highlights: externalCruise.highlights ?? [],
106
+ inclusionsHtml: externalCruise.inclusionsHtml ?? null,
107
+ exclusionsHtml: externalCruise.exclusionsHtml ?? null,
108
+ regionIds: externalCruise.regionIds ?? [],
109
+ waterwayIds: externalCruise.waterwayIds ?? [],
110
+ portIds: externalCruise.portIds ?? [],
111
+ countryIso: externalCruise.countryIso ?? [],
112
+ regions: externalCruise.regions ?? [],
113
+ waterways: externalCruise.waterways ?? [],
114
+ ports: externalCruise.ports ?? [],
115
+ countries: externalCruise.countries ?? [],
116
+ themes: externalCruise.themes ?? [],
117
+ heroImageUrl: externalCruise.heroImageUrl ?? null,
118
+ mapImageUrl: externalCruise.mapImageUrl ?? null,
119
+ status: externalCruise.status ?? "draft",
120
+ externalRefs: { [`${adapter.name}-detach-source`]: externalCruise.sourceRef.externalId },
121
+ })
122
+ .returning();
123
+ if (!cruiseRow)
124
+ throw new Error("Failed to insert detached cruise");
125
+ // 3. Snapshot sailings with their itinerary day overrides. v1 falls back to
126
+ // the default ship for every sailing when an external sailing references
127
+ // a different ship — multi-ship sailing detach can be added later.
128
+ if (localShipId) {
129
+ const sailings = await adapter.listSailingsForCruise(externalCruise.sourceRef);
130
+ for (const sailing of sailings) {
131
+ const [sailingRow] = await tx
132
+ .insert(cruiseSailings)
133
+ .values({
134
+ cruiseId: cruiseRow.id,
135
+ shipId: localShipId,
136
+ departureDate: sailing.departureDate,
137
+ returnDate: sailing.returnDate,
138
+ embarkPortFacilityId: null,
139
+ embarkPortCanonicalPlaceId: sailing.embarkPortCanonicalPlaceId ?? null,
140
+ disembarkPortFacilityId: null,
141
+ disembarkPortCanonicalPlaceId: sailing.disembarkPortCanonicalPlaceId ?? null,
142
+ direction: sailing.direction ?? null,
143
+ availabilityNote: sailing.availabilityNote ?? null,
144
+ isCharter: sailing.isCharter ?? false,
145
+ salesStatus: sailing.salesStatus ?? "open",
146
+ externalRefs: { [`${adapter.name}-detach-source`]: sailing.sourceRef.externalId },
147
+ lastSyncedAt: new Date(),
148
+ })
149
+ .returning();
150
+ if (!sailingRow)
151
+ throw new Error("Failed to insert detached sailing");
152
+ const days = await adapter.fetchSailingItinerary(sailing.sourceRef);
153
+ for (const day of days) {
154
+ await tx.insert(cruiseSailingDays).values({
155
+ sailingId: sailingRow.id,
156
+ dayNumber: day.dayNumber,
157
+ title: day.title ?? null,
158
+ description: day.description ?? null,
159
+ portFacilityId: null,
160
+ portCanonicalPlaceId: day.portCanonicalPlaceId ?? null,
161
+ arrivalTime: day.arrivalTime ?? null,
162
+ departureTime: day.departureTime ?? null,
163
+ isOvernight: day.isOvernight ?? null,
164
+ isSeaDay: day.isSeaDay ?? null,
165
+ isExpeditionLanding: day.isExpeditionLanding ?? null,
166
+ isSkipped: false,
167
+ meals: day.meals ?? null,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ // 4. Recompute aggregates so the new cruise reports correct cached fields.
173
+ await cruisesService.recomputeCruiseAggregates(tx, cruiseRow.id);
174
+ const [refreshed] = await tx.select().from(cruises).where(eq(cruises.id, cruiseRow.id)).limit(1);
175
+ return refreshed ?? cruiseRow;
176
+ });
177
+ }
178
+ async function ensureUniqueCruiseSlug(tx, baseSlug, suffix) {
179
+ const candidate = suffix ? `${baseSlug}-${suffix}` : baseSlug;
180
+ const [exists] = await tx
181
+ .select({ id: cruises.id })
182
+ .from(cruises)
183
+ .where(eq(cruises.slug, candidate))
184
+ .limit(1);
185
+ if (!exists)
186
+ return candidate;
187
+ return `${candidate}-${Math.random().toString(36).slice(2, 6)}`;
188
+ }
189
+ async function ensureUniqueShipSlug(tx, baseSlug, suffix) {
190
+ const candidate = suffix ? `${baseSlug}-${suffix}` : baseSlug;
191
+ const [exists] = await tx
192
+ .select({ id: cruiseShips.id })
193
+ .from(cruiseShips)
194
+ .where(eq(cruiseShips.slug, candidate))
195
+ .limit(1);
196
+ if (!exists)
197
+ return candidate;
198
+ return `${candidate}-${Math.random().toString(36).slice(2, 6)}`;
199
+ }
@@ -0,0 +1,11 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ import type { CruiseEnrichmentProgram } from "./schema-content.js";
3
+ import type { InsertEnrichmentProgram, ReplaceEnrichmentPrograms, UpdateEnrichmentProgram } from "./validation-content.js";
4
+ export declare const cruiseEnrichmentService: {
5
+ listEnrichmentPrograms(db: PostgresJsDatabase, cruiseId: string): Promise<CruiseEnrichmentProgram[]>;
6
+ createEnrichmentProgram(db: PostgresJsDatabase, data: InsertEnrichmentProgram): Promise<CruiseEnrichmentProgram>;
7
+ updateEnrichmentProgram(db: PostgresJsDatabase, id: string, data: UpdateEnrichmentProgram): Promise<CruiseEnrichmentProgram | null>;
8
+ deleteEnrichmentProgram(db: PostgresJsDatabase, id: string): Promise<boolean>;
9
+ replaceEnrichmentPrograms(db: PostgresJsDatabase, payload: ReplaceEnrichmentPrograms): Promise<CruiseEnrichmentProgram[]>;
10
+ };
11
+ //# sourceMappingURL=service-enrichment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-enrichment.d.ts","sourceRoot":"","sources":["../src/service-enrichment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAGlE,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,yBAAyB,CAAA;AAEhC,eAAO,MAAM,uBAAuB;+BAE5B,kBAAkB,YACZ,MAAM,GACf,OAAO,CAAC,uBAAuB,EAAE,CAAC;gCAS/B,kBAAkB,QAChB,uBAAuB,GAC5B,OAAO,CAAC,uBAAuB,CAAC;gCAO7B,kBAAkB,MAClB,MAAM,QACJ,uBAAuB,GAC5B,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;gCASR,kBAAkB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;kCAS7E,kBAAkB,WACb,yBAAyB,GACjC,OAAO,CAAC,uBAAuB,EAAE,CAAC;CAatC,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { asc, eq } from "drizzle-orm";
2
+ import { cruiseEnrichmentPrograms } from "./schema-content.js";
3
+ import { setUpdated } from "./service-shared.js";
4
+ export const cruiseEnrichmentService = {
5
+ async listEnrichmentPrograms(db, cruiseId) {
6
+ return db
7
+ .select()
8
+ .from(cruiseEnrichmentPrograms)
9
+ .where(eq(cruiseEnrichmentPrograms.cruiseId, cruiseId))
10
+ .orderBy(asc(cruiseEnrichmentPrograms.sortOrder), asc(cruiseEnrichmentPrograms.name));
11
+ },
12
+ async createEnrichmentProgram(db, data) {
13
+ const [row] = await db.insert(cruiseEnrichmentPrograms).values(data).returning();
14
+ if (!row)
15
+ throw new Error("Failed to create enrichment program");
16
+ return row;
17
+ },
18
+ async updateEnrichmentProgram(db, id, data) {
19
+ const [row] = await db
20
+ .update(cruiseEnrichmentPrograms)
21
+ .set({ ...data, ...setUpdated })
22
+ .where(eq(cruiseEnrichmentPrograms.id, id))
23
+ .returning();
24
+ return row ?? null;
25
+ },
26
+ async deleteEnrichmentProgram(db, id) {
27
+ const result = await db
28
+ .delete(cruiseEnrichmentPrograms)
29
+ .where(eq(cruiseEnrichmentPrograms.id, id))
30
+ .returning({ id: cruiseEnrichmentPrograms.id });
31
+ return result.length > 0;
32
+ },
33
+ async replaceEnrichmentPrograms(db, payload) {
34
+ return db.transaction(async (tx) => {
35
+ await tx
36
+ .delete(cruiseEnrichmentPrograms)
37
+ .where(eq(cruiseEnrichmentPrograms.cruiseId, payload.cruiseId));
38
+ if (payload.programs.length === 0)
39
+ return [];
40
+ const inserted = await tx
41
+ .insert(cruiseEnrichmentPrograms)
42
+ .values(payload.programs.map((p) => ({ ...p, cruiseId: payload.cruiseId })))
43
+ .returning();
44
+ return inserted;
45
+ });
46
+ },
47
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Provider-agnostic external cruise catalog refresh.
3
+ *
4
+ * Reconciles both local browse/search projections (`cruise_search_index`) and,
5
+ * when catalog runtime dependencies are supplied, catalog sourced entries plus
6
+ * catalog search slices. The service never imports a concrete provider.
7
+ */
8
+ import type { DocumentBuilder, FieldPolicyRegistry, IndexerService } from "@voyant-travel/catalog";
9
+ import { type SourceAdapterRegistry, type SyncProgressEvent, type SyncSourcesSummary } from "@voyant-travel/catalog/booking-engine";
10
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
11
+ import { type ExternalAdapterRefreshResult } from "./service-search.js";
12
+ export interface ExternalCruiseCatalogRefreshOptions {
13
+ db: PostgresJsDatabase;
14
+ /**
15
+ * Optional catalog source registry. Supplying it lets the refresh update
16
+ * `catalog_sourced_entries` and catalog search slices from cruise shims.
17
+ */
18
+ sourceAdapterRegistry?: SourceAdapterRegistry;
19
+ indexerService?: IndexerService;
20
+ fieldPolicyRegistries?: ReadonlyMap<string, FieldPolicyRegistry>;
21
+ wrapCatalogBuilder?: (builder: DocumentBuilder) => DocumentBuilder;
22
+ onCatalogProgress?: (event: SyncProgressEvent) => void;
23
+ }
24
+ export interface ExternalCruiseCatalogRefreshResult {
25
+ cruiseSearchIndex: {
26
+ adapters: Array<{
27
+ adapter: string;
28
+ } & ExternalAdapterRefreshResult>;
29
+ upserted: number;
30
+ removed: number;
31
+ errors: Array<{
32
+ adapter: string;
33
+ error: string;
34
+ }>;
35
+ };
36
+ catalog?: SyncSourcesSummary;
37
+ }
38
+ export declare function refreshExternalCruiseCatalog(options: ExternalCruiseCatalogRefreshOptions): Promise<ExternalCruiseCatalogRefreshResult>;
39
+ //# sourceMappingURL=service-external-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-external-refresh.d.ts","sourceRoot":"","sources":["../src/service-external-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAClG,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAExB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,EAAwB,KAAK,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAE7F,MAAM,WAAW,mCAAmC;IAClD,EAAE,EAAE,kBAAkB,CAAA;IACtB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,qBAAqB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAChE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,eAAe,CAAA;IAClE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;CACvD;AAED,MAAM,WAAW,kCAAkC;IACjD,iBAAiB,EAAE;QACjB,QAAQ,EAAE,KAAK,CACb;YACE,OAAO,EAAE,MAAM,CAAA;SAChB,GAAG,4BAA4B,CACjC,CAAA;QACD,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAClD,CAAA;IACD,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAC7B;AAED,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,kCAAkC,CAAC,CAsC7C"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Provider-agnostic external cruise catalog refresh.
3
+ *
4
+ * Reconciles both local browse/search projections (`cruise_search_index`) and,
5
+ * when catalog runtime dependencies are supplied, catalog sourced entries plus
6
+ * catalog search slices. The service never imports a concrete provider.
7
+ */
8
+ import { syncSources, } from "@voyant-travel/catalog/booking-engine";
9
+ import { listCruiseAdapters } from "./adapters/registry.js";
10
+ import { cruisesSearchService } from "./service-search.js";
11
+ export async function refreshExternalCruiseCatalog(options) {
12
+ const adapters = listCruiseAdapters();
13
+ const cruiseSearchIndex = {
14
+ adapters: [],
15
+ upserted: 0,
16
+ removed: 0,
17
+ errors: [],
18
+ };
19
+ for (const adapter of adapters) {
20
+ try {
21
+ const result = await cruisesSearchService.refreshExternalForAdapter(options.db, adapter);
22
+ cruiseSearchIndex.adapters.push({ adapter: adapter.name, ...result });
23
+ cruiseSearchIndex.upserted += result.upserted;
24
+ cruiseSearchIndex.removed += result.removed;
25
+ }
26
+ catch (err) {
27
+ cruiseSearchIndex.errors.push({
28
+ adapter: adapter.name,
29
+ error: err instanceof Error ? err.message : String(err),
30
+ });
31
+ }
32
+ }
33
+ let catalog;
34
+ if (options.sourceAdapterRegistry && options.indexerService && options.fieldPolicyRegistries) {
35
+ catalog = await syncSources({
36
+ registry: options.sourceAdapterRegistry,
37
+ indexerService: options.indexerService,
38
+ fieldPolicyRegistries: options.fieldPolicyRegistries,
39
+ db: options.db,
40
+ verticals: ["cruises"],
41
+ pruneMissing: true,
42
+ ...(options.wrapCatalogBuilder ? { wrapBuilder: options.wrapCatalogBuilder } : {}),
43
+ ...(options.onCatalogProgress ? { onProgress: options.onCatalogProgress } : {}),
44
+ });
45
+ }
46
+ return { cruiseSearchIndex, ...(catalog ? { catalog } : {}) };
47
+ }
@@ -0,0 +1,22 @@
1
+ import type { CruiseDay, CruiseSailingDay } from "./schema-itinerary.js";
2
+ export type EffectiveItineraryDay = {
3
+ dayNumber: number;
4
+ title: string | null;
5
+ description: string | null;
6
+ portFacilityId: string | null;
7
+ portCanonicalPlaceId: string | null;
8
+ arrivalTime: string | null;
9
+ departureTime: string | null;
10
+ isOvernight: boolean;
11
+ isSeaDay: boolean;
12
+ isExpeditionLanding: boolean;
13
+ isSkipped: boolean;
14
+ meals: {
15
+ breakfast?: boolean;
16
+ lunch?: boolean;
17
+ dinner?: boolean;
18
+ };
19
+ hasOverride: boolean;
20
+ };
21
+ export declare function mergeDay(base: CruiseDay, override: CruiseSailingDay | undefined): EffectiveItineraryDay;
22
+ //# sourceMappingURL=service-itinerary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-itinerary.d.ts","sourceRoot":"","sources":["../src/service-itinerary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExE,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IACjE,WAAW,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,gBAAgB,GAAG,SAAS,GACrC,qBAAqB,CAiCvB"}