@curless/hotel-storefront 0.45.1 → 0.46.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.
Files changed (51) hide show
  1. package/dist/card.generated.d.ts +1 -1
  2. package/dist/card.generated.js +2 -2
  3. package/dist/card.generated.js.map +1 -1
  4. package/dist/config.d.ts +36 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +8 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/data.d.ts +2 -0
  9. package/dist/data.d.ts.map +1 -1
  10. package/dist/data.js +281 -19
  11. package/dist/data.js.map +1 -1
  12. package/dist/demo-hotels.d.ts +52 -1
  13. package/dist/demo-hotels.d.ts.map +1 -1
  14. package/dist/demo-hotels.js +45 -11
  15. package/dist/demo-hotels.js.map +1 -1
  16. package/dist/huazhu/backend.d.ts.map +1 -1
  17. package/dist/huazhu/backend.js +9 -5
  18. package/dist/huazhu/backend.js.map +1 -1
  19. package/dist/legal.d.ts.map +1 -1
  20. package/dist/legal.js +38 -9
  21. package/dist/legal.js.map +1 -1
  22. package/dist/lib.d.ts +2 -2
  23. package/dist/lib.d.ts.map +1 -1
  24. package/dist/lib.js +1 -1
  25. package/dist/lib.js.map +1 -1
  26. package/dist/room-filters.d.ts +76 -0
  27. package/dist/room-filters.d.ts.map +1 -0
  28. package/dist/room-filters.js +191 -0
  29. package/dist/room-filters.js.map +1 -0
  30. package/dist/server.d.ts +2 -2
  31. package/dist/server.d.ts.map +1 -1
  32. package/dist/server.js +8 -4
  33. package/dist/server.js.map +1 -1
  34. package/dist/supplier.d.ts +1 -0
  35. package/dist/supplier.d.ts.map +1 -1
  36. package/dist/supplier.js +5 -1
  37. package/dist/supplier.js.map +1 -1
  38. package/dist/surface.d.ts.map +1 -1
  39. package/dist/surface.js +5 -1
  40. package/dist/surface.js.map +1 -1
  41. package/dist/tools.d.ts +20 -2
  42. package/dist/tools.d.ts.map +1 -1
  43. package/dist/tools.js +158 -9
  44. package/dist/tools.js.map +1 -1
  45. package/dist/types.d.ts +36 -4
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/vocab.d.ts +19 -0
  48. package/dist/vocab.d.ts.map +1 -1
  49. package/dist/vocab.js +48 -2
  50. package/dist/vocab.js.map +1 -1
  51. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  import type { HotelBackend } from './backend.js';
2
+ import type { DemoCapabilities } from './config.js';
2
3
  import type { StateFile } from './state.js';
3
- import type { Booking, ExtraKind, HotelNames, HotelPolicyTopic, Names, TripLine } from './types.js';
4
+ import type { BedType, Booking, ExtraKind, HotelNames, HotelPolicyTopic, MealPlan, Names, RateLabel, TripLine, WindowKind } from './types.js';
4
5
  /**
5
6
  * The hotels, out of a JSON file, priced by us.
6
7
  *
@@ -17,23 +18,63 @@ import type { Booking, ExtraKind, HotelNames, HotelPolicyTopic, Names, TripLine
17
18
  * - a date nobody gave: no stay, no price,
18
19
  * - a cancellation fee: previewed with its rule before anything is cancelled.
19
20
  */
