@curless/hotel-storefront 0.23.1 → 0.24.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/README.md +28 -11
- package/dist/__tests__/__fixtures__/huazhu-fake.d.ts +54 -0
- package/dist/__tests__/__fixtures__/huazhu-fake.d.ts.map +1 -0
- package/dist/__tests__/__fixtures__/huazhu-fake.js +340 -0
- package/dist/__tests__/__fixtures__/huazhu-fake.js.map +1 -0
- package/dist/__tests__/huazhu-backend.test.d.ts +2 -0
- package/dist/__tests__/huazhu-backend.test.d.ts.map +1 -0
- package/dist/__tests__/huazhu-backend.test.js +434 -0
- package/dist/__tests__/huazhu-backend.test.js.map +1 -0
- package/dist/__tests__/huazhu-cancel-policy.test.d.ts +2 -0
- package/dist/__tests__/huazhu-cancel-policy.test.d.ts.map +1 -0
- package/dist/__tests__/huazhu-cancel-policy.test.js +82 -0
- package/dist/__tests__/huazhu-cancel-policy.test.js.map +1 -0
- package/dist/__tests__/huazhu-sellable.test.d.ts +2 -0
- package/dist/__tests__/huazhu-sellable.test.d.ts.map +1 -0
- package/dist/__tests__/huazhu-sellable.test.js +192 -0
- package/dist/__tests__/huazhu-sellable.test.js.map +1 -0
- package/dist/__tests__/server.test.js +129 -4
- package/dist/__tests__/server.test.js.map +1 -1
- package/dist/__tests__/tool-descriptions.test.js +57 -4
- package/dist/__tests__/tool-descriptions.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +2 -0
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/backend.d.ts +27 -0
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +7 -0
- package/dist/backend.js.map +1 -1
- package/dist/card.generated.d.ts +1 -1
- package/dist/card.generated.js +2 -2
- package/dist/card.generated.js.map +1 -1
- package/dist/config.d.ts +52 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/facilities.d.ts.map +1 -1
- package/dist/facilities.js +7 -5
- package/dist/facilities.js.map +1 -1
- package/dist/huazhu/backend.d.ts +40 -0
- package/dist/huazhu/backend.d.ts.map +1 -0
- package/dist/huazhu/backend.js +1318 -0
- package/dist/huazhu/backend.js.map +1 -0
- package/dist/huazhu/bookings.d.ts +81 -0
- package/dist/huazhu/bookings.d.ts.map +1 -0
- package/dist/huazhu/bookings.js +189 -0
- package/dist/huazhu/bookings.js.map +1 -0
- package/dist/huazhu/cancel-policy.d.ts +69 -0
- package/dist/huazhu/cancel-policy.d.ts.map +1 -0
- package/dist/huazhu/cancel-policy.js +201 -0
- package/dist/huazhu/cancel-policy.js.map +1 -0
- package/dist/huazhu/catalog.d.ts +75 -0
- package/dist/huazhu/catalog.d.ts.map +1 -0
- package/dist/huazhu/catalog.js +251 -0
- package/dist/huazhu/catalog.js.map +1 -0
- package/dist/huazhu/check.d.ts +5 -0
- package/dist/huazhu/check.d.ts.map +1 -0
- package/dist/huazhu/check.js +170 -0
- package/dist/huazhu/check.js.map +1 -0
- package/dist/huazhu/client.d.ts +100 -0
- package/dist/huazhu/client.d.ts.map +1 -0
- package/dist/huazhu/client.js +232 -0
- package/dist/huazhu/client.js.map +1 -0
- package/dist/huazhu/sellable.d.ts +81 -0
- package/dist/huazhu/sellable.d.ts.map +1 -0
- package/dist/huazhu/sellable.js +219 -0
- package/dist/huazhu/sellable.js.map +1 -0
- package/dist/huazhu/wire.d.ts +389 -0
- package/dist/huazhu/wire.d.ts.map +1 -0
- package/dist/huazhu/wire.js +72 -0
- package/dist/huazhu/wire.js.map +1 -0
- package/dist/index.js +18 -4
- package/dist/index.js.map +1 -1
- package/dist/legal.d.ts +4 -3
- package/dist/legal.d.ts.map +1 -1
- package/dist/legal.js +33 -18
- package/dist/legal.js.map +1 -1
- package/dist/lib.d.ts +8 -3
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +8 -1
- package/dist/lib.js.map +1 -1
- package/dist/server.d.ts +20 -8
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +132 -28
- package/dist/server.js.map +1 -1
- package/dist/surface.d.ts +2 -1
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +37 -10
- package/dist/surface.js.map +1 -1
- package/dist/tools.d.ts +33 -20
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +130 -11
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +21 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ until someone names the nights.** Everything that can carry a price takes a
|
|
|
19
19
|
deliberately separate from the parts that can. A connector that guesses "this
|
|
20
20
|
weekend" books someone the wrong nights, and they find out at the front desk.
|
|
21
21
|
|
|
22
|
-
## The
|
|
22
|
+
## The tools
|
|
23
23
|
|
|
24
24
|
| | |
|
|
25
25
|
|---|---|
|
|
@@ -27,7 +27,7 @@ weekend" books someone the wrong nights, and they find out at the front desk.
|
|
|
27
27
|
| `get_<brand>_hotel` | One hotel; with `checkIn`/`checkOut`, its rooms priced for those nights |
|
|
28
28
|
| `list_<brand>_extras` | Transfers, dining, experiences, spa, family |
|
|
29
29
|
| `add_to_<brand>_trip` · `view_` · `clear_` | The trip: room nights plus add-ons, priced as one |
|
|
30
|
-
| `request_<brand>_booking` | Holds the rooms,
|
|
30
|
+
| `request_<brand>_booking` | Holds the rooms (demo) or books them, paid at the hotel (a group's own API); a confirmation code per stay |
|
|
31
31
|
| `list_my_<brand>_bookings` | |
|
|
32
32
|
| `preview_<brand>_cancellation` · `cancel_<brand>_booking` | The fee and its rule, before anything is cancelled |
|
|
33
33
|
| `get_<brand>_hotel_policies` | What the property itself publishes |
|
|
@@ -41,19 +41,36 @@ attestations require.
|
|
|
41
41
|
- **No dates, no line.** `add_to_*_trip` asks rather than guessing.
|
|
42
42
|
- **Preview, then cancel.** `cancel_*_booking` returns the fee and its rule and
|
|
43
43
|
cancels nothing until it is called again with `confirmed`.
|
|
44
|
-
- **Held is not paid.** A booking
|
|
45
|
-
the answer says so, and the card says so in as many words.
|
|
44
|
+
- **Held is not paid, and booked is not paid.** A booking takes no money and
|
|
45
|
+
collects no card; the answer says so, and the card says so in as many words.
|
|
46
46
|
|
|
47
47
|
## Where the rooms come from
|
|
48
48
|
|
|
49
|
-
Everything goes through one `HotelBackend` interface
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
Everything goes through one `HotelBackend` interface, and there are two:
|
|
50
|
+
|
|
51
|
+
- **`data.source: "demo"`** reads a JSON file and prices it (`DemoHotels`).
|
|
52
|
+
Every price-bearing answer carries `demo: true` and says so in words — an
|
|
53
|
+
invented rate presented as bookable is the one failure a booking connector
|
|
54
|
+
cannot have.
|
|
55
|
+
- **`data.source: "api"`, `data.api.provider: "huazhu"`** books for real
|
|
56
|
+
through Huazhu's distributor OpenAPI: the hotel list kept on disk and
|
|
57
|
+
current, prices, rules and rooms left asked for live, `prebook` before every
|
|
58
|
+
booking, one reservation per stay paid at the hotel, and a booking whose
|
|
59
|
+
answer was lost followed up by the consistency query for the eight minutes
|
|
60
|
+
Huazhu's rules require. Credentials come from the environment
|
|
61
|
+
(`HUAZHU_CLIENT_ID`, `HUAZHU_CLIENT_SECRET`, `HUAZHU_DISTRIBUTOR_ID`), never
|
|
62
|
+
the config.
|
|
63
|
+
|
|
64
|
+
A backend says what it cannot do through `capabilities` — Huazhu has no loyalty
|
|
65
|
+
sign-in, no add-ons and no in-place date change — and the tools, the server
|
|
66
|
+
instructions, the card and the legal pages leave those out rather than offering
|
|
67
|
+
something that always says no.
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
```bash
|
|
70
|
+
# The first call against a real environment, read-only - it never books:
|
|
71
|
+
HUAZHU_CLIENT_ID=… HUAZHU_CLIENT_SECRET=… HUAZHU_DISTRIBUTOR_ID=… \
|
|
72
|
+
npx curless-hotel-storefront --check ./config.json
|
|
73
|
+
```
|
|
57
74
|
|
|
58
75
|
## Payment
|
|
59
76
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { BookRequest, DailyOffer, HotelStatic, OrderStatus, Product } from '../../huazhu/wire.js';
|
|
2
|
+
export type FakeRate = {
|
|
3
|
+
product: Product;
|
|
4
|
+
/** Taxes in, per room-night, for up to `adults` adults. */
|
|
5
|
+
price: (date: string) => number;
|
|
6
|
+
before?: (date: string) => number;
|
|
7
|
+
adults?: number;
|
|
8
|
+
inventory?: (date: string) => number;
|
|
9
|
+
guarantee?: string;
|
|
10
|
+
cancel?: string;
|
|
11
|
+
meal?: {
|
|
12
|
+
type: string;
|
|
13
|
+
count: number;
|
|
14
|
+
};
|
|
15
|
+
restriction?: Partial<Record<keyof DailyOffer['restriction'], (date: string) => unknown>>;
|
|
16
|
+
};
|
|
17
|
+
/** A failure injected on `path`: after `skip` good calls, `times` times (default once). */
|
|
18
|
+
type Fail = {
|
|
19
|
+
path: string;
|
|
20
|
+
kind: 'unreachable' | 'http502' | 'answer-lost' | number;
|
|
21
|
+
times?: number;
|
|
22
|
+
skip?: number;
|
|
23
|
+
};
|
|
24
|
+
export type FakeBooking = {
|
|
25
|
+
resId: string;
|
|
26
|
+
distributorResId: string;
|
|
27
|
+
request: BookRequest;
|
|
28
|
+
status: OrderStatus;
|
|
29
|
+
cancelCode: string;
|
|
30
|
+
};
|
|
31
|
+
export declare const createFakeHuazhu: (opts: {
|
|
32
|
+
hotels: HotelStatic[];
|
|
33
|
+
rates: Record<string, FakeRate[]>;
|
|
34
|
+
now: () => number;
|
|
35
|
+
distributorId?: string;
|
|
36
|
+
clientId?: string;
|
|
37
|
+
secret?: string;
|
|
38
|
+
}) => {
|
|
39
|
+
fetch: typeof fetch;
|
|
40
|
+
calls: {
|
|
41
|
+
path: string;
|
|
42
|
+
body: unknown;
|
|
43
|
+
headers: Record<string, string>;
|
|
44
|
+
}[];
|
|
45
|
+
bookings: Map<string, FakeBooking>;
|
|
46
|
+
fail: (f: Fail) => number;
|
|
47
|
+
retireToken: () => void;
|
|
48
|
+
readonly tokens: number;
|
|
49
|
+
};
|
|
50
|
+
/** One domestic hotel shaped like the documentation's example. */
|
|
51
|
+
export declare const fakeHotel: (id: string, over?: Partial<HotelStatic>) => HotelStatic;
|
|
52
|
+
export declare const product: (roomTypeCode: string, rateCode: string, over?: Partial<Product>) => Product;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=huazhu-fake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huazhu-fake.d.ts","sourceRoot":"","sources":["../../../src/__tests__/__fixtures__/huazhu-fake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EAEX,OAAO,EACR,MAAM,sBAAsB,CAAC;AAW9B,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,2DAA2D;IAC3D,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC;CAC3F,CAAC;AAEF,2FAA2F;AAC3F,KAAK,IAAI,GAAG;IACV,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM;IACrC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;WA6SW,OAAO,KAAK;;cAtSD,MAAM;cAAQ,OAAO;iBAAW,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;cAyS/D,IAAI;;;CAQjB,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,EAAE,OAAM,OAAO,CAAC,WAAW,CAAM,KAAG,WAwDtE,CAAC;AAEH,eAAO,MAAM,OAAO,GAClB,cAAc,MAAM,EACpB,UAAU,MAAM,EAChB,OAAM,OAAO,CAAC,OAAO,CAAM,KAC1B,OAQD,CAAC"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { addDays, nights } from '../../dates.js';
|
|
2
|
+
export const createFakeHuazhu = (opts) => {
|
|
3
|
+
const distributorId = opts.distributorId ?? 'CURLESS';
|
|
4
|
+
const basic = Buffer.from(`${opts.clientId ?? 'cid'}:${opts.secret ?? 'sec'}`).toString('base64');
|
|
5
|
+
let token = '';
|
|
6
|
+
let tokens = 0;
|
|
7
|
+
const fails = [];
|
|
8
|
+
const bookings = new Map();
|
|
9
|
+
const calls = [];
|
|
10
|
+
const held = new Map();
|
|
11
|
+
let resSeq = 1000;
|
|
12
|
+
const envelope = (code, content, message = code === 1000 ? 'Success' : 'Error', responseDes = '') => new Response(JSON.stringify({ code, ...(content !== undefined ? { content } : {}), message, responseDes }), {
|
|
13
|
+
status: 200,
|
|
14
|
+
headers: { 'content-type': 'application/json' },
|
|
15
|
+
});
|
|
16
|
+
const today = () => new Date(opts.now() + 8 * 3_600_000).toISOString().slice(0, 10);
|
|
17
|
+
const dates = (start, end) => {
|
|
18
|
+
const out = [];
|
|
19
|
+
for (let d = start; d <= end; d = addDays(d, 1))
|
|
20
|
+
out.push(d);
|
|
21
|
+
return out;
|
|
22
|
+
};
|
|
23
|
+
const key = (hotelId, p) => `${hotelId}|${p.roomTypeCode}|${p.rateCode}`;
|
|
24
|
+
const left = (hotelId, r, d) => Math.max(0, (r.inventory?.(d) ?? 5) - (held.get(`${key(hotelId, r.product)}|${d}`) ?? 0));
|
|
25
|
+
const offerOf = (hotelId, r, days) => {
|
|
26
|
+
const restriction = {
|
|
27
|
+
close: days.map((d) => r.restriction?.close?.(d) ?? false),
|
|
28
|
+
minStayArrival: days.map((d) => r.restriction?.minStayArrival?.(d) ?? null),
|
|
29
|
+
maxStayArrival: days.map((d) => r.restriction?.maxStayArrival?.(d) ?? 999),
|
|
30
|
+
minStayThrough: days.map((d) => r.restriction?.minStayThrough?.(d) ?? 0),
|
|
31
|
+
maxStayThrough: days.map((d) => r.restriction?.maxStayThrough?.(d) ?? 0),
|
|
32
|
+
minAdvanceDay: days.map((d) => r.restriction?.minAdvanceDay?.(d) ?? null),
|
|
33
|
+
maxAdvanceDay: days.map((d) => r.restriction?.maxAdvanceDay?.(d) ?? 999),
|
|
34
|
+
cta: days.map((d) => r.restriction?.cta?.(d) ?? false),
|
|
35
|
+
ctd: days.map((d) => r.restriction?.ctd?.(d) ?? false),
|
|
36
|
+
fplos: days.map((d) => r.restriction?.fplos?.(d) ?? null),
|
|
37
|
+
};
|
|
38
|
+
void hotelId;
|
|
39
|
+
return {
|
|
40
|
+
roomTypeCode: r.product.roomTypeCode,
|
|
41
|
+
rateCode: r.product.rateCode,
|
|
42
|
+
currencyCode: 'CNY',
|
|
43
|
+
rates: [
|
|
44
|
+
{
|
|
45
|
+
maxAdultCount: r.adults ?? 2,
|
|
46
|
+
amountAfterTax: days.map((d) => r.price(d)),
|
|
47
|
+
...(r.before ? { amountBeforeTax: days.map((d) => r.before?.(d) ?? 0) } : {}),
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
mealPlanType: r.meal?.type ?? 'RO',
|
|
51
|
+
mealPlanCounts: days.map(() => r.meal?.count ?? 0),
|
|
52
|
+
restriction,
|
|
53
|
+
guaranteePolicies: days.map(() => ({ code: r.guarantee ?? 'PL' })),
|
|
54
|
+
cancelPolicies: days.map(() => ({ code: r.cancel ?? '6PM1D1N_100P' })),
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const handle = async (url, init) => {
|
|
58
|
+
const path = url.pathname;
|
|
59
|
+
const headers = Object.fromEntries(new Headers(init.headers).entries());
|
|
60
|
+
const body = init.body ? JSON.parse(String(init.body)) : undefined;
|
|
61
|
+
calls.push({ path, body, headers });
|
|
62
|
+
const f = fails.find((x) => x.path === path);
|
|
63
|
+
let passedOver = false;
|
|
64
|
+
if (f && (f.skip ?? 0) > 0) {
|
|
65
|
+
f.skip = (f.skip ?? 0) - 1;
|
|
66
|
+
passedOver = true;
|
|
67
|
+
}
|
|
68
|
+
else if (f && f.kind !== 'answer-lost') {
|
|
69
|
+
f.times = (f.times ?? 1) - 1;
|
|
70
|
+
if (f.times <= 0)
|
|
71
|
+
fails.splice(fails.indexOf(f), 1);
|
|
72
|
+
if (f.kind === 'unreachable')
|
|
73
|
+
throw new TypeError('fetch failed: ECONNRESET');
|
|
74
|
+
if (f.kind === 'http502')
|
|
75
|
+
return new Response('bad gateway', { status: 502 });
|
|
76
|
+
return envelope(f.kind, undefined, 'Injected', 'injected by the test');
|
|
77
|
+
}
|
|
78
|
+
if (path === '/oauth/token') {
|
|
79
|
+
if (headers.authorization !== `Basic ${basic}`)
|
|
80
|
+
return new Response('{"error":"invalid_client"}', { status: 401 });
|
|
81
|
+
tokens += 1;
|
|
82
|
+
token = `tok-${tokens}`;
|
|
83
|
+
return new Response(JSON.stringify({
|
|
84
|
+
access_token: token,
|
|
85
|
+
token_type: 'Bearer',
|
|
86
|
+
expires_in: 3600,
|
|
87
|
+
scope: 'ALL',
|
|
88
|
+
}), { status: 200 });
|
|
89
|
+
}
|
|
90
|
+
// Every business call: the four headers, and the current token.
|
|
91
|
+
if (headers.distributorid !== distributorId)
|
|
92
|
+
return envelope(2003, undefined, 'Invalid distributor ID');
|
|
93
|
+
if (!headers.timestamp || !headers.traceid)
|
|
94
|
+
return envelope(2004, undefined, 'Required field missing', 'timestamp/traceId');
|
|
95
|
+
if (headers.authorization !== `Bearer ${token}`)
|
|
96
|
+
return envelope(2002, undefined, 'Invalid token');
|
|
97
|
+
const hotel = (id) => opts.hotels.find((h) => h.hotelId === id);
|
|
98
|
+
switch (path) {
|
|
99
|
+
case '/hotels':
|
|
100
|
+
return envelope(1000, opts.hotels.map((h) => ({ hotelId: h.hotelId, hotelName: h.hotelName })));
|
|
101
|
+
case '/hotel': {
|
|
102
|
+
const h = hotel(body.hotelId);
|
|
103
|
+
return h ? envelope(1000, h) : envelope(3201, undefined, 'Invalid hotel Id');
|
|
104
|
+
}
|
|
105
|
+
case '/ari/products': {
|
|
106
|
+
if (!hotel(body.hotelId))
|
|
107
|
+
return envelope(4101, undefined, 'Invalid hotel Id');
|
|
108
|
+
return envelope(1000, {
|
|
109
|
+
hotelId: body.hotelId,
|
|
110
|
+
sellDays: 90,
|
|
111
|
+
products: (opts.rates[body.hotelId] ?? []).map((r) => r.product),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
case '/ari/daily/offers':
|
|
115
|
+
case '/ari/daily/inventory': {
|
|
116
|
+
if (!hotel(body.hotelId))
|
|
117
|
+
return envelope(path.endsWith('offers') ? 4201 : 4304, undefined, 'Invalid hotel Id');
|
|
118
|
+
if (!body.checkinType)
|
|
119
|
+
return envelope(2004, undefined, 'Required field missing', 'checkinType');
|
|
120
|
+
if (nights(body.startDate, body.endDate) > 29 || body.endDate < body.startDate)
|
|
121
|
+
return envelope(path.endsWith('offers') ? 4203 : 4301, undefined, 'Start date and end date does not match the rules');
|
|
122
|
+
if (body.startDate < addDays(today(), -1))
|
|
123
|
+
return envelope(path.endsWith('offers') ? 4205 : 4303, undefined, 'Start date is invalid');
|
|
124
|
+
const days = dates(body.startDate, body.endDate);
|
|
125
|
+
const rates = opts.rates[body.hotelId] ?? [];
|
|
126
|
+
if (path.endsWith('offers')) {
|
|
127
|
+
return envelope(1000, {
|
|
128
|
+
hotelId: body.hotelId,
|
|
129
|
+
startDate: body.startDate,
|
|
130
|
+
endDate: body.endDate,
|
|
131
|
+
dailyOffers: rates.map((r) => offerOf(body.hotelId, r, days)),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return envelope(1000, {
|
|
135
|
+
hotelId: body.hotelId,
|
|
136
|
+
startDate: body.startDate,
|
|
137
|
+
endDate: body.endDate,
|
|
138
|
+
dailyInventories: rates.map((r) => ({
|
|
139
|
+
roomTypeCode: r.product.roomTypeCode,
|
|
140
|
+
rateCode: r.product.rateCode,
|
|
141
|
+
inventories: days.map((d) => left(body.hotelId, r, d)),
|
|
142
|
+
})),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
case '/reservation/prebook':
|
|
146
|
+
case '/reservation/book': {
|
|
147
|
+
const req = body;
|
|
148
|
+
const booking = path.endsWith('book') && !path.endsWith('prebook');
|
|
149
|
+
if (booking) {
|
|
150
|
+
if (!req.distributorResId)
|
|
151
|
+
return envelope(2004, undefined, 'Required field missing', 'distributorResId');
|
|
152
|
+
const had = [...bookings.values()].find((b) => b.distributorResId === req.distributorResId);
|
|
153
|
+
if (had)
|
|
154
|
+
return envelope(5218, undefined, 'DistributorResId already exist');
|
|
155
|
+
if (!req.contactPerson?.lastName || req.contactPerson.lastName.length > 16)
|
|
156
|
+
return envelope(2005, undefined, 'Invalid field', 'contactPerson.lastName');
|
|
157
|
+
}
|
|
158
|
+
const line = req.reservations?.[0];
|
|
159
|
+
if (!line)
|
|
160
|
+
return envelope(2004, undefined, 'Required field missing', 'reservations');
|
|
161
|
+
const r = (opts.rates[req.hotelId] ?? []).find((x) => x.product.roomTypeCode === line.roomTypeCode && x.product.rateCode === line.rateCode);
|
|
162
|
+
if (!r)
|
|
163
|
+
return envelope(booking ? 5236 : 5123, undefined, 'No match found');
|
|
164
|
+
const nightsOf = dates(line.checkin, addDays(line.checkout, -1));
|
|
165
|
+
const want = nightsOf.map((d) => r.price(d));
|
|
166
|
+
const priceOk = want.length === line.amountAfterTax.length &&
|
|
167
|
+
want.every((x, i) => x === line.amountAfterTax[i]);
|
|
168
|
+
const ari = {
|
|
169
|
+
checkin: line.checkin,
|
|
170
|
+
checkout: line.checkout,
|
|
171
|
+
...offerOf(req.hotelId, r, nightsOf),
|
|
172
|
+
inventories: nightsOf.map((d) => left(req.hotelId, r, d)),
|
|
173
|
+
};
|
|
174
|
+
if (!priceOk)
|
|
175
|
+
return envelope(booking ? 5209 : 5108, { hotelId: req.hotelId, reservationsAri: [ari] }, 'Price incorrect for room');
|
|
176
|
+
if (nightsOf.some((d) => left(req.hotelId, r, d) < line.roomCount))
|
|
177
|
+
return envelope(booking ? 5210 : 5109, { hotelId: req.hotelId, reservationsAri: [ari] }, 'No rooms available for requested dates');
|
|
178
|
+
const guarantee = r.guarantee ?? 'PL';
|
|
179
|
+
const allowed = {
|
|
180
|
+
PL: ['NGPL', 'OGPL', 'CCPL'],
|
|
181
|
+
GTX: ['OGPL', 'OPN', 'CCPL', 'CPN'],
|
|
182
|
+
PN: ['OPN', 'CCPN', 'CPN'],
|
|
183
|
+
};
|
|
184
|
+
if (!(allowed[guarantee] ?? []).includes(req.paymentType))
|
|
185
|
+
return envelope(booking ? 5211 : 5114, undefined, 'Payment type invalid');
|
|
186
|
+
if (!booking)
|
|
187
|
+
return envelope(1000, {
|
|
188
|
+
hotelId: req.hotelId,
|
|
189
|
+
preBookToken: `PB${calls.length}`,
|
|
190
|
+
reservationsAri: [ari],
|
|
191
|
+
});
|
|
192
|
+
resSeq += 1;
|
|
193
|
+
const resId = `R${req.hotelId}${resSeq}`;
|
|
194
|
+
for (const d of nightsOf) {
|
|
195
|
+
const k = `${key(req.hotelId, r.product)}|${d}`;
|
|
196
|
+
held.set(k, (held.get(k) ?? 0) + line.roomCount);
|
|
197
|
+
}
|
|
198
|
+
bookings.set(resId, {
|
|
199
|
+
resId,
|
|
200
|
+
distributorResId: req.distributorResId,
|
|
201
|
+
request: req,
|
|
202
|
+
status: 'HOTEL_RESERVATION',
|
|
203
|
+
cancelCode: r.cancel ?? '6PM1D1N_100P',
|
|
204
|
+
});
|
|
205
|
+
const lost = passedOver
|
|
206
|
+
? undefined
|
|
207
|
+
: fails.find((x) => x.path === path && x.kind === 'answer-lost');
|
|
208
|
+
if (lost) {
|
|
209
|
+
fails.splice(fails.indexOf(lost), 1);
|
|
210
|
+
throw new TypeError('fetch failed: read timeout');
|
|
211
|
+
}
|
|
212
|
+
return envelope(1000, { resId, resCode: `RC${resSeq}` });
|
|
213
|
+
}
|
|
214
|
+
case '/reservation/detail': {
|
|
215
|
+
const b = bookings.get(body.resId);
|
|
216
|
+
if (!b)
|
|
217
|
+
return envelope(5302, undefined, 'Reservation not found');
|
|
218
|
+
const line = b.request.reservations[0];
|
|
219
|
+
return envelope(1000, {
|
|
220
|
+
hotelId: b.request.hotelId,
|
|
221
|
+
checkInType: 'DAY',
|
|
222
|
+
paymentType: b.request.paymentType,
|
|
223
|
+
distributorResId: b.distributorResId,
|
|
224
|
+
resId: b.resId,
|
|
225
|
+
status: b.status,
|
|
226
|
+
bookingTime: opts.now(),
|
|
227
|
+
reservations: [
|
|
228
|
+
{
|
|
229
|
+
...line,
|
|
230
|
+
cancelPolicyCode: b.cancelCode,
|
|
231
|
+
estimatedArrivalTime: line.estimatedArrivalTime ?? '12:00',
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
case '/reservation/cancel': {
|
|
237
|
+
const b = bookings.get(body.resId);
|
|
238
|
+
if (!b)
|
|
239
|
+
return envelope(5403, undefined, 'Reservation not found');
|
|
240
|
+
if (b.status === 'HOTEL_CANCEL')
|
|
241
|
+
return envelope(5402, undefined, 'Reservation already cancelled');
|
|
242
|
+
b.status = 'HOTEL_CANCEL';
|
|
243
|
+
const line = b.request.reservations[0];
|
|
244
|
+
for (const d of dates(line.checkin, addDays(line.checkout, -1))) {
|
|
245
|
+
const k = `${b.request.hotelId}|${line.roomTypeCode}|${line.rateCode}|${d}`;
|
|
246
|
+
held.set(k, Math.max(0, (held.get(k) ?? 0) - line.roomCount));
|
|
247
|
+
}
|
|
248
|
+
return envelope(1000, { penaltyAmount: 0, penaltyCurrencyCode: 'CNY' });
|
|
249
|
+
}
|
|
250
|
+
case '/reservation/consistency/query': {
|
|
251
|
+
const b = [...bookings.values()].find((x) => x.distributorResId === body.distributorResId);
|
|
252
|
+
return b
|
|
253
|
+
? envelope(1000, { resId: b.resId, status: b.status })
|
|
254
|
+
: envelope(5602, undefined, 'Reservation not found');
|
|
255
|
+
}
|
|
256
|
+
default:
|
|
257
|
+
return new Response('not found', { status: 404 });
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
return {
|
|
261
|
+
fetch: (async (input, init) => handle(new URL(typeof input === 'string' ? input : input instanceof URL ? input.href : input.url), init ?? {})),
|
|
262
|
+
calls,
|
|
263
|
+
bookings,
|
|
264
|
+
fail: (f) => fails.push(f),
|
|
265
|
+
retireToken: () => {
|
|
266
|
+
token = `retired-${token}`;
|
|
267
|
+
},
|
|
268
|
+
get tokens() {
|
|
269
|
+
return tokens;
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
/** One domestic hotel shaped like the documentation's example. */
|
|
274
|
+
export const fakeHotel = (id, over = {}) => ({
|
|
275
|
+
hotelId: id,
|
|
276
|
+
hotelName: `汉庭酒店(上海人民广场${id}店)`,
|
|
277
|
+
hotelNameEn: `Hanting Hotel Shanghai People's Square ${id}`,
|
|
278
|
+
brandCode: 2,
|
|
279
|
+
brandName: '汉庭',
|
|
280
|
+
provinceNo: '310000',
|
|
281
|
+
provinceName: '上海市',
|
|
282
|
+
cityNo: '310100',
|
|
283
|
+
cityName: '上海市',
|
|
284
|
+
countyNo: '310101',
|
|
285
|
+
countyName: '黄浦区',
|
|
286
|
+
hotelAddress: '上海市黄浦区延安东路1号',
|
|
287
|
+
hotelAddressEn: "1 Yan'an East Road, Huangpu District, Shanghai",
|
|
288
|
+
telephone: '63200000',
|
|
289
|
+
hotelWordIntroduce: '近人民广场地铁站,步行可达南京路步行街。',
|
|
290
|
+
international: false,
|
|
291
|
+
tradeCurrency: 'CNY',
|
|
292
|
+
hotelRoomTypeList: [
|
|
293
|
+
{
|
|
294
|
+
roomTypeCode: 'DR1',
|
|
295
|
+
roomTypeName: '高级大床房',
|
|
296
|
+
hotelArea: 20,
|
|
297
|
+
isHasWindow: '1',
|
|
298
|
+
maxOccupancy: 999,
|
|
299
|
+
status: 1,
|
|
300
|
+
bedTypeList: [{ bedTypeCode: 'A', bedSpecNo: '-1', bedTypeName: '大床', bedSpec: '1.8m' }],
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
roomTypeCode: 'TR1',
|
|
304
|
+
roomTypeName: '高级双床房',
|
|
305
|
+
hotelArea: 22,
|
|
306
|
+
isHasWindow: '3',
|
|
307
|
+
maxOccupancy: 2,
|
|
308
|
+
status: 1,
|
|
309
|
+
bedTypeList: [{ bedTypeCode: 'B', bedSpecNo: '-1', bedTypeName: '双床', bedSpec: '1.2m' }],
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
hotelServiceList: [
|
|
313
|
+
{ childClassCode: 71, childClassName: '健身房' },
|
|
314
|
+
{ childClassCode: 49, childClassName: '中餐厅' },
|
|
315
|
+
],
|
|
316
|
+
hotelPhotoList: [
|
|
317
|
+
{ typeCode: 'ImagePhoto', fileUrl: 'http://ws-p.example.com/f/a.jpg', sortId: 20, status: 1 },
|
|
318
|
+
{
|
|
319
|
+
typeCode: 'RoomType',
|
|
320
|
+
typeMappingCode: 'DR1',
|
|
321
|
+
fileUrl: 'http://ws-p.example.com/f/dr1.jpg',
|
|
322
|
+
sortId: 10,
|
|
323
|
+
status: 1,
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
hotelTrafficList: [
|
|
327
|
+
{ destinationType: '9', destinationName: '人民广场', destinationDistance: '300m' },
|
|
328
|
+
],
|
|
329
|
+
...over,
|
|
330
|
+
});
|
|
331
|
+
export const product = (roomTypeCode, rateCode, over = {}) => ({
|
|
332
|
+
roomTypeCode,
|
|
333
|
+
roomTypeName: roomTypeCode === 'DR1' ? '高级大床房' : '高级双床房',
|
|
334
|
+
rateCode,
|
|
335
|
+
rateCodeName: rateCode,
|
|
336
|
+
checkinType: 'DAY',
|
|
337
|
+
promotion: false,
|
|
338
|
+
...over,
|
|
339
|
+
});
|
|
340
|
+
//# sourceMappingURL=huazhu-fake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huazhu-fake.js","sourceRoot":"","sources":["../../../src/__tests__/__fixtures__/huazhu-fake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huazhu-backend.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/huazhu-backend.test.ts"],"names":[],"mappings":""}
|