@agenzo/merchant-cli 0.8.14 → 0.8.16
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 +614 -176
- package/dist/index.js.map +1 -1
- package/package.json +28 -28
package/dist/index.js
CHANGED
|
@@ -1050,7 +1050,7 @@ var bookSchema = {
|
|
|
1050
1050
|
"payment-token-id": {
|
|
1051
1051
|
type: "string",
|
|
1052
1052
|
required: false,
|
|
1053
|
-
description: "
|
|
1053
|
+
description: "DEPRECATED \u2014 use `ride-elife create-order` + `pay-order` for network-token direct charge. A single-step book carrying a network token hits Charge_Service strict order\u2194token binding and is rejected server-side with a retriable=false guidance error. Kept only for backward compatibility; monthly_settlement / EVO / no-credential booking still work via book"
|
|
1054
1054
|
},
|
|
1055
1055
|
member: MEMBER_FLAG_SCHEMA,
|
|
1056
1056
|
"passenger-name": { type: "string", required: true, description: "Passenger full name" },
|
|
@@ -1106,6 +1106,125 @@ var bookSchema = {
|
|
|
1106
1106
|
PARAM_IDEMPOTENCY_KEY_REQUIRED: "Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes."
|
|
1107
1107
|
}
|
|
1108
1108
|
};
|
|
1109
|
+
var rideCreateOrderSchema = {
|
|
1110
|
+
cli: CLI_NAME,
|
|
1111
|
+
noun: NOUN,
|
|
1112
|
+
verb: "create-order",
|
|
1113
|
+
description: "Lock a ride fare without charging (status AWAITING_PAYMENT). Returns the authoritative order_ref to bind as the network token external_transaction_id, then settle with pay-order. No payment credentials here \u2014 funding happens in pay-order",
|
|
1114
|
+
flags: {
|
|
1115
|
+
"quote-id": { type: "string", required: true, description: "Quote id from quote response (vehicle_classes[].price.quote_id)" },
|
|
1116
|
+
"vehicle-class": { type: "string", required: true, description: "Vehicle class: Sedan / SUV / MPV-5 / MPV-7 / Van / Luxury / Train" },
|
|
1117
|
+
"price-amount": { type: "float", required: true, description: "Fare in decimal currency units (NOT cents), from the quote" },
|
|
1118
|
+
"price-currency": { type: "string", required: false, default: "USD", description: "ISO 4217 currency code" },
|
|
1119
|
+
member: MEMBER_FLAG_SCHEMA,
|
|
1120
|
+
"passenger-name": { type: "string", required: true, description: "Passenger full name" },
|
|
1121
|
+
"passenger-phone": { type: "string", required: true, description: "Passenger phone in E.164 format (e.g. +14155551234)" },
|
|
1122
|
+
"passenger-email": { type: "string", required: true, description: "Passenger email (persisted at lock; eLife needs it when pay-order creates the ride)" },
|
|
1123
|
+
"luggage-count": { type: "int", required: false, description: "Number of luggage items" },
|
|
1124
|
+
"special-requests": { type: "string", required: false, description: "Free-text special requests or notes" },
|
|
1125
|
+
"pickup-lat": { type: "float", required: false, description: "Pickup latitude (must match the quote)", constraints: "-90 to 90" },
|
|
1126
|
+
"pickup-lng": { type: "float", required: false, description: "Pickup longitude (must match the quote)", constraints: "-180 to 180" },
|
|
1127
|
+
"pickup-name": { type: "string", required: false, description: "Pickup location name (must match the quote)" },
|
|
1128
|
+
"dropoff-lat": { type: "float", required: false, description: "Dropoff latitude (must match the quote)", constraints: "-90 to 90" },
|
|
1129
|
+
"dropoff-lng": { type: "float", required: false, description: "Dropoff longitude (must match the quote)", constraints: "-180 to 180" },
|
|
1130
|
+
"dropoff-name": { type: "string", required: false, description: "Dropoff location name (must match the quote)" },
|
|
1131
|
+
"pickup-time": { type: "int|string", required: false, description: "Epoch seconds or 'now' (must match the quote)" },
|
|
1132
|
+
"meet-and-greet": { type: "bool", required: false, default: false, description: "Enable meet & greet service" },
|
|
1133
|
+
"meet-and-greet-price": { type: "float", required: false, description: "Meet & greet surcharge from the quote (meet_and_greet.price.amount)" },
|
|
1134
|
+
"welcome-sign": { type: "string", required: false, description: "Welcome sign text (meet & greet)" },
|
|
1135
|
+
"child-seat-count": { type: "int", required: false, description: "Number of child seats needed", constraints: "0 to 5" },
|
|
1136
|
+
"infant-seat-count": { type: "int", required: false, description: "Number of infant seats needed", constraints: "0 to 5" },
|
|
1137
|
+
"toddler-seat-count": { type: "int", required: false, description: "Number of toddler seats needed", constraints: "0 to 5" },
|
|
1138
|
+
"arrival-flight-no": { type: "string", required: false, description: "Arrival flight number (airport pickup)" },
|
|
1139
|
+
"arrival-airline": { type: "string", required: false, description: "Arrival airline name" },
|
|
1140
|
+
"departure-flight-no": { type: "string", required: false, description: "Departure flight number (airport dropoff)" },
|
|
1141
|
+
"departure-airline": { type: "string", required: false, description: "Departure airline name" },
|
|
1142
|
+
"idempotency-key": {
|
|
1143
|
+
type: "string",
|
|
1144
|
+
required: true,
|
|
1145
|
+
description: "Unique key (1-128 chars [A-Za-z0-9_-]) forwarded verbatim as the Idempotency-Key header; never auto-generated"
|
|
1146
|
+
}
|
|
1147
|
+
},
|
|
1148
|
+
response: {
|
|
1149
|
+
order_id: { type: "string", description: "Authoritative order_ref (rio_\u2026, = order document _id). Bind it as the network token external_transaction_id and pass it to pay-order" },
|
|
1150
|
+
status: { type: "string", description: "AWAITING_PAYMENT after a successful lock" },
|
|
1151
|
+
payment_status: { type: "string", description: "PENDING after lock (funds untouched)" },
|
|
1152
|
+
is_scheduled: { type: "bool", description: "true = scheduled/airport ride; false = realtime" },
|
|
1153
|
+
order_type: { type: "string", description: "'realtime' or 'airport'" },
|
|
1154
|
+
price: { type: "object", description: "{ amount, currency, quote_id } \u2014 the authoritative amount + currency the token must match" }
|
|
1155
|
+
},
|
|
1156
|
+
example: {
|
|
1157
|
+
command: 'agenzo-merchant-cli ride-elife create-order --quote-id qte_01HZXD --vehicle-class Sedan --price-amount 42.50 --passenger-name "Alice" --passenger-phone +14155551234 --passenger-email alice@example.com --idempotency-key ride-create-123',
|
|
1158
|
+
output_summary: "Returns order_id (the order_ref). Bind it as the token external_transaction_id, mint the token for price.amount, then settle with `ride-elife pay-order --order-id <order_ref>`."
|
|
1159
|
+
},
|
|
1160
|
+
error_recovery: {
|
|
1161
|
+
QUOTE_EXPIRED: "Re-invoke 'quote' for a fresh quote_id, then retry 'create-order' with the SAME --idempotency-key.",
|
|
1162
|
+
VEHICLE_CLASS_MISMATCH: "The vehicle-class does not match the quote. Re-quote and pass the exact vehicle_class back.",
|
|
1163
|
+
PRICE_MISMATCH: "The submitted total does not equal the authoritative fare. Re-quote and pass price-amount from the fresh quote.",
|
|
1164
|
+
IDEMPOTENCY_CONFLICT: "Same --idempotency-key reused with different order params. Use a fresh idempotency-key.",
|
|
1165
|
+
PARAM_IDEMPOTENCY_KEY_REQUIRED: "Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes."
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
var ridePayOrderSchema = {
|
|
1169
|
+
cli: CLI_NAME,
|
|
1170
|
+
noun: NOUN,
|
|
1171
|
+
verb: "pay-order",
|
|
1172
|
+
description: "Settle a locked ride order created by create-order. Charging happens in this step (create-order only locks the fare and moves no money). Provide EXACTLY ONE of --payment-token-id (network-token direct charge \u2014 the main path; charge(order_id=order_ref) triggers strict order\u2194token binding) or --payment-method-id (EVO bound-card fallback); both missing or both present is rejected as PARAM_INVALID before any request. The amount/currency are NOT accepted here \u2014 the platform settles at the order-locked authoritative amount and the token minted amount. On success the order becomes status=PAID / payment_status=SETTLED",
|
|
1173
|
+
flags: {
|
|
1174
|
+
"order-id": {
|
|
1175
|
+
type: "string",
|
|
1176
|
+
required: true,
|
|
1177
|
+
description: "The authoritative order_ref (rio_\u2026) from create-order.response.order_id to settle"
|
|
1178
|
+
},
|
|
1179
|
+
"payment-token-id": {
|
|
1180
|
+
type: "string",
|
|
1181
|
+
required: "conditional",
|
|
1182
|
+
description: "Network-token id (UnionPay/Visa) for the direct-charge main path. Bind order_ref as its external_transaction_id first. Exactly one of --payment-token-id / --payment-method-id is required (mutually exclusive)"
|
|
1183
|
+
},
|
|
1184
|
+
"payment-method-id": {
|
|
1185
|
+
type: "string",
|
|
1186
|
+
required: "conditional",
|
|
1187
|
+
description: "Bound-card id to charge via EVO preauth+capture (fallback path). Exactly one of --payment-token-id / --payment-method-id is required (mutually exclusive)"
|
|
1188
|
+
},
|
|
1189
|
+
"authorized-merchant-trans-id": {
|
|
1190
|
+
type: "string",
|
|
1191
|
+
required: false,
|
|
1192
|
+
description: "Resume a 3DS challenge: merchant trans id of an already-authorised EVO preauth returned by a prior AUTHENTICATION_REQUIRED response"
|
|
1193
|
+
},
|
|
1194
|
+
"evo-explicit": {
|
|
1195
|
+
type: "bool",
|
|
1196
|
+
required: false,
|
|
1197
|
+
default: false,
|
|
1198
|
+
description: "[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call ride via the EVO bound-card fallback rail. Set true ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side. Ignored for monthly_settlement and on the payment-token-id direct-charge path."
|
|
1199
|
+
},
|
|
1200
|
+
"idempotency-key": {
|
|
1201
|
+
type: "string",
|
|
1202
|
+
required: true,
|
|
1203
|
+
description: "Unique key (1-128 chars [A-Za-z0-9_-]) forwarded verbatim as the Idempotency-Key header; never auto-generated"
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
response: {
|
|
1207
|
+
order_id: { type: "string", description: "Authoritative order_ref (rio_\u2026, = order document _id) that was settled" },
|
|
1208
|
+
ride_id: { type: "string|int", description: "eLife upstream ride id, assigned once create_ride succeeds \u2014 use for `ride-elife get`" },
|
|
1209
|
+
status: { type: "string", description: "PAID after a successful settlement" },
|
|
1210
|
+
payment_status: { type: "string", description: "SETTLED after a successful network-token direct charge" },
|
|
1211
|
+
payment_channel: { type: "string", description: "'upi_agent' for the network-token direct-charge path" },
|
|
1212
|
+
price: { type: "object", description: "{ amount, currency, quote_id } \u2014 the authoritative amount the token matched" }
|
|
1213
|
+
},
|
|
1214
|
+
example: {
|
|
1215
|
+
command: "agenzo-merchant-cli ride-elife pay-order --order-id rio_01HZXD --payment-token-id ntk_01J2ABC --idempotency-key ride-pay-123",
|
|
1216
|
+
output_summary: "Settles the order via network-token direct charge and creates the ride. Returns order_id + ride_id; the order becomes status=PAID / payment_status=SETTLED. Poll `ride-elife get --order-id <ride_id>` for driver dispatch."
|
|
1217
|
+
},
|
|
1218
|
+
error_recovery: {
|
|
1219
|
+
PARAM_INVALID: "Provide EXACTLY ONE of --payment-token-id or --payment-method-id (both missing or both present is invalid), and a non-empty --order-id.",
|
|
1220
|
+
TOKEN_ORDER_MISMATCH: "The token's external_transaction_id is not this order_ref. Mint a token bound to THIS order_ref (external_transaction_id = order_ref) and retry; no funds moved.",
|
|
1221
|
+
RESOURCE_STATE_INVALID: "The order is not in AWAITING_PAYMENT (it may already be PAID or CANCELLED). Check status via get; do NOT retry pay-order.",
|
|
1222
|
+
RIDE_NOT_FOUND: "No order for this --order-id. Verify it is the order_ref returned by create-order. Do NOT retry.",
|
|
1223
|
+
QUOTE_EXPIRED: "The quote expired before settlement. Re-quote; if the authoritative price is unchanged retry pay-order with the SAME order_ref + SAME token and a NEW --idempotency-key, otherwise create a new order.",
|
|
1224
|
+
BOOKING_FAILED: "eLife create_ride failed after a successful charge; the charge was reversed and the order stays AWAITING_PAYMENT. Retry with a NEW --idempotency-key.",
|
|
1225
|
+
PARAM_IDEMPOTENCY_KEY_REQUIRED: "Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes."
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1109
1228
|
var rideGetSchema = {
|
|
1110
1229
|
cli: CLI_NAME,
|
|
1111
1230
|
noun: NOUN,
|
|
@@ -1519,9 +1638,30 @@ var hotelPayOrderSchema = {
|
|
|
1519
1638
|
cli: CLI_NAME,
|
|
1520
1639
|
noun: HOTEL_NOUN,
|
|
1521
1640
|
verb: "pay-order",
|
|
1522
|
-
description:
|
|
1641
|
+
description: "Settle an existing AWAITING_PAYMENT order created by create-order. Charging happens in this step \u2014 platform create-order only locks inventory/price and moves no money (lock-then-pay). Optional payment credentials (--payment-method-id / --payment-token-id / --authorized-merchant-trans-id) are forwarded to the pay body; omit them to let the platform settle by billing_mode (monthly_settlement deducts credit; pay_per_call selects the developer default card / EVO preauth). Token wins over method id server-side. On EVO cardholder authentication the response is AUTHENTICATION_REQUIRED with a three_ds_url + merchant_trans_id; resume by re-calling pay-order with --authorized-merchant-trans-id. On success the order becomes PAID. Supports --watch to poll on PAYMENT_NOT_COMPLETED until PAID",
|
|
1523
1642
|
flags: {
|
|
1524
|
-
"order-id": { type: "string", required: true, description: "Order to settle (create-order.response.order_id).
|
|
1643
|
+
"order-id": { type: "string", required: true, description: "Order to settle (create-order.response.order_id)." },
|
|
1644
|
+
"payment-method-id": {
|
|
1645
|
+
type: "string",
|
|
1646
|
+
required: false,
|
|
1647
|
+
description: "Optional bound-card id to charge (pay_per_call / EVO preauth). Ignored for monthly_settlement and when payment-token-id is set."
|
|
1648
|
+
},
|
|
1649
|
+
"payment-token-id": {
|
|
1650
|
+
type: "string",
|
|
1651
|
+
required: false,
|
|
1652
|
+
description: "Optional network-token id (UnionPay/Visa). When set the platform settles via network-token direct charge instead of EVO preauth+capture. Wins over payment-method-id."
|
|
1653
|
+
},
|
|
1654
|
+
"authorized-merchant-trans-id": {
|
|
1655
|
+
type: "string",
|
|
1656
|
+
required: false,
|
|
1657
|
+
description: "Resume a 3DS challenge: merchant trans id of an already-authorised preauth returned by a prior AUTHENTICATION_REQUIRED response. Reuses that authorization instead of creating a new one (pay_per_call only)."
|
|
1658
|
+
},
|
|
1659
|
+
"evo-explicit": {
|
|
1660
|
+
type: "bool",
|
|
1661
|
+
required: false,
|
|
1662
|
+
default: false,
|
|
1663
|
+
description: "[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call order via the EVO bound-card fallback rail. Set true ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side. Ignored for monthly_settlement and on the payment-token-id direct-charge path."
|
|
1664
|
+
},
|
|
1525
1665
|
"idempotency-key": {
|
|
1526
1666
|
type: "string",
|
|
1527
1667
|
required: true,
|
|
@@ -2201,6 +2341,7 @@ var flightPayOrderSchema = flightSchema(
|
|
|
2201
2341
|
"payment-method-id": { type: "string", required: false, description: "Optional bound-card id to charge (pay_per_call only; omit to use the default card)." },
|
|
2202
2342
|
"payment-token-id": { type: "string", required: false, description: "Optional network-token id; settles via direct charge instead of EVO preauth." },
|
|
2203
2343
|
"authorized-merchant-trans-id": { type: "string", required: false, description: "Resume a 3DS challenge with an already-authorised preauth trans id." },
|
|
2344
|
+
"evo-explicit": { type: "bool", required: false, default: false, description: "[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call order via the EVO bound-card fallback rail. Set true ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side." },
|
|
2204
2345
|
"idempotency-key": { type: "string", required: true, description: "Forwarded verbatim as the Idempotency-Key header." }
|
|
2205
2346
|
},
|
|
2206
2347
|
{ order_no: { type: "string", description: "Our order reference." }, status: { type: "string", description: "PAID on success; AUTHENTICATION_REQUIRED when the card needs 3DS." } },
|
|
@@ -2546,7 +2687,7 @@ function registerBookCommand(parent, deps) {
|
|
|
2546
2687
|
"Bound payment method id to charge (pay_per_call mode only)"
|
|
2547
2688
|
).option(
|
|
2548
2689
|
"--payment-token-id <id>",
|
|
2549
|
-
"
|
|
2690
|
+
"DEPRECATED \u2014 use `ride-elife create-order` + `pay-order` for network-token direct charge. A single-step book carrying a network token hits Charge_Service strict order\u2194token binding and is rejected server-side with a retriable=false guidance error. Kept only for backward compatibility; monthly_settlement / EVO / no-credential booking still work via book."
|
|
2550
2691
|
).option(
|
|
2551
2692
|
"--authorized-merchant-trans-id <id>",
|
|
2552
2693
|
"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)."
|
|
@@ -2662,13 +2803,292 @@ function registerBookCommand(parent, deps) {
|
|
|
2662
2803
|
});
|
|
2663
2804
|
}
|
|
2664
2805
|
|
|
2665
|
-
// src/ride-elife/
|
|
2806
|
+
// src/ride-elife/create-order.ts
|
|
2807
|
+
import { confirm as confirm2 } from "@inquirer/prompts";
|
|
2666
2808
|
function need3(value, flag) {
|
|
2667
2809
|
if (value === void 0) {
|
|
2668
2810
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2669
2811
|
}
|
|
2670
2812
|
return value;
|
|
2671
2813
|
}
|
|
2814
|
+
function num3(value, flag) {
|
|
2815
|
+
const n = Number(need3(value, flag));
|
|
2816
|
+
if (!Number.isFinite(n)) {
|
|
2817
|
+
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
2818
|
+
}
|
|
2819
|
+
return n;
|
|
2820
|
+
}
|
|
2821
|
+
function phone2(value, flag) {
|
|
2822
|
+
const raw = need3(value, flag);
|
|
2823
|
+
const cleaned = raw.replace(/[\s-]/g, "");
|
|
2824
|
+
if (!/^\+[1-9]\d{7,14}$/.test(cleaned)) {
|
|
2825
|
+
throw new CliError(
|
|
2826
|
+
"PARAM_INVALID",
|
|
2827
|
+
`--${flag} must be a valid international phone number, e.g. +14155552671.`
|
|
2828
|
+
);
|
|
2829
|
+
}
|
|
2830
|
+
return cleaned;
|
|
2831
|
+
}
|
|
2832
|
+
function seatCount2(value, flag) {
|
|
2833
|
+
const n = num3(value, flag);
|
|
2834
|
+
if (!Number.isInteger(n) || n < 0 || n > 5) {
|
|
2835
|
+
throw new CliError("PARAM_INVALID", `--${flag} must be an integer between 0 and 5.`);
|
|
2836
|
+
}
|
|
2837
|
+
return n;
|
|
2838
|
+
}
|
|
2839
|
+
function formatCreateOrder(data) {
|
|
2840
|
+
const orderRef = String(data.order_ref ?? data.order_id ?? "-");
|
|
2841
|
+
const lines = [
|
|
2842
|
+
["Order ref", orderRef],
|
|
2843
|
+
["Status", String(data.status ?? "-")],
|
|
2844
|
+
["Payment status", String(data.payment_status ?? "-")]
|
|
2845
|
+
];
|
|
2846
|
+
if (data.price) {
|
|
2847
|
+
lines.push(["Amount", `${data.price.amount} ${data.price.currency}`]);
|
|
2848
|
+
if (data.price.quote_id) lines.push(["Quote ID", String(data.price.quote_id)]);
|
|
2849
|
+
}
|
|
2850
|
+
if (data.is_scheduled !== void 0) lines.push(["Scheduled", String(data.is_scheduled)]);
|
|
2851
|
+
if (data.order_type) lines.push(["Order type", String(data.order_type)]);
|
|
2852
|
+
return [
|
|
2853
|
+
Formatter.keyValue(lines),
|
|
2854
|
+
Formatter.status(
|
|
2855
|
+
"info",
|
|
2856
|
+
`Fare locked (AWAITING_PAYMENT) \u2014 bind ${orderRef} as the network token external_transaction_id, then settle with 'ride-elife pay-order --order-id ${orderRef}'. No funds moved yet.`
|
|
2857
|
+
)
|
|
2858
|
+
].join("\n\n");
|
|
2859
|
+
}
|
|
2860
|
+
function registerRideCreateOrderCommand(parent, deps) {
|
|
2861
|
+
const cmd = parent.command("create-order").description("Lock a ride fare without charging (await payment); returns the order_ref to pay").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--quote-id <id>", "Quote id from `ride-elife quote`").option("--vehicle-class <class>", "Chosen vehicle class").option("--price-amount <amount>", "Fare in decimal currency units (not cents)").option("--price-currency <currency>", "Currency code (default USD)").option("--passenger-name <name>", "Passenger full name").option("--passenger-phone <phone>", "Passenger phone").option("--passenger-email <email>", "Passenger email").option("--luggage-count <n>", "Luggage count").option("--special-requests <text>", "Free-text special requests").option("--pickup-lat <lat>", "Pickup latitude").option("--pickup-lng <lng>", "Pickup longitude").option("--pickup-name <name>", "Pickup location name").option("--dropoff-lat <lat>", "Dropoff latitude").option("--dropoff-lng <lng>", "Dropoff longitude").option("--dropoff-name <name>", "Dropoff location name").option("--pickup-time <time>", 'Pickup time: epoch seconds, or "now"').option("--meet-and-greet", "Enable meet & greet service").option("--meet-and-greet-price <amount>", "Meet & greet surcharge").option("--welcome-sign <text>", "Welcome sign text").option("--child-seat-count <n>", "Number of child seats needed (0-5)").option("--infant-seat-count <n>", "Number of infant seats needed (0-5)").option("--toddler-seat-count <n>", "Number of toddler seats needed (0-5)").option("--arrival-flight-no <no>", "Arrival flight number").option("--arrival-airline <airline>", "Arrival airline").option("--departure-flight-no <no>", "Departure flight number").option("--departure-airline <airline>", "Departure airline").option("--member <id>", MEMBER_OPTION_DESCRIPTION).option(
|
|
2862
|
+
"--idempotency-key <key>",
|
|
2863
|
+
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
2864
|
+
);
|
|
2865
|
+
attachSchemaHelp(cmd, rideCreateOrderSchema);
|
|
2866
|
+
cmd.action(async () => {
|
|
2867
|
+
const opts = cmd.optsWithGlobals();
|
|
2868
|
+
const format = resolveFormat(opts.format);
|
|
2869
|
+
const isYes = Boolean(opts.yes);
|
|
2870
|
+
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
2871
|
+
message: "API Key:",
|
|
2872
|
+
type: "password"
|
|
2873
|
+
});
|
|
2874
|
+
const quoteId = need3(opts.quoteId, "quote-id");
|
|
2875
|
+
const priceAmount = num3(opts.priceAmount, "price-amount");
|
|
2876
|
+
const priceCurrency = opts.priceCurrency ?? "USD";
|
|
2877
|
+
const body = {
|
|
2878
|
+
quote_id: quoteId,
|
|
2879
|
+
vehicle_class: need3(opts.vehicleClass, "vehicle-class"),
|
|
2880
|
+
price_amount: priceAmount,
|
|
2881
|
+
price_currency: priceCurrency,
|
|
2882
|
+
passenger_name: need3(opts.passengerName, "passenger-name"),
|
|
2883
|
+
passenger_phone: phone2(opts.passengerPhone, "passenger-phone"),
|
|
2884
|
+
passenger_email: need3(opts.passengerEmail, "passenger-email")
|
|
2885
|
+
};
|
|
2886
|
+
const member = memberIdOf(opts);
|
|
2887
|
+
if (member !== void 0) body.member_id = member;
|
|
2888
|
+
if (opts.luggageCount !== void 0) {
|
|
2889
|
+
body.luggage_count = num3(opts.luggageCount, "luggage-count");
|
|
2890
|
+
}
|
|
2891
|
+
if (opts.specialRequests) body.special_requests = opts.specialRequests;
|
|
2892
|
+
if (opts.pickupLat || opts.pickupLng || opts.pickupName) {
|
|
2893
|
+
body.pickup = {
|
|
2894
|
+
lat: num3(opts.pickupLat, "pickup-lat"),
|
|
2895
|
+
lng: num3(opts.pickupLng, "pickup-lng"),
|
|
2896
|
+
name: need3(opts.pickupName, "pickup-name")
|
|
2897
|
+
};
|
|
2898
|
+
}
|
|
2899
|
+
if (opts.dropoffLat || opts.dropoffLng || opts.dropoffName) {
|
|
2900
|
+
body.dropoff = {
|
|
2901
|
+
lat: num3(opts.dropoffLat, "dropoff-lat"),
|
|
2902
|
+
lng: num3(opts.dropoffLng, "dropoff-lng"),
|
|
2903
|
+
name: need3(opts.dropoffName, "dropoff-name")
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
if (opts.pickupTime) {
|
|
2907
|
+
body.pickup_time = opts.pickupTime === "now" ? "now" : num3(opts.pickupTime, "pickup-time");
|
|
2908
|
+
}
|
|
2909
|
+
if (opts.meetAndGreet) body.meet_and_greet = true;
|
|
2910
|
+
if (opts.meetAndGreetPrice !== void 0) {
|
|
2911
|
+
body.meet_and_greet_price = num3(opts.meetAndGreetPrice, "meet-and-greet-price");
|
|
2912
|
+
}
|
|
2913
|
+
if (opts.welcomeSign) body.welcome_sign = opts.welcomeSign;
|
|
2914
|
+
if (opts.childSeatCount !== void 0) {
|
|
2915
|
+
body.child_seat_count = seatCount2(opts.childSeatCount, "child-seat-count");
|
|
2916
|
+
}
|
|
2917
|
+
if (opts.infantSeatCount !== void 0) {
|
|
2918
|
+
body.infant_seat_count = seatCount2(opts.infantSeatCount, "infant-seat-count");
|
|
2919
|
+
}
|
|
2920
|
+
if (opts.toddlerSeatCount !== void 0) {
|
|
2921
|
+
body.toddler_seat_count = seatCount2(opts.toddlerSeatCount, "toddler-seat-count");
|
|
2922
|
+
}
|
|
2923
|
+
if (opts.arrivalFlightNo || opts.arrivalAirline) {
|
|
2924
|
+
body.arrival_flight = {
|
|
2925
|
+
flight_no: opts.arrivalFlightNo,
|
|
2926
|
+
airline: opts.arrivalAirline
|
|
2927
|
+
};
|
|
2928
|
+
}
|
|
2929
|
+
if (opts.departureFlightNo || opts.departureAirline) {
|
|
2930
|
+
body.departure_flight = {
|
|
2931
|
+
flight_no: opts.departureFlightNo,
|
|
2932
|
+
airline: opts.departureAirline
|
|
2933
|
+
};
|
|
2934
|
+
}
|
|
2935
|
+
if (!isYes) {
|
|
2936
|
+
const confirmed = await confirm2({
|
|
2937
|
+
message: `Lock this ride fare for ${priceAmount} ${priceCurrency}? This reserves the order (AWAITING_PAYMENT) but does NOT charge yet.`,
|
|
2938
|
+
default: false
|
|
2939
|
+
});
|
|
2940
|
+
if (!confirmed) {
|
|
2941
|
+
throw new CliError("CLIENT_ABORTED", "Order creation aborted by user.");
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
2945
|
+
yes: isYes,
|
|
2946
|
+
commandPath: "ride-elife create-order"
|
|
2947
|
+
});
|
|
2948
|
+
const spinner = format === "json" ? null : createSpinner("Locking ride fare...");
|
|
2949
|
+
const result = await deps.apiClient.post(
|
|
2950
|
+
"/ride/create-order",
|
|
2951
|
+
{ type: "api-key", key: apiKey },
|
|
2952
|
+
body,
|
|
2953
|
+
{ "Idempotency-Key": idempotencyKey }
|
|
2954
|
+
);
|
|
2955
|
+
spinner?.stop();
|
|
2956
|
+
if (!result.success) {
|
|
2957
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
2958
|
+
}
|
|
2959
|
+
const data = result.data;
|
|
2960
|
+
const configManager = new ConfigManager();
|
|
2961
|
+
const commandResult = {
|
|
2962
|
+
data,
|
|
2963
|
+
text: () => formatCreateOrder(data)
|
|
2964
|
+
};
|
|
2965
|
+
await renderWithContext(commandResult, { format }, configManager);
|
|
2966
|
+
});
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
// src/ride-elife/pay-order.ts
|
|
2970
|
+
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
2971
|
+
function need4(value, flag) {
|
|
2972
|
+
if (value === void 0) {
|
|
2973
|
+
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2974
|
+
}
|
|
2975
|
+
return value;
|
|
2976
|
+
}
|
|
2977
|
+
function assertExactlyOneCredential(paymentTokenId, paymentMethodId) {
|
|
2978
|
+
const hasToken = paymentTokenId !== void 0;
|
|
2979
|
+
const hasMethod = paymentMethodId !== void 0;
|
|
2980
|
+
if (!hasToken && !hasMethod) {
|
|
2981
|
+
throw new CliError(
|
|
2982
|
+
"PARAM_INVALID",
|
|
2983
|
+
"Invalid payment credential options: provide exactly one of --payment-token-id (network-token direct charge) or --payment-method-id (EVO bound card). Neither was given."
|
|
2984
|
+
);
|
|
2985
|
+
}
|
|
2986
|
+
if (hasToken && hasMethod) {
|
|
2987
|
+
throw new CliError(
|
|
2988
|
+
"PARAM_INVALID",
|
|
2989
|
+
"Invalid payment credential options: --payment-token-id and --payment-method-id are mutually exclusive \u2014 provide exactly one, not both."
|
|
2990
|
+
);
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
function formatPayOrder(data) {
|
|
2994
|
+
const orderRef = String(data.order_ref ?? data.order_id ?? "-");
|
|
2995
|
+
const lines = [
|
|
2996
|
+
["Order ref", orderRef],
|
|
2997
|
+
["Status", String(data.status ?? "-")],
|
|
2998
|
+
["Payment status", String(data.payment_status ?? "-")]
|
|
2999
|
+
];
|
|
3000
|
+
if (data.ride_id !== void 0) lines.push(["Ride ID", String(data.ride_id)]);
|
|
3001
|
+
if (data.payment_channel) lines.push(["Payment channel", String(data.payment_channel)]);
|
|
3002
|
+
if (data.price) {
|
|
3003
|
+
lines.push(["Amount", `${data.price.amount} ${data.price.currency}`]);
|
|
3004
|
+
if (data.price.quote_id) lines.push(["Quote ID", String(data.price.quote_id)]);
|
|
3005
|
+
}
|
|
3006
|
+
return [
|
|
3007
|
+
Formatter.keyValue(lines),
|
|
3008
|
+
Formatter.status(
|
|
3009
|
+
"success",
|
|
3010
|
+
`Order ${orderRef} settled \u2014 ${data.status ?? "PAID"} / ${data.payment_status ?? "SETTLED"}.`
|
|
3011
|
+
)
|
|
3012
|
+
].join("\n\n");
|
|
3013
|
+
}
|
|
3014
|
+
function registerRidePayOrderCommand(parent, deps) {
|
|
3015
|
+
const cmd = parent.command("pay-order").description("Settle a locked ride order by --order-id (charges the card, creates the ride)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "The order_ref (rio_\u2026) from create-order to settle").option(
|
|
3016
|
+
"--payment-token-id <id>",
|
|
3017
|
+
"Network-token id (unionpay/visa direct-charge path). Exactly one of --payment-token-id / --payment-method-id is required."
|
|
3018
|
+
).option(
|
|
3019
|
+
"--payment-method-id <id>",
|
|
3020
|
+
"Bound-card id to charge via EVO preauth+capture (fallback path). Exactly one of --payment-token-id / --payment-method-id is required."
|
|
3021
|
+
).option(
|
|
3022
|
+
"--authorized-merchant-trans-id <id>",
|
|
3023
|
+
"Resume a 3DS challenge: merchant trans id of an already-authorised preauth"
|
|
3024
|
+
).option(
|
|
3025
|
+
"--evo-explicit",
|
|
3026
|
+
"[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call ride via the EVO bound-card fallback rail. Set ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side."
|
|
3027
|
+
).option(
|
|
3028
|
+
"--idempotency-key <key>",
|
|
3029
|
+
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
3030
|
+
);
|
|
3031
|
+
attachSchemaHelp(cmd, ridePayOrderSchema);
|
|
3032
|
+
cmd.action(async () => {
|
|
3033
|
+
const opts = cmd.optsWithGlobals();
|
|
3034
|
+
const format = resolveFormat(opts.format);
|
|
3035
|
+
const isYes = Boolean(opts.yes);
|
|
3036
|
+
const orderId = need4(opts.orderId, "order-id");
|
|
3037
|
+
const paymentTokenId = opts.paymentTokenId;
|
|
3038
|
+
const paymentMethodId = opts.paymentMethodId;
|
|
3039
|
+
assertExactlyOneCredential(paymentTokenId, paymentMethodId);
|
|
3040
|
+
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
3041
|
+
message: "API Key:",
|
|
3042
|
+
type: "password"
|
|
3043
|
+
});
|
|
3044
|
+
const body = { order_id: orderId };
|
|
3045
|
+
if (paymentTokenId !== void 0) body.payment_token_id = paymentTokenId;
|
|
3046
|
+
if (paymentMethodId !== void 0) body.payment_method_id = paymentMethodId;
|
|
3047
|
+
if (opts.authorizedMerchantTransId !== void 0) {
|
|
3048
|
+
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
3049
|
+
}
|
|
3050
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
3051
|
+
if (!isYes) {
|
|
3052
|
+
const confirmed = await confirm3({
|
|
3053
|
+
message: `Settle ride order ${orderId}? This charges the card and creates the ride (AWAITING_PAYMENT \u2192 PAID).`,
|
|
3054
|
+
default: false
|
|
3055
|
+
});
|
|
3056
|
+
if (!confirmed) {
|
|
3057
|
+
throw new CliError("CLIENT_ABORTED", "Payment aborted by user.");
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
3061
|
+
yes: isYes,
|
|
3062
|
+
commandPath: "ride-elife pay-order"
|
|
3063
|
+
});
|
|
3064
|
+
const spinner = format === "json" ? null : createSpinner("Settling ride order...");
|
|
3065
|
+
const result = await deps.apiClient.post(
|
|
3066
|
+
"/ride/pay",
|
|
3067
|
+
{ type: "api-key", key: apiKey },
|
|
3068
|
+
body,
|
|
3069
|
+
{ "Idempotency-Key": idempotencyKey }
|
|
3070
|
+
);
|
|
3071
|
+
spinner?.stop();
|
|
3072
|
+
if (!result.success) {
|
|
3073
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
3074
|
+
}
|
|
3075
|
+
const data = result.data;
|
|
3076
|
+
const configManager = new ConfigManager();
|
|
3077
|
+
const commandResult = {
|
|
3078
|
+
data,
|
|
3079
|
+
text: () => formatPayOrder(data)
|
|
3080
|
+
};
|
|
3081
|
+
await renderWithContext(commandResult, { format }, configManager);
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
// src/ride-elife/get.ts
|
|
3086
|
+
function need5(value, flag) {
|
|
3087
|
+
if (value === void 0) {
|
|
3088
|
+
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3089
|
+
}
|
|
3090
|
+
return value;
|
|
3091
|
+
}
|
|
2672
3092
|
function formatGetOrder(data) {
|
|
2673
3093
|
const lines = [
|
|
2674
3094
|
["Ride ID", String(data.ride_id ?? "-")],
|
|
@@ -2695,8 +3115,8 @@ function formatGetOrder(data) {
|
|
|
2695
3115
|
}
|
|
2696
3116
|
if (data.driver) {
|
|
2697
3117
|
const driver = data.driver;
|
|
2698
|
-
const
|
|
2699
|
-
lines.push(["Driver", `${driver.name ?? "-"}${
|
|
3118
|
+
const phone3 = driver.phone_number ? ` (${driver.phone_number})` : "";
|
|
3119
|
+
lines.push(["Driver", `${driver.name ?? "-"}${phone3}`]);
|
|
2700
3120
|
}
|
|
2701
3121
|
if (data.vehicle) {
|
|
2702
3122
|
const v = data.vehicle;
|
|
@@ -2723,7 +3143,7 @@ function registerRideGetCommand(parent, deps) {
|
|
|
2723
3143
|
message: "API Key:",
|
|
2724
3144
|
type: "password"
|
|
2725
3145
|
});
|
|
2726
|
-
const orderId =
|
|
3146
|
+
const orderId = need5(opts.orderId, "order-id");
|
|
2727
3147
|
if (opts.watch) {
|
|
2728
3148
|
await watchRideStatus(deps.apiClient, apiKey, orderId, {
|
|
2729
3149
|
intervalSeconds: resolveSeconds(
|
|
@@ -2757,8 +3177,8 @@ function registerRideGetCommand(parent, deps) {
|
|
|
2757
3177
|
}
|
|
2758
3178
|
|
|
2759
3179
|
// src/ride-elife/cancel.ts
|
|
2760
|
-
import { confirm as
|
|
2761
|
-
function
|
|
3180
|
+
import { confirm as confirm4 } from "@inquirer/prompts";
|
|
3181
|
+
function need6(value, flag) {
|
|
2762
3182
|
if (value === void 0) {
|
|
2763
3183
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2764
3184
|
}
|
|
@@ -2793,9 +3213,9 @@ function registerCancelCommand(parent, deps) {
|
|
|
2793
3213
|
message: "API Key:",
|
|
2794
3214
|
type: "password"
|
|
2795
3215
|
});
|
|
2796
|
-
const orderId =
|
|
3216
|
+
const orderId = need6(opts.orderId, "order-id");
|
|
2797
3217
|
if (!isYes) {
|
|
2798
|
-
const confirmed = await
|
|
3218
|
+
const confirmed = await confirm4({
|
|
2799
3219
|
message: `Cancel ride ${orderId}? This may incur a fee.`,
|
|
2800
3220
|
default: false
|
|
2801
3221
|
});
|
|
@@ -2829,14 +3249,14 @@ function registerCancelCommand(parent, deps) {
|
|
|
2829
3249
|
}
|
|
2830
3250
|
|
|
2831
3251
|
// src/ride-elife/update.ts
|
|
2832
|
-
import { confirm as
|
|
2833
|
-
function
|
|
3252
|
+
import { confirm as confirm5 } from "@inquirer/prompts";
|
|
3253
|
+
function need7(value, flag) {
|
|
2834
3254
|
if (value === void 0) {
|
|
2835
3255
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2836
3256
|
}
|
|
2837
3257
|
return value;
|
|
2838
3258
|
}
|
|
2839
|
-
function
|
|
3259
|
+
function num4(value, flag) {
|
|
2840
3260
|
if (value === void 0) return void 0;
|
|
2841
3261
|
const parsed = Number(value);
|
|
2842
3262
|
if (!Number.isFinite(parsed)) {
|
|
@@ -2845,7 +3265,7 @@ function num3(value, flag) {
|
|
|
2845
3265
|
return parsed;
|
|
2846
3266
|
}
|
|
2847
3267
|
function int(value, flag) {
|
|
2848
|
-
const parsed =
|
|
3268
|
+
const parsed = num4(value, flag);
|
|
2849
3269
|
if (parsed === void 0) return void 0;
|
|
2850
3270
|
if (!Number.isInteger(parsed)) {
|
|
2851
3271
|
throw new CliError("PARAM_INVALID", `--${flag} must be an integer.`);
|
|
@@ -2870,8 +3290,8 @@ function location(lat, lng, name, side) {
|
|
|
2870
3290
|
);
|
|
2871
3291
|
}
|
|
2872
3292
|
return {
|
|
2873
|
-
lat:
|
|
2874
|
-
lng:
|
|
3293
|
+
lat: num4(lat, `${side}-lat`),
|
|
3294
|
+
lng: num4(lng, `${side}-lng`),
|
|
2875
3295
|
name
|
|
2876
3296
|
};
|
|
2877
3297
|
}
|
|
@@ -2897,7 +3317,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2897
3317
|
message: "API Key:",
|
|
2898
3318
|
type: "password"
|
|
2899
3319
|
});
|
|
2900
|
-
const orderId =
|
|
3320
|
+
const orderId = need7(opts.orderId, "order-id");
|
|
2901
3321
|
const mgTouched = process.argv.some(
|
|
2902
3322
|
(a) => a === "--meet-and-greet" || a === "--no-meet-and-greet"
|
|
2903
3323
|
);
|
|
@@ -2907,7 +3327,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2907
3327
|
};
|
|
2908
3328
|
set("quote_id", opts.quoteId);
|
|
2909
3329
|
set("vehicle_class", opts.vehicleClass);
|
|
2910
|
-
set("price_amount",
|
|
3330
|
+
set("price_amount", num4(opts.priceAmount, "price-amount"));
|
|
2911
3331
|
set("price_currency", opts.priceCurrency);
|
|
2912
3332
|
set(
|
|
2913
3333
|
"pickup",
|
|
@@ -2954,7 +3374,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2954
3374
|
);
|
|
2955
3375
|
}
|
|
2956
3376
|
if (!isYes) {
|
|
2957
|
-
const confirmed = await
|
|
3377
|
+
const confirmed = await confirm5({
|
|
2958
3378
|
message: `Apply ${Object.keys(body).length} change(s) to ride ${orderId}? The fare may change.`,
|
|
2959
3379
|
default: false
|
|
2960
3380
|
});
|
|
@@ -2988,7 +3408,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2988
3408
|
}
|
|
2989
3409
|
|
|
2990
3410
|
// src/ride-elife/trip-status.ts
|
|
2991
|
-
function
|
|
3411
|
+
function need8(value, flag) {
|
|
2992
3412
|
if (value === void 0) {
|
|
2993
3413
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2994
3414
|
}
|
|
@@ -3026,7 +3446,7 @@ function registerRideTripStatusCommand(parent, deps) {
|
|
|
3026
3446
|
message: "API Key:",
|
|
3027
3447
|
type: "password"
|
|
3028
3448
|
});
|
|
3029
|
-
const orderId =
|
|
3449
|
+
const orderId = need8(opts.orderId, "order-id");
|
|
3030
3450
|
const leg = tripNo(opts.tripNo);
|
|
3031
3451
|
const spinner = format === "json" ? null : createSpinner("Fetching trip status...");
|
|
3032
3452
|
const result = await deps.apiClient.get(
|
|
@@ -3555,28 +3975,28 @@ function registerOrdersGetCommand(parent, deps) {
|
|
|
3555
3975
|
}
|
|
3556
3976
|
|
|
3557
3977
|
// src/hotel-redaug/search.ts
|
|
3558
|
-
function
|
|
3978
|
+
function need9(value, flag) {
|
|
3559
3979
|
if (value === void 0) {
|
|
3560
3980
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3561
3981
|
}
|
|
3562
3982
|
return value;
|
|
3563
3983
|
}
|
|
3564
|
-
function
|
|
3565
|
-
const n = Number(
|
|
3984
|
+
function num5(value, flag) {
|
|
3985
|
+
const n = Number(need9(value, flag));
|
|
3566
3986
|
if (!Number.isFinite(n)) {
|
|
3567
3987
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3568
3988
|
}
|
|
3569
3989
|
return n;
|
|
3570
3990
|
}
|
|
3571
3991
|
function coord(value, flag, min, max) {
|
|
3572
|
-
const n =
|
|
3992
|
+
const n = num5(value, flag);
|
|
3573
3993
|
if (n < min || n > max) {
|
|
3574
3994
|
throw new CliError("PARAM_INVALID", `--${flag} must be between ${min} and ${max}.`);
|
|
3575
3995
|
}
|
|
3576
3996
|
return n;
|
|
3577
3997
|
}
|
|
3578
3998
|
function positiveInt3(value, flag) {
|
|
3579
|
-
const n =
|
|
3999
|
+
const n = num5(value, flag);
|
|
3580
4000
|
if (!Number.isInteger(n) || n <= 0) {
|
|
3581
4001
|
throw new CliError("PARAM_INVALID", `--${flag} must be a positive integer.`);
|
|
3582
4002
|
}
|
|
@@ -3584,7 +4004,7 @@ function positiveInt3(value, flag) {
|
|
|
3584
4004
|
}
|
|
3585
4005
|
var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3586
4006
|
function stayDate(value, flag) {
|
|
3587
|
-
const raw =
|
|
4007
|
+
const raw = need9(value, flag);
|
|
3588
4008
|
if (!YMD_RE.test(raw)) {
|
|
3589
4009
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3590
4010
|
}
|
|
@@ -3656,21 +4076,21 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
3656
4076
|
const pageSize = positiveInt3(opts.pageSize, "page-size");
|
|
3657
4077
|
const body = {};
|
|
3658
4078
|
if (hasDestination) {
|
|
3659
|
-
body.destination_id =
|
|
4079
|
+
body.destination_id = need9(opts.destinationId, "destination-id");
|
|
3660
4080
|
} else {
|
|
3661
4081
|
body.lat = coord(opts.lat, "lat", -90, 90);
|
|
3662
4082
|
body.lng = coord(opts.lng, "lng", -180, 180);
|
|
3663
4083
|
}
|
|
3664
|
-
body.distance =
|
|
4084
|
+
body.distance = num5(opts.distance, "distance");
|
|
3665
4085
|
body.check_in = checkIn;
|
|
3666
4086
|
body.check_out = checkOut;
|
|
3667
|
-
body.adults =
|
|
3668
|
-
body.children =
|
|
3669
|
-
body.room_num =
|
|
3670
|
-
if (opts.star !== void 0) body.star =
|
|
4087
|
+
body.adults = num5(opts.adults, "adults");
|
|
4088
|
+
body.children = num5(opts.children, "children");
|
|
4089
|
+
body.room_num = num5(opts.roomNum, "room-num");
|
|
4090
|
+
if (opts.star !== void 0) body.star = num5(opts.star, "star");
|
|
3671
4091
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
3672
|
-
if (opts.priceMin !== void 0) body.price_min =
|
|
3673
|
-
if (opts.priceMax !== void 0) body.price_max =
|
|
4092
|
+
if (opts.priceMin !== void 0) body.price_min = num5(opts.priceMin, "price-min");
|
|
4093
|
+
if (opts.priceMax !== void 0) body.price_max = num5(opts.priceMax, "price-max");
|
|
3674
4094
|
if (opts.sortBy !== void 0) body.sort_by = opts.sortBy;
|
|
3675
4095
|
body.page = page;
|
|
3676
4096
|
body.page_size = pageSize;
|
|
@@ -3699,14 +4119,14 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
3699
4119
|
}
|
|
3700
4120
|
|
|
3701
4121
|
// src/hotel-redaug/quote.ts
|
|
3702
|
-
function
|
|
4122
|
+
function need10(value, flag) {
|
|
3703
4123
|
if (value === void 0) {
|
|
3704
4124
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3705
4125
|
}
|
|
3706
4126
|
return value;
|
|
3707
4127
|
}
|
|
3708
|
-
function
|
|
3709
|
-
const n = Number(
|
|
4128
|
+
function num6(value, flag) {
|
|
4129
|
+
const n = Number(need10(value, flag));
|
|
3710
4130
|
if (!Number.isFinite(n)) {
|
|
3711
4131
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3712
4132
|
}
|
|
@@ -3714,7 +4134,7 @@ function num5(value, flag) {
|
|
|
3714
4134
|
}
|
|
3715
4135
|
var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3716
4136
|
function stayDate2(value, flag) {
|
|
3717
|
-
const raw =
|
|
4137
|
+
const raw = need10(value, flag);
|
|
3718
4138
|
if (!YMD_RE2.test(raw)) {
|
|
3719
4139
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3720
4140
|
}
|
|
@@ -3754,7 +4174,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3754
4174
|
message: "API Key:",
|
|
3755
4175
|
type: "password"
|
|
3756
4176
|
});
|
|
3757
|
-
const hotelId =
|
|
4177
|
+
const hotelId = need10(opts.hotelId, "hotel-id");
|
|
3758
4178
|
const checkIn = stayDate2(opts.checkIn, "check-in");
|
|
3759
4179
|
const checkOut = stayDate2(opts.checkOut, "check-out");
|
|
3760
4180
|
if (!(checkOut > checkIn)) {
|
|
@@ -3764,9 +4184,9 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3764
4184
|
hotel_id: hotelId,
|
|
3765
4185
|
check_in: checkIn,
|
|
3766
4186
|
check_out: checkOut,
|
|
3767
|
-
adults:
|
|
3768
|
-
children:
|
|
3769
|
-
room_num:
|
|
4187
|
+
adults: num6(opts.adults, "adults"),
|
|
4188
|
+
children: num6(opts.children, "children"),
|
|
4189
|
+
room_num: num6(opts.roomNum, "room-num"),
|
|
3770
4190
|
nationality: opts.nationality
|
|
3771
4191
|
};
|
|
3772
4192
|
const result = await deps.apiClient.post(
|
|
@@ -3788,7 +4208,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3788
4208
|
}
|
|
3789
4209
|
|
|
3790
4210
|
// src/hotel-redaug/create-order.ts
|
|
3791
|
-
import { confirm as
|
|
4211
|
+
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
3792
4212
|
function parsePriceItems(raw) {
|
|
3793
4213
|
const INVALID = "--price-items must be a JSON array of {sale_date (string), sale_price (number), breakfast_num (number)}.";
|
|
3794
4214
|
let parsed;
|
|
@@ -3846,14 +4266,14 @@ function parseCancellation(raw) {
|
|
|
3846
4266
|
}
|
|
3847
4267
|
return parsed;
|
|
3848
4268
|
}
|
|
3849
|
-
function
|
|
4269
|
+
function need11(value, flag) {
|
|
3850
4270
|
if (value === void 0) {
|
|
3851
4271
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3852
4272
|
}
|
|
3853
4273
|
return value;
|
|
3854
4274
|
}
|
|
3855
|
-
function
|
|
3856
|
-
const n = Number(
|
|
4275
|
+
function num7(value, flag) {
|
|
4276
|
+
const n = Number(need11(value, flag));
|
|
3857
4277
|
if (!Number.isFinite(n)) {
|
|
3858
4278
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3859
4279
|
}
|
|
@@ -3861,7 +4281,7 @@ function num6(value, flag) {
|
|
|
3861
4281
|
}
|
|
3862
4282
|
var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3863
4283
|
function stayDate3(value, flag) {
|
|
3864
|
-
const raw =
|
|
4284
|
+
const raw = need11(value, flag);
|
|
3865
4285
|
if (!YMD_RE3.test(raw)) {
|
|
3866
4286
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3867
4287
|
}
|
|
@@ -3872,7 +4292,7 @@ function stayDate3(value, flag) {
|
|
|
3872
4292
|
}
|
|
3873
4293
|
return raw;
|
|
3874
4294
|
}
|
|
3875
|
-
function
|
|
4295
|
+
function formatCreateOrder2(data) {
|
|
3876
4296
|
const lines = [
|
|
3877
4297
|
["Order ID", String(data.order_id ?? "-")],
|
|
3878
4298
|
["FC order code", String(data.fc_order_code ?? "-")],
|
|
@@ -3930,18 +4350,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3930
4350
|
message: "API Key:",
|
|
3931
4351
|
type: "password"
|
|
3932
4352
|
});
|
|
3933
|
-
const productToken =
|
|
3934
|
-
const totalAmount =
|
|
3935
|
-
const currency =
|
|
3936
|
-
const priceItems = parsePriceItems(
|
|
4353
|
+
const productToken = need11(opts.productToken, "product-token");
|
|
4354
|
+
const totalAmount = num7(opts.totalAmount, "total-amount");
|
|
4355
|
+
const currency = need11(opts.currency, "currency");
|
|
4356
|
+
const priceItems = parsePriceItems(need11(opts.priceItems, "price-items"));
|
|
3937
4357
|
const checkIn = stayDate3(opts.checkIn, "check-in");
|
|
3938
4358
|
const checkOut = stayDate3(opts.checkOut, "check-out");
|
|
3939
4359
|
if (!(checkOut > checkIn)) {
|
|
3940
4360
|
throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
|
|
3941
4361
|
}
|
|
3942
|
-
const guestName =
|
|
3943
|
-
const contactName =
|
|
3944
|
-
const contactPhone =
|
|
4362
|
+
const guestName = need11(opts.guestName, "guest-name");
|
|
4363
|
+
const contactName = need11(opts.contactName, "contact-name");
|
|
4364
|
+
const contactPhone = need11(opts.contactPhone, "contact-phone");
|
|
3945
4365
|
const body = {
|
|
3946
4366
|
product_token: productToken,
|
|
3947
4367
|
total_amount: totalAmount,
|
|
@@ -3949,9 +4369,9 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3949
4369
|
price_items: priceItems,
|
|
3950
4370
|
check_in: checkIn,
|
|
3951
4371
|
check_out: checkOut,
|
|
3952
|
-
room_num:
|
|
3953
|
-
adults:
|
|
3954
|
-
children:
|
|
4372
|
+
room_num: num7(opts.roomNum, "room-num"),
|
|
4373
|
+
adults: num7(opts.adults, "adults"),
|
|
4374
|
+
children: num7(opts.children, "children"),
|
|
3955
4375
|
nationality: opts.nationality,
|
|
3956
4376
|
guest_name: guestName,
|
|
3957
4377
|
contact_name: contactName,
|
|
@@ -3975,7 +4395,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3975
4395
|
if (member !== void 0) body.member_id = member;
|
|
3976
4396
|
if (!isYes) {
|
|
3977
4397
|
const chargeNote = opts.paymentTokenId !== void 0 ? "Payment has already been captured via UPI Agent Pay; this only locks the room." : "This locks the rate but does NOT charge anything yet.";
|
|
3978
|
-
const confirmed = await
|
|
4398
|
+
const confirmed = await confirm6({
|
|
3979
4399
|
message: `Create this hotel order for ${totalAmount} ${currency} (check-in ${checkIn}, check-out ${checkOut})? ${chargeNote}`,
|
|
3980
4400
|
default: false
|
|
3981
4401
|
});
|
|
@@ -4002,14 +4422,14 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4002
4422
|
const configManager = new ConfigManager();
|
|
4003
4423
|
const commandResult = {
|
|
4004
4424
|
data,
|
|
4005
|
-
text: () =>
|
|
4425
|
+
text: () => formatCreateOrder2(data)
|
|
4006
4426
|
};
|
|
4007
4427
|
await renderWithContext(commandResult, { format }, configManager);
|
|
4008
4428
|
});
|
|
4009
4429
|
}
|
|
4010
4430
|
|
|
4011
4431
|
// src/hotel-redaug/pay-order.ts
|
|
4012
|
-
import { confirm as
|
|
4432
|
+
import { confirm as confirm7 } from "@inquirer/prompts";
|
|
4013
4433
|
|
|
4014
4434
|
// src/hotel-redaug/watch.ts
|
|
4015
4435
|
var DEFAULT_ORDER_WATCH_INTERVAL_SECONDS = 5;
|
|
@@ -4132,7 +4552,7 @@ async function watchCheckoutStatus(apiClient, apiKey, taskOrderCode, opts) {
|
|
|
4132
4552
|
// src/hotel-redaug/pay-order.ts
|
|
4133
4553
|
var DEFAULT_PAY_WATCH_INTERVAL_SECONDS = 5;
|
|
4134
4554
|
var DEFAULT_PAY_WATCH_TIMEOUT_SECONDS = 300;
|
|
4135
|
-
function
|
|
4555
|
+
function formatPayOrder2(data) {
|
|
4136
4556
|
const lines = [
|
|
4137
4557
|
["Order ID", String(data.order_id ?? "-")],
|
|
4138
4558
|
["Order status", String(data.order_status ?? "-")]
|
|
@@ -4151,7 +4571,13 @@ function isPaymentTerminal(record) {
|
|
|
4151
4571
|
return status === "PAID";
|
|
4152
4572
|
}
|
|
4153
4573
|
function registerHotelPayOrderCommand(parent, deps) {
|
|
4154
|
-
const cmd = parent.command("pay-order").description("Settle an existing hotel order (path decided by billing_mode: monthly_settlement or pay_per_call)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "Order ID to pay (from create-order response)").option(
|
|
4574
|
+
const cmd = parent.command("pay-order").description("Settle an existing hotel order (path decided by billing_mode: monthly_settlement or pay_per_call)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-id <id>", "Order ID to pay (from create-order response)").option("--payment-method-id <id>", "Optional bound-card id to charge (pay_per_call / EVO preauth)").option("--payment-token-id <id>", "Optional network-token id (unionpay/visa charge path)").option(
|
|
4575
|
+
"--authorized-merchant-trans-id <id>",
|
|
4576
|
+
"Resume a 3DS challenge: merchant trans id of an already-authorised preauth"
|
|
4577
|
+
).option(
|
|
4578
|
+
"--evo-explicit",
|
|
4579
|
+
"[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call order via the EVO bound-card fallback rail. Set ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side."
|
|
4580
|
+
).option(
|
|
4155
4581
|
"--idempotency-key <key>",
|
|
4156
4582
|
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
4157
4583
|
).option("--watch", "Poll until PAID or timeout (NDJSON output)", false).option(
|
|
@@ -4184,8 +4610,14 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4184
4610
|
const watchInterval = resolveSeconds(opts.watchInterval, DEFAULT_PAY_WATCH_INTERVAL_SECONDS);
|
|
4185
4611
|
const watchTimeout = resolveSeconds(opts.watchTimeout, DEFAULT_PAY_WATCH_TIMEOUT_SECONDS);
|
|
4186
4612
|
const body = {};
|
|
4613
|
+
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
4614
|
+
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
4615
|
+
if (opts.authorizedMerchantTransId !== void 0) {
|
|
4616
|
+
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
4617
|
+
}
|
|
4618
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
4187
4619
|
if (!isYes) {
|
|
4188
|
-
const confirmed = await
|
|
4620
|
+
const confirmed = await confirm7({
|
|
4189
4621
|
message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
|
|
4190
4622
|
default: false
|
|
4191
4623
|
});
|
|
@@ -4212,7 +4644,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4212
4644
|
const configManager = new ConfigManager();
|
|
4213
4645
|
const commandResult = {
|
|
4214
4646
|
data,
|
|
4215
|
-
text: () =>
|
|
4647
|
+
text: () => formatPayOrder2(data)
|
|
4216
4648
|
};
|
|
4217
4649
|
await renderWithContext(commandResult, { format }, configManager);
|
|
4218
4650
|
} else {
|
|
@@ -4263,7 +4695,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4263
4695
|
}
|
|
4264
4696
|
|
|
4265
4697
|
// src/hotel-redaug/get.ts
|
|
4266
|
-
function
|
|
4698
|
+
function need12(value, flag) {
|
|
4267
4699
|
if (value === void 0) {
|
|
4268
4700
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4269
4701
|
}
|
|
@@ -4301,8 +4733,8 @@ function formatGetOrder2(data) {
|
|
|
4301
4733
|
}
|
|
4302
4734
|
if (data.guest?.name) lines.push(["Guest", String(data.guest.name)]);
|
|
4303
4735
|
if (data.contact?.name) {
|
|
4304
|
-
const
|
|
4305
|
-
lines.push(["Contact", `${data.contact.name}${
|
|
4736
|
+
const phone3 = data.contact.phone ? ` (+${data.contact.country_code ?? ""} ${data.contact.phone})` : "";
|
|
4737
|
+
lines.push(["Contact", `${data.contact.name}${phone3}`]);
|
|
4306
4738
|
}
|
|
4307
4739
|
if (data.arrive_time) lines.push(["Arrive time", String(data.arrive_time)]);
|
|
4308
4740
|
if (data.special_requests) lines.push(["Special requests", String(data.special_requests)]);
|
|
@@ -4327,7 +4759,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4327
4759
|
message: "API Key:",
|
|
4328
4760
|
type: "password"
|
|
4329
4761
|
});
|
|
4330
|
-
const orderId =
|
|
4762
|
+
const orderId = need12(opts.orderId, "order-id");
|
|
4331
4763
|
if (opts.watch) {
|
|
4332
4764
|
await watchOrderStatus(deps.apiClient, apiKey, orderId, {
|
|
4333
4765
|
intervalSeconds: resolveSeconds(
|
|
@@ -4361,7 +4793,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4361
4793
|
}
|
|
4362
4794
|
|
|
4363
4795
|
// src/hotel-redaug/cancel.ts
|
|
4364
|
-
function
|
|
4796
|
+
function need13(value, flag) {
|
|
4365
4797
|
if (value === void 0) {
|
|
4366
4798
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4367
4799
|
}
|
|
@@ -4414,8 +4846,8 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4414
4846
|
message: "API Key:",
|
|
4415
4847
|
type: "password"
|
|
4416
4848
|
});
|
|
4417
|
-
const orderId =
|
|
4418
|
-
const fcOrderCode =
|
|
4849
|
+
const orderId = need13(opts.orderId, "order-id");
|
|
4850
|
+
const fcOrderCode = need13(opts.fcOrderCode, "fc-order-code");
|
|
4419
4851
|
const body = { fc_order_code: fcOrderCode };
|
|
4420
4852
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
4421
4853
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -4444,15 +4876,15 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4444
4876
|
}
|
|
4445
4877
|
|
|
4446
4878
|
// src/hotel-redaug/checkout.ts
|
|
4447
|
-
import { confirm as
|
|
4448
|
-
function
|
|
4879
|
+
import { confirm as confirm8 } from "@inquirer/prompts";
|
|
4880
|
+
function need14(value, flag) {
|
|
4449
4881
|
if (value === void 0) {
|
|
4450
4882
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4451
4883
|
}
|
|
4452
4884
|
return value;
|
|
4453
4885
|
}
|
|
4454
|
-
function
|
|
4455
|
-
const n = Number(
|
|
4886
|
+
function num8(value, flag) {
|
|
4887
|
+
const n = Number(need14(value, flag));
|
|
4456
4888
|
if (!Number.isFinite(n)) {
|
|
4457
4889
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4458
4890
|
}
|
|
@@ -4518,11 +4950,11 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4518
4950
|
message: "API Key:",
|
|
4519
4951
|
type: "password"
|
|
4520
4952
|
});
|
|
4521
|
-
const orderId =
|
|
4522
|
-
const fcOrderCode =
|
|
4523
|
-
const reason =
|
|
4524
|
-
const checkoutRooms = parseCheckoutRooms(
|
|
4525
|
-
const refundType =
|
|
4953
|
+
const orderId = need14(opts.orderId, "order-id");
|
|
4954
|
+
const fcOrderCode = need14(opts.fcOrderCode, "fc-order-code");
|
|
4955
|
+
const reason = need14(opts.reason, "reason");
|
|
4956
|
+
const checkoutRooms = parseCheckoutRooms(need14(opts.checkoutRooms, "checkout-rooms"));
|
|
4957
|
+
const refundType = num8(opts.refundType, "refund-type");
|
|
4526
4958
|
const body = {
|
|
4527
4959
|
fc_order_code: fcOrderCode,
|
|
4528
4960
|
reason,
|
|
@@ -4530,7 +4962,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4530
4962
|
checkout_rooms: checkoutRooms
|
|
4531
4963
|
};
|
|
4532
4964
|
if (!isYes) {
|
|
4533
|
-
const confirmed = await
|
|
4965
|
+
const confirmed = await confirm8({
|
|
4534
4966
|
message: `Request check-out / out-of-policy cancellation for order ${orderId} (${checkoutRooms.length} room(s))? The property must approve and charges may apply.`,
|
|
4535
4967
|
default: false
|
|
4536
4968
|
});
|
|
@@ -4564,7 +4996,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4564
4996
|
}
|
|
4565
4997
|
|
|
4566
4998
|
// src/hotel-redaug/get-checkout.ts
|
|
4567
|
-
function
|
|
4999
|
+
function need15(value, flag) {
|
|
4568
5000
|
if (value === void 0) {
|
|
4569
5001
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4570
5002
|
}
|
|
@@ -4600,7 +5032,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
|
|
|
4600
5032
|
message: "API Key:",
|
|
4601
5033
|
type: "password"
|
|
4602
5034
|
});
|
|
4603
|
-
const taskOrderCode =
|
|
5035
|
+
const taskOrderCode = need15(opts.taskOrderCode, "task-order-code");
|
|
4604
5036
|
if (opts.watch) {
|
|
4605
5037
|
await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
|
|
4606
5038
|
intervalSeconds: resolveSeconds(
|
|
@@ -4704,7 +5136,7 @@ function registerHotelListOrdersCommand(parent, deps) {
|
|
|
4704
5136
|
}
|
|
4705
5137
|
|
|
4706
5138
|
// src/hotel-redaug/find-destination.ts
|
|
4707
|
-
function
|
|
5139
|
+
function need16(value, flag) {
|
|
4708
5140
|
if (value === void 0 || value.trim() === "") {
|
|
4709
5141
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4710
5142
|
}
|
|
@@ -4738,7 +5170,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
4738
5170
|
message: "API Key:",
|
|
4739
5171
|
type: "password"
|
|
4740
5172
|
});
|
|
4741
|
-
const keyword =
|
|
5173
|
+
const keyword = need16(opts.keyword, "keyword");
|
|
4742
5174
|
const body = { keyword };
|
|
4743
5175
|
if (opts.dataType !== void 0) {
|
|
4744
5176
|
body.data_type = opts.dataType;
|
|
@@ -4762,21 +5194,21 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
4762
5194
|
}
|
|
4763
5195
|
|
|
4764
5196
|
// src/hotel-redaug/hotel-filters.ts
|
|
4765
|
-
function
|
|
5197
|
+
function need17(value, flag) {
|
|
4766
5198
|
if (value === void 0 || value.trim() === "") {
|
|
4767
5199
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4768
5200
|
}
|
|
4769
5201
|
return value;
|
|
4770
5202
|
}
|
|
4771
|
-
function
|
|
4772
|
-
const n = Number(
|
|
5203
|
+
function num9(value, flag) {
|
|
5204
|
+
const n = Number(need17(value, flag));
|
|
4773
5205
|
if (!Number.isFinite(n)) {
|
|
4774
5206
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4775
5207
|
}
|
|
4776
5208
|
return n;
|
|
4777
5209
|
}
|
|
4778
5210
|
function coord2(value, flag, min, max) {
|
|
4779
|
-
const n =
|
|
5211
|
+
const n = num9(value, flag);
|
|
4780
5212
|
if (n < min || n > max) {
|
|
4781
5213
|
throw new CliError("PARAM_INVALID", `--${flag} must be between ${min} and ${max}.`);
|
|
4782
5214
|
}
|
|
@@ -4849,12 +5281,12 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
4849
5281
|
}
|
|
4850
5282
|
const body = {};
|
|
4851
5283
|
if (hasDestination) {
|
|
4852
|
-
body.destination_id =
|
|
5284
|
+
body.destination_id = need17(opts.destinationId, "destination-id");
|
|
4853
5285
|
} else {
|
|
4854
5286
|
body.lat = coord2(opts.lat, "lat", -90, 90);
|
|
4855
5287
|
body.lng = coord2(opts.lng, "lng", -180, 180);
|
|
4856
5288
|
}
|
|
4857
|
-
body.distance =
|
|
5289
|
+
body.distance = num9(opts.distance, "distance");
|
|
4858
5290
|
const result = await deps.apiClient.post(
|
|
4859
5291
|
"/hotel/filters",
|
|
4860
5292
|
{ type: "api-key", key: apiKey },
|
|
@@ -4874,7 +5306,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
4874
5306
|
}
|
|
4875
5307
|
|
|
4876
5308
|
// src/hotel-redaug/list-cities.ts
|
|
4877
|
-
function
|
|
5309
|
+
function need18(value, flag) {
|
|
4878
5310
|
if (value === void 0 || value.trim() === "") {
|
|
4879
5311
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4880
5312
|
}
|
|
@@ -4907,7 +5339,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
4907
5339
|
message: "API Key:",
|
|
4908
5340
|
type: "password"
|
|
4909
5341
|
});
|
|
4910
|
-
const country =
|
|
5342
|
+
const country = need18(opts.country, "country");
|
|
4911
5343
|
const body = { country_code: country };
|
|
4912
5344
|
const result = await deps.apiClient.post(
|
|
4913
5345
|
"/hotel/cities",
|
|
@@ -4928,7 +5360,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
4928
5360
|
}
|
|
4929
5361
|
|
|
4930
5362
|
// src/hotel-redaug/hotel-detail.ts
|
|
4931
|
-
function
|
|
5363
|
+
function need19(value, flag) {
|
|
4932
5364
|
if (value === void 0 || value.trim() === "") {
|
|
4933
5365
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4934
5366
|
}
|
|
@@ -5075,7 +5507,7 @@ function registerHotelDetailCommand(parent, deps) {
|
|
|
5075
5507
|
message: "API Key:",
|
|
5076
5508
|
type: "password"
|
|
5077
5509
|
});
|
|
5078
|
-
const hotelId =
|
|
5510
|
+
const hotelId = need19(opts.hotelId, "hotel-id");
|
|
5079
5511
|
const rawWithImages = opts.withImages;
|
|
5080
5512
|
const withImages = rawWithImages !== "false" && rawWithImages !== false;
|
|
5081
5513
|
const settings = parseSettings(opts.settings);
|
|
@@ -5283,14 +5715,14 @@ function registerHotelSkillCommand(parent) {
|
|
|
5283
5715
|
}
|
|
5284
5716
|
|
|
5285
5717
|
// src/flight-flink/_helpers.ts
|
|
5286
|
-
function
|
|
5718
|
+
function need20(value, flag) {
|
|
5287
5719
|
if (value === void 0) {
|
|
5288
5720
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5289
5721
|
}
|
|
5290
5722
|
return value;
|
|
5291
5723
|
}
|
|
5292
|
-
function
|
|
5293
|
-
const n = Number(
|
|
5724
|
+
function num10(value, flag) {
|
|
5725
|
+
const n = Number(need20(value, flag));
|
|
5294
5726
|
if (!Number.isFinite(n)) {
|
|
5295
5727
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5296
5728
|
}
|
|
@@ -5325,7 +5757,7 @@ function registerFindAirportCommand(parent, deps) {
|
|
|
5325
5757
|
const opts = cmd.optsWithGlobals();
|
|
5326
5758
|
const format = resolveFormat(opts.format);
|
|
5327
5759
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5328
|
-
const keyword =
|
|
5760
|
+
const keyword = need20(opts.keyword, "keyword");
|
|
5329
5761
|
const spinner = format === "json" ? null : createSpinner("Resolving airports...");
|
|
5330
5762
|
const result = await deps.apiClient.post(
|
|
5331
5763
|
"/flight/find-airport",
|
|
@@ -5351,8 +5783,8 @@ function registerListAirportsCommand(parent, deps) {
|
|
|
5351
5783
|
const format = resolveFormat(opts.format);
|
|
5352
5784
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5353
5785
|
const body = {
|
|
5354
|
-
page:
|
|
5355
|
-
page_size:
|
|
5786
|
+
page: num10(opts.page, "page"),
|
|
5787
|
+
page_size: num10(opts.pageSize, "page-size")
|
|
5356
5788
|
};
|
|
5357
5789
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
5358
5790
|
const spinner = format === "json" ? null : createSpinner("Fetching airports...");
|
|
@@ -5376,8 +5808,8 @@ function registerListAirlinesCommand(parent, deps) {
|
|
|
5376
5808
|
const format = resolveFormat(opts.format);
|
|
5377
5809
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5378
5810
|
const body = {
|
|
5379
|
-
page:
|
|
5380
|
-
page_size:
|
|
5811
|
+
page: num10(opts.page, "page"),
|
|
5812
|
+
page_size: num10(opts.pageSize, "page-size")
|
|
5381
5813
|
};
|
|
5382
5814
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
5383
5815
|
const spinner = format === "json" ? null : createSpinner("Fetching airlines...");
|
|
@@ -5421,13 +5853,13 @@ function registerSearchCommand(parent, deps) {
|
|
|
5421
5853
|
const format = resolveFormat(opts.format);
|
|
5422
5854
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5423
5855
|
const body = {
|
|
5424
|
-
trip_type:
|
|
5425
|
-
journeys: jsonArray(
|
|
5856
|
+
trip_type: num10(opts.tripType, "trip-type"),
|
|
5857
|
+
journeys: jsonArray(need20(opts.journeys, "journeys"), "journeys"),
|
|
5426
5858
|
cabin_class: opts.cabinClass,
|
|
5427
|
-
adult_num:
|
|
5428
|
-
child_num:
|
|
5429
|
-
infant_num:
|
|
5430
|
-
transfer_number:
|
|
5859
|
+
adult_num: num10(opts.adultNum, "adult-num"),
|
|
5860
|
+
child_num: num10(opts.childNum, "child-num"),
|
|
5861
|
+
infant_num: num10(opts.infantNum, "infant-num"),
|
|
5862
|
+
transfer_number: num10(opts.transferNumber, "transfer-number")
|
|
5431
5863
|
};
|
|
5432
5864
|
if (opts.airline !== void 0) body.airline = opts.airline;
|
|
5433
5865
|
if (opts.journeyId !== void 0) {
|
|
@@ -5453,7 +5885,7 @@ function registerMoreOffersCommand(parent, deps) {
|
|
|
5453
5885
|
const opts = cmd.optsWithGlobals();
|
|
5454
5886
|
const format = resolveFormat(opts.format);
|
|
5455
5887
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5456
|
-
const productToken =
|
|
5888
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5457
5889
|
const spinner = format === "json" ? null : createSpinner("Fetching offers...");
|
|
5458
5890
|
const result = await deps.apiClient.post(
|
|
5459
5891
|
"/flight/more-offers",
|
|
@@ -5474,7 +5906,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5474
5906
|
const opts = cmd.optsWithGlobals();
|
|
5475
5907
|
const format = resolveFormat(opts.format);
|
|
5476
5908
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5477
|
-
const productToken =
|
|
5909
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5478
5910
|
const spinner = format === "json" ? null : createSpinner("Verifying price...");
|
|
5479
5911
|
const result = await deps.apiClient.post(
|
|
5480
5912
|
"/flight/verify",
|
|
@@ -5496,7 +5928,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5496
5928
|
}
|
|
5497
5929
|
|
|
5498
5930
|
// src/flight-flink/create-order.ts
|
|
5499
|
-
import { confirm as
|
|
5931
|
+
import { confirm as confirm9 } from "@inquirer/prompts";
|
|
5500
5932
|
function registerCreateOrderCommand(parent, deps) {
|
|
5501
5933
|
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("--passengers <json>", "JSON array of passengers (gender/id_type are strings)").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(
|
|
5502
5934
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5508,19 +5940,19 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5508
5940
|
const format = resolveFormat(opts.format);
|
|
5509
5941
|
const isYes = Boolean(opts.yes);
|
|
5510
5942
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5511
|
-
const productToken =
|
|
5512
|
-
const totalAmount =
|
|
5513
|
-
const currency =
|
|
5943
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5944
|
+
const totalAmount = num10(opts.totalAmount, "total-amount");
|
|
5945
|
+
const currency = need20(opts.currency, "currency");
|
|
5514
5946
|
const body = {
|
|
5515
5947
|
product_token: productToken,
|
|
5516
5948
|
total_amount: totalAmount,
|
|
5517
5949
|
currency,
|
|
5518
|
-
trip_type:
|
|
5519
|
-
contact_name:
|
|
5520
|
-
contact_region:
|
|
5521
|
-
contact_phone:
|
|
5522
|
-
contact_email:
|
|
5523
|
-
passengers: jsonArray(
|
|
5950
|
+
trip_type: num10(opts.tripType, "trip-type"),
|
|
5951
|
+
contact_name: need20(opts.contactName, "contact-name"),
|
|
5952
|
+
contact_region: need20(opts.contactRegion, "contact-region"),
|
|
5953
|
+
contact_phone: need20(opts.contactPhone, "contact-phone"),
|
|
5954
|
+
contact_email: need20(opts.contactEmail, "contact-email"),
|
|
5955
|
+
passengers: jsonArray(need20(opts.passengers, "passengers"), "passengers")
|
|
5524
5956
|
};
|
|
5525
5957
|
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
5526
5958
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
@@ -5530,7 +5962,7 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5530
5962
|
const member = memberIdOf(opts);
|
|
5531
5963
|
if (member !== void 0) body.member_id = member;
|
|
5532
5964
|
if (!isYes) {
|
|
5533
|
-
const ok = await
|
|
5965
|
+
const ok = await confirm9({
|
|
5534
5966
|
message: `Create this flight order for ${totalAmount} ${currency}? This locks the fare but does NOT charge yet.`,
|
|
5535
5967
|
default: false
|
|
5536
5968
|
});
|
|
@@ -5569,11 +6001,14 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5569
6001
|
}
|
|
5570
6002
|
|
|
5571
6003
|
// src/flight-flink/pay-order.ts
|
|
5572
|
-
import { confirm as
|
|
6004
|
+
import { confirm as confirm10 } from "@inquirer/prompts";
|
|
5573
6005
|
function registerPayOrderCommand(parent, deps) {
|
|
5574
6006
|
const cmd = parent.command("pay-order").description("Settle a created order by --order-no (triggers ticketing)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference from create-order").option("--payment-method-id <id>", "Optional bound-card id to charge (pay_per_call only)").option("--payment-token-id <id>", "Optional network-token id (unionpay/visa charge path)").option(
|
|
5575
6007
|
"--authorized-merchant-trans-id <id>",
|
|
5576
6008
|
"Resume a 3DS challenge: merchant trans id of an already-authorised preauth"
|
|
6009
|
+
).option(
|
|
6010
|
+
"--evo-explicit",
|
|
6011
|
+
"[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call order via the EVO bound-card fallback rail. Set ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side."
|
|
5577
6012
|
).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5578
6013
|
attachSchemaHelp(cmd, flightPayOrderSchema);
|
|
5579
6014
|
cmd.action(async () => {
|
|
@@ -5581,9 +6016,9 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
5581
6016
|
const format = resolveFormat(opts.format);
|
|
5582
6017
|
const isYes = Boolean(opts.yes);
|
|
5583
6018
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5584
|
-
const orderNo =
|
|
6019
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5585
6020
|
if (!isYes) {
|
|
5586
|
-
const ok = await
|
|
6021
|
+
const ok = await confirm10({
|
|
5587
6022
|
message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
|
|
5588
6023
|
default: false
|
|
5589
6024
|
});
|
|
@@ -5600,6 +6035,7 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
5600
6035
|
if (opts.authorizedMerchantTransId !== void 0) {
|
|
5601
6036
|
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
5602
6037
|
}
|
|
6038
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
5603
6039
|
const result = await deps.apiClient.post(
|
|
5604
6040
|
`/flight/${encodeURIComponent(orderNo)}/pay`,
|
|
5605
6041
|
{ type: "api-key", key: apiKey },
|
|
@@ -5632,12 +6068,12 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
5632
6068
|
const opts = cmd.optsWithGlobals();
|
|
5633
6069
|
const format = resolveFormat(opts.format);
|
|
5634
6070
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5635
|
-
const orderNo =
|
|
6071
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5636
6072
|
const path = `/flight/${encodeURIComponent(orderNo)}/status`;
|
|
5637
6073
|
const auth = { type: "api-key", key: apiKey };
|
|
5638
6074
|
if (opts.watch) {
|
|
5639
|
-
const interval =
|
|
5640
|
-
const timeoutMs =
|
|
6075
|
+
const interval = num10(opts.watchInterval, "watch-interval") * 1e3;
|
|
6076
|
+
const timeoutMs = num10(opts.watchTimeout, "watch-timeout") * 1e3;
|
|
5641
6077
|
const deadline = Date.now() + timeoutMs;
|
|
5642
6078
|
for (; ; ) {
|
|
5643
6079
|
const r = await deps.apiClient.get(path, auth);
|
|
@@ -5672,7 +6108,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
5672
6108
|
}
|
|
5673
6109
|
|
|
5674
6110
|
// src/flight-flink/cancel-order.ts
|
|
5675
|
-
import { confirm as
|
|
6111
|
+
import { confirm as confirm11 } from "@inquirer/prompts";
|
|
5676
6112
|
function registerCancelOrderCommand(parent, deps) {
|
|
5677
6113
|
const cmd = parent.command("cancel-order").description("Cancel an un-ticketed flight order (with refund)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference").option("--reason <text>", "Optional cancellation reason").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5678
6114
|
attachSchemaHelp(cmd, flightCancelOrderSchema);
|
|
@@ -5681,9 +6117,9 @@ function registerCancelOrderCommand(parent, deps) {
|
|
|
5681
6117
|
const format = resolveFormat(opts.format);
|
|
5682
6118
|
const isYes = Boolean(opts.yes);
|
|
5683
6119
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5684
|
-
const orderNo =
|
|
6120
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5685
6121
|
if (!isYes) {
|
|
5686
|
-
const ok = await
|
|
6122
|
+
const ok = await confirm11({
|
|
5687
6123
|
message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
|
|
5688
6124
|
default: false
|
|
5689
6125
|
});
|
|
@@ -5728,8 +6164,8 @@ function registerListOrdersCommand2(parent, deps) {
|
|
|
5728
6164
|
if (opts.status !== void 0) params.set("status", opts.status);
|
|
5729
6165
|
const member = memberIdOf(opts);
|
|
5730
6166
|
if (member !== void 0) params.set("member_id", member);
|
|
5731
|
-
params.set("page", String(
|
|
5732
|
-
params.set("page_size", String(
|
|
6167
|
+
params.set("page", String(num10(opts.page, "page")));
|
|
6168
|
+
params.set("page_size", String(num10(opts.pageSize, "page-size")));
|
|
5733
6169
|
const spinner = format === "json" ? null : createSpinner("Fetching flight orders...");
|
|
5734
6170
|
const result = await deps.apiClient.get(
|
|
5735
6171
|
`/flight/orders?${params.toString()}`,
|
|
@@ -5757,10 +6193,10 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
5757
6193
|
const format = resolveFormat(opts.format);
|
|
5758
6194
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5759
6195
|
const body = {
|
|
5760
|
-
order_no:
|
|
5761
|
-
date:
|
|
5762
|
-
passenger:
|
|
5763
|
-
segment_id:
|
|
6196
|
+
order_no: need20(opts.orderNo, "order-no"),
|
|
6197
|
+
date: need20(opts.date, "date"),
|
|
6198
|
+
passenger: need20(opts.passenger, "passenger"),
|
|
6199
|
+
segment_id: need20(opts.segmentId, "segment-id"),
|
|
5764
6200
|
cabin_class: opts.cabinClass
|
|
5765
6201
|
};
|
|
5766
6202
|
const spinner = format === "json" ? null : createSpinner("Searching change options...");
|
|
@@ -5776,7 +6212,7 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
5776
6212
|
}
|
|
5777
6213
|
|
|
5778
6214
|
// src/flight-flink/change-apply.ts
|
|
5779
|
-
import { confirm as
|
|
6215
|
+
import { confirm as confirm12 } from "@inquirer/prompts";
|
|
5780
6216
|
function registerChangeApplyCommand(parent, deps) {
|
|
5781
6217
|
const cmd = parent.command("change-apply").description("Submit a change request (returns change_order_no, pending review)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference").option("--passenger <code>", "passengerCode").option("--segment-id <ids>", "Comma-separated segment ids").option("--product-token <token>", "Change priceKey token").option("--contact-name <name>", "Contact name").option("--contact-region <code>", "Contact region").option("--contact-phone <phone>", "Contact phone").option("--contact-email <email>", "Contact email").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5782
6218
|
attachSchemaHelp(cmd, flightChangeApplySchema);
|
|
@@ -5786,17 +6222,17 @@ function registerChangeApplyCommand(parent, deps) {
|
|
|
5786
6222
|
const isYes = Boolean(opts.yes);
|
|
5787
6223
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5788
6224
|
const body = {
|
|
5789
|
-
order_no:
|
|
5790
|
-
passenger:
|
|
5791
|
-
segment_id:
|
|
5792
|
-
product_token:
|
|
5793
|
-
contact_name:
|
|
5794
|
-
contact_region:
|
|
5795
|
-
contact_phone:
|
|
5796
|
-
contact_email:
|
|
6225
|
+
order_no: need20(opts.orderNo, "order-no"),
|
|
6226
|
+
passenger: need20(opts.passenger, "passenger"),
|
|
6227
|
+
segment_id: need20(opts.segmentId, "segment-id"),
|
|
6228
|
+
product_token: need20(opts.productToken, "product-token"),
|
|
6229
|
+
contact_name: need20(opts.contactName, "contact-name"),
|
|
6230
|
+
contact_region: need20(opts.contactRegion, "contact-region"),
|
|
6231
|
+
contact_phone: need20(opts.contactPhone, "contact-phone"),
|
|
6232
|
+
contact_email: need20(opts.contactEmail, "contact-email")
|
|
5797
6233
|
};
|
|
5798
6234
|
if (!isYes) {
|
|
5799
|
-
const ok = await
|
|
6235
|
+
const ok = await confirm12({
|
|
5800
6236
|
message: `Submit a change request for order ${body.order_no}?`,
|
|
5801
6237
|
default: false
|
|
5802
6238
|
});
|
|
@@ -5827,7 +6263,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
5827
6263
|
const opts = cmd.optsWithGlobals();
|
|
5828
6264
|
const format = resolveFormat(opts.format);
|
|
5829
6265
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5830
|
-
const changeOrderNo =
|
|
6266
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
5831
6267
|
const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
|
|
5832
6268
|
const result = await deps.apiClient.get(
|
|
5833
6269
|
`/flight/change/${encodeURIComponent(changeOrderNo)}`,
|
|
@@ -5840,7 +6276,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
5840
6276
|
}
|
|
5841
6277
|
|
|
5842
6278
|
// src/flight-flink/change-cancel.ts
|
|
5843
|
-
import { confirm as
|
|
6279
|
+
import { confirm as confirm13 } from "@inquirer/prompts";
|
|
5844
6280
|
function registerChangeCancelCommand(parent, deps) {
|
|
5845
6281
|
const cmd = parent.command("change-cancel").description("Cancel a change request (immediate terminal)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--change-order-no <id>", "Change order number").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5846
6282
|
attachSchemaHelp(cmd, flightChangeCancelSchema);
|
|
@@ -5849,9 +6285,9 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
5849
6285
|
const format = resolveFormat(opts.format);
|
|
5850
6286
|
const isYes = Boolean(opts.yes);
|
|
5851
6287
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5852
|
-
const changeOrderNo =
|
|
6288
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
5853
6289
|
if (!isYes) {
|
|
5854
|
-
const ok = await
|
|
6290
|
+
const ok = await confirm13({ message: `Cancel change request ${changeOrderNo}?`, default: false });
|
|
5855
6291
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
|
|
5856
6292
|
}
|
|
5857
6293
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5872,7 +6308,7 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
5872
6308
|
}
|
|
5873
6309
|
|
|
5874
6310
|
// src/flight-flink/change-pay.ts
|
|
5875
|
-
import { confirm as
|
|
6311
|
+
import { confirm as confirm14 } from "@inquirer/prompts";
|
|
5876
6312
|
function registerChangePayCommand(parent, deps) {
|
|
5877
6313
|
const cmd = parent.command("change-pay").description("Pay a change request fee (like a normal order) and trigger change ticketing").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--change-order-no <id>", "Change order number").option("--order-no <id>", "Original order reference (ownership check)").option("--amount <amount>", "Change fee total in decimal units (change-detail price_total)").option("--currency <currency>", "ISO 4217 currency code", "USD").option("--payment-method-id <id>", "Optional bound-card id (EVO path)").option("--payment-token-id <id>", "Optional UPI network-token id (unionpay charge path)").option(
|
|
5878
6314
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5884,10 +6320,10 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5884
6320
|
const format = resolveFormat(opts.format);
|
|
5885
6321
|
const isYes = Boolean(opts.yes);
|
|
5886
6322
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5887
|
-
const changeOrderNo =
|
|
5888
|
-
const orderNo =
|
|
5889
|
-
const amount =
|
|
5890
|
-
const currency =
|
|
6323
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
6324
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
6325
|
+
const amount = num10(opts.amount, "amount");
|
|
6326
|
+
const currency = need20(opts.currency, "currency");
|
|
5891
6327
|
const body = {
|
|
5892
6328
|
order_no: orderNo,
|
|
5893
6329
|
amount,
|
|
@@ -5901,7 +6337,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5901
6337
|
if (!isYes) {
|
|
5902
6338
|
const isResume = opts.authorizedMerchantTransId !== void 0;
|
|
5903
6339
|
const message = isResume ? `Resume change fee ${amount} ${currency} for change order ${changeOrderNo}? The card is already authorised; this captures it and triggers change ticketing.` : `Pay change fee ${amount} ${currency} for change order ${changeOrderNo}? This charges the customer and triggers change ticketing.`;
|
|
5904
|
-
const ok = await
|
|
6340
|
+
const ok = await confirm14({ message, default: false });
|
|
5905
6341
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change payment aborted by user.");
|
|
5906
6342
|
}
|
|
5907
6343
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5948,7 +6384,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5948
6384
|
}
|
|
5949
6385
|
|
|
5950
6386
|
// src/flight-flink/refund-apply.ts
|
|
5951
|
-
import { confirm as
|
|
6387
|
+
import { confirm as confirm15 } from "@inquirer/prompts";
|
|
5952
6388
|
function registerRefundApplyCommand(parent, deps) {
|
|
5953
6389
|
const cmd = parent.command("refund-apply").description("Submit a refund request (returns refund_order_no, pending review)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference").option("--passenger <code>", "passengerCode").option("--segment-id <ids>", "Comma-separated segment ids").option("--reason-type <n>", "Refund reason type code").option("--reason <text>", "Free-text reason").option("--contact-name <name>", "Contact name").option("--contact-region <code>", "Contact region").option("--contact-phone <phone>", "Contact phone").option("--contact-email <email>", "Contact email").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5954
6390
|
attachSchemaHelp(cmd, flightRefundApplySchema);
|
|
@@ -5958,18 +6394,18 @@ function registerRefundApplyCommand(parent, deps) {
|
|
|
5958
6394
|
const isYes = Boolean(opts.yes);
|
|
5959
6395
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5960
6396
|
const body = {
|
|
5961
|
-
order_no:
|
|
5962
|
-
passenger:
|
|
5963
|
-
segment_id:
|
|
5964
|
-
reason_type:
|
|
5965
|
-
contact_name:
|
|
5966
|
-
contact_region:
|
|
5967
|
-
contact_phone:
|
|
5968
|
-
contact_email:
|
|
6397
|
+
order_no: need20(opts.orderNo, "order-no"),
|
|
6398
|
+
passenger: need20(opts.passenger, "passenger"),
|
|
6399
|
+
segment_id: need20(opts.segmentId, "segment-id"),
|
|
6400
|
+
reason_type: num10(opts.reasonType, "reason-type"),
|
|
6401
|
+
contact_name: need20(opts.contactName, "contact-name"),
|
|
6402
|
+
contact_region: need20(opts.contactRegion, "contact-region"),
|
|
6403
|
+
contact_phone: need20(opts.contactPhone, "contact-phone"),
|
|
6404
|
+
contact_email: need20(opts.contactEmail, "contact-email")
|
|
5969
6405
|
};
|
|
5970
6406
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
5971
6407
|
if (!isYes) {
|
|
5972
|
-
const ok = await
|
|
6408
|
+
const ok = await confirm15({
|
|
5973
6409
|
message: `Submit a refund request for order ${body.order_no}?`,
|
|
5974
6410
|
default: false
|
|
5975
6411
|
});
|
|
@@ -6000,7 +6436,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6000
6436
|
const opts = cmd.optsWithGlobals();
|
|
6001
6437
|
const format = resolveFormat(opts.format);
|
|
6002
6438
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6003
|
-
const refundOrderNo =
|
|
6439
|
+
const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
|
|
6004
6440
|
const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
|
|
6005
6441
|
const result = await deps.apiClient.get(
|
|
6006
6442
|
`/flight/refund/${encodeURIComponent(refundOrderNo)}`,
|
|
@@ -6013,7 +6449,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6013
6449
|
}
|
|
6014
6450
|
|
|
6015
6451
|
// src/flight-flink/refund-confirm.ts
|
|
6016
|
-
import { confirm as
|
|
6452
|
+
import { confirm as confirm16 } from "@inquirer/prompts";
|
|
6017
6453
|
function registerRefundConfirmCommand(parent, deps) {
|
|
6018
6454
|
const cmd = parent.command("refund-confirm").description('Confirm ("1") or cancel ("2") a refund').option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--refund-order-no <id>", "Refund order number").option("--confirm <flag>", '"1" confirm / "2" cancel').option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
6019
6455
|
attachSchemaHelp(cmd, flightRefundConfirmSchema);
|
|
@@ -6022,14 +6458,14 @@ function registerRefundConfirmCommand(parent, deps) {
|
|
|
6022
6458
|
const format = resolveFormat(opts.format);
|
|
6023
6459
|
const isYes = Boolean(opts.yes);
|
|
6024
6460
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6025
|
-
const refundOrderNo =
|
|
6026
|
-
const confirmFlag =
|
|
6461
|
+
const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
|
|
6462
|
+
const confirmFlag = need20(opts.confirm, "confirm");
|
|
6027
6463
|
if (confirmFlag !== "1" && confirmFlag !== "2") {
|
|
6028
6464
|
throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
|
|
6029
6465
|
}
|
|
6030
6466
|
if (!isYes) {
|
|
6031
6467
|
const action = confirmFlag === "1" ? "confirm" : "cancel";
|
|
6032
|
-
const ok = await
|
|
6468
|
+
const ok = await confirm16({ message: `${action} refund ${refundOrderNo}?`, default: false });
|
|
6033
6469
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Refund confirmation aborted by user.");
|
|
6034
6470
|
}
|
|
6035
6471
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -6192,6 +6628,8 @@ Key notes:
|
|
|
6192
6628
|
);
|
|
6193
6629
|
registerQuoteCommand(rideCmd, deps);
|
|
6194
6630
|
registerBookCommand(rideCmd, deps);
|
|
6631
|
+
registerRideCreateOrderCommand(rideCmd, deps);
|
|
6632
|
+
registerRidePayOrderCommand(rideCmd, deps);
|
|
6195
6633
|
registerRideGetCommand(rideCmd, deps);
|
|
6196
6634
|
registerCancelCommand(rideCmd, deps);
|
|
6197
6635
|
registerRideUpdateCommand(rideCmd, deps);
|