21
+ /**
22
+ * One thing that can be sold: a room (the one-level file, one price) or ONE
23
+ * RATE of a room type (the two-level file, `rates` - see data.ts). The reader
24
+ * (`parseHotelData`) turns the second into the first: a type with three rates
25
+ * is three of these, each carrying the type in `roomType`, so everything below
26
+ * sells, holds and prices a `RawRoom` and never asks which kind of file it came
27
+ * from.
28
+ */
20
29
  export type RawRoom = {
30
+ /** A room's id; a rate's id, unique in the hotel - what a trip holds. */
21
31
  id: string;
32
+ /** A room's name; a rate's is the whole offer's - "Deluxe King · Flexible". */
22
33
  name: string;
23
34
  /** `name` in the card's languages - see `Room.names`. */
24
35
  names?: Names;
25
36
  sleeps: number;
26
37
  sizeSqm?: number;
27
38
  beds?: string;
39
+ /** What `beds` says, as codes - see `Room.bedTypes`. */
40
+ bedTypes?: BedType[];
28
41
  view?: string;
42
+ /** The window `view` is about, as a code - see `Room.window`. */
43
+ window?: WindowKind;
44
+ /** Whether the rate includes breakfast: a rate's is "one or more". */
29
45
  breakfast: boolean;
30
46
  imageUrl?: string;
47
+ /** Every photograph, `imageUrl` first - see `Room.images`. */
48
+ images?: string[];
49
+ /** Which floors - see `Room.floor`. */
50
+ floor?: string;
31
51
  /** Written the way a human writes it - 3800, not 380000. */
32
52
  nightly: number;
33
53
  roomsLeft: number;
34
54
  refundable: boolean;
35
55
  /** Hours before arrival that cancelling is still free. Absent on a non-refundable rate. */
36
56
  freeCancelHours?: number;
57
+ /** A rate only: the room type it is a rate of - see `Room.roomType`. */
58
+ roomType?: {
59
+ id: string;
60
+ name: string;
61
+ names?: Names;
62
+ };
63
+ /** A rate only: its own id and name, apart from the type's - see `Room.rate`. */
64
+ rate?: {
65
+ id: string;
66
+ name: string;
67
+ names?: Names;
68
+ };
69
+ /** A rate only, and only where it says how many breakfasts: the meal, as a code. */
70
+ meal?: MealPlan;
71
+ /** A rate only: the meal's label, then the offers it says it is (early booking …). */
72
+ labels?: RateLabel[];
73
+ /**
74
+ * Said by the file: 'at-hotel'. There is no 'prepaid' - this backend takes no
75
+ * money, and `parseHotelData` refuses a rate that says it does.
76
+ */
77
+ payment?: 'at-hotel';
37
78
  };
