@agenzo/merchant-cli 0.8.15 → 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 +588 -173
- 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,
|
|
@@ -1537,6 +1656,12 @@ var hotelPayOrderSchema = {
|
|
|
1537
1656
|
required: false,
|
|
1538
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)."
|
|
1539
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
|
+
},
|
|
1540
1665
|
"idempotency-key": {
|
|
1541
1666
|
type: "string",
|
|
1542
1667
|
required: true,
|
|
@@ -2216,6 +2341,7 @@ var flightPayOrderSchema = flightSchema(
|
|
|
2216
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)." },
|
|
2217
2342
|
"payment-token-id": { type: "string", required: false, description: "Optional network-token id; settles via direct charge instead of EVO preauth." },
|
|
2218
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." },
|
|
2219
2345
|
"idempotency-key": { type: "string", required: true, description: "Forwarded verbatim as the Idempotency-Key header." }
|
|
2220
2346
|
},
|
|
2221
2347
|
{ order_no: { type: "string", description: "Our order reference." }, status: { type: "string", description: "PAID on success; AUTHENTICATION_REQUIRED when the card needs 3DS." } },
|
|
@@ -2561,7 +2687,7 @@ function registerBookCommand(parent, deps) {
|
|
|
2561
2687
|
"Bound payment method id to charge (pay_per_call mode only)"
|
|
2562
2688
|
).option(
|
|
2563
2689
|
"--payment-token-id <id>",
|
|
2564
|
-
"
|
|
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."
|
|
2565
2691
|
).option(
|
|
2566
2692
|
"--authorized-merchant-trans-id <id>",
|
|
2567
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)."
|
|
@@ -2677,13 +2803,292 @@ function registerBookCommand(parent, deps) {
|
|
|
2677
2803
|
});
|
|
2678
2804
|
}
|
|
2679
2805
|
|
|
2680
|
-
// src/ride-elife/
|
|
2806
|
+
// src/ride-elife/create-order.ts
|
|
2807
|
+
import { confirm as confirm2 } from "@inquirer/prompts";
|
|
2681
2808
|
function need3(value, flag) {
|
|
2682
2809
|
if (value === void 0) {
|
|
2683
2810
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2684
2811
|
}
|
|
2685
2812
|
return value;
|
|
2686
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
|
+
}
|
|
2687
3092
|
function formatGetOrder(data) {
|
|
2688
3093
|
const lines = [
|
|
2689
3094
|
["Ride ID", String(data.ride_id ?? "-")],
|
|
@@ -2710,8 +3115,8 @@ function formatGetOrder(data) {
|
|
|
2710
3115
|
}
|
|
2711
3116
|
if (data.driver) {
|
|
2712
3117
|
const driver = data.driver;
|
|
2713
|
-
const
|
|
2714
|
-
lines.push(["Driver", `${driver.name ?? "-"}${
|
|
3118
|
+
const phone3 = driver.phone_number ? ` (${driver.phone_number})` : "";
|
|
3119
|
+
lines.push(["Driver", `${driver.name ?? "-"}${phone3}`]);
|
|
2715
3120
|
}
|
|
2716
3121
|
if (data.vehicle) {
|
|
2717
3122
|
const v = data.vehicle;
|
|
@@ -2738,7 +3143,7 @@ function registerRideGetCommand(parent, deps) {
|
|
|
2738
3143
|
message: "API Key:",
|
|
2739
3144
|
type: "password"
|
|
2740
3145
|
});
|
|
2741
|
-
const orderId =
|
|
3146
|
+
const orderId = need5(opts.orderId, "order-id");
|
|
2742
3147
|
if (opts.watch) {
|
|
2743
3148
|
await watchRideStatus(deps.apiClient, apiKey, orderId, {
|
|
2744
3149
|
intervalSeconds: resolveSeconds(
|
|
@@ -2772,8 +3177,8 @@ function registerRideGetCommand(parent, deps) {
|
|
|
2772
3177
|
}
|
|
2773
3178
|
|
|
2774
3179
|
// src/ride-elife/cancel.ts
|
|
2775
|
-
import { confirm as
|
|
2776
|
-
function
|
|
3180
|
+
import { confirm as confirm4 } from "@inquirer/prompts";
|
|
3181
|
+
function need6(value, flag) {
|
|
2777
3182
|
if (value === void 0) {
|
|
2778
3183
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2779
3184
|
}
|
|
@@ -2808,9 +3213,9 @@ function registerCancelCommand(parent, deps) {
|
|
|
2808
3213
|
message: "API Key:",
|
|
2809
3214
|
type: "password"
|
|
2810
3215
|
});
|
|
2811
|
-
const orderId =
|
|
3216
|
+
const orderId = need6(opts.orderId, "order-id");
|
|
2812
3217
|
if (!isYes) {
|
|
2813
|
-
const confirmed = await
|
|
3218
|
+
const confirmed = await confirm4({
|
|
2814
3219
|
message: `Cancel ride ${orderId}? This may incur a fee.`,
|
|
2815
3220
|
default: false
|
|
2816
3221
|
});
|
|
@@ -2844,14 +3249,14 @@ function registerCancelCommand(parent, deps) {
|
|
|
2844
3249
|
}
|
|
2845
3250
|
|
|
2846
3251
|
// src/ride-elife/update.ts
|
|
2847
|
-
import { confirm as
|
|
2848
|
-
function
|
|
3252
|
+
import { confirm as confirm5 } from "@inquirer/prompts";
|
|
3253
|
+
function need7(value, flag) {
|
|
2849
3254
|
if (value === void 0) {
|
|
2850
3255
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2851
3256
|
}
|
|
2852
3257
|
return value;
|
|
2853
3258
|
}
|
|
2854
|
-
function
|
|
3259
|
+
function num4(value, flag) {
|
|
2855
3260
|
if (value === void 0) return void 0;
|
|
2856
3261
|
const parsed = Number(value);
|
|
2857
3262
|
if (!Number.isFinite(parsed)) {
|
|
@@ -2860,7 +3265,7 @@ function num3(value, flag) {
|
|
|
2860
3265
|
return parsed;
|
|
2861
3266
|
}
|
|
2862
3267
|
function int(value, flag) {
|
|
2863
|
-
const parsed =
|
|
3268
|
+
const parsed = num4(value, flag);
|
|
2864
3269
|
if (parsed === void 0) return void 0;
|
|
2865
3270
|
if (!Number.isInteger(parsed)) {
|
|
2866
3271
|
throw new CliError("PARAM_INVALID", `--${flag} must be an integer.`);
|
|
@@ -2885,8 +3290,8 @@ function location(lat, lng, name, side) {
|
|
|
2885
3290
|
);
|
|
2886
3291
|
}
|
|
2887
3292
|
return {
|
|
2888
|
-
lat:
|
|
2889
|
-
lng:
|
|
3293
|
+
lat: num4(lat, `${side}-lat`),
|
|
3294
|
+
lng: num4(lng, `${side}-lng`),
|
|
2890
3295
|
name
|
|
2891
3296
|
};
|
|
2892
3297
|
}
|
|
@@ -2912,7 +3317,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2912
3317
|
message: "API Key:",
|
|
2913
3318
|
type: "password"
|
|
2914
3319
|
});
|
|
2915
|
-
const orderId =
|
|
3320
|
+
const orderId = need7(opts.orderId, "order-id");
|
|
2916
3321
|
const mgTouched = process.argv.some(
|
|
2917
3322
|
(a) => a === "--meet-and-greet" || a === "--no-meet-and-greet"
|
|
2918
3323
|
);
|
|
@@ -2922,7 +3327,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2922
3327
|
};
|
|
2923
3328
|
set("quote_id", opts.quoteId);
|
|
2924
3329
|
set("vehicle_class", opts.vehicleClass);
|
|
2925
|
-
set("price_amount",
|
|
3330
|
+
set("price_amount", num4(opts.priceAmount, "price-amount"));
|
|
2926
3331
|
set("price_currency", opts.priceCurrency);
|
|
2927
3332
|
set(
|
|
2928
3333
|
"pickup",
|
|
@@ -2969,7 +3374,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2969
3374
|
);
|
|
2970
3375
|
}
|
|
2971
3376
|
if (!isYes) {
|
|
2972
|
-
const confirmed = await
|
|
3377
|
+
const confirmed = await confirm5({
|
|
2973
3378
|
message: `Apply ${Object.keys(body).length} change(s) to ride ${orderId}? The fare may change.`,
|
|
2974
3379
|
default: false
|
|
2975
3380
|
});
|
|
@@ -3003,7 +3408,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
3003
3408
|
}
|
|
3004
3409
|
|
|
3005
3410
|
// src/ride-elife/trip-status.ts
|
|
3006
|
-
function
|
|
3411
|
+
function need8(value, flag) {
|
|
3007
3412
|
if (value === void 0) {
|
|
3008
3413
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3009
3414
|
}
|
|
@@ -3041,7 +3446,7 @@ function registerRideTripStatusCommand(parent, deps) {
|
|
|
3041
3446
|
message: "API Key:",
|
|
3042
3447
|
type: "password"
|
|
3043
3448
|
});
|
|
3044
|
-
const orderId =
|
|
3449
|
+
const orderId = need8(opts.orderId, "order-id");
|
|
3045
3450
|
const leg = tripNo(opts.tripNo);
|
|
3046
3451
|
const spinner = format === "json" ? null : createSpinner("Fetching trip status...");
|
|
3047
3452
|
const result = await deps.apiClient.get(
|
|
@@ -3570,28 +3975,28 @@ function registerOrdersGetCommand(parent, deps) {
|
|
|
3570
3975
|
}
|
|
3571
3976
|
|
|
3572
3977
|
// src/hotel-redaug/search.ts
|
|
3573
|
-
function
|
|
3978
|
+
function need9(value, flag) {
|
|
3574
3979
|
if (value === void 0) {
|
|
3575
3980
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3576
3981
|
}
|
|
3577
3982
|
return value;
|
|
3578
3983
|
}
|
|
3579
|
-
function
|
|
3580
|
-
const n = Number(
|
|
3984
|
+
function num5(value, flag) {
|
|
3985
|
+
const n = Number(need9(value, flag));
|
|
3581
3986
|
if (!Number.isFinite(n)) {
|
|
3582
3987
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3583
3988
|
}
|
|
3584
3989
|
return n;
|
|
3585
3990
|
}
|
|
3586
3991
|
function coord(value, flag, min, max) {
|
|
3587
|
-
const n =
|
|
3992
|
+
const n = num5(value, flag);
|
|
3588
3993
|
if (n < min || n > max) {
|
|
3589
3994
|
throw new CliError("PARAM_INVALID", `--${flag} must be between ${min} and ${max}.`);
|
|
3590
3995
|
}
|
|
3591
3996
|
return n;
|
|
3592
3997
|
}
|
|
3593
3998
|
function positiveInt3(value, flag) {
|
|
3594
|
-
const n =
|
|
3999
|
+
const n = num5(value, flag);
|
|
3595
4000
|
if (!Number.isInteger(n) || n <= 0) {
|
|
3596
4001
|
throw new CliError("PARAM_INVALID", `--${flag} must be a positive integer.`);
|
|
3597
4002
|
}
|
|
@@ -3599,7 +4004,7 @@ function positiveInt3(value, flag) {
|
|
|
3599
4004
|
}
|
|
3600
4005
|
var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3601
4006
|
function stayDate(value, flag) {
|
|
3602
|
-
const raw =
|
|
4007
|
+
const raw = need9(value, flag);
|
|
3603
4008
|
if (!YMD_RE.test(raw)) {
|
|
3604
4009
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3605
4010
|
}
|
|
@@ -3671,21 +4076,21 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
3671
4076
|
const pageSize = positiveInt3(opts.pageSize, "page-size");
|
|
3672
4077
|
const body = {};
|
|
3673
4078
|
if (hasDestination) {
|
|
3674
|
-
body.destination_id =
|
|
4079
|
+
body.destination_id = need9(opts.destinationId, "destination-id");
|
|
3675
4080
|
} else {
|
|
3676
4081
|
body.lat = coord(opts.lat, "lat", -90, 90);
|
|
3677
4082
|
body.lng = coord(opts.lng, "lng", -180, 180);
|
|
3678
4083
|
}
|
|
3679
|
-
body.distance =
|
|
4084
|
+
body.distance = num5(opts.distance, "distance");
|
|
3680
4085
|
body.check_in = checkIn;
|
|
3681
4086
|
body.check_out = checkOut;
|
|
3682
|
-
body.adults =
|
|
3683
|
-
body.children =
|
|
3684
|
-
body.room_num =
|
|
3685
|
-
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");
|
|
3686
4091
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
3687
|
-
if (opts.priceMin !== void 0) body.price_min =
|
|
3688
|
-
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");
|
|
3689
4094
|
if (opts.sortBy !== void 0) body.sort_by = opts.sortBy;
|
|
3690
4095
|
body.page = page;
|
|
3691
4096
|
body.page_size = pageSize;
|
|
@@ -3714,14 +4119,14 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
3714
4119
|
}
|
|
3715
4120
|
|
|
3716
4121
|
// src/hotel-redaug/quote.ts
|
|
3717
|
-
function
|
|
4122
|
+
function need10(value, flag) {
|
|
3718
4123
|
if (value === void 0) {
|
|
3719
4124
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3720
4125
|
}
|
|
3721
4126
|
return value;
|
|
3722
4127
|
}
|
|
3723
|
-
function
|
|
3724
|
-
const n = Number(
|
|
4128
|
+
function num6(value, flag) {
|
|
4129
|
+
const n = Number(need10(value, flag));
|
|
3725
4130
|
if (!Number.isFinite(n)) {
|
|
3726
4131
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3727
4132
|
}
|
|
@@ -3729,7 +4134,7 @@ function num5(value, flag) {
|
|
|
3729
4134
|
}
|
|
3730
4135
|
var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3731
4136
|
function stayDate2(value, flag) {
|
|
3732
|
-
const raw =
|
|
4137
|
+
const raw = need10(value, flag);
|
|
3733
4138
|
if (!YMD_RE2.test(raw)) {
|
|
3734
4139
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3735
4140
|
}
|
|
@@ -3769,7 +4174,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3769
4174
|
message: "API Key:",
|
|
3770
4175
|
type: "password"
|
|
3771
4176
|
});
|
|
3772
|
-
const hotelId =
|
|
4177
|
+
const hotelId = need10(opts.hotelId, "hotel-id");
|
|
3773
4178
|
const checkIn = stayDate2(opts.checkIn, "check-in");
|
|
3774
4179
|
const checkOut = stayDate2(opts.checkOut, "check-out");
|
|
3775
4180
|
if (!(checkOut > checkIn)) {
|
|
@@ -3779,9 +4184,9 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3779
4184
|
hotel_id: hotelId,
|
|
3780
4185
|
check_in: checkIn,
|
|
3781
4186
|
check_out: checkOut,
|
|
3782
|
-
adults:
|
|
3783
|
-
children:
|
|
3784
|
-
room_num:
|
|
4187
|
+
adults: num6(opts.adults, "adults"),
|
|
4188
|
+
children: num6(opts.children, "children"),
|
|
4189
|
+
room_num: num6(opts.roomNum, "room-num"),
|
|
3785
4190
|
nationality: opts.nationality
|
|
3786
4191
|
};
|
|
3787
4192
|
const result = await deps.apiClient.post(
|
|
@@ -3803,7 +4208,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3803
4208
|
}
|
|
3804
4209
|
|
|
3805
4210
|
// src/hotel-redaug/create-order.ts
|
|
3806
|
-
import { confirm as
|
|
4211
|
+
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
3807
4212
|
function parsePriceItems(raw) {
|
|
3808
4213
|
const INVALID = "--price-items must be a JSON array of {sale_date (string), sale_price (number), breakfast_num (number)}.";
|
|
3809
4214
|
let parsed;
|
|
@@ -3861,14 +4266,14 @@ function parseCancellation(raw) {
|
|
|
3861
4266
|
}
|
|
3862
4267
|
return parsed;
|
|
3863
4268
|
}
|
|
3864
|
-
function
|
|
4269
|
+
function need11(value, flag) {
|
|
3865
4270
|
if (value === void 0) {
|
|
3866
4271
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3867
4272
|
}
|
|
3868
4273
|
return value;
|
|
3869
4274
|
}
|
|
3870
|
-
function
|
|
3871
|
-
const n = Number(
|
|
4275
|
+
function num7(value, flag) {
|
|
4276
|
+
const n = Number(need11(value, flag));
|
|
3872
4277
|
if (!Number.isFinite(n)) {
|
|
3873
4278
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3874
4279
|
}
|
|
@@ -3876,7 +4281,7 @@ function num6(value, flag) {
|
|
|
3876
4281
|
}
|
|
3877
4282
|
var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3878
4283
|
function stayDate3(value, flag) {
|
|
3879
|
-
const raw =
|
|
4284
|
+
const raw = need11(value, flag);
|
|
3880
4285
|
if (!YMD_RE3.test(raw)) {
|
|
3881
4286
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3882
4287
|
}
|
|
@@ -3887,7 +4292,7 @@ function stayDate3(value, flag) {
|
|
|
3887
4292
|
}
|
|
3888
4293
|
return raw;
|
|
3889
4294
|
}
|
|
3890
|
-
function
|
|
4295
|
+
function formatCreateOrder2(data) {
|
|
3891
4296
|
const lines = [
|
|
3892
4297
|
["Order ID", String(data.order_id ?? "-")],
|
|
3893
4298
|
["FC order code", String(data.fc_order_code ?? "-")],
|
|
@@ -3945,18 +4350,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3945
4350
|
message: "API Key:",
|
|
3946
4351
|
type: "password"
|
|
3947
4352
|
});
|
|
3948
|
-
const productToken =
|
|
3949
|
-
const totalAmount =
|
|
3950
|
-
const currency =
|
|
3951
|
-
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"));
|
|
3952
4357
|
const checkIn = stayDate3(opts.checkIn, "check-in");
|
|
3953
4358
|
const checkOut = stayDate3(opts.checkOut, "check-out");
|
|
3954
4359
|
if (!(checkOut > checkIn)) {
|
|
3955
4360
|
throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
|
|
3956
4361
|
}
|
|
3957
|
-
const guestName =
|
|
3958
|
-
const contactName =
|
|
3959
|
-
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");
|
|
3960
4365
|
const body = {
|
|
3961
4366
|
product_token: productToken,
|
|
3962
4367
|
total_amount: totalAmount,
|
|
@@ -3964,9 +4369,9 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3964
4369
|
price_items: priceItems,
|
|
3965
4370
|
check_in: checkIn,
|
|
3966
4371
|
check_out: checkOut,
|
|
3967
|
-
room_num:
|
|
3968
|
-
adults:
|
|
3969
|
-
children:
|
|
4372
|
+
room_num: num7(opts.roomNum, "room-num"),
|
|
4373
|
+
adults: num7(opts.adults, "adults"),
|
|
4374
|
+
children: num7(opts.children, "children"),
|
|
3970
4375
|
nationality: opts.nationality,
|
|
3971
4376
|
guest_name: guestName,
|
|
3972
4377
|
contact_name: contactName,
|
|
@@ -3990,7 +4395,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3990
4395
|
if (member !== void 0) body.member_id = member;
|
|
3991
4396
|
if (!isYes) {
|
|
3992
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.";
|
|
3993
|
-
const confirmed = await
|
|
4398
|
+
const confirmed = await confirm6({
|
|
3994
4399
|
message: `Create this hotel order for ${totalAmount} ${currency} (check-in ${checkIn}, check-out ${checkOut})? ${chargeNote}`,
|
|
3995
4400
|
default: false
|
|
3996
4401
|
});
|
|
@@ -4017,14 +4422,14 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4017
4422
|
const configManager = new ConfigManager();
|
|
4018
4423
|
const commandResult = {
|
|
4019
4424
|
data,
|
|
4020
|
-
text: () =>
|
|
4425
|
+
text: () => formatCreateOrder2(data)
|
|
4021
4426
|
};
|
|
4022
4427
|
await renderWithContext(commandResult, { format }, configManager);
|
|
4023
4428
|
});
|
|
4024
4429
|
}
|
|
4025
4430
|
|
|
4026
4431
|
// src/hotel-redaug/pay-order.ts
|
|
4027
|
-
import { confirm as
|
|
4432
|
+
import { confirm as confirm7 } from "@inquirer/prompts";
|
|
4028
4433
|
|
|
4029
4434
|
// src/hotel-redaug/watch.ts
|
|
4030
4435
|
var DEFAULT_ORDER_WATCH_INTERVAL_SECONDS = 5;
|
|
@@ -4147,7 +4552,7 @@ async function watchCheckoutStatus(apiClient, apiKey, taskOrderCode, opts) {
|
|
|
4147
4552
|
// src/hotel-redaug/pay-order.ts
|
|
4148
4553
|
var DEFAULT_PAY_WATCH_INTERVAL_SECONDS = 5;
|
|
4149
4554
|
var DEFAULT_PAY_WATCH_TIMEOUT_SECONDS = 300;
|
|
4150
|
-
function
|
|
4555
|
+
function formatPayOrder2(data) {
|
|
4151
4556
|
const lines = [
|
|
4152
4557
|
["Order ID", String(data.order_id ?? "-")],
|
|
4153
4558
|
["Order status", String(data.order_status ?? "-")]
|
|
@@ -4169,6 +4574,9 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4169
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(
|
|
4170
4575
|
"--authorized-merchant-trans-id <id>",
|
|
4171
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."
|
|
4172
4580
|
).option(
|
|
4173
4581
|
"--idempotency-key <key>",
|
|
4174
4582
|
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
@@ -4207,8 +4615,9 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4207
4615
|
if (opts.authorizedMerchantTransId !== void 0) {
|
|
4208
4616
|
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
4209
4617
|
}
|
|
4618
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
4210
4619
|
if (!isYes) {
|
|
4211
|
-
const confirmed = await
|
|
4620
|
+
const confirmed = await confirm7({
|
|
4212
4621
|
message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
|
|
4213
4622
|
default: false
|
|
4214
4623
|
});
|
|
@@ -4235,7 +4644,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4235
4644
|
const configManager = new ConfigManager();
|
|
4236
4645
|
const commandResult = {
|
|
4237
4646
|
data,
|
|
4238
|
-
text: () =>
|
|
4647
|
+
text: () => formatPayOrder2(data)
|
|
4239
4648
|
};
|
|
4240
4649
|
await renderWithContext(commandResult, { format }, configManager);
|
|
4241
4650
|
} else {
|
|
@@ -4286,7 +4695,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4286
4695
|
}
|
|
4287
4696
|
|
|
4288
4697
|
// src/hotel-redaug/get.ts
|
|
4289
|
-
function
|
|
4698
|
+
function need12(value, flag) {
|
|
4290
4699
|
if (value === void 0) {
|
|
4291
4700
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4292
4701
|
}
|
|
@@ -4324,8 +4733,8 @@ function formatGetOrder2(data) {
|
|
|
4324
4733
|
}
|
|
4325
4734
|
if (data.guest?.name) lines.push(["Guest", String(data.guest.name)]);
|
|
4326
4735
|
if (data.contact?.name) {
|
|
4327
|
-
const
|
|
4328
|
-
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}`]);
|
|
4329
4738
|
}
|
|
4330
4739
|
if (data.arrive_time) lines.push(["Arrive time", String(data.arrive_time)]);
|
|
4331
4740
|
if (data.special_requests) lines.push(["Special requests", String(data.special_requests)]);
|
|
@@ -4350,7 +4759,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4350
4759
|
message: "API Key:",
|
|
4351
4760
|
type: "password"
|
|
4352
4761
|
});
|
|
4353
|
-
const orderId =
|
|
4762
|
+
const orderId = need12(opts.orderId, "order-id");
|
|
4354
4763
|
if (opts.watch) {
|
|
4355
4764
|
await watchOrderStatus(deps.apiClient, apiKey, orderId, {
|
|
4356
4765
|
intervalSeconds: resolveSeconds(
|
|
@@ -4384,7 +4793,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4384
4793
|
}
|
|
4385
4794
|
|
|
4386
4795
|
// src/hotel-redaug/cancel.ts
|
|
4387
|
-
function
|
|
4796
|
+
function need13(value, flag) {
|
|
4388
4797
|
if (value === void 0) {
|
|
4389
4798
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4390
4799
|
}
|
|
@@ -4437,8 +4846,8 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4437
4846
|
message: "API Key:",
|
|
4438
4847
|
type: "password"
|
|
4439
4848
|
});
|
|
4440
|
-
const orderId =
|
|
4441
|
-
const fcOrderCode =
|
|
4849
|
+
const orderId = need13(opts.orderId, "order-id");
|
|
4850
|
+
const fcOrderCode = need13(opts.fcOrderCode, "fc-order-code");
|
|
4442
4851
|
const body = { fc_order_code: fcOrderCode };
|
|
4443
4852
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
4444
4853
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -4467,15 +4876,15 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4467
4876
|
}
|
|
4468
4877
|
|
|
4469
4878
|
// src/hotel-redaug/checkout.ts
|
|
4470
|
-
import { confirm as
|
|
4471
|
-
function
|
|
4879
|
+
import { confirm as confirm8 } from "@inquirer/prompts";
|
|
4880
|
+
function need14(value, flag) {
|
|
4472
4881
|
if (value === void 0) {
|
|
4473
4882
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4474
4883
|
}
|
|
4475
4884
|
return value;
|
|
4476
4885
|
}
|
|
4477
|
-
function
|
|
4478
|
-
const n = Number(
|
|
4886
|
+
function num8(value, flag) {
|
|
4887
|
+
const n = Number(need14(value, flag));
|
|
4479
4888
|
if (!Number.isFinite(n)) {
|
|
4480
4889
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4481
4890
|
}
|
|
@@ -4541,11 +4950,11 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4541
4950
|
message: "API Key:",
|
|
4542
4951
|
type: "password"
|
|
4543
4952
|
});
|
|
4544
|
-
const orderId =
|
|
4545
|
-
const fcOrderCode =
|
|
4546
|
-
const reason =
|
|
4547
|
-
const checkoutRooms = parseCheckoutRooms(
|
|
4548
|
-
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");
|
|
4549
4958
|
const body = {
|
|
4550
4959
|
fc_order_code: fcOrderCode,
|
|
4551
4960
|
reason,
|
|
@@ -4553,7 +4962,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4553
4962
|
checkout_rooms: checkoutRooms
|
|
4554
4963
|
};
|
|
4555
4964
|
if (!isYes) {
|
|
4556
|
-
const confirmed = await
|
|
4965
|
+
const confirmed = await confirm8({
|
|
4557
4966
|
message: `Request check-out / out-of-policy cancellation for order ${orderId} (${checkoutRooms.length} room(s))? The property must approve and charges may apply.`,
|
|
4558
4967
|
default: false
|
|
4559
4968
|
});
|
|
@@ -4587,7 +4996,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4587
4996
|
}
|
|
4588
4997
|
|
|
4589
4998
|
// src/hotel-redaug/get-checkout.ts
|
|
4590
|
-
function
|
|
4999
|
+
function need15(value, flag) {
|
|
4591
5000
|
if (value === void 0) {
|
|
4592
5001
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4593
5002
|
}
|
|
@@ -4623,7 +5032,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
|
|
|
4623
5032
|
message: "API Key:",
|
|
4624
5033
|
type: "password"
|
|
4625
5034
|
});
|
|
4626
|
-
const taskOrderCode =
|
|
5035
|
+
const taskOrderCode = need15(opts.taskOrderCode, "task-order-code");
|
|
4627
5036
|
if (opts.watch) {
|
|
4628
5037
|
await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
|
|
4629
5038
|
intervalSeconds: resolveSeconds(
|
|
@@ -4727,7 +5136,7 @@ function registerHotelListOrdersCommand(parent, deps) {
|
|
|
4727
5136
|
}
|
|
4728
5137
|
|
|
4729
5138
|
// src/hotel-redaug/find-destination.ts
|
|
4730
|
-
function
|
|
5139
|
+
function need16(value, flag) {
|
|
4731
5140
|
if (value === void 0 || value.trim() === "") {
|
|
4732
5141
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4733
5142
|
}
|
|
@@ -4761,7 +5170,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
4761
5170
|
message: "API Key:",
|
|
4762
5171
|
type: "password"
|
|
4763
5172
|
});
|
|
4764
|
-
const keyword =
|
|
5173
|
+
const keyword = need16(opts.keyword, "keyword");
|
|
4765
5174
|
const body = { keyword };
|
|
4766
5175
|
if (opts.dataType !== void 0) {
|
|
4767
5176
|
body.data_type = opts.dataType;
|
|
@@ -4785,21 +5194,21 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
4785
5194
|
}
|
|
4786
5195
|
|
|
4787
5196
|
// src/hotel-redaug/hotel-filters.ts
|
|
4788
|
-
function
|
|
5197
|
+
function need17(value, flag) {
|
|
4789
5198
|
if (value === void 0 || value.trim() === "") {
|
|
4790
5199
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4791
5200
|
}
|
|
4792
5201
|
return value;
|
|
4793
5202
|
}
|
|
4794
|
-
function
|
|
4795
|
-
const n = Number(
|
|
5203
|
+
function num9(value, flag) {
|
|
5204
|
+
const n = Number(need17(value, flag));
|
|
4796
5205
|
if (!Number.isFinite(n)) {
|
|
4797
5206
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4798
5207
|
}
|
|
4799
5208
|
return n;
|
|
4800
5209
|
}
|
|
4801
5210
|
function coord2(value, flag, min, max) {
|
|
4802
|
-
const n =
|
|
5211
|
+
const n = num9(value, flag);
|
|
4803
5212
|
if (n < min || n > max) {
|
|
4804
5213
|
throw new CliError("PARAM_INVALID", `--${flag} must be between ${min} and ${max}.`);
|
|
4805
5214
|
}
|
|
@@ -4872,12 +5281,12 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
4872
5281
|
}
|
|
4873
5282
|
const body = {};
|
|
4874
5283
|
if (hasDestination) {
|
|
4875
|
-
body.destination_id =
|
|
5284
|
+
body.destination_id = need17(opts.destinationId, "destination-id");
|
|
4876
5285
|
} else {
|
|
4877
5286
|
body.lat = coord2(opts.lat, "lat", -90, 90);
|
|
4878
5287
|
body.lng = coord2(opts.lng, "lng", -180, 180);
|
|
4879
5288
|
}
|
|
4880
|
-
body.distance =
|
|
5289
|
+
body.distance = num9(opts.distance, "distance");
|
|
4881
5290
|
const result = await deps.apiClient.post(
|
|
4882
5291
|
"/hotel/filters",
|
|
4883
5292
|
{ type: "api-key", key: apiKey },
|
|
@@ -4897,7 +5306,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
4897
5306
|
}
|
|
4898
5307
|
|
|
4899
5308
|
// src/hotel-redaug/list-cities.ts
|
|
4900
|
-
function
|
|
5309
|
+
function need18(value, flag) {
|
|
4901
5310
|
if (value === void 0 || value.trim() === "") {
|
|
4902
5311
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4903
5312
|
}
|
|
@@ -4930,7 +5339,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
4930
5339
|
message: "API Key:",
|
|
4931
5340
|
type: "password"
|
|
4932
5341
|
});
|
|
4933
|
-
const country =
|
|
5342
|
+
const country = need18(opts.country, "country");
|
|
4934
5343
|
const body = { country_code: country };
|
|
4935
5344
|
const result = await deps.apiClient.post(
|
|
4936
5345
|
"/hotel/cities",
|
|
@@ -4951,7 +5360,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
4951
5360
|
}
|
|
4952
5361
|
|
|
4953
5362
|
// src/hotel-redaug/hotel-detail.ts
|
|
4954
|
-
function
|
|
5363
|
+
function need19(value, flag) {
|
|
4955
5364
|
if (value === void 0 || value.trim() === "") {
|
|
4956
5365
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4957
5366
|
}
|
|
@@ -5098,7 +5507,7 @@ function registerHotelDetailCommand(parent, deps) {
|
|
|
5098
5507
|
message: "API Key:",
|
|
5099
5508
|
type: "password"
|
|
5100
5509
|
});
|
|
5101
|
-
const hotelId =
|
|
5510
|
+
const hotelId = need19(opts.hotelId, "hotel-id");
|
|
5102
5511
|
const rawWithImages = opts.withImages;
|
|
5103
5512
|
const withImages = rawWithImages !== "false" && rawWithImages !== false;
|
|
5104
5513
|
const settings = parseSettings(opts.settings);
|
|
@@ -5306,14 +5715,14 @@ function registerHotelSkillCommand(parent) {
|
|
|
5306
5715
|
}
|
|
5307
5716
|
|
|
5308
5717
|
// src/flight-flink/_helpers.ts
|
|
5309
|
-
function
|
|
5718
|
+
function need20(value, flag) {
|
|
5310
5719
|
if (value === void 0) {
|
|
5311
5720
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5312
5721
|
}
|
|
5313
5722
|
return value;
|
|
5314
5723
|
}
|
|
5315
|
-
function
|
|
5316
|
-
const n = Number(
|
|
5724
|
+
function num10(value, flag) {
|
|
5725
|
+
const n = Number(need20(value, flag));
|
|
5317
5726
|
if (!Number.isFinite(n)) {
|
|
5318
5727
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5319
5728
|
}
|
|
@@ -5348,7 +5757,7 @@ function registerFindAirportCommand(parent, deps) {
|
|
|
5348
5757
|
const opts = cmd.optsWithGlobals();
|
|
5349
5758
|
const format = resolveFormat(opts.format);
|
|
5350
5759
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5351
|
-
const keyword =
|
|
5760
|
+
const keyword = need20(opts.keyword, "keyword");
|
|
5352
5761
|
const spinner = format === "json" ? null : createSpinner("Resolving airports...");
|
|
5353
5762
|
const result = await deps.apiClient.post(
|
|
5354
5763
|
"/flight/find-airport",
|
|
@@ -5374,8 +5783,8 @@ function registerListAirportsCommand(parent, deps) {
|
|
|
5374
5783
|
const format = resolveFormat(opts.format);
|
|
5375
5784
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5376
5785
|
const body = {
|
|
5377
|
-
page:
|
|
5378
|
-
page_size:
|
|
5786
|
+
page: num10(opts.page, "page"),
|
|
5787
|
+
page_size: num10(opts.pageSize, "page-size")
|
|
5379
5788
|
};
|
|
5380
5789
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
5381
5790
|
const spinner = format === "json" ? null : createSpinner("Fetching airports...");
|
|
@@ -5399,8 +5808,8 @@ function registerListAirlinesCommand(parent, deps) {
|
|
|
5399
5808
|
const format = resolveFormat(opts.format);
|
|
5400
5809
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5401
5810
|
const body = {
|
|
5402
|
-
page:
|
|
5403
|
-
page_size:
|
|
5811
|
+
page: num10(opts.page, "page"),
|
|
5812
|
+
page_size: num10(opts.pageSize, "page-size")
|
|
5404
5813
|
};
|
|
5405
5814
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
5406
5815
|
const spinner = format === "json" ? null : createSpinner("Fetching airlines...");
|
|
@@ -5444,13 +5853,13 @@ function registerSearchCommand(parent, deps) {
|
|
|
5444
5853
|
const format = resolveFormat(opts.format);
|
|
5445
5854
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5446
5855
|
const body = {
|
|
5447
|
-
trip_type:
|
|
5448
|
-
journeys: jsonArray(
|
|
5856
|
+
trip_type: num10(opts.tripType, "trip-type"),
|
|
5857
|
+
journeys: jsonArray(need20(opts.journeys, "journeys"), "journeys"),
|
|
5449
5858
|
cabin_class: opts.cabinClass,
|
|
5450
|
-
adult_num:
|
|
5451
|
-
child_num:
|
|
5452
|
-
infant_num:
|
|
5453
|
-
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")
|
|
5454
5863
|
};
|
|
5455
5864
|
if (opts.airline !== void 0) body.airline = opts.airline;
|
|
5456
5865
|
if (opts.journeyId !== void 0) {
|
|
@@ -5476,7 +5885,7 @@ function registerMoreOffersCommand(parent, deps) {
|
|
|
5476
5885
|
const opts = cmd.optsWithGlobals();
|
|
5477
5886
|
const format = resolveFormat(opts.format);
|
|
5478
5887
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5479
|
-
const productToken =
|
|
5888
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5480
5889
|
const spinner = format === "json" ? null : createSpinner("Fetching offers...");
|
|
5481
5890
|
const result = await deps.apiClient.post(
|
|
5482
5891
|
"/flight/more-offers",
|
|
@@ -5497,7 +5906,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5497
5906
|
const opts = cmd.optsWithGlobals();
|
|
5498
5907
|
const format = resolveFormat(opts.format);
|
|
5499
5908
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5500
|
-
const productToken =
|
|
5909
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5501
5910
|
const spinner = format === "json" ? null : createSpinner("Verifying price...");
|
|
5502
5911
|
const result = await deps.apiClient.post(
|
|
5503
5912
|
"/flight/verify",
|
|
@@ -5519,7 +5928,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5519
5928
|
}
|
|
5520
5929
|
|
|
5521
5930
|
// src/flight-flink/create-order.ts
|
|
5522
|
-
import { confirm as
|
|
5931
|
+
import { confirm as confirm9 } from "@inquirer/prompts";
|
|
5523
5932
|
function registerCreateOrderCommand(parent, deps) {
|
|
5524
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(
|
|
5525
5934
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5531,19 +5940,19 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5531
5940
|
const format = resolveFormat(opts.format);
|
|
5532
5941
|
const isYes = Boolean(opts.yes);
|
|
5533
5942
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5534
|
-
const productToken =
|
|
5535
|
-
const totalAmount =
|
|
5536
|
-
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");
|
|
5537
5946
|
const body = {
|
|
5538
5947
|
product_token: productToken,
|
|
5539
5948
|
total_amount: totalAmount,
|
|
5540
5949
|
currency,
|
|
5541
|
-
trip_type:
|
|
5542
|
-
contact_name:
|
|
5543
|
-
contact_region:
|
|
5544
|
-
contact_phone:
|
|
5545
|
-
contact_email:
|
|
5546
|
-
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")
|
|
5547
5956
|
};
|
|
5548
5957
|
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
5549
5958
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
@@ -5553,7 +5962,7 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5553
5962
|
const member = memberIdOf(opts);
|
|
5554
5963
|
if (member !== void 0) body.member_id = member;
|
|
5555
5964
|
if (!isYes) {
|
|
5556
|
-
const ok = await
|
|
5965
|
+
const ok = await confirm9({
|
|
5557
5966
|
message: `Create this flight order for ${totalAmount} ${currency}? This locks the fare but does NOT charge yet.`,
|
|
5558
5967
|
default: false
|
|
5559
5968
|
});
|
|
@@ -5592,11 +6001,14 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5592
6001
|
}
|
|
5593
6002
|
|
|
5594
6003
|
// src/flight-flink/pay-order.ts
|
|
5595
|
-
import { confirm as
|
|
6004
|
+
import { confirm as confirm10 } from "@inquirer/prompts";
|
|
5596
6005
|
function registerPayOrderCommand(parent, deps) {
|
|
5597
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(
|
|
5598
6007
|
"--authorized-merchant-trans-id <id>",
|
|
5599
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."
|
|
5600
6012
|
).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5601
6013
|
attachSchemaHelp(cmd, flightPayOrderSchema);
|
|
5602
6014
|
cmd.action(async () => {
|
|
@@ -5604,9 +6016,9 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
5604
6016
|
const format = resolveFormat(opts.format);
|
|
5605
6017
|
const isYes = Boolean(opts.yes);
|
|
5606
6018
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5607
|
-
const orderNo =
|
|
6019
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5608
6020
|
if (!isYes) {
|
|
5609
|
-
const ok = await
|
|
6021
|
+
const ok = await confirm10({
|
|
5610
6022
|
message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
|
|
5611
6023
|
default: false
|
|
5612
6024
|
});
|
|
@@ -5623,6 +6035,7 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
5623
6035
|
if (opts.authorizedMerchantTransId !== void 0) {
|
|
5624
6036
|
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
5625
6037
|
}
|
|
6038
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
5626
6039
|
const result = await deps.apiClient.post(
|
|
5627
6040
|
`/flight/${encodeURIComponent(orderNo)}/pay`,
|
|
5628
6041
|
{ type: "api-key", key: apiKey },
|
|
@@ -5655,12 +6068,12 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
5655
6068
|
const opts = cmd.optsWithGlobals();
|
|
5656
6069
|
const format = resolveFormat(opts.format);
|
|
5657
6070
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5658
|
-
const orderNo =
|
|
6071
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5659
6072
|
const path = `/flight/${encodeURIComponent(orderNo)}/status`;
|
|
5660
6073
|
const auth = { type: "api-key", key: apiKey };
|
|
5661
6074
|
if (opts.watch) {
|
|
5662
|
-
const interval =
|
|
5663
|
-
const timeoutMs =
|
|
6075
|
+
const interval = num10(opts.watchInterval, "watch-interval") * 1e3;
|
|
6076
|
+
const timeoutMs = num10(opts.watchTimeout, "watch-timeout") * 1e3;
|
|
5664
6077
|
const deadline = Date.now() + timeoutMs;
|
|
5665
6078
|
for (; ; ) {
|
|
5666
6079
|
const r = await deps.apiClient.get(path, auth);
|
|
@@ -5695,7 +6108,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
5695
6108
|
}
|
|
5696
6109
|
|
|
5697
6110
|
// src/flight-flink/cancel-order.ts
|
|
5698
|
-
import { confirm as
|
|
6111
|
+
import { confirm as confirm11 } from "@inquirer/prompts";
|
|
5699
6112
|
function registerCancelOrderCommand(parent, deps) {
|
|
5700
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");
|
|
5701
6114
|
attachSchemaHelp(cmd, flightCancelOrderSchema);
|
|
@@ -5704,9 +6117,9 @@ function registerCancelOrderCommand(parent, deps) {
|
|
|
5704
6117
|
const format = resolveFormat(opts.format);
|
|
5705
6118
|
const isYes = Boolean(opts.yes);
|
|
5706
6119
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5707
|
-
const orderNo =
|
|
6120
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5708
6121
|
if (!isYes) {
|
|
5709
|
-
const ok = await
|
|
6122
|
+
const ok = await confirm11({
|
|
5710
6123
|
message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
|
|
5711
6124
|
default: false
|
|
5712
6125
|
});
|
|
@@ -5751,8 +6164,8 @@ function registerListOrdersCommand2(parent, deps) {
|
|
|
5751
6164
|
if (opts.status !== void 0) params.set("status", opts.status);
|
|
5752
6165
|
const member = memberIdOf(opts);
|
|
5753
6166
|
if (member !== void 0) params.set("member_id", member);
|
|
5754
|
-
params.set("page", String(
|
|
5755
|
-
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")));
|
|
5756
6169
|
const spinner = format === "json" ? null : createSpinner("Fetching flight orders...");
|
|
5757
6170
|
const result = await deps.apiClient.get(
|
|
5758
6171
|
`/flight/orders?${params.toString()}`,
|
|
@@ -5780,10 +6193,10 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
5780
6193
|
const format = resolveFormat(opts.format);
|
|
5781
6194
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5782
6195
|
const body = {
|
|
5783
|
-
order_no:
|
|
5784
|
-
date:
|
|
5785
|
-
passenger:
|
|
5786
|
-
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"),
|
|
5787
6200
|
cabin_class: opts.cabinClass
|
|
5788
6201
|
};
|
|
5789
6202
|
const spinner = format === "json" ? null : createSpinner("Searching change options...");
|
|
@@ -5799,7 +6212,7 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
5799
6212
|
}
|
|
5800
6213
|
|
|
5801
6214
|
// src/flight-flink/change-apply.ts
|
|
5802
|
-
import { confirm as
|
|
6215
|
+
import { confirm as confirm12 } from "@inquirer/prompts";
|
|
5803
6216
|
function registerChangeApplyCommand(parent, deps) {
|
|
5804
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");
|
|
5805
6218
|
attachSchemaHelp(cmd, flightChangeApplySchema);
|
|
@@ -5809,17 +6222,17 @@ function registerChangeApplyCommand(parent, deps) {
|
|
|
5809
6222
|
const isYes = Boolean(opts.yes);
|
|
5810
6223
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5811
6224
|
const body = {
|
|
5812
|
-
order_no:
|
|
5813
|
-
passenger:
|
|
5814
|
-
segment_id:
|
|
5815
|
-
product_token:
|
|
5816
|
-
contact_name:
|
|
5817
|
-
contact_region:
|
|
5818
|
-
contact_phone:
|
|
5819
|
-
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")
|
|
5820
6233
|
};
|
|
5821
6234
|
if (!isYes) {
|
|
5822
|
-
const ok = await
|
|
6235
|
+
const ok = await confirm12({
|
|
5823
6236
|
message: `Submit a change request for order ${body.order_no}?`,
|
|
5824
6237
|
default: false
|
|
5825
6238
|
});
|
|
@@ -5850,7 +6263,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
5850
6263
|
const opts = cmd.optsWithGlobals();
|
|
5851
6264
|
const format = resolveFormat(opts.format);
|
|
5852
6265
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5853
|
-
const changeOrderNo =
|
|
6266
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
5854
6267
|
const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
|
|
5855
6268
|
const result = await deps.apiClient.get(
|
|
5856
6269
|
`/flight/change/${encodeURIComponent(changeOrderNo)}`,
|
|
@@ -5863,7 +6276,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
5863
6276
|
}
|
|
5864
6277
|
|
|
5865
6278
|
// src/flight-flink/change-cancel.ts
|
|
5866
|
-
import { confirm as
|
|
6279
|
+
import { confirm as confirm13 } from "@inquirer/prompts";
|
|
5867
6280
|
function registerChangeCancelCommand(parent, deps) {
|
|
5868
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");
|
|
5869
6282
|
attachSchemaHelp(cmd, flightChangeCancelSchema);
|
|
@@ -5872,9 +6285,9 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
5872
6285
|
const format = resolveFormat(opts.format);
|
|
5873
6286
|
const isYes = Boolean(opts.yes);
|
|
5874
6287
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5875
|
-
const changeOrderNo =
|
|
6288
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
5876
6289
|
if (!isYes) {
|
|
5877
|
-
const ok = await
|
|
6290
|
+
const ok = await confirm13({ message: `Cancel change request ${changeOrderNo}?`, default: false });
|
|
5878
6291
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
|
|
5879
6292
|
}
|
|
5880
6293
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5895,7 +6308,7 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
5895
6308
|
}
|
|
5896
6309
|
|
|
5897
6310
|
// src/flight-flink/change-pay.ts
|
|
5898
|
-
import { confirm as
|
|
6311
|
+
import { confirm as confirm14 } from "@inquirer/prompts";
|
|
5899
6312
|
function registerChangePayCommand(parent, deps) {
|
|
5900
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(
|
|
5901
6314
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5907,10 +6320,10 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5907
6320
|
const format = resolveFormat(opts.format);
|
|
5908
6321
|
const isYes = Boolean(opts.yes);
|
|
5909
6322
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5910
|
-
const changeOrderNo =
|
|
5911
|
-
const orderNo =
|
|
5912
|
-
const amount =
|
|
5913
|
-
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");
|
|
5914
6327
|
const body = {
|
|
5915
6328
|
order_no: orderNo,
|
|
5916
6329
|
amount,
|
|
@@ -5924,7 +6337,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5924
6337
|
if (!isYes) {
|
|
5925
6338
|
const isResume = opts.authorizedMerchantTransId !== void 0;
|
|
5926
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.`;
|
|
5927
|
-
const ok = await
|
|
6340
|
+
const ok = await confirm14({ message, default: false });
|
|
5928
6341
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change payment aborted by user.");
|
|
5929
6342
|
}
|
|
5930
6343
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5971,7 +6384,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5971
6384
|
}
|
|
5972
6385
|
|
|
5973
6386
|
// src/flight-flink/refund-apply.ts
|
|
5974
|
-
import { confirm as
|
|
6387
|
+
import { confirm as confirm15 } from "@inquirer/prompts";
|
|
5975
6388
|
function registerRefundApplyCommand(parent, deps) {
|
|
5976
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");
|
|
5977
6390
|
attachSchemaHelp(cmd, flightRefundApplySchema);
|
|
@@ -5981,18 +6394,18 @@ function registerRefundApplyCommand(parent, deps) {
|
|
|
5981
6394
|
const isYes = Boolean(opts.yes);
|
|
5982
6395
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5983
6396
|
const body = {
|
|
5984
|
-
order_no:
|
|
5985
|
-
passenger:
|
|
5986
|
-
segment_id:
|
|
5987
|
-
reason_type:
|
|
5988
|
-
contact_name:
|
|
5989
|
-
contact_region:
|
|
5990
|
-
contact_phone:
|
|
5991
|
-
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")
|
|
5992
6405
|
};
|
|
5993
6406
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
5994
6407
|
if (!isYes) {
|
|
5995
|
-
const ok = await
|
|
6408
|
+
const ok = await confirm15({
|
|
5996
6409
|
message: `Submit a refund request for order ${body.order_no}?`,
|
|
5997
6410
|
default: false
|
|
5998
6411
|
});
|
|
@@ -6023,7 +6436,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6023
6436
|
const opts = cmd.optsWithGlobals();
|
|
6024
6437
|
const format = resolveFormat(opts.format);
|
|
6025
6438
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6026
|
-
const refundOrderNo =
|
|
6439
|
+
const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
|
|
6027
6440
|
const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
|
|
6028
6441
|
const result = await deps.apiClient.get(
|
|
6029
6442
|
`/flight/refund/${encodeURIComponent(refundOrderNo)}`,
|
|
@@ -6036,7 +6449,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6036
6449
|
}
|
|
6037
6450
|
|
|
6038
6451
|
// src/flight-flink/refund-confirm.ts
|
|
6039
|
-
import { confirm as
|
|
6452
|
+
import { confirm as confirm16 } from "@inquirer/prompts";
|
|
6040
6453
|
function registerRefundConfirmCommand(parent, deps) {
|
|
6041
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");
|
|
6042
6455
|
attachSchemaHelp(cmd, flightRefundConfirmSchema);
|
|
@@ -6045,14 +6458,14 @@ function registerRefundConfirmCommand(parent, deps) {
|
|
|
6045
6458
|
const format = resolveFormat(opts.format);
|
|
6046
6459
|
const isYes = Boolean(opts.yes);
|
|
6047
6460
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6048
|
-
const refundOrderNo =
|
|
6049
|
-
const confirmFlag =
|
|
6461
|
+
const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
|
|
6462
|
+
const confirmFlag = need20(opts.confirm, "confirm");
|
|
6050
6463
|
if (confirmFlag !== "1" && confirmFlag !== "2") {
|
|
6051
6464
|
throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
|
|
6052
6465
|
}
|
|
6053
6466
|
if (!isYes) {
|
|
6054
6467
|
const action = confirmFlag === "1" ? "confirm" : "cancel";
|
|
6055
|
-
const ok = await
|
|
6468
|
+
const ok = await confirm16({ message: `${action} refund ${refundOrderNo}?`, default: false });
|
|
6056
6469
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Refund confirmation aborted by user.");
|
|
6057
6470
|
}
|
|
6058
6471
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -6215,6 +6628,8 @@ Key notes:
|
|
|
6215
6628
|
);
|
|
6216
6629
|
registerQuoteCommand(rideCmd, deps);
|
|
6217
6630
|
registerBookCommand(rideCmd, deps);
|
|
6631
|
+
registerRideCreateOrderCommand(rideCmd, deps);
|
|
6632
|
+
registerRidePayOrderCommand(rideCmd, deps);
|
|
6218
6633
|
registerRideGetCommand(rideCmd, deps);
|
|
6219
6634
|
registerCancelCommand(rideCmd, deps);
|
|
6220
6635
|
registerRideUpdateCommand(rideCmd, deps);
|