@agenzo/merchant-cli 0.9.3 → 0.9.5
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 +343 -343
- package/dist/index.js +514 -112
- package/dist/index.js.map +1 -1
- package/package.json +28 -28
package/dist/index.js
CHANGED
|
@@ -62,6 +62,7 @@ var CODE_NUM = {
|
|
|
62
62
|
BOOKING_RESTRICTED: 4310,
|
|
63
63
|
PAYORDER_FAILED: 4311,
|
|
64
64
|
PAYORDER_FAILED_AFTER_PAYMENT: 4312,
|
|
65
|
+
OFFER_UNAVAILABLE: 4401,
|
|
65
66
|
RATE_LIMITED: 5001,
|
|
66
67
|
UPSTREAM_ERROR: 5101,
|
|
67
68
|
INTERNAL_ERROR: 5201,
|
|
@@ -249,6 +250,7 @@ var STABLE_MESSAGE = {
|
|
|
249
250
|
BOOKING_RESTRICTED: "This room has a booking condition that your request doesn't meet. Please check the room's booking rules and adjust your request.",
|
|
250
251
|
PAYORDER_FAILED: "The hotel order was created, but payment failed. Retry payment for the existing order.",
|
|
251
252
|
PAYORDER_FAILED_AFTER_PAYMENT: "Payment was received, but hotel confirmation failed. Contact support for reconciliation.",
|
|
253
|
+
OFFER_UNAVAILABLE: "The selected flight is no longer available. Please search again and pick another flight.",
|
|
252
254
|
NOT_IMPLEMENTED: "This operation is not implemented yet."
|
|
253
255
|
};
|
|
254
256
|
function errorDetailLines(envelope) {
|
|
@@ -848,6 +850,12 @@ function render(result, opts) {
|
|
|
848
850
|
process.stdout.write(`${result.text()}
|
|
849
851
|
`);
|
|
850
852
|
}
|
|
853
|
+
function notify(format, type, message) {
|
|
854
|
+
if (format === "json") {
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
console.error(Formatter.status(type, message));
|
|
858
|
+
}
|
|
851
859
|
async function renderWithContext(result, opts, configManager) {
|
|
852
860
|
if (opts.format !== "json") {
|
|
853
861
|
render(result, opts);
|
|
@@ -1432,6 +1440,123 @@ var rideTripStatusSchema = {
|
|
|
1432
1440
|
BOOKING_FAILED: "Transient upstream error. Retry once after 5s, or fall back to `ride-elife get` for whole-ride status."
|
|
1433
1441
|
}
|
|
1434
1442
|
};
|
|
1443
|
+
var RIDE_ORDER_ID_FLAG = {
|
|
1444
|
+
type: "string",
|
|
1445
|
+
required: true,
|
|
1446
|
+
description: "The numeric ride_id returned by book (NOT the rio_... order_id)"
|
|
1447
|
+
};
|
|
1448
|
+
var CALLBACK_IDEMPOTENCY_FLAG = {
|
|
1449
|
+
type: "string",
|
|
1450
|
+
required: true,
|
|
1451
|
+
description: "Unique key (1-128 chars [A-Za-z0-9_-]) forwarded verbatim as the Idempotency-Key header; never auto-generated"
|
|
1452
|
+
};
|
|
1453
|
+
var CALLBACK_SUBSCRIPTION_FLAGS = {
|
|
1454
|
+
"callback-url": { type: "string", required: true, description: "https URL that receives status events; internal addresses are rejected by the platform" },
|
|
1455
|
+
adapter: { type: "string", required: false, default: "techtanium_v1", description: "Outbound event shape" },
|
|
1456
|
+
"signature-mode": { type: "string", required: false, default: "off", description: "off / optional / required" },
|
|
1457
|
+
"callback-api-key": { type: "string", required: false, description: "API key sent to your endpoint; omit to keep the stored one (never echoed back)" },
|
|
1458
|
+
"rotate-secret": { type: "bool", required: false, default: false, description: "Issue a new signing secret; the old one stops verifying" },
|
|
1459
|
+
"idempotency-key": CALLBACK_IDEMPOTENCY_FLAG
|
|
1460
|
+
};
|
|
1461
|
+
var CALLBACK_SUBSCRIPTION_RESPONSE = {
|
|
1462
|
+
callback_url: { type: "string", description: "Registered destination" },
|
|
1463
|
+
adapter: { type: "string", description: "Outbound event shape" },
|
|
1464
|
+
signature_mode: { type: "string", description: "off / optional / required" },
|
|
1465
|
+
status: { type: "string", description: "Registration status" },
|
|
1466
|
+
callback_secret: { type: "string", description: "Signing secret \u2014 present ONLY in the set response that issued it; store it, it cannot be read back" }
|
|
1467
|
+
};
|
|
1468
|
+
var CALLBACK_ERRORS = {
|
|
1469
|
+
RIDE_NOT_FOUND: "The ride is not yours or does not exist; check the ride_id from book/list-orders.",
|
|
1470
|
+
PARAM_INVALID: "Fix the flag named in the message (https URL, signature-mode, ranges) and retry.",
|
|
1471
|
+
PARAM_IDEMPOTENCY_KEY_REQUIRED: "Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes."
|
|
1472
|
+
};
|
|
1473
|
+
var rideCallbackSetSchema = {
|
|
1474
|
+
cli: CLI_NAME,
|
|
1475
|
+
noun: NOUN,
|
|
1476
|
+
verb: "callback-set",
|
|
1477
|
+
description: "Register (or update) where one ride's status events are forwarded; takes priority over the default",
|
|
1478
|
+
flags: { "order-id": RIDE_ORDER_ID_FLAG, ...CALLBACK_SUBSCRIPTION_FLAGS },
|
|
1479
|
+
response: { ride_id: { type: "string|int", description: "Ride id" }, order_id: { type: "string", description: "rio_... order id" }, ...CALLBACK_SUBSCRIPTION_RESPONSE },
|
|
1480
|
+
example: {
|
|
1481
|
+
command: "agenzo-merchant-cli ride-elife callback-set --order-id 4112961 --callback-url https://example.com/ride-events --idempotency-key cb-1",
|
|
1482
|
+
output_summary: "Returns the registration; the first registration also returns callback_secret once."
|
|
1483
|
+
},
|
|
1484
|
+
error_recovery: CALLBACK_ERRORS
|
|
1485
|
+
};
|
|
1486
|
+
var rideCallbackGetSchema = {
|
|
1487
|
+
cli: CLI_NAME,
|
|
1488
|
+
noun: NOUN,
|
|
1489
|
+
verb: "callback-get",
|
|
1490
|
+
description: "Show one ride's callback registration (the signing secret is never returned)",
|
|
1491
|
+
flags: { "order-id": RIDE_ORDER_ID_FLAG },
|
|
1492
|
+
response: { ride_id: { type: "string|int", description: "Ride id" }, order_id: { type: "string", description: "rio_... order id" }, ...CALLBACK_SUBSCRIPTION_RESPONSE },
|
|
1493
|
+
example: { command: "agenzo-merchant-cli ride-elife callback-get --order-id 4112961", output_summary: "Returns the registration without the secret." },
|
|
1494
|
+
error_recovery: { RIDE_NOT_FOUND: CALLBACK_ERRORS.RIDE_NOT_FOUND }
|
|
1495
|
+
};
|
|
1496
|
+
var rideCallbackDefaultSetSchema = {
|
|
1497
|
+
cli: CLI_NAME,
|
|
1498
|
+
noun: NOUN,
|
|
1499
|
+
verb: "callback-default-set",
|
|
1500
|
+
description: "Register (or update) the developer-wide fallback used by rides that have no callback of their own",
|
|
1501
|
+
flags: CALLBACK_SUBSCRIPTION_FLAGS,
|
|
1502
|
+
response: { developer_id: { type: "string", description: "Owner of the default" }, ...CALLBACK_SUBSCRIPTION_RESPONSE },
|
|
1503
|
+
example: {
|
|
1504
|
+
command: "agenzo-merchant-cli ride-elife callback-default-set --callback-url https://example.com/ride-events --idempotency-key cbd-1",
|
|
1505
|
+
output_summary: "Configure once so events for rides booked later are never dropped."
|
|
1506
|
+
},
|
|
1507
|
+
error_recovery: { PARAM_INVALID: CALLBACK_ERRORS.PARAM_INVALID, PARAM_IDEMPOTENCY_KEY_REQUIRED: CALLBACK_ERRORS.PARAM_IDEMPOTENCY_KEY_REQUIRED }
|
|
1508
|
+
};
|
|
1509
|
+
var rideCallbackDefaultGetSchema = {
|
|
1510
|
+
cli: CLI_NAME,
|
|
1511
|
+
noun: NOUN,
|
|
1512
|
+
verb: "callback-default-get",
|
|
1513
|
+
description: "Show the developer-wide fallback callback (the signing secret is never returned)",
|
|
1514
|
+
flags: {},
|
|
1515
|
+
response: { developer_id: { type: "string", description: "Owner of the default" }, ...CALLBACK_SUBSCRIPTION_RESPONSE },
|
|
1516
|
+
example: { command: "agenzo-merchant-cli ride-elife callback-default-get", output_summary: "Returns the default without the secret." }
|
|
1517
|
+
};
|
|
1518
|
+
var rideCallbackDeliveriesSchema = {
|
|
1519
|
+
cli: CLI_NAME,
|
|
1520
|
+
noun: NOUN,
|
|
1521
|
+
verb: "callback-deliveries",
|
|
1522
|
+
description: "List one ride's callback forwarding records (pending / delivered / dead)",
|
|
1523
|
+
flags: {
|
|
1524
|
+
"order-id": RIDE_ORDER_ID_FLAG,
|
|
1525
|
+
limit: { type: "int", required: false, default: 50, description: "Page size 1-100" },
|
|
1526
|
+
offset: { type: "int", required: false, default: 0, description: "Records to skip" }
|
|
1527
|
+
},
|
|
1528
|
+
response: {
|
|
1529
|
+
ride_id: { type: "string|int", description: "Ride id" },
|
|
1530
|
+
limit: { type: "int", description: "Page size used" },
|
|
1531
|
+
offset: { type: "int", description: "Offset used" },
|
|
1532
|
+
count: { type: "int", description: "Records in this page" },
|
|
1533
|
+
deliveries: { type: "array", description: "Forwarding records: event_id, status, attempts, last_error, timestamps" }
|
|
1534
|
+
},
|
|
1535
|
+
example: { command: "agenzo-merchant-cli ride-elife callback-deliveries --order-id 4112961", output_summary: "Shows what was forwarded and where it stalled." },
|
|
1536
|
+
error_recovery: { RIDE_NOT_FOUND: CALLBACK_ERRORS.RIDE_NOT_FOUND, PARAM_INVALID: CALLBACK_ERRORS.PARAM_INVALID }
|
|
1537
|
+
};
|
|
1538
|
+
var rideCallbackReplaySchema = {
|
|
1539
|
+
cli: CLI_NAME,
|
|
1540
|
+
noun: NOUN,
|
|
1541
|
+
verb: "callback-replay",
|
|
1542
|
+
description: "Requeue one ride's dead (or failed) callback records; delivered records are never re-sent",
|
|
1543
|
+
flags: {
|
|
1544
|
+
"order-id": RIDE_ORDER_ID_FLAG,
|
|
1545
|
+
"event-id": { type: "string", required: false, description: "Requeue only this record (default: all dead records)" },
|
|
1546
|
+
"include-failed": { type: "bool", required: false, default: false, description: "Also requeue pending records that already failed" },
|
|
1547
|
+
"reset-attempts": { type: "bool", required: false, default: false, description: "Reset the retry counter of requeued records" },
|
|
1548
|
+
"idempotency-key": CALLBACK_IDEMPOTENCY_FLAG
|
|
1549
|
+
},
|
|
1550
|
+
response: {
|
|
1551
|
+
ride_id: { type: "string", description: "Ride id" },
|
|
1552
|
+
requeued: { type: "int", description: "Number of records set back to pending" }
|
|
1553
|
+
},
|
|
1554
|
+
example: {
|
|
1555
|
+
command: "agenzo-merchant-cli ride-elife callback-replay --order-id 4112961 --idempotency-key rp-1",
|
|
1556
|
+
output_summary: "Requeues dead records; the delivery worker re-sends them on its next pass."
|
|
1557
|
+
},
|
|
1558
|
+
error_recovery: CALLBACK_ERRORS
|
|
1559
|
+
};
|
|
1435
1560
|
var listOrdersSchema = {
|
|
1436
1561
|
cli: CLI_NAME,
|
|
1437
1562
|
noun: NOUN,
|
|
@@ -2380,6 +2505,39 @@ var ordersPayBatchSchema = {
|
|
|
2380
2505
|
AUTHENTICATION_REQUIRED: "EVO requires cardholder 3DS: open three_ds_url, finish authentication, then replay pay-batch with the SAME idempotency-key (or use --watch to poll automatically)."
|
|
2381
2506
|
}
|
|
2382
2507
|
};
|
|
2508
|
+
var ordersGetPaymentGroupSchema = {
|
|
2509
|
+
cli: CLI_NAME,
|
|
2510
|
+
noun: ORDERS_NOUN,
|
|
2511
|
+
verb: "get-payment-group",
|
|
2512
|
+
description: "Get the status of an aggregate settlement created by `orders pay-batch` (read-only; never re-sends the payment)",
|
|
2513
|
+
flags: {
|
|
2514
|
+
"payment-group-id": { type: "string", required: true, description: "payment_group_id returned by `orders pay-batch` (1-64 chars)" }
|
|
2515
|
+
},
|
|
2516
|
+
response: {
|
|
2517
|
+
payment_group_id: { type: "string", description: "The payment group" },
|
|
2518
|
+
status: { type: "string", description: "settled | partially_settled | failed | uncertain" },
|
|
2519
|
+
currency: { type: "string", description: "ISO 4217 currency of the aggregate settlement" },
|
|
2520
|
+
total_amount: { type: "float", description: "Aggregate total in DECIMAL units" },
|
|
2521
|
+
per_order: {
|
|
2522
|
+
type: "array",
|
|
2523
|
+
description: "Per-order outcome, same shape as pay-batch",
|
|
2524
|
+
items: {
|
|
2525
|
+
order_id: { type: "string", description: "Order id" },
|
|
2526
|
+
domain: { type: "string", description: "hotel | flight | ride" },
|
|
2527
|
+
status: { type: "string", description: "confirmed | refunded | failed" },
|
|
2528
|
+
amount: { type: "float", description: "Authoritative order amount (decimal)" },
|
|
2529
|
+
refunded_amount: { type: "float", description: "Amount refunded when upstream confirmation failed" }
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
},
|
|
2533
|
+
example: {
|
|
2534
|
+
command: "agenzo-merchant-cli orders get-payment-group --payment-group-id pg_...",
|
|
2535
|
+
output_summary: "Returns the batch status and per-order results; use it instead of replaying pay-batch to check progress."
|
|
2536
|
+
},
|
|
2537
|
+
error_recovery: {
|
|
2538
|
+
PARAM_INVALID: "Pass the payment_group_id exactly as pay-batch returned it (1-64 chars)."
|
|
2539
|
+
}
|
|
2540
|
+
};
|
|
2383
2541
|
function flightSchema(verb, description, flags, response, example, extra = {}) {
|
|
2384
2542
|
return { cli: CLI_NAME, noun: FLIGHT_NOUN, verb, description, flags, response, example, ...extra };
|
|
2385
2543
|
}
|
|
@@ -2457,13 +2615,21 @@ var flightMoreOffersSchema = flightSchema(
|
|
|
2457
2615
|
);
|
|
2458
2616
|
var flightVerifySchema = flightSchema(
|
|
2459
2617
|
"verify",
|
|
2460
|
-
"Pre-booking price verification. Returns the authoritative product_token and a price_changed flag; pass the returned token to create-order.",
|
|
2461
|
-
{
|
|
2618
|
+
"Pre-booking price verification. Returns the authoritative product_token and a price_changed flag; pass the returned token to create-order. With --previous-total-price set, supplier 1002/1950 no longer dead-ends: the platform re-searches the SAME flight from the token and returns the refreshed fare; if that flight can no longer be found it fails with OFFER_UNAVAILABLE (pick another flight).",
|
|
2619
|
+
{
|
|
2620
|
+
"product-token": { type: "string", required: true, description: "Opaque token from search." },
|
|
2621
|
+
"previous-total-price": { type: "int", required: false, description: "Total price of the selected offer; enables the one-shot re-search refresh on supplier 1002/1950. Omit to keep the legacy behavior (error surfaces as-is)." },
|
|
2622
|
+
"cabin-class": { type: "string", required: false, description: "Cabin class to re-search with when refreshing (economy | premium_economy | business | first). Omitted falls back to economy." },
|
|
2623
|
+
"adult-num": { type: "int", required: false, description: "Adults to re-search with when refreshing (1-9)." },
|
|
2624
|
+
"child-num": { type: "int", required: false, description: "Children to re-search with when refreshing (0-9)." },
|
|
2625
|
+
"infant-num": { type: "int", required: false, description: "Infants to re-search with when refreshing (0-9)." }
|
|
2626
|
+
},
|
|
2462
2627
|
{
|
|
2463
2628
|
product_token: { type: "string", description: "Authoritative token to pass to create-order." },
|
|
2464
2629
|
total_price: { type: "int", description: "Verified total price (integer)." },
|
|
2465
2630
|
currency: { type: "string", description: "Currency code." },
|
|
2466
2631
|
price_changed: { type: "bool", description: "True if the price changed since search; re-confirm with the user." },
|
|
2632
|
+
previous_total_price: { type: "int", description: "The selected offer\u2019s price at pick time; present when the request carried previous-total-price. If it differs from total_price the fare was refreshed by a re-search (show the user the old \u2192 new price)." },
|
|
2467
2633
|
journeys: { type: "array", description: "The COMPLETE itinerary being priced \u2014 every leg, not just the last one relayed. Use it to show the full trip on a confirmation screen." }
|
|
2468
2634
|
},
|
|
2469
2635
|
{ command: "agenzo-merchant-cli flight-flink verify --product-token pt_...", output_summary: "Returns the authoritative product_token + price_changed." }
|
|
@@ -2480,7 +2646,8 @@ var flightCreateOrderSchema = flightSchema(
|
|
|
2480
2646
|
"contact-region": { type: "string", required: true, description: "Contact phone country code (no +)." },
|
|
2481
2647
|
"contact-phone": { type: "string", required: true, description: "Contact phone." },
|
|
2482
2648
|
"contact-email": { type: "string", required: true, description: "Contact email." },
|
|
2483
|
-
passengers: { type: "json", required: true, description: 'JSON array of passengers. gender/id_type are STRINGS ("1"/"2"). child/infant require adult_passenger_name.' },
|
|
2649
|
+
passengers: { type: "json", required: true, description: 'JSON array of passengers. gender/id_type are STRINGS ("1"/"2"). child/infant require adult_passenger_name. A saved traveller can be passed as just {"traveller_token":"tvp_...","type":"adult"} (from token-cli travellers list); the server fills in the ID details.' },
|
|
2650
|
+
"save-travellers": { type: "bool", required: false, description: "Save the fully filled passengers of this order as frequent travellers. Set only when the user explicitly asked to save them." },
|
|
2484
2651
|
member: MEMBER_FLAG_SCHEMA,
|
|
2485
2652
|
"idempotency-key": { type: "string", required: true, description: "Forwarded verbatim as the Idempotency-Key header." }
|
|
2486
2653
|
},
|
|
@@ -3734,6 +3901,185 @@ function registerListOrdersCommand(parent, deps) {
|
|
|
3734
3901
|
});
|
|
3735
3902
|
}
|
|
3736
3903
|
|
|
3904
|
+
// src/ride-elife/callback.ts
|
|
3905
|
+
var SIGNATURE_MODES = ["off", "optional", "required"];
|
|
3906
|
+
var DELIVERIES_LIMIT_MAX = 100;
|
|
3907
|
+
function need9(value, flag) {
|
|
3908
|
+
if (value === void 0 || String(value).trim() === "") {
|
|
3909
|
+
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3910
|
+
}
|
|
3911
|
+
return String(value);
|
|
3912
|
+
}
|
|
3913
|
+
function intFlag(value, flag, min, max) {
|
|
3914
|
+
if (value === void 0) return void 0;
|
|
3915
|
+
const parsed = Number(value);
|
|
3916
|
+
if (!Number.isInteger(parsed) || parsed < min || max !== void 0 && parsed > max) {
|
|
3917
|
+
const range = max === void 0 ? `>= ${min}` : `${min}-${max}`;
|
|
3918
|
+
throw new CliError("PARAM_INVALID", `--${flag} must be an integer ${range}.`);
|
|
3919
|
+
}
|
|
3920
|
+
return parsed;
|
|
3921
|
+
}
|
|
3922
|
+
async function apiKeyOf(opts) {
|
|
3923
|
+
return PromptEngine.resolveInput(opts.apiKey, {
|
|
3924
|
+
message: "API Key:",
|
|
3925
|
+
type: "password"
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3928
|
+
function subscriptionBody(opts) {
|
|
3929
|
+
const body = { callback_url: need9(opts.callbackUrl, "callback-url") };
|
|
3930
|
+
if (opts.adapter !== void 0) body.adapter = need9(opts.adapter, "adapter");
|
|
3931
|
+
if (opts.signatureMode !== void 0) {
|
|
3932
|
+
const mode = String(opts.signatureMode);
|
|
3933
|
+
if (!SIGNATURE_MODES.includes(mode)) {
|
|
3934
|
+
throw new CliError("PARAM_INVALID", `--signature-mode must be one of ${SIGNATURE_MODES.join(" / ")}.`);
|
|
3935
|
+
}
|
|
3936
|
+
body.signature_mode = mode;
|
|
3937
|
+
}
|
|
3938
|
+
if (opts.callbackApiKey !== void 0) body.callback_api_key = String(opts.callbackApiKey);
|
|
3939
|
+
if (opts.rotateSecret) body.rotate_secret = true;
|
|
3940
|
+
return body;
|
|
3941
|
+
}
|
|
3942
|
+
function formatSubscription(data) {
|
|
3943
|
+
const lines = [];
|
|
3944
|
+
for (const key of ["ride_id", "order_id", "developer_id", "callback_url", "adapter", "signature_mode", "status"]) {
|
|
3945
|
+
if (data[key] !== void 0 && data[key] !== null) lines.push([key, String(data[key])]);
|
|
3946
|
+
}
|
|
3947
|
+
const out = [Formatter.keyValue(lines)];
|
|
3948
|
+
if (typeof data.callback_secret === "string" && data.callback_secret) {
|
|
3949
|
+
out.push("", Formatter.keyValue([["callback_secret", data.callback_secret]]));
|
|
3950
|
+
out.push("Save this signing secret now \u2014 it is shown only once and cannot be read back.");
|
|
3951
|
+
}
|
|
3952
|
+
return out.join("\n");
|
|
3953
|
+
}
|
|
3954
|
+
async function render2(data, text, format) {
|
|
3955
|
+
const commandResult = { data, text };
|
|
3956
|
+
await renderWithContext(commandResult, { format }, new ConfigManager());
|
|
3957
|
+
}
|
|
3958
|
+
function withSubscriptionFlags(cmd) {
|
|
3959
|
+
return cmd.option("--callback-url <url>", "https URL that receives ride status events (must not be an internal address)").option("--adapter <name>", "Outbound event shape (default techtanium_v1)").option("--signature-mode <mode>", "off / optional / required (default off)").option("--callback-api-key <key>", "API key the platform sends to your endpoint; omit to keep the stored one").option("--rotate-secret", "Issue a new HMAC signing secret (breaks verification with the old one)").option("--idempotency-key <key>", "Idempotency key forwarded verbatim as the Idempotency-Key header");
|
|
3960
|
+
}
|
|
3961
|
+
async function postSubscription(deps, cmd, path, commandPath, doneMessage) {
|
|
3962
|
+
const opts = cmd.optsWithGlobals();
|
|
3963
|
+
const format = resolveFormat(opts.format);
|
|
3964
|
+
const target = path(opts);
|
|
3965
|
+
const body = subscriptionBody(opts);
|
|
3966
|
+
const apiKey = await apiKeyOf(opts);
|
|
3967
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
3968
|
+
yes: Boolean(opts.yes),
|
|
3969
|
+
commandPath
|
|
3970
|
+
});
|
|
3971
|
+
const result = await deps.apiClient.post(
|
|
3972
|
+
target,
|
|
3973
|
+
{ type: "api-key", key: apiKey },
|
|
3974
|
+
body,
|
|
3975
|
+
{ "Idempotency-Key": idempotencyKey }
|
|
3976
|
+
);
|
|
3977
|
+
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
3978
|
+
notify(format, "success", doneMessage);
|
|
3979
|
+
await render2(result.data, () => formatSubscription(result.data), format);
|
|
3980
|
+
}
|
|
3981
|
+
async function getJson(deps, cmd, path, text, params) {
|
|
3982
|
+
const opts = cmd.optsWithGlobals();
|
|
3983
|
+
const format = resolveFormat(opts.format);
|
|
3984
|
+
const target = path(opts);
|
|
3985
|
+
const query = params?.(opts);
|
|
3986
|
+
const apiKey = await apiKeyOf(opts);
|
|
3987
|
+
const result = await deps.apiClient.get(target, { type: "api-key", key: apiKey }, query);
|
|
3988
|
+
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
3989
|
+
await render2(result.data, () => text(result.data), format);
|
|
3990
|
+
}
|
|
3991
|
+
var ridePath = (opts, suffix) => `/ride/${encodeURIComponent(need9(opts.orderId, "order-id"))}/callback${suffix}`;
|
|
3992
|
+
function registerRideCallbackCommands(parent, deps) {
|
|
3993
|
+
const set = withSubscriptionFlags(
|
|
3994
|
+
parent.command("callback-set").description("Register (or update) where one ride's status events are forwarded").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "The numeric ride_id returned by book")
|
|
3995
|
+
);
|
|
3996
|
+
attachSchemaHelp(set, rideCallbackSetSchema);
|
|
3997
|
+
set.action(
|
|
3998
|
+
() => postSubscription(deps, set, (o) => ridePath(o, ""), "ride-elife callback-set", "Ride callback registered")
|
|
3999
|
+
);
|
|
4000
|
+
const get = parent.command("callback-get").description("Show one ride's callback registration (the signing secret is never returned)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "The numeric ride_id returned by book");
|
|
4001
|
+
attachSchemaHelp(get, rideCallbackGetSchema);
|
|
4002
|
+
get.action(() => getJson(deps, get, (o) => ridePath(o, ""), formatSubscription));
|
|
4003
|
+
const defSet = withSubscriptionFlags(
|
|
4004
|
+
parent.command("callback-default-set").description("Register (or update) the developer-wide fallback for rides without their own callback").option("--api-key <key>", "API Key for authentication (X-Api-Key)")
|
|
4005
|
+
);
|
|
4006
|
+
attachSchemaHelp(defSet, rideCallbackDefaultSetSchema);
|
|
4007
|
+
defSet.action(
|
|
4008
|
+
() => postSubscription(
|
|
4009
|
+
deps,
|
|
4010
|
+
defSet,
|
|
4011
|
+
() => "/ride/callback/default",
|
|
4012
|
+
"ride-elife callback-default-set",
|
|
4013
|
+
"Default ride callback registered"
|
|
4014
|
+
)
|
|
4015
|
+
);
|
|
4016
|
+
const defGet = parent.command("callback-default-get").description("Show the developer-wide fallback callback (the signing secret is never returned)").option("--api-key <key>", "API Key for authentication (X-Api-Key)");
|
|
4017
|
+
attachSchemaHelp(defGet, rideCallbackDefaultGetSchema);
|
|
4018
|
+
defGet.action(() => getJson(deps, defGet, () => "/ride/callback/default", formatSubscription));
|
|
4019
|
+
const deliveries = parent.command("callback-deliveries").description("List one ride's callback forwarding records (pending / delivered / dead)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "The numeric ride_id returned by book").option("--limit <n>", `Page size 1-${DELIVERIES_LIMIT_MAX} (default 50)`).option("--offset <n>", "Records to skip (default 0)");
|
|
4020
|
+
attachSchemaHelp(deliveries, rideCallbackDeliveriesSchema);
|
|
4021
|
+
deliveries.action(
|
|
4022
|
+
() => getJson(
|
|
4023
|
+
deps,
|
|
4024
|
+
deliveries,
|
|
4025
|
+
(o) => ridePath(o, "/deliveries"),
|
|
4026
|
+
(data) => {
|
|
4027
|
+
const rows = data.deliveries ?? [];
|
|
4028
|
+
if (rows.length === 0) return Formatter.status("info", "No callback deliveries");
|
|
4029
|
+
return Formatter.table(
|
|
4030
|
+
["Event", "Status", "Attempts", "Last error"],
|
|
4031
|
+
rows.map((r) => [
|
|
4032
|
+
String(r.event_id ?? "-"),
|
|
4033
|
+
String(r.status ?? "-"),
|
|
4034
|
+
String(r.attempts ?? "-"),
|
|
4035
|
+
String(r.last_error ?? "-")
|
|
4036
|
+
])
|
|
4037
|
+
);
|
|
4038
|
+
},
|
|
4039
|
+
(o) => {
|
|
4040
|
+
const limit = intFlag(o.limit, "limit", 1, DELIVERIES_LIMIT_MAX);
|
|
4041
|
+
const offset = intFlag(o.offset, "offset", 0);
|
|
4042
|
+
const params = {};
|
|
4043
|
+
if (limit !== void 0) params.limit = String(limit);
|
|
4044
|
+
if (offset !== void 0) params.offset = String(offset);
|
|
4045
|
+
return Object.keys(params).length > 0 ? params : void 0;
|
|
4046
|
+
}
|
|
4047
|
+
)
|
|
4048
|
+
);
|
|
4049
|
+
const replay = parent.command("callback-replay").description("Requeue one ride's dead (or failed) callback records; delivered records are never re-sent").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "The numeric ride_id returned by book").option("--event-id <id>", "Requeue only this record (default: all dead records of the ride)").option("--include-failed", "Also requeue pending records that already failed at least once").option("--reset-attempts", "Reset the retry counter of requeued records").option("--idempotency-key <key>", "Idempotency key forwarded verbatim as the Idempotency-Key header");
|
|
4050
|
+
attachSchemaHelp(replay, rideCallbackReplaySchema);
|
|
4051
|
+
replay.action(async () => {
|
|
4052
|
+
const opts = replay.optsWithGlobals();
|
|
4053
|
+
const format = resolveFormat(opts.format);
|
|
4054
|
+
const target = ridePath(opts, "/replay");
|
|
4055
|
+
const body = {};
|
|
4056
|
+
if (opts.eventId !== void 0) body.event_id = need9(opts.eventId, "event-id");
|
|
4057
|
+
if (opts.includeFailed) body.include_failed = true;
|
|
4058
|
+
if (opts.resetAttempts) body.reset_attempts = true;
|
|
4059
|
+
const apiKey = await apiKeyOf(opts);
|
|
4060
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
4061
|
+
yes: Boolean(opts.yes),
|
|
4062
|
+
commandPath: "ride-elife callback-replay"
|
|
4063
|
+
});
|
|
4064
|
+
const result = await deps.apiClient.post(
|
|
4065
|
+
target,
|
|
4066
|
+
{ type: "api-key", key: apiKey },
|
|
4067
|
+
body,
|
|
4068
|
+
{ "Idempotency-Key": idempotencyKey }
|
|
4069
|
+
);
|
|
4070
|
+
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
4071
|
+
notify(format, "success", `Requeued ${String(result.data.requeued ?? 0)} callback record(s)`);
|
|
4072
|
+
await render2(
|
|
4073
|
+
result.data,
|
|
4074
|
+
() => Formatter.keyValue([
|
|
4075
|
+
["Ride ID", String(result.data.ride_id ?? "-")],
|
|
4076
|
+
["Requeued", String(result.data.requeued ?? 0)]
|
|
4077
|
+
]),
|
|
4078
|
+
format
|
|
4079
|
+
);
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
|
|
3737
4083
|
// src/services/registry.ts
|
|
3738
4084
|
var SERVICE_REGISTRY = [
|
|
3739
4085
|
{
|
|
@@ -4298,7 +4644,7 @@ function registerOrdersPayBatchCommand(parent, deps) {
|
|
|
4298
4644
|
message: "API Key:",
|
|
4299
4645
|
type: "password"
|
|
4300
4646
|
});
|
|
4301
|
-
const orderIds = parseOrderIds(
|
|
4647
|
+
const orderIds = parseOrderIds(need10(opts.orderIds, "order-ids"));
|
|
4302
4648
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
4303
4649
|
yes: isYes,
|
|
4304
4650
|
commandPath: "orders pay-batch"
|
|
@@ -4368,22 +4714,59 @@ function registerOrdersPayBatchCommand(parent, deps) {
|
|
|
4368
4714
|
}
|
|
4369
4715
|
});
|
|
4370
4716
|
}
|
|
4371
|
-
function
|
|
4717
|
+
function need10(value, flag) {
|
|
4372
4718
|
if (value === void 0) {
|
|
4373
4719
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4374
4720
|
}
|
|
4375
4721
|
return value;
|
|
4376
4722
|
}
|
|
4377
4723
|
|
|
4724
|
+
// src/orders/get-payment-group.ts
|
|
4725
|
+
var PAYMENT_GROUP_ID_MAX = 64;
|
|
4726
|
+
function registerOrdersGetPaymentGroupCommand(parent, deps) {
|
|
4727
|
+
const cmd = parent.command("get-payment-group").description("Get the status of an aggregate settlement created by `orders pay-batch` (read-only)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").requiredOption("--payment-group-id <id>", "payment_group_id returned by `orders pay-batch`");
|
|
4728
|
+
attachSchemaHelp(cmd, ordersGetPaymentGroupSchema);
|
|
4729
|
+
cmd.action(async () => {
|
|
4730
|
+
const opts = cmd.optsWithGlobals();
|
|
4731
|
+
const format = resolveFormat(opts.format);
|
|
4732
|
+
const groupId = String(opts.paymentGroupId ?? "").trim();
|
|
4733
|
+
if (!groupId || groupId.length > PAYMENT_GROUP_ID_MAX) {
|
|
4734
|
+
throw new CliError(
|
|
4735
|
+
"PARAM_INVALID",
|
|
4736
|
+
`--payment-group-id must be 1-${PAYMENT_GROUP_ID_MAX} characters.`
|
|
4737
|
+
);
|
|
4738
|
+
}
|
|
4739
|
+
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
4740
|
+
message: "API Key:",
|
|
4741
|
+
type: "password"
|
|
4742
|
+
});
|
|
4743
|
+
const spinner = format === "json" ? null : createSpinner("Fetching payment group...");
|
|
4744
|
+
const result = await deps.apiClient.get(
|
|
4745
|
+
`/orders/payment-groups/${encodeURIComponent(groupId)}`,
|
|
4746
|
+
{ type: "api-key", key: apiKey }
|
|
4747
|
+
);
|
|
4748
|
+
spinner?.stop();
|
|
4749
|
+
if (!result.success) {
|
|
4750
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
4751
|
+
}
|
|
4752
|
+
const data = result.data;
|
|
4753
|
+
const commandResult = {
|
|
4754
|
+
data,
|
|
4755
|
+
text: () => formatPayBatch(data)
|
|
4756
|
+
};
|
|
4757
|
+
await renderWithContext(commandResult, { format }, new ConfigManager());
|
|
4758
|
+
});
|
|
4759
|
+
}
|
|
4760
|
+
|
|
4378
4761
|
// src/hotel-redaug/search.ts
|
|
4379
|
-
function
|
|
4762
|
+
function need11(value, flag) {
|
|
4380
4763
|
if (value === void 0) {
|
|
4381
4764
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4382
4765
|
}
|
|
4383
4766
|
return value;
|
|
4384
4767
|
}
|
|
4385
4768
|
function num5(value, flag) {
|
|
4386
|
-
const n = Number(
|
|
4769
|
+
const n = Number(need11(value, flag));
|
|
4387
4770
|
if (!Number.isFinite(n)) {
|
|
4388
4771
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4389
4772
|
}
|
|
@@ -4405,7 +4788,7 @@ function positiveInt3(value, flag) {
|
|
|
4405
4788
|
}
|
|
4406
4789
|
var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
4407
4790
|
function stayDate(value, flag) {
|
|
4408
|
-
const raw =
|
|
4791
|
+
const raw = need11(value, flag);
|
|
4409
4792
|
if (!YMD_RE.test(raw)) {
|
|
4410
4793
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
4411
4794
|
}
|
|
@@ -4477,7 +4860,7 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
4477
4860
|
const pageSize = positiveInt3(opts.pageSize, "page-size");
|
|
4478
4861
|
const body = {};
|
|
4479
4862
|
if (hasDestination) {
|
|
4480
|
-
body.destination_id =
|
|
4863
|
+
body.destination_id = need11(opts.destinationId, "destination-id");
|
|
4481
4864
|
} else {
|
|
4482
4865
|
body.lat = coord(opts.lat, "lat", -90, 90);
|
|
4483
4866
|
body.lng = coord(opts.lng, "lng", -180, 180);
|
|
@@ -4520,14 +4903,14 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
4520
4903
|
}
|
|
4521
4904
|
|
|
4522
4905
|
// src/hotel-redaug/quote.ts
|
|
4523
|
-
function
|
|
4906
|
+
function need12(value, flag) {
|
|
4524
4907
|
if (value === void 0) {
|
|
4525
4908
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4526
4909
|
}
|
|
4527
4910
|
return value;
|
|
4528
4911
|
}
|
|
4529
4912
|
function num6(value, flag) {
|
|
4530
|
-
const n = Number(
|
|
4913
|
+
const n = Number(need12(value, flag));
|
|
4531
4914
|
if (!Number.isFinite(n)) {
|
|
4532
4915
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4533
4916
|
}
|
|
@@ -4535,7 +4918,7 @@ function num6(value, flag) {
|
|
|
4535
4918
|
}
|
|
4536
4919
|
var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
4537
4920
|
function stayDate2(value, flag) {
|
|
4538
|
-
const raw =
|
|
4921
|
+
const raw = need12(value, flag);
|
|
4539
4922
|
if (!YMD_RE2.test(raw)) {
|
|
4540
4923
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
4541
4924
|
}
|
|
@@ -4575,7 +4958,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
4575
4958
|
message: "API Key:",
|
|
4576
4959
|
type: "password"
|
|
4577
4960
|
});
|
|
4578
|
-
const hotelId =
|
|
4961
|
+
const hotelId = need12(opts.hotelId, "hotel-id");
|
|
4579
4962
|
const checkIn = stayDate2(opts.checkIn, "check-in");
|
|
4580
4963
|
const checkOut = stayDate2(opts.checkOut, "check-out");
|
|
4581
4964
|
if (!(checkOut > checkIn)) {
|
|
@@ -4695,14 +5078,14 @@ function parseCancellation(raw) {
|
|
|
4695
5078
|
}
|
|
4696
5079
|
return parsed;
|
|
4697
5080
|
}
|
|
4698
|
-
function
|
|
5081
|
+
function need13(value, flag) {
|
|
4699
5082
|
if (value === void 0) {
|
|
4700
5083
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4701
5084
|
}
|
|
4702
5085
|
return value;
|
|
4703
5086
|
}
|
|
4704
5087
|
function num7(value, flag) {
|
|
4705
|
-
const n = Number(
|
|
5088
|
+
const n = Number(need13(value, flag));
|
|
4706
5089
|
if (!Number.isFinite(n)) {
|
|
4707
5090
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4708
5091
|
}
|
|
@@ -4710,7 +5093,7 @@ function num7(value, flag) {
|
|
|
4710
5093
|
}
|
|
4711
5094
|
var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
4712
5095
|
function stayDate3(value, flag) {
|
|
4713
|
-
const raw =
|
|
5096
|
+
const raw = need13(value, flag);
|
|
4714
5097
|
if (!YMD_RE3.test(raw)) {
|
|
4715
5098
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
4716
5099
|
}
|
|
@@ -4782,18 +5165,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4782
5165
|
message: "API Key:",
|
|
4783
5166
|
type: "password"
|
|
4784
5167
|
});
|
|
4785
|
-
const productToken =
|
|
5168
|
+
const productToken = need13(opts.productToken, "product-token");
|
|
4786
5169
|
const totalAmount = num7(opts.totalAmount, "total-amount");
|
|
4787
|
-
const currency =
|
|
4788
|
-
const priceItems = parsePriceItems(
|
|
5170
|
+
const currency = need13(opts.currency, "currency");
|
|
5171
|
+
const priceItems = parsePriceItems(need13(opts.priceItems, "price-items"));
|
|
4789
5172
|
const checkIn = stayDate3(opts.checkIn, "check-in");
|
|
4790
5173
|
const checkOut = stayDate3(opts.checkOut, "check-out");
|
|
4791
5174
|
if (!(checkOut > checkIn)) {
|
|
4792
5175
|
throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
|
|
4793
5176
|
}
|
|
4794
|
-
const guestName =
|
|
4795
|
-
const contactName =
|
|
4796
|
-
const contactPhone =
|
|
5177
|
+
const guestName = need13(opts.guestName, "guest-name");
|
|
5178
|
+
const contactName = need13(opts.contactName, "contact-name");
|
|
5179
|
+
const contactPhone = need13(opts.contactPhone, "contact-phone");
|
|
4797
5180
|
const body = {
|
|
4798
5181
|
product_token: productToken,
|
|
4799
5182
|
total_amount: totalAmount,
|
|
@@ -5145,7 +5528,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
5145
5528
|
}
|
|
5146
5529
|
|
|
5147
5530
|
// src/hotel-redaug/get.ts
|
|
5148
|
-
function
|
|
5531
|
+
function need14(value, flag) {
|
|
5149
5532
|
if (value === void 0) {
|
|
5150
5533
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5151
5534
|
}
|
|
@@ -5209,7 +5592,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
5209
5592
|
message: "API Key:",
|
|
5210
5593
|
type: "password"
|
|
5211
5594
|
});
|
|
5212
|
-
const orderId =
|
|
5595
|
+
const orderId = need14(opts.orderId, "order-id");
|
|
5213
5596
|
if (opts.watch) {
|
|
5214
5597
|
await watchOrderStatus(deps.apiClient, apiKey, orderId, {
|
|
5215
5598
|
intervalSeconds: resolveSeconds(
|
|
@@ -5243,7 +5626,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
5243
5626
|
}
|
|
5244
5627
|
|
|
5245
5628
|
// src/hotel-redaug/cancel.ts
|
|
5246
|
-
function
|
|
5629
|
+
function need15(value, flag) {
|
|
5247
5630
|
if (value === void 0) {
|
|
5248
5631
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5249
5632
|
}
|
|
@@ -5296,8 +5679,8 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
5296
5679
|
message: "API Key:",
|
|
5297
5680
|
type: "password"
|
|
5298
5681
|
});
|
|
5299
|
-
const orderId =
|
|
5300
|
-
const fcOrderCode =
|
|
5682
|
+
const orderId = need15(opts.orderId, "order-id");
|
|
5683
|
+
const fcOrderCode = need15(opts.fcOrderCode, "fc-order-code");
|
|
5301
5684
|
const body = { fc_order_code: fcOrderCode };
|
|
5302
5685
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
5303
5686
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5327,14 +5710,14 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
5327
5710
|
|
|
5328
5711
|
// src/hotel-redaug/checkout.ts
|
|
5329
5712
|
import { confirm as confirm9 } from "@inquirer/prompts";
|
|
5330
|
-
function
|
|
5713
|
+
function need16(value, flag) {
|
|
5331
5714
|
if (value === void 0) {
|
|
5332
5715
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5333
5716
|
}
|
|
5334
5717
|
return value;
|
|
5335
5718
|
}
|
|
5336
5719
|
function num8(value, flag) {
|
|
5337
|
-
const n = Number(
|
|
5720
|
+
const n = Number(need16(value, flag));
|
|
5338
5721
|
if (!Number.isFinite(n)) {
|
|
5339
5722
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5340
5723
|
}
|
|
@@ -5400,10 +5783,10 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
5400
5783
|
message: "API Key:",
|
|
5401
5784
|
type: "password"
|
|
5402
5785
|
});
|
|
5403
|
-
const orderId =
|
|
5404
|
-
const fcOrderCode =
|
|
5405
|
-
const reason =
|
|
5406
|
-
const checkoutRooms = parseCheckoutRooms(
|
|
5786
|
+
const orderId = need16(opts.orderId, "order-id");
|
|
5787
|
+
const fcOrderCode = need16(opts.fcOrderCode, "fc-order-code");
|
|
5788
|
+
const reason = need16(opts.reason, "reason");
|
|
5789
|
+
const checkoutRooms = parseCheckoutRooms(need16(opts.checkoutRooms, "checkout-rooms"));
|
|
5407
5790
|
const refundType = num8(opts.refundType, "refund-type");
|
|
5408
5791
|
const body = {
|
|
5409
5792
|
fc_order_code: fcOrderCode,
|
|
@@ -5446,7 +5829,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
5446
5829
|
}
|
|
5447
5830
|
|
|
5448
5831
|
// src/hotel-redaug/get-checkout.ts
|
|
5449
|
-
function
|
|
5832
|
+
function need17(value, flag) {
|
|
5450
5833
|
if (value === void 0) {
|
|
5451
5834
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5452
5835
|
}
|
|
@@ -5482,7 +5865,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
|
|
|
5482
5865
|
message: "API Key:",
|
|
5483
5866
|
type: "password"
|
|
5484
5867
|
});
|
|
5485
|
-
const taskOrderCode =
|
|
5868
|
+
const taskOrderCode = need17(opts.taskOrderCode, "task-order-code");
|
|
5486
5869
|
if (opts.watch) {
|
|
5487
5870
|
await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
|
|
5488
5871
|
intervalSeconds: resolveSeconds(
|
|
@@ -5586,7 +5969,7 @@ function registerHotelListOrdersCommand(parent, deps) {
|
|
|
5586
5969
|
}
|
|
5587
5970
|
|
|
5588
5971
|
// src/hotel-redaug/find-destination.ts
|
|
5589
|
-
function
|
|
5972
|
+
function need18(value, flag) {
|
|
5590
5973
|
if (value === void 0 || value.trim() === "") {
|
|
5591
5974
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5592
5975
|
}
|
|
@@ -5620,7 +6003,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
5620
6003
|
message: "API Key:",
|
|
5621
6004
|
type: "password"
|
|
5622
6005
|
});
|
|
5623
|
-
const keyword =
|
|
6006
|
+
const keyword = need18(opts.keyword, "keyword");
|
|
5624
6007
|
const body = { keyword };
|
|
5625
6008
|
if (opts.dataType !== void 0) {
|
|
5626
6009
|
body.data_type = opts.dataType;
|
|
@@ -5644,14 +6027,14 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
5644
6027
|
}
|
|
5645
6028
|
|
|
5646
6029
|
// src/hotel-redaug/hotel-filters.ts
|
|
5647
|
-
function
|
|
6030
|
+
function need19(value, flag) {
|
|
5648
6031
|
if (value === void 0 || value.trim() === "") {
|
|
5649
6032
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5650
6033
|
}
|
|
5651
6034
|
return value;
|
|
5652
6035
|
}
|
|
5653
6036
|
function num9(value, flag) {
|
|
5654
|
-
const n = Number(
|
|
6037
|
+
const n = Number(need19(value, flag));
|
|
5655
6038
|
if (!Number.isFinite(n)) {
|
|
5656
6039
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5657
6040
|
}
|
|
@@ -5731,7 +6114,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
5731
6114
|
}
|
|
5732
6115
|
const body = {};
|
|
5733
6116
|
if (hasDestination) {
|
|
5734
|
-
body.destination_id =
|
|
6117
|
+
body.destination_id = need19(opts.destinationId, "destination-id");
|
|
5735
6118
|
} else {
|
|
5736
6119
|
body.lat = coord2(opts.lat, "lat", -90, 90);
|
|
5737
6120
|
body.lng = coord2(opts.lng, "lng", -180, 180);
|
|
@@ -5756,7 +6139,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
5756
6139
|
}
|
|
5757
6140
|
|
|
5758
6141
|
// src/hotel-redaug/list-cities.ts
|
|
5759
|
-
function
|
|
6142
|
+
function need20(value, flag) {
|
|
5760
6143
|
if (value === void 0 || value.trim() === "") {
|
|
5761
6144
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5762
6145
|
}
|
|
@@ -5789,7 +6172,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
5789
6172
|
message: "API Key:",
|
|
5790
6173
|
type: "password"
|
|
5791
6174
|
});
|
|
5792
|
-
const country =
|
|
6175
|
+
const country = need20(opts.country, "country");
|
|
5793
6176
|
const body = { country_code: country };
|
|
5794
6177
|
const result = await deps.apiClient.post(
|
|
5795
6178
|
"/hotel/cities",
|
|
@@ -5810,7 +6193,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
5810
6193
|
}
|
|
5811
6194
|
|
|
5812
6195
|
// src/hotel-redaug/hotel-detail.ts
|
|
5813
|
-
function
|
|
6196
|
+
function need21(value, flag) {
|
|
5814
6197
|
if (value === void 0 || value.trim() === "") {
|
|
5815
6198
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5816
6199
|
}
|
|
@@ -5957,7 +6340,7 @@ function registerHotelDetailCommand(parent, deps) {
|
|
|
5957
6340
|
message: "API Key:",
|
|
5958
6341
|
type: "password"
|
|
5959
6342
|
});
|
|
5960
|
-
const hotelId =
|
|
6343
|
+
const hotelId = need21(opts.hotelId, "hotel-id");
|
|
5961
6344
|
const rawWithImages = opts.withImages;
|
|
5962
6345
|
const withImages = rawWithImages !== "false" && rawWithImages !== false;
|
|
5963
6346
|
const settings = parseSettings(opts.settings);
|
|
@@ -6165,14 +6548,14 @@ function registerHotelSkillCommand(parent) {
|
|
|
6165
6548
|
}
|
|
6166
6549
|
|
|
6167
6550
|
// src/flight-flink/_helpers.ts
|
|
6168
|
-
function
|
|
6551
|
+
function need22(value, flag) {
|
|
6169
6552
|
if (value === void 0) {
|
|
6170
6553
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
6171
6554
|
}
|
|
6172
6555
|
return value;
|
|
6173
6556
|
}
|
|
6174
6557
|
function num10(value, flag) {
|
|
6175
|
-
const n = Number(
|
|
6558
|
+
const n = Number(need22(value, flag));
|
|
6176
6559
|
if (!Number.isFinite(n)) {
|
|
6177
6560
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
6178
6561
|
}
|
|
@@ -6193,7 +6576,7 @@ function jsonArray(raw, flag) {
|
|
|
6193
6576
|
function resolveApiKey(flag) {
|
|
6194
6577
|
return PromptEngine.resolveInput(flag, { message: "API Key:", type: "password" });
|
|
6195
6578
|
}
|
|
6196
|
-
async function
|
|
6579
|
+
async function render3(data, format, text) {
|
|
6197
6580
|
const resolved = resolveFormat(format);
|
|
6198
6581
|
const result = { data, text: () => text(data) };
|
|
6199
6582
|
await renderWithContext(result, { format: resolved }, new ConfigManager());
|
|
@@ -6207,7 +6590,7 @@ function registerFindAirportCommand(parent, deps) {
|
|
|
6207
6590
|
const opts = cmd.optsWithGlobals();
|
|
6208
6591
|
const format = resolveFormat(opts.format);
|
|
6209
6592
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6210
|
-
const keyword =
|
|
6593
|
+
const keyword = need22(opts.keyword, "keyword");
|
|
6211
6594
|
const spinner = format === "json" ? null : createSpinner("Resolving airports...");
|
|
6212
6595
|
const result = await deps.apiClient.post(
|
|
6213
6596
|
"/flight/find-airport",
|
|
@@ -6216,7 +6599,7 @@ function registerFindAirportCommand(parent, deps) {
|
|
|
6216
6599
|
);
|
|
6217
6600
|
spinner?.stop();
|
|
6218
6601
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6219
|
-
await
|
|
6602
|
+
await render3(
|
|
6220
6603
|
result.data,
|
|
6221
6604
|
opts.format,
|
|
6222
6605
|
(d) => JSON.stringify(d.airports ?? d, null, 2)
|
|
@@ -6245,7 +6628,7 @@ function registerListAirportsCommand(parent, deps) {
|
|
|
6245
6628
|
);
|
|
6246
6629
|
spinner?.stop();
|
|
6247
6630
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6248
|
-
await
|
|
6631
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6249
6632
|
});
|
|
6250
6633
|
}
|
|
6251
6634
|
|
|
@@ -6270,7 +6653,7 @@ function registerListAirlinesCommand(parent, deps) {
|
|
|
6270
6653
|
);
|
|
6271
6654
|
spinner?.stop();
|
|
6272
6655
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6273
|
-
await
|
|
6656
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6274
6657
|
});
|
|
6275
6658
|
}
|
|
6276
6659
|
|
|
@@ -6290,7 +6673,7 @@ function registerListNationalitiesCommand(parent, deps) {
|
|
|
6290
6673
|
);
|
|
6291
6674
|
spinner?.stop();
|
|
6292
6675
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6293
|
-
await
|
|
6676
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6294
6677
|
});
|
|
6295
6678
|
}
|
|
6296
6679
|
|
|
@@ -6304,7 +6687,7 @@ function registerSearchCommand(parent, deps) {
|
|
|
6304
6687
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6305
6688
|
const body = {
|
|
6306
6689
|
trip_type: num10(opts.tripType, "trip-type"),
|
|
6307
|
-
journeys: jsonArray(
|
|
6690
|
+
journeys: jsonArray(need22(opts.journeys, "journeys"), "journeys"),
|
|
6308
6691
|
cabin_class: opts.cabinClass,
|
|
6309
6692
|
adult_num: num10(opts.adultNum, "adult-num"),
|
|
6310
6693
|
child_num: num10(opts.childNum, "child-num"),
|
|
@@ -6323,7 +6706,7 @@ function registerSearchCommand(parent, deps) {
|
|
|
6323
6706
|
);
|
|
6324
6707
|
spinner?.stop();
|
|
6325
6708
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6326
|
-
await
|
|
6709
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6327
6710
|
});
|
|
6328
6711
|
}
|
|
6329
6712
|
|
|
@@ -6335,7 +6718,7 @@ function registerMoreOffersCommand(parent, deps) {
|
|
|
6335
6718
|
const opts = cmd.optsWithGlobals();
|
|
6336
6719
|
const format = resolveFormat(opts.format);
|
|
6337
6720
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6338
|
-
const productToken =
|
|
6721
|
+
const productToken = need22(opts.productToken, "product-token");
|
|
6339
6722
|
const spinner = format === "json" ? null : createSpinner("Fetching offers...");
|
|
6340
6723
|
const result = await deps.apiClient.post(
|
|
6341
6724
|
"/flight/more-offers",
|
|
@@ -6344,34 +6727,44 @@ function registerMoreOffersCommand(parent, deps) {
|
|
|
6344
6727
|
);
|
|
6345
6728
|
spinner?.stop();
|
|
6346
6729
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6347
|
-
await
|
|
6730
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6348
6731
|
});
|
|
6349
6732
|
}
|
|
6350
6733
|
|
|
6351
6734
|
// src/flight-flink/verify.ts
|
|
6352
6735
|
function registerVerifyCommand(parent, deps) {
|
|
6353
|
-
const cmd = parent.command("verify").description("Verify the latest price before booking; returns the authoritative product_token").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Opaque token from search");
|
|
6736
|
+
const cmd = parent.command("verify").description("Verify the latest price before booking; returns the authoritative product_token").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Opaque token from search").option("--previous-total-price <n>", "Total price of the selected offer; enables the one-shot re-search refresh on supplier 1002/1950").option("--cabin-class <c>", "Cabin class to re-search with (economy | premium_economy | business | first)").option("--adult-num <n>", "Adults to re-search with (1-9)").option("--child-num <n>", "Children to re-search with (0-9)").option("--infant-num <n>", "Infants to re-search with (0-9)");
|
|
6354
6737
|
attachSchemaHelp(cmd, flightVerifySchema);
|
|
6355
6738
|
cmd.action(async () => {
|
|
6356
6739
|
const opts = cmd.optsWithGlobals();
|
|
6357
6740
|
const format = resolveFormat(opts.format);
|
|
6358
6741
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6359
|
-
const productToken =
|
|
6742
|
+
const productToken = need22(opts.productToken, "product-token");
|
|
6743
|
+
const body = { product_token: productToken };
|
|
6744
|
+
if (opts.previousTotalPrice !== void 0) {
|
|
6745
|
+
body.previous_total_price = num10(opts.previousTotalPrice, "previous-total-price");
|
|
6746
|
+
}
|
|
6747
|
+
if (opts.cabinClass !== void 0) body.cabin_class = opts.cabinClass;
|
|
6748
|
+
if (opts.adultNum !== void 0) body.adult_num = num10(opts.adultNum, "adult-num");
|
|
6749
|
+
if (opts.childNum !== void 0) body.child_num = num10(opts.childNum, "child-num");
|
|
6750
|
+
if (opts.infantNum !== void 0) body.infant_num = num10(opts.infantNum, "infant-num");
|
|
6360
6751
|
const spinner = format === "json" ? null : createSpinner("Verifying price...");
|
|
6361
6752
|
const result = await deps.apiClient.post(
|
|
6362
6753
|
"/flight/verify",
|
|
6363
6754
|
{ type: "api-key", key: apiKey },
|
|
6364
|
-
|
|
6755
|
+
body
|
|
6365
6756
|
);
|
|
6366
6757
|
spinner?.stop();
|
|
6367
6758
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6368
|
-
await
|
|
6759
|
+
await render3(
|
|
6369
6760
|
result.data,
|
|
6370
6761
|
opts.format,
|
|
6371
6762
|
(d) => Formatter.keyValue([
|
|
6372
6763
|
["Product token", String(d.product_token ?? "-")],
|
|
6373
6764
|
["Total price", `${d.total_price ?? "-"} ${d.currency ?? ""}`.trim()],
|
|
6374
|
-
["Price changed", String(d.price_changed)]
|
|
6765
|
+
["Price changed", String(d.price_changed)],
|
|
6766
|
+
// 刷新路径:平台带回选中时的原价,人读 output 里直接看出 原价 → 新价。
|
|
6767
|
+
...d.previous_total_price != null ? [["Previous total price", String(d.previous_total_price)]] : []
|
|
6375
6768
|
])
|
|
6376
6769
|
);
|
|
6377
6770
|
});
|
|
@@ -6380,7 +6773,10 @@ function registerVerifyCommand(parent, deps) {
|
|
|
6380
6773
|
// src/flight-flink/create-order.ts
|
|
6381
6774
|
import { confirm as confirm10 } from "@inquirer/prompts";
|
|
6382
6775
|
function registerCreateOrderCommand(parent, deps) {
|
|
6383
|
-
const cmd = parent.command("create-order").description("Create a flight order without charging (locks the fare, await payment)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Authoritative rate token from verify").option("--total-amount <amount>", "Verified total price in decimal units").option("--currency <currency>", "ISO 4217 currency code").option("--trip-type <n>", "1/2/3", "1").option("--contact-name <name>", "Booking contact name").option("--contact-region <code>", "Contact phone country code (no '+')").option("--contact-phone <phone>", "Booking contact phone").option("--contact-email <email>", "Booking contact email").option(
|
|
6776
|
+
const cmd = parent.command("create-order").description("Create a flight order without charging (locks the fare, await payment)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Authoritative rate token from verify").option("--total-amount <amount>", "Verified total price in decimal units").option("--currency <currency>", "ISO 4217 currency code").option("--trip-type <n>", "1/2/3", "1").option("--contact-name <name>", "Booking contact name").option("--contact-region <code>", "Contact phone country code (no '+')").option("--contact-phone <phone>", "Booking contact phone").option("--contact-email <email>", "Booking contact email").option(
|
|
6777
|
+
"--passengers <json>",
|
|
6778
|
+
'JSON array of passengers (gender/id_type are strings). A passenger may be just {"traveller_token":"tvp_...","type":"adult"} from token-cli travellers list.'
|
|
6779
|
+
).option("--save-travellers", "Save the fully filled passengers as frequent travellers (only when the user asked)").option("--payment-method-id <id>", "Optional bound-card id (pay_per_call only)").option("--payment-token-id <id>", "Optional UPI network-token id (unionpay charge path)").option(
|
|
6384
6780
|
"--authorized-merchant-trans-id <id>",
|
|
6385
6781
|
"EVO merchant transaction id of an already-authorised preauth (3DS challenge resume). When set, the server reuses that authorization instead of creating a new one, avoiding a second hold on the card (pay_per_call mode only)."
|
|
6386
6782
|
).option("--member <id>", MEMBER_OPTION_DESCRIPTION).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
@@ -6390,20 +6786,21 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
6390
6786
|
const format = resolveFormat(opts.format);
|
|
6391
6787
|
const isYes = Boolean(opts.yes);
|
|
6392
6788
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6393
|
-
const productToken =
|
|
6789
|
+
const productToken = need22(opts.productToken, "product-token");
|
|
6394
6790
|
const totalAmount = num10(opts.totalAmount, "total-amount");
|
|
6395
|
-
const currency =
|
|
6791
|
+
const currency = need22(opts.currency, "currency");
|
|
6396
6792
|
const body = {
|
|
6397
6793
|
product_token: productToken,
|
|
6398
6794
|
total_amount: totalAmount,
|
|
6399
6795
|
currency,
|
|
6400
6796
|
trip_type: num10(opts.tripType, "trip-type"),
|
|
6401
|
-
contact_name:
|
|
6402
|
-
contact_region:
|
|
6403
|
-
contact_phone:
|
|
6404
|
-
contact_email:
|
|
6405
|
-
passengers: jsonArray(
|
|
6797
|
+
contact_name: need22(opts.contactName, "contact-name"),
|
|
6798
|
+
contact_region: need22(opts.contactRegion, "contact-region"),
|
|
6799
|
+
contact_phone: need22(opts.contactPhone, "contact-phone"),
|
|
6800
|
+
contact_email: need22(opts.contactEmail, "contact-email"),
|
|
6801
|
+
passengers: jsonArray(need22(opts.passengers, "passengers"), "passengers")
|
|
6406
6802
|
};
|
|
6803
|
+
if (opts.saveTravellers) body.save_travellers = true;
|
|
6407
6804
|
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
6408
6805
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
6409
6806
|
if (opts.authorizedMerchantTransId) {
|
|
@@ -6431,7 +6828,7 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
6431
6828
|
);
|
|
6432
6829
|
spinner?.stop();
|
|
6433
6830
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6434
|
-
await
|
|
6831
|
+
await render3(
|
|
6435
6832
|
result.data,
|
|
6436
6833
|
opts.format,
|
|
6437
6834
|
(d) => [
|
|
@@ -6475,7 +6872,7 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
6475
6872
|
const format = resolveFormat(opts.format);
|
|
6476
6873
|
const isYes = Boolean(opts.yes);
|
|
6477
6874
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6478
|
-
const orderNo =
|
|
6875
|
+
const orderNo = need22(opts.orderNo, "order-no");
|
|
6479
6876
|
if (!isYes) {
|
|
6480
6877
|
const ok = await confirm11({
|
|
6481
6878
|
message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
|
|
@@ -6508,7 +6905,7 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
6508
6905
|
);
|
|
6509
6906
|
spinner?.stop();
|
|
6510
6907
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6511
|
-
await
|
|
6908
|
+
await render3(result.data, opts.format, (d) => {
|
|
6512
6909
|
const rows = [
|
|
6513
6910
|
["Order no", String(d.order_no ?? "-")],
|
|
6514
6911
|
["Status", String(d.status ?? "-")],
|
|
@@ -6533,7 +6930,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
6533
6930
|
const opts = cmd.optsWithGlobals();
|
|
6534
6931
|
const format = resolveFormat(opts.format);
|
|
6535
6932
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6536
|
-
const orderNo =
|
|
6933
|
+
const orderNo = need22(opts.orderNo, "order-no");
|
|
6537
6934
|
const path = `/flight/${encodeURIComponent(orderNo)}/status`;
|
|
6538
6935
|
const auth = { type: "api-key", key: apiKey };
|
|
6539
6936
|
if (opts.watch) {
|
|
@@ -6558,7 +6955,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
6558
6955
|
const result = await deps.apiClient.get(path, auth);
|
|
6559
6956
|
spinner?.stop();
|
|
6560
6957
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6561
|
-
await
|
|
6958
|
+
await render3(
|
|
6562
6959
|
result.data,
|
|
6563
6960
|
opts.format,
|
|
6564
6961
|
(d) => Formatter.keyValue([
|
|
@@ -6582,7 +6979,7 @@ function registerCancelOrderCommand(parent, deps) {
|
|
|
6582
6979
|
const format = resolveFormat(opts.format);
|
|
6583
6980
|
const isYes = Boolean(opts.yes);
|
|
6584
6981
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6585
|
-
const orderNo =
|
|
6982
|
+
const orderNo = need22(opts.orderNo, "order-no");
|
|
6586
6983
|
if (!isYes) {
|
|
6587
6984
|
const ok = await confirm12({
|
|
6588
6985
|
message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
|
|
@@ -6605,7 +7002,7 @@ function registerCancelOrderCommand(parent, deps) {
|
|
|
6605
7002
|
);
|
|
6606
7003
|
spinner?.stop();
|
|
6607
7004
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6608
|
-
await
|
|
7005
|
+
await render3(
|
|
6609
7006
|
result.data,
|
|
6610
7007
|
opts.format,
|
|
6611
7008
|
(d) => Formatter.keyValue([
|
|
@@ -6638,7 +7035,7 @@ function registerListOrdersCommand2(parent, deps) {
|
|
|
6638
7035
|
);
|
|
6639
7036
|
spinner?.stop();
|
|
6640
7037
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6641
|
-
await
|
|
7038
|
+
await render3(result.data, opts.format, (d) => {
|
|
6642
7039
|
const rows = (d.orders ?? []).map((o) => [
|
|
6643
7040
|
String(o.order_no ?? "-"),
|
|
6644
7041
|
String(o.status ?? "-"),
|
|
@@ -6658,10 +7055,10 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
6658
7055
|
const format = resolveFormat(opts.format);
|
|
6659
7056
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6660
7057
|
const body = {
|
|
6661
|
-
order_no:
|
|
6662
|
-
date:
|
|
6663
|
-
passenger:
|
|
6664
|
-
segment_id:
|
|
7058
|
+
order_no: need22(opts.orderNo, "order-no"),
|
|
7059
|
+
date: need22(opts.date, "date"),
|
|
7060
|
+
passenger: need22(opts.passenger, "passenger"),
|
|
7061
|
+
segment_id: need22(opts.segmentId, "segment-id"),
|
|
6665
7062
|
cabin_class: opts.cabinClass
|
|
6666
7063
|
};
|
|
6667
7064
|
const spinner = format === "json" ? null : createSpinner("Searching change options...");
|
|
@@ -6672,7 +7069,7 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
6672
7069
|
);
|
|
6673
7070
|
spinner?.stop();
|
|
6674
7071
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6675
|
-
await
|
|
7072
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6676
7073
|
});
|
|
6677
7074
|
}
|
|
6678
7075
|
|
|
@@ -6687,14 +7084,14 @@ function registerChangeApplyCommand(parent, deps) {
|
|
|
6687
7084
|
const isYes = Boolean(opts.yes);
|
|
6688
7085
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6689
7086
|
const body = {
|
|
6690
|
-
order_no:
|
|
6691
|
-
passenger:
|
|
6692
|
-
segment_id:
|
|
6693
|
-
product_token:
|
|
6694
|
-
contact_name:
|
|
6695
|
-
contact_region:
|
|
6696
|
-
contact_phone:
|
|
6697
|
-
contact_email:
|
|
7087
|
+
order_no: need22(opts.orderNo, "order-no"),
|
|
7088
|
+
passenger: need22(opts.passenger, "passenger"),
|
|
7089
|
+
segment_id: need22(opts.segmentId, "segment-id"),
|
|
7090
|
+
product_token: need22(opts.productToken, "product-token"),
|
|
7091
|
+
contact_name: need22(opts.contactName, "contact-name"),
|
|
7092
|
+
contact_region: need22(opts.contactRegion, "contact-region"),
|
|
7093
|
+
contact_phone: need22(opts.contactPhone, "contact-phone"),
|
|
7094
|
+
contact_email: need22(opts.contactEmail, "contact-email")
|
|
6698
7095
|
};
|
|
6699
7096
|
if (!isYes) {
|
|
6700
7097
|
const ok = await confirm13({
|
|
@@ -6716,7 +7113,7 @@ function registerChangeApplyCommand(parent, deps) {
|
|
|
6716
7113
|
);
|
|
6717
7114
|
spinner?.stop();
|
|
6718
7115
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6719
|
-
await
|
|
7116
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6720
7117
|
});
|
|
6721
7118
|
}
|
|
6722
7119
|
|
|
@@ -6728,7 +7125,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
6728
7125
|
const opts = cmd.optsWithGlobals();
|
|
6729
7126
|
const format = resolveFormat(opts.format);
|
|
6730
7127
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6731
|
-
const changeOrderNo =
|
|
7128
|
+
const changeOrderNo = need22(opts.changeOrderNo, "change-order-no");
|
|
6732
7129
|
const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
|
|
6733
7130
|
const result = await deps.apiClient.get(
|
|
6734
7131
|
`/flight/change/${encodeURIComponent(changeOrderNo)}`,
|
|
@@ -6736,7 +7133,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
6736
7133
|
);
|
|
6737
7134
|
spinner?.stop();
|
|
6738
7135
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6739
|
-
await
|
|
7136
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6740
7137
|
});
|
|
6741
7138
|
}
|
|
6742
7139
|
|
|
@@ -6750,7 +7147,7 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
6750
7147
|
const format = resolveFormat(opts.format);
|
|
6751
7148
|
const isYes = Boolean(opts.yes);
|
|
6752
7149
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6753
|
-
const changeOrderNo =
|
|
7150
|
+
const changeOrderNo = need22(opts.changeOrderNo, "change-order-no");
|
|
6754
7151
|
if (!isYes) {
|
|
6755
7152
|
const ok = await confirm14({ message: `Cancel change request ${changeOrderNo}?`, default: false });
|
|
6756
7153
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
|
|
@@ -6768,7 +7165,7 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
6768
7165
|
);
|
|
6769
7166
|
spinner?.stop();
|
|
6770
7167
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6771
|
-
await
|
|
7168
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6772
7169
|
});
|
|
6773
7170
|
}
|
|
6774
7171
|
|
|
@@ -6785,10 +7182,10 @@ function registerChangePayCommand(parent, deps) {
|
|
|
6785
7182
|
const format = resolveFormat(opts.format);
|
|
6786
7183
|
const isYes = Boolean(opts.yes);
|
|
6787
7184
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6788
|
-
const changeOrderNo =
|
|
6789
|
-
const orderNo =
|
|
7185
|
+
const changeOrderNo = need22(opts.changeOrderNo, "change-order-no");
|
|
7186
|
+
const orderNo = need22(opts.orderNo, "order-no");
|
|
6790
7187
|
const amount = num10(opts.amount, "amount");
|
|
6791
|
-
const currency =
|
|
7188
|
+
const currency = need22(opts.currency, "currency");
|
|
6792
7189
|
const body = {
|
|
6793
7190
|
order_no: orderNo,
|
|
6794
7191
|
amount,
|
|
@@ -6818,7 +7215,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
6818
7215
|
);
|
|
6819
7216
|
spinner?.stop();
|
|
6820
7217
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6821
|
-
await
|
|
7218
|
+
await render3(result.data, opts.format, (d) => {
|
|
6822
7219
|
const challenge = d.challenge ?? null;
|
|
6823
7220
|
if (challenge) {
|
|
6824
7221
|
return [
|
|
@@ -6859,14 +7256,14 @@ function registerRefundApplyCommand(parent, deps) {
|
|
|
6859
7256
|
const isYes = Boolean(opts.yes);
|
|
6860
7257
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6861
7258
|
const body = {
|
|
6862
|
-
order_no:
|
|
6863
|
-
passenger:
|
|
6864
|
-
segment_id:
|
|
7259
|
+
order_no: need22(opts.orderNo, "order-no"),
|
|
7260
|
+
passenger: need22(opts.passenger, "passenger"),
|
|
7261
|
+
segment_id: need22(opts.segmentId, "segment-id"),
|
|
6865
7262
|
reason_type: num10(opts.reasonType, "reason-type"),
|
|
6866
|
-
contact_name:
|
|
6867
|
-
contact_region:
|
|
6868
|
-
contact_phone:
|
|
6869
|
-
contact_email:
|
|
7263
|
+
contact_name: need22(opts.contactName, "contact-name"),
|
|
7264
|
+
contact_region: need22(opts.contactRegion, "contact-region"),
|
|
7265
|
+
contact_phone: need22(opts.contactPhone, "contact-phone"),
|
|
7266
|
+
contact_email: need22(opts.contactEmail, "contact-email")
|
|
6870
7267
|
};
|
|
6871
7268
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
6872
7269
|
if (!isYes) {
|
|
@@ -6889,7 +7286,7 @@ function registerRefundApplyCommand(parent, deps) {
|
|
|
6889
7286
|
);
|
|
6890
7287
|
spinner?.stop();
|
|
6891
7288
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6892
|
-
await
|
|
7289
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6893
7290
|
});
|
|
6894
7291
|
}
|
|
6895
7292
|
|
|
@@ -6901,7 +7298,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6901
7298
|
const opts = cmd.optsWithGlobals();
|
|
6902
7299
|
const format = resolveFormat(opts.format);
|
|
6903
7300
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6904
|
-
const refundOrderNo =
|
|
7301
|
+
const refundOrderNo = need22(opts.refundOrderNo, "refund-order-no");
|
|
6905
7302
|
const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
|
|
6906
7303
|
const result = await deps.apiClient.get(
|
|
6907
7304
|
`/flight/refund/${encodeURIComponent(refundOrderNo)}`,
|
|
@@ -6909,7 +7306,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6909
7306
|
);
|
|
6910
7307
|
spinner?.stop();
|
|
6911
7308
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6912
|
-
await
|
|
7309
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6913
7310
|
});
|
|
6914
7311
|
}
|
|
6915
7312
|
|
|
@@ -6923,8 +7320,8 @@ function registerRefundConfirmCommand(parent, deps) {
|
|
|
6923
7320
|
const format = resolveFormat(opts.format);
|
|
6924
7321
|
const isYes = Boolean(opts.yes);
|
|
6925
7322
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6926
|
-
const refundOrderNo =
|
|
6927
|
-
const confirmFlag =
|
|
7323
|
+
const refundOrderNo = need22(opts.refundOrderNo, "refund-order-no");
|
|
7324
|
+
const confirmFlag = need22(opts.confirm, "confirm");
|
|
6928
7325
|
if (confirmFlag !== "1" && confirmFlag !== "2") {
|
|
6929
7326
|
throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
|
|
6930
7327
|
}
|
|
@@ -6946,7 +7343,7 @@ function registerRefundConfirmCommand(parent, deps) {
|
|
|
6946
7343
|
);
|
|
6947
7344
|
spinner?.stop();
|
|
6948
7345
|
if (!result.success) throw CliError.fromApi(result, { auth: "api-key" });
|
|
6949
|
-
await
|
|
7346
|
+
await render3(result.data, opts.format, (d) => JSON.stringify(d, null, 2));
|
|
6950
7347
|
});
|
|
6951
7348
|
}
|
|
6952
7349
|
|
|
@@ -7079,6 +7476,9 @@ Workflow (typical order):
|
|
|
7079
7476
|
(write; needs --idempotency-key; the fare may change)
|
|
7080
7477
|
trip-status (optional) Status + driver location points of ONE leg of a multi-leg ride
|
|
7081
7478
|
list-orders (standalone) List the developer's previous ride orders
|
|
7479
|
+
callback-* (standalone) Status-event forwarding to your own https endpoint:
|
|
7480
|
+
callback-set/-get (one ride), callback-default-set/-get (fallback for all
|
|
7481
|
+
rides), callback-deliveries / callback-replay (inspect and re-send)
|
|
7082
7482
|
|
|
7083
7483
|
Key notes:
|
|
7084
7484
|
\u2022 Coordinates are NOT geocoded by the backend \u2014 supply --pickup-lat/lng and --dropoff-lat/lng.
|
|
@@ -7108,6 +7508,7 @@ Key notes:
|
|
|
7108
7508
|
registerRideUpdateCommand(rideCmd, deps);
|
|
7109
7509
|
registerRideTripStatusCommand(rideCmd, deps);
|
|
7110
7510
|
registerListOrdersCommand(rideCmd, deps);
|
|
7511
|
+
registerRideCallbackCommands(rideCmd, deps);
|
|
7111
7512
|
const servicesCmd = program.command("services").description("Merchant service discovery");
|
|
7112
7513
|
registerServicesListCommand(servicesCmd, { discoveryClient, program });
|
|
7113
7514
|
registerServiceGetCommand(servicesCmd, { discoveryClient, program });
|
|
@@ -7117,6 +7518,7 @@ Key notes:
|
|
|
7117
7518
|
registerOrdersListCommand(ordersCmd, deps);
|
|
7118
7519
|
registerOrdersGetCommand(ordersCmd, deps);
|
|
7119
7520
|
registerOrdersPayBatchCommand(ordersCmd, deps);
|
|
7521
|
+
registerOrdersGetPaymentGroupCommand(ordersCmd, deps);
|
|
7120
7522
|
const hotelCmd = program.command("hotel-redaug").description(
|
|
7121
7523
|
`Hotel booking (Redaug) \u2014 international hotel search, quote, create-order, pay-order, cancel, and check-out.
|
|
7122
7524
|
|