38
79
  export type RawExtra = {
39
80
  id: string;
@@ -54,6 +95,11 @@ export type RawHotel = {
54
95
  /** ISO 3166-1 alpha-2 - see `Hotel.countryCode`. */
55
96
  countryCode?: string;
56
97
  area?: string;
98
+ /** Where it is, in decimal degrees - see `Hotel.geo`. */
99
+ geo?: {
100
+ lat: number;
101
+ lng: number;
102
+ };
57
103
  /** Its names in the card's languages, as its group publishes them - see `Names`. */
58
104
  names?: HotelNames;
59
105
  summary: string;
@@ -149,6 +195,11 @@ export type DemoHotelsOptions = {
149
195
  * two demonstration suppliers tells their codes apart by it.
150
196
  */
151
197
  codePrefix?: string;
198
+ /**
199
+ * What to switch off (or on) in `FULL_CAPABILITIES` - the config's
200
+ * `data.capabilities`. Absent, the demonstration offers everything.
201
+ */
202
+ capabilities?: DemoCapabilities;
152
203
  };
153
204
  /**
154
205
  * A booking as this file keeps it: the booking, and the conversations that may
@@ -1 +1 @@
1
- {"version":3,"file":"demo-hotels.d.ts","sourceRoot":"","sources":["../src/demo-hotels.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"demo-hotels.d.ts","sourceRoot":"","sources":["../src/demo-hotels.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { addDays, arrivalInstant, atHotelIso, atHotelTime, eachNight, isWeekendN
4
4
  import { FACILITIES, hasFacility } from './facilities.js';
5
5
  import { addMoney, formatMoney, minorFactor, money, multiplyMoney, taxOn, toMinor, wholeUnits, } from './money.js';
6
6
  import { roomNamesOf } from './names.js';
7
+ import { bedKindsOf } from './room-filters.js';
7
8
  import { MAX_EXTRA_QUANTITY, MAX_ROOMS_PER_LINE } from './trip.js';
8
9
  export const demoError = (code, message) => Object.assign(new Error(message), { code });
9
10
  const POLICY_TITLES = {
@@ -115,6 +116,12 @@ const publicBooking = (b) => {
115
116
  * it would otherwise ride along on another hotel's booking.
116
117
  */
117
118
  /** A room too small for the party, as its code - see `partyNeedsOf`. */
119
+ /** What a trip line says of a room's breakfast - a rate that says how many says it. */
120
+ const breakfastWords = (r) => r.meal?.plan === 'breakfast' && r.meal.count
121
+ ? `Breakfast for ${r.meal.count}`
122
+ : r.breakfast
123
+ ? 'Breakfast included'
124
+ : undefined;
118
125
  const partyCode = (guests, sleeps) => {
119
126
  const { code, args } = partyNeedsOf(guests, sleeps);
120
127
  return { code, args };
@@ -481,9 +488,14 @@ export const createDemoHotels = (opts) => {
481
488
  sleeps: r.sleeps,
482
489
  sizeSqm: r.sizeSqm,
483
490
  beds: r.beds,
491
+ ...(r.bedTypes ? { bedTypes: r.bedTypes } : {}),
484
492
  view: r.view,
493
+ ...(r.window ? { window: r.window } : {}),
485
494
  breakfast: r.breakfast,
495
+ ...(r.meal ? { meal: r.meal } : {}),
486
496
  imageUrl: r.imageUrl,
497
+ ...(r.images ? { images: r.images } : {}),
498
+ ...(r.floor ? { floor: r.floor } : {}),
487
499
  // The average, because a Friday costs more than a Tuesday. `stayTotal` is
488
500
  // the number to compare hotels on, and it is exact.
489
501
  nightly: wholeUnits(money(roomSubtotal.minor / perNight.length, h.currency)),
@@ -507,6 +519,13 @@ export const createDemoHotels = (opts) => {
507
519
  ? { freeCancellationLocal: atHotelTime(Date.parse(freeUntil), offsetOf(h)) }
508
520
  : {}),
509
521
  roomsLeft: Math.max(0, r.roomsLeft - heldOn(h.id, r.id, stay, ignore)),
522
+ // A rate of a room type, the way Huazhu's are: the type and the rate
523
+ // beside the whole offer's name, so the card and the tools fold a type's
524
+ // rates into one row.
525
+ ...(r.roomType ? { roomType: r.roomType } : {}),
526
+ ...(r.rate ? { rate: r.rate } : {}),
527
+ ...(r.labels ? { labels: r.labels } : {}),
528
+ ...(r.payment ? { payment: r.payment } : {}),
510
529
  };
511
530
  };
512
531
  const toHotel = (h) => {
@@ -521,6 +540,7 @@ export const createDemoHotels = (opts) => {
521
540
  country: h.country,
522
541
  ...(h.countryCode ? { countryCode: h.countryCode } : {}),
523
542
  area: h.area,
543
+ ...(h.geo ? { geo: h.geo } : {}),
524
544
  ...(h.names ? { names: h.names } : {}),
525
545
  summary: h.summary,
526
546
  amenities: h.amenities,
@@ -643,9 +663,16 @@ export const createDemoHotels = (opts) => {
643
663
  /** A room type by its id or the name the hotel prints. */
644
664
  const roomOf = (h, ref) => {
645
665
  const wanted = ref.trim().toLowerCase();
646
- return (h.rooms.find((r) => r.id.toLowerCase() === wanted) ??
647
- h.rooms.find((r) => r.name.toLowerCase() === wanted) ??
648
- h.rooms.find((r) => r.name.toLowerCase().includes(wanted) && wanted.length >= 4));
666
+ const exact = h.rooms.find((r) => r.id.toLowerCase() === wanted) ??
667
+ h.rooms.find((r) => r.name.toLowerCase() === wanted);
668
+ if (exact || wanted.length < 4)
669
+ return exact;
670
+ const part = h.rooms.filter((r) => r.name.toLowerCase().includes(wanted));
671
+ // ⚠️ A WORD THAT FITS SEVERAL RATES OF A TYPE PICKS NONE OF THEM. "Deluxe
672
+ // King" is the first of its rates by the file's order - which may be the
673
+ // one that cannot be cancelled. A room that is its own type keeps the old
674
+ // reading: the first.
675
+ return part.length > 1 && part.some((r) => r.rate) ? undefined : part[0];
649
676
  };
650
677
  const quoteTrip = async (trip, who, ignore) => {
651
678
  sweep();
@@ -745,9 +772,13 @@ export const createDemoHotels = (opts) => {
745
772
  roomRef: raw.id,
746
773
  title: raw.name,
747
774
  ...(raw.names ? { titleNames: raw.names } : {}),
748
- detail: [raw.beds, raw.view, raw.breakfast ? 'Breakfast included' : undefined]
749
- .filter(Boolean)
750
- .join(' · '),
775
+ detail: [raw.beds, raw.view, breakfastWords(raw)].filter(Boolean).join(' · '),
776
+ // A rate's rate name, window and meal as codes, for a card in another
777
+ // language - the parts of `detail`, as Huazhu's lines carry them.
778
+ ...(raw.rate ? { rate: { name: raw.rate.name } } : {}),
779
+ ...(raw.bedTypes ? { bedTypes: raw.bedTypes } : {}),
780
+ ...(raw.window ? { window: raw.window } : {}),
781
+ ...(raw.meal ? { meal: raw.meal } : {}),
751
782
  stay: line.stay,
752
783
  nights: room.nights,
753
784
  quantity: wanted,
@@ -1194,6 +1225,7 @@ export const createDemoHotels = (opts) => {
1194
1225
  brand: opts.data.brand,
1195
1226
  capabilities: {
1196
1227
  ...FULL_CAPABILITIES,
1228
+ ...opts.capabilities,
1197
1229
  ...(opts.data.membership ? { programme: opts.data.membership.programme } : {}),
1198
1230
  codePrefix,
1199
1231
  },
@@ -1258,8 +1290,8 @@ export const createDemoHotels = (opts) => {
1258
1290
  // ⚠️ THE FILTERS, and what each would leave with the others applied - the
1259
1291
  // count a chip shows before it is pressed (robin, 2026-09-28: 「筛选可以,
1260
1292
  // 加上」). A brand is one at a time; facilities and room terms all apply.
1261
- // A room term is about a ROOM: a hotel passes when it has one, and on a
1262
- // dated search that is the room that gets priced.
1293
+ // A room term is about a ROOM: a hotel passes when it has one that meets
1294
+ // ALL of them, and on a dated search that is the room that gets priced.
1263
1295
  const f = q.filters ?? {};
1264
1296
  const stayAsked = q.stay;
1265
1297
  const wantRooms = Math.max(1, Math.min(MAX_ROOMS_PER_LINE, Math.floor(q.rooms ?? 1)));
@@ -1267,10 +1299,12 @@ export const createDemoHotels = (opts) => {
1267
1299
  // free cancellation is a window that has not closed yet, not a rate that
1268
1300
  // once had one.
1269
1301
  const roomOk = (h, r, over) => (!over.freeCancellation || (stayAsked ? !!freeUntilOf(h, r, stayAsked) : r.refundable)) &&
1270
- (!over.breakfast || !!r.breakfast);
1302
+ (!over.breakfast || !!r.breakfast) &&
1303
+ (!over.bed || bedKindsOf(r)[over.bed]);
1271
1304
  const passes = (h, over) => (!over.brand || h.brand.toLowerCase() === over.brand.toLowerCase()) &&
1272
1305
  (over.facilities ?? []).every((k) => hasFacility(h.amenities, k)) &&
1273
- (!(over.freeCancellation || over.breakfast) || h.rooms.some((r) => roomOk(h, r, over)));
1306
+ (!(over.freeCancellation || over.breakfast || over.bed) ||
1307
+ h.rooms.some((r) => roomOk(h, r, over)));
1274
1308
  const matches = placed.filter((h) => passes(h, f));
1275
1309
  // ⚠️ NAMED NIGHTS ARE PRICED, EVERY HOTEL (robin, 2026-09-28, with Trip.com
1276
1310
  // and the group's own site as the reference: a place, then the dates,
@@ -1287,7 +1321,7 @@ export const createDemoHotels = (opts) => {
1287
1321
  const bestFor = (h, over) => {
1288
1322
  if (!stayAsked)
1289
1323
  return null;
1290
- const k = `${h.id}|${!!over.freeCancellation}|${!!over.breakfast}`;
1324
+ const k = `${h.id}|${!!over.freeCancellation}|${!!over.breakfast}|${over.bed ?? ''}`;
1291
1325
  const known = best.get(k);
1292
1326
  if (known !== undefined)
1293
1327
  return known;