@agenzo/merchant-cli 0.8.15 → 0.8.17
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/dist/index.js +642 -199
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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,
|
|
@@ -2037,63 +2162,72 @@ var unifiedOrdersListSchema = {
|
|
|
2037
2162
|
cli: CLI_NAME,
|
|
2038
2163
|
noun: ORDERS_NOUN,
|
|
2039
2164
|
verb: "list",
|
|
2040
|
-
description:
|
|
2165
|
+
description: "List orders across ALL providers (ride + hotel + flight) with common filters and offset/cursor pagination. Use domain-specific list-orders only for provider-specific fields.",
|
|
2041
2166
|
flags: {
|
|
2042
|
-
"order-type": { type: "string", required: false, description: "
|
|
2167
|
+
"order-type": { type: "string", required: false, description: "Legacy single order type: ride | hotel | flight" },
|
|
2168
|
+
"order-types": { type: "string", required: false, description: "Comma-separated order types: ride,hotel,flight" },
|
|
2043
2169
|
member: MEMBER_FLAG_SCHEMA,
|
|
2044
|
-
status: { type: "string", required: false, description: "
|
|
2045
|
-
|
|
2046
|
-
"
|
|
2170
|
+
status: { type: "string", required: false, description: "Legacy single normalized status: PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED" },
|
|
2171
|
+
statuses: { type: "string", required: false, description: "Comma-separated normalized statuses" },
|
|
2172
|
+
"created-from": { type: "string", required: false, description: "ISO 8601 created-at lower bound (inclusive)" },
|
|
2173
|
+
"created-to": { type: "string", required: false, description: "ISO 8601 created-at upper bound (exclusive)" },
|
|
2174
|
+
cursor: { type: "string", required: false, description: "Opaque cursor returned by the previous page" },
|
|
2175
|
+
page: { type: "int", required: false, default: 1, description: "Legacy 1-based page number", constraints: ">= 1" },
|
|
2176
|
+
"page-size": { type: "int", required: false, default: 20, description: "Items per page", constraints: "1-100" }
|
|
2047
2177
|
},
|
|
2048
2178
|
response: {
|
|
2049
2179
|
orders: {
|
|
2050
2180
|
type: "array",
|
|
2051
|
-
description: "Slim cross-provider
|
|
2181
|
+
description: "Slim cross-provider index items. Call `orders get` for business-specific detail.",
|
|
2052
2182
|
items: {
|
|
2053
|
-
order_id: { type: "string", description: "Order id (rio_
|
|
2054
|
-
member_id: { type: "string|null", description: "
|
|
2055
|
-
order_type: { type: "string", description: "
|
|
2056
|
-
status: { type: "string", description: "
|
|
2057
|
-
|
|
2183
|
+
order_id: { type: "string", description: "Order id (rio_..., hho_..., or ffo_...). Pass to `orders get`." },
|
|
2184
|
+
member_id: { type: "string|null", description: "Attributed end-user id; null when unattributed" },
|
|
2185
|
+
order_type: { type: "string", description: "ride | hotel | flight" },
|
|
2186
|
+
status: { type: "string", description: "Original provider-domain status for display" },
|
|
2187
|
+
unified_status: { type: "string", description: "PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED" },
|
|
2188
|
+
amount: { type: "float|null", description: "Order amount in decimal currency units" },
|
|
2058
2189
|
currency: { type: "string|null", description: "ISO 4217 currency code" },
|
|
2059
2190
|
created_at: { type: "string|null", description: "ISO 8601 datetime" },
|
|
2060
2191
|
updated_at: { type: "string|null", description: "ISO 8601 datetime" }
|
|
2061
2192
|
}
|
|
2062
2193
|
},
|
|
2063
2194
|
total: { type: "int", description: "Total matching orders across all providers" },
|
|
2064
|
-
page: { type: "int", description: "
|
|
2065
|
-
page_size: { type: "int", description: "Items per page" }
|
|
2195
|
+
page: { type: "int", description: "Legacy current page" },
|
|
2196
|
+
page_size: { type: "int", description: "Items per page" },
|
|
2197
|
+
next_cursor: { type: "string|null", description: "Opaque cursor for the next page; null at the end" },
|
|
2198
|
+
has_more: { type: "bool", description: "Whether another page is available" },
|
|
2199
|
+
applied_filters: { type: "object", description: "Normalized filters applied by the platform" }
|
|
2066
2200
|
},
|
|
2067
2201
|
example: {
|
|
2068
|
-
command: "agenzo-merchant-cli orders list --
|
|
2069
|
-
output_summary: "Returns
|
|
2202
|
+
command: "agenzo-merchant-cli orders list --order-types flight,hotel --created-from 2026-07-01T00:00:00Z --page-size 20",
|
|
2203
|
+
output_summary: "Returns ride, hotel, and flight orders with stable pagination metadata."
|
|
2070
2204
|
},
|
|
2071
2205
|
error_recovery: {
|
|
2072
|
-
INVALID_REQUEST: "
|
|
2206
|
+
INVALID_REQUEST: "Fix invalid type/status/date/cursor filters and retry.",
|
|
2073
2207
|
INTERNAL_ERROR: "Transient backend error. Retry once after a short delay.",
|
|
2074
|
-
PARAM_INVALID: "
|
|
2208
|
+
PARAM_INVALID: "Fix conflicting or invalid CLI options, then retry."
|
|
2075
2209
|
}
|
|
2076
2210
|
};
|
|
2077
2211
|
var unifiedOrdersGetSchema = {
|
|
2078
2212
|
cli: CLI_NAME,
|
|
2079
2213
|
noun: ORDERS_NOUN,
|
|
2080
2214
|
verb: "get",
|
|
2081
|
-
description: "Get a
|
|
2215
|
+
description: "Get a ride, hotel, or flight order detail by id. The platform resolves order_id to the owning domain and returns that domain detail shape.",
|
|
2082
2216
|
flags: {
|
|
2083
|
-
"order-id": { type: "string", required: true, description: "Order id from `orders list` (rio_
|
|
2217
|
+
"order-id": { type: "string", required: true, description: "Order id from `orders list` (rio_..., hho_..., or ffo_...)" }
|
|
2084
2218
|
},
|
|
2085
2219
|
response: {
|
|
2086
2220
|
"(varies by order_type)": {
|
|
2087
2221
|
type: "object",
|
|
2088
|
-
description: "
|
|
2222
|
+
description: "Delegated ride, hotel, or flight detail. Treat the result as an opaque domain object and surface the returned fields."
|
|
2089
2223
|
}
|
|
2090
2224
|
},
|
|
2091
2225
|
example: {
|
|
2092
|
-
command: "agenzo-merchant-cli orders get --order-id
|
|
2093
|
-
output_summary: "Returns the order's
|
|
2226
|
+
command: "agenzo-merchant-cli orders get --order-id ffo_01K...",
|
|
2227
|
+
output_summary: "Returns the order's provider-domain detail."
|
|
2094
2228
|
},
|
|
2095
2229
|
error_recovery: {
|
|
2096
|
-
ORDER_NOT_FOUND: "The order_id does not exist or does not belong to this developer/org. Verify the id from `orders list`.
|
|
2230
|
+
ORDER_NOT_FOUND: "The order_id does not exist or does not belong to this developer/org. Verify the id from `orders list`.",
|
|
2097
2231
|
INTERNAL_ERROR: "The order's provider detail lookup is temporarily unavailable. Retry once after a short delay."
|
|
2098
2232
|
}
|
|
2099
2233
|
};
|
|
@@ -2216,6 +2350,7 @@ var flightPayOrderSchema = flightSchema(
|
|
|
2216
2350
|
"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
2351
|
"payment-token-id": { type: "string", required: false, description: "Optional network-token id; settles via direct charge instead of EVO preauth." },
|
|
2218
2352
|
"authorized-merchant-trans-id": { type: "string", required: false, description: "Resume a 3DS challenge with an already-authorised preauth trans id." },
|
|
2353
|
+
"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
2354
|
"idempotency-key": { type: "string", required: true, description: "Forwarded verbatim as the Idempotency-Key header." }
|
|
2220
2355
|
},
|
|
2221
2356
|
{ order_no: { type: "string", description: "Our order reference." }, status: { type: "string", description: "PAID on success; AUTHENTICATION_REQUIRED when the card needs 3DS." } },
|
|
@@ -2561,7 +2696,7 @@ function registerBookCommand(parent, deps) {
|
|
|
2561
2696
|
"Bound payment method id to charge (pay_per_call mode only)"
|
|
2562
2697
|
).option(
|
|
2563
2698
|
"--payment-token-id <id>",
|
|
2564
|
-
"
|
|
2699
|
+
"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
2700
|
).option(
|
|
2566
2701
|
"--authorized-merchant-trans-id <id>",
|
|
2567
2702
|
"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 +2812,292 @@ function registerBookCommand(parent, deps) {
|
|
|
2677
2812
|
});
|
|
2678
2813
|
}
|
|
2679
2814
|
|
|
2680
|
-
// src/ride-elife/
|
|
2815
|
+
// src/ride-elife/create-order.ts
|
|
2816
|
+
import { confirm as confirm2 } from "@inquirer/prompts";
|
|
2681
2817
|
function need3(value, flag) {
|
|
2682
2818
|
if (value === void 0) {
|
|
2683
2819
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2684
2820
|
}
|
|
2685
2821
|
return value;
|
|
2686
2822
|
}
|
|
2823
|
+
function num3(value, flag) {
|
|
2824
|
+
const n = Number(need3(value, flag));
|
|
2825
|
+
if (!Number.isFinite(n)) {
|
|
2826
|
+
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
2827
|
+
}
|
|
2828
|
+
return n;
|
|
2829
|
+
}
|
|
2830
|
+
function phone2(value, flag) {
|
|
2831
|
+
const raw = need3(value, flag);
|
|
2832
|
+
const cleaned = raw.replace(/[\s-]/g, "");
|
|
2833
|
+
if (!/^\+[1-9]\d{7,14}$/.test(cleaned)) {
|
|
2834
|
+
throw new CliError(
|
|
2835
|
+
"PARAM_INVALID",
|
|
2836
|
+
`--${flag} must be a valid international phone number, e.g. +14155552671.`
|
|
2837
|
+
);
|
|
2838
|
+
}
|
|
2839
|
+
return cleaned;
|
|
2840
|
+
}
|
|
2841
|
+
function seatCount2(value, flag) {
|
|
2842
|
+
const n = num3(value, flag);
|
|
2843
|
+
if (!Number.isInteger(n) || n < 0 || n > 5) {
|
|
2844
|
+
throw new CliError("PARAM_INVALID", `--${flag} must be an integer between 0 and 5.`);
|
|
2845
|
+
}
|
|
2846
|
+
return n;
|
|
2847
|
+
}
|
|
2848
|
+
function formatCreateOrder(data) {
|
|
2849
|
+
const orderRef = String(data.order_ref ?? data.order_id ?? "-");
|
|
2850
|
+
const lines = [
|
|
2851
|
+
["Order ref", orderRef],
|
|
2852
|
+
["Status", String(data.status ?? "-")],
|
|
2853
|
+
["Payment status", String(data.payment_status ?? "-")]
|
|
2854
|
+
];
|
|
2855
|
+
if (data.price) {
|
|
2856
|
+
lines.push(["Amount", `${data.price.amount} ${data.price.currency}`]);
|
|
2857
|
+
if (data.price.quote_id) lines.push(["Quote ID", String(data.price.quote_id)]);
|
|
2858
|
+
}
|
|
2859
|
+
if (data.is_scheduled !== void 0) lines.push(["Scheduled", String(data.is_scheduled)]);
|
|
2860
|
+
if (data.order_type) lines.push(["Order type", String(data.order_type)]);
|
|
2861
|
+
return [
|
|
2862
|
+
Formatter.keyValue(lines),
|
|
2863
|
+
Formatter.status(
|
|
2864
|
+
"info",
|
|
2865
|
+
`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.`
|
|
2866
|
+
)
|
|
2867
|
+
].join("\n\n");
|
|
2868
|
+
}
|
|
2869
|
+
function registerRideCreateOrderCommand(parent, deps) {
|
|
2870
|
+
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(
|
|
2871
|
+
"--idempotency-key <key>",
|
|
2872
|
+
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
2873
|
+
);
|
|
2874
|
+
attachSchemaHelp(cmd, rideCreateOrderSchema);
|
|
2875
|
+
cmd.action(async () => {
|
|
2876
|
+
const opts = cmd.optsWithGlobals();
|
|
2877
|
+
const format = resolveFormat(opts.format);
|
|
2878
|
+
const isYes = Boolean(opts.yes);
|
|
2879
|
+
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
2880
|
+
message: "API Key:",
|
|
2881
|
+
type: "password"
|
|
2882
|
+
});
|
|
2883
|
+
const quoteId = need3(opts.quoteId, "quote-id");
|
|
2884
|
+
const priceAmount = num3(opts.priceAmount, "price-amount");
|
|
2885
|
+
const priceCurrency = opts.priceCurrency ?? "USD";
|
|
2886
|
+
const body = {
|
|
2887
|
+
quote_id: quoteId,
|
|
2888
|
+
vehicle_class: need3(opts.vehicleClass, "vehicle-class"),
|
|
2889
|
+
price_amount: priceAmount,
|
|
2890
|
+
price_currency: priceCurrency,
|
|
2891
|
+
passenger_name: need3(opts.passengerName, "passenger-name"),
|
|
2892
|
+
passenger_phone: phone2(opts.passengerPhone, "passenger-phone"),
|
|
2893
|
+
passenger_email: need3(opts.passengerEmail, "passenger-email")
|
|
2894
|
+
};
|
|
2895
|
+
const member = memberIdOf(opts);
|
|
2896
|
+
if (member !== void 0) body.member_id = member;
|
|
2897
|
+
if (opts.luggageCount !== void 0) {
|
|
2898
|
+
body.luggage_count = num3(opts.luggageCount, "luggage-count");
|
|
2899
|
+
}
|
|
2900
|
+
if (opts.specialRequests) body.special_requests = opts.specialRequests;
|
|
2901
|
+
if (opts.pickupLat || opts.pickupLng || opts.pickupName) {
|
|
2902
|
+
body.pickup = {
|
|
2903
|
+
lat: num3(opts.pickupLat, "pickup-lat"),
|
|
2904
|
+
lng: num3(opts.pickupLng, "pickup-lng"),
|
|
2905
|
+
name: need3(opts.pickupName, "pickup-name")
|
|
2906
|
+
};
|
|
2907
|
+
}
|
|
2908
|
+
if (opts.dropoffLat || opts.dropoffLng || opts.dropoffName) {
|
|
2909
|
+
body.dropoff = {
|
|
2910
|
+
lat: num3(opts.dropoffLat, "dropoff-lat"),
|
|
2911
|
+
lng: num3(opts.dropoffLng, "dropoff-lng"),
|
|
2912
|
+
name: need3(opts.dropoffName, "dropoff-name")
|
|
2913
|
+
};
|
|
2914
|
+
}
|
|
2915
|
+
if (opts.pickupTime) {
|
|
2916
|
+
body.pickup_time = opts.pickupTime === "now" ? "now" : num3(opts.pickupTime, "pickup-time");
|
|
2917
|
+
}
|
|
2918
|
+
if (opts.meetAndGreet) body.meet_and_greet = true;
|
|
2919
|
+
if (opts.meetAndGreetPrice !== void 0) {
|
|
2920
|
+
body.meet_and_greet_price = num3(opts.meetAndGreetPrice, "meet-and-greet-price");
|
|
2921
|
+
}
|
|
2922
|
+
if (opts.welcomeSign) body.welcome_sign = opts.welcomeSign;
|
|
2923
|
+
if (opts.childSeatCount !== void 0) {
|
|
2924
|
+
body.child_seat_count = seatCount2(opts.childSeatCount, "child-seat-count");
|
|
2925
|
+
}
|
|
2926
|
+
if (opts.infantSeatCount !== void 0) {
|
|
2927
|
+
body.infant_seat_count = seatCount2(opts.infantSeatCount, "infant-seat-count");
|
|
2928
|
+
}
|
|
2929
|
+
if (opts.toddlerSeatCount !== void 0) {
|
|
2930
|
+
body.toddler_seat_count = seatCount2(opts.toddlerSeatCount, "toddler-seat-count");
|
|
2931
|
+
}
|
|
2932
|
+
if (opts.arrivalFlightNo || opts.arrivalAirline) {
|
|
2933
|
+
body.arrival_flight = {
|
|
2934
|
+
flight_no: opts.arrivalFlightNo,
|
|
2935
|
+
airline: opts.arrivalAirline
|
|
2936
|
+
};
|
|
2937
|
+
}
|
|
2938
|
+
if (opts.departureFlightNo || opts.departureAirline) {
|
|
2939
|
+
body.departure_flight = {
|
|
2940
|
+
flight_no: opts.departureFlightNo,
|
|
2941
|
+
airline: opts.departureAirline
|
|
2942
|
+
};
|
|
2943
|
+
}
|
|
2944
|
+
if (!isYes) {
|
|
2945
|
+
const confirmed = await confirm2({
|
|
2946
|
+
message: `Lock this ride fare for ${priceAmount} ${priceCurrency}? This reserves the order (AWAITING_PAYMENT) but does NOT charge yet.`,
|
|
2947
|
+
default: false
|
|
2948
|
+
});
|
|
2949
|
+
if (!confirmed) {
|
|
2950
|
+
throw new CliError("CLIENT_ABORTED", "Order creation aborted by user.");
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
2954
|
+
yes: isYes,
|
|
2955
|
+
commandPath: "ride-elife create-order"
|
|
2956
|
+
});
|
|
2957
|
+
const spinner = format === "json" ? null : createSpinner("Locking ride fare...");
|
|
2958
|
+
const result = await deps.apiClient.post(
|
|
2959
|
+
"/ride/create-order",
|
|
2960
|
+
{ type: "api-key", key: apiKey },
|
|
2961
|
+
body,
|
|
2962
|
+
{ "Idempotency-Key": idempotencyKey }
|
|
2963
|
+
);
|
|
2964
|
+
spinner?.stop();
|
|
2965
|
+
if (!result.success) {
|
|
2966
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
2967
|
+
}
|
|
2968
|
+
const data = result.data;
|
|
2969
|
+
const configManager = new ConfigManager();
|
|
2970
|
+
const commandResult = {
|
|
2971
|
+
data,
|
|
2972
|
+
text: () => formatCreateOrder(data)
|
|
2973
|
+
};
|
|
2974
|
+
await renderWithContext(commandResult, { format }, configManager);
|
|
2975
|
+
});
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2978
|
+
// src/ride-elife/pay-order.ts
|
|
2979
|
+
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
2980
|
+
function need4(value, flag) {
|
|
2981
|
+
if (value === void 0) {
|
|
2982
|
+
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2983
|
+
}
|
|
2984
|
+
return value;
|
|
2985
|
+
}
|
|
2986
|
+
function assertExactlyOneCredential(paymentTokenId, paymentMethodId) {
|
|
2987
|
+
const hasToken = paymentTokenId !== void 0;
|
|
2988
|
+
const hasMethod = paymentMethodId !== void 0;
|
|
2989
|
+
if (!hasToken && !hasMethod) {
|
|
2990
|
+
throw new CliError(
|
|
2991
|
+
"PARAM_INVALID",
|
|
2992
|
+
"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."
|
|
2993
|
+
);
|
|
2994
|
+
}
|
|
2995
|
+
if (hasToken && hasMethod) {
|
|
2996
|
+
throw new CliError(
|
|
2997
|
+
"PARAM_INVALID",
|
|
2998
|
+
"Invalid payment credential options: --payment-token-id and --payment-method-id are mutually exclusive \u2014 provide exactly one, not both."
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
function formatPayOrder(data) {
|
|
3003
|
+
const orderRef = String(data.order_ref ?? data.order_id ?? "-");
|
|
3004
|
+
const lines = [
|
|
3005
|
+
["Order ref", orderRef],
|
|
3006
|
+
["Status", String(data.status ?? "-")],
|
|
3007
|
+
["Payment status", String(data.payment_status ?? "-")]
|
|
3008
|
+
];
|
|
3009
|
+
if (data.ride_id !== void 0) lines.push(["Ride ID", String(data.ride_id)]);
|
|
3010
|
+
if (data.payment_channel) lines.push(["Payment channel", String(data.payment_channel)]);
|
|
3011
|
+
if (data.price) {
|
|
3012
|
+
lines.push(["Amount", `${data.price.amount} ${data.price.currency}`]);
|
|
3013
|
+
if (data.price.quote_id) lines.push(["Quote ID", String(data.price.quote_id)]);
|
|
3014
|
+
}
|
|
3015
|
+
return [
|
|
3016
|
+
Formatter.keyValue(lines),
|
|
3017
|
+
Formatter.status(
|
|
3018
|
+
"success",
|
|
3019
|
+
`Order ${orderRef} settled \u2014 ${data.status ?? "PAID"} / ${data.payment_status ?? "SETTLED"}.`
|
|
3020
|
+
)
|
|
3021
|
+
].join("\n\n");
|
|
3022
|
+
}
|
|
3023
|
+
function registerRidePayOrderCommand(parent, deps) {
|
|
3024
|
+
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(
|
|
3025
|
+
"--payment-token-id <id>",
|
|
3026
|
+
"Network-token id (unionpay/visa direct-charge path). Exactly one of --payment-token-id / --payment-method-id is required."
|
|
3027
|
+
).option(
|
|
3028
|
+
"--payment-method-id <id>",
|
|
3029
|
+
"Bound-card id to charge via EVO preauth+capture (fallback path). Exactly one of --payment-token-id / --payment-method-id is required."
|
|
3030
|
+
).option(
|
|
3031
|
+
"--authorized-merchant-trans-id <id>",
|
|
3032
|
+
"Resume a 3DS challenge: merchant trans id of an already-authorised preauth"
|
|
3033
|
+
).option(
|
|
3034
|
+
"--evo-explicit",
|
|
3035
|
+
"[\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."
|
|
3036
|
+
).option(
|
|
3037
|
+
"--idempotency-key <key>",
|
|
3038
|
+
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
3039
|
+
);
|
|
3040
|
+
attachSchemaHelp(cmd, ridePayOrderSchema);
|
|
3041
|
+
cmd.action(async () => {
|
|
3042
|
+
const opts = cmd.optsWithGlobals();
|
|
3043
|
+
const format = resolveFormat(opts.format);
|
|
3044
|
+
const isYes = Boolean(opts.yes);
|
|
3045
|
+
const orderId = need4(opts.orderId, "order-id");
|
|
3046
|
+
const paymentTokenId = opts.paymentTokenId;
|
|
3047
|
+
const paymentMethodId = opts.paymentMethodId;
|
|
3048
|
+
assertExactlyOneCredential(paymentTokenId, paymentMethodId);
|
|
3049
|
+
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
3050
|
+
message: "API Key:",
|
|
3051
|
+
type: "password"
|
|
3052
|
+
});
|
|
3053
|
+
const body = { order_id: orderId };
|
|
3054
|
+
if (paymentTokenId !== void 0) body.payment_token_id = paymentTokenId;
|
|
3055
|
+
if (paymentMethodId !== void 0) body.payment_method_id = paymentMethodId;
|
|
3056
|
+
if (opts.authorizedMerchantTransId !== void 0) {
|
|
3057
|
+
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
3058
|
+
}
|
|
3059
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
3060
|
+
if (!isYes) {
|
|
3061
|
+
const confirmed = await confirm3({
|
|
3062
|
+
message: `Settle ride order ${orderId}? This charges the card and creates the ride (AWAITING_PAYMENT \u2192 PAID).`,
|
|
3063
|
+
default: false
|
|
3064
|
+
});
|
|
3065
|
+
if (!confirmed) {
|
|
3066
|
+
throw new CliError("CLIENT_ABORTED", "Payment aborted by user.");
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
3070
|
+
yes: isYes,
|
|
3071
|
+
commandPath: "ride-elife pay-order"
|
|
3072
|
+
});
|
|
3073
|
+
const spinner = format === "json" ? null : createSpinner("Settling ride order...");
|
|
3074
|
+
const result = await deps.apiClient.post(
|
|
3075
|
+
"/ride/pay",
|
|
3076
|
+
{ type: "api-key", key: apiKey },
|
|
3077
|
+
body,
|
|
3078
|
+
{ "Idempotency-Key": idempotencyKey }
|
|
3079
|
+
);
|
|
3080
|
+
spinner?.stop();
|
|
3081
|
+
if (!result.success) {
|
|
3082
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
3083
|
+
}
|
|
3084
|
+
const data = result.data;
|
|
3085
|
+
const configManager = new ConfigManager();
|
|
3086
|
+
const commandResult = {
|
|
3087
|
+
data,
|
|
3088
|
+
text: () => formatPayOrder(data)
|
|
3089
|
+
};
|
|
3090
|
+
await renderWithContext(commandResult, { format }, configManager);
|
|
3091
|
+
});
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
// src/ride-elife/get.ts
|
|
3095
|
+
function need5(value, flag) {
|
|
3096
|
+
if (value === void 0) {
|
|
3097
|
+
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3098
|
+
}
|
|
3099
|
+
return value;
|
|
3100
|
+
}
|
|
2687
3101
|
function formatGetOrder(data) {
|
|
2688
3102
|
const lines = [
|
|
2689
3103
|
["Ride ID", String(data.ride_id ?? "-")],
|
|
@@ -2710,8 +3124,8 @@ function formatGetOrder(data) {
|
|
|
2710
3124
|
}
|
|
2711
3125
|
if (data.driver) {
|
|
2712
3126
|
const driver = data.driver;
|
|
2713
|
-
const
|
|
2714
|
-
lines.push(["Driver", `${driver.name ?? "-"}${
|
|
3127
|
+
const phone3 = driver.phone_number ? ` (${driver.phone_number})` : "";
|
|
3128
|
+
lines.push(["Driver", `${driver.name ?? "-"}${phone3}`]);
|
|
2715
3129
|
}
|
|
2716
3130
|
if (data.vehicle) {
|
|
2717
3131
|
const v = data.vehicle;
|
|
@@ -2738,7 +3152,7 @@ function registerRideGetCommand(parent, deps) {
|
|
|
2738
3152
|
message: "API Key:",
|
|
2739
3153
|
type: "password"
|
|
2740
3154
|
});
|
|
2741
|
-
const orderId =
|
|
3155
|
+
const orderId = need5(opts.orderId, "order-id");
|
|
2742
3156
|
if (opts.watch) {
|
|
2743
3157
|
await watchRideStatus(deps.apiClient, apiKey, orderId, {
|
|
2744
3158
|
intervalSeconds: resolveSeconds(
|
|
@@ -2772,8 +3186,8 @@ function registerRideGetCommand(parent, deps) {
|
|
|
2772
3186
|
}
|
|
2773
3187
|
|
|
2774
3188
|
// src/ride-elife/cancel.ts
|
|
2775
|
-
import { confirm as
|
|
2776
|
-
function
|
|
3189
|
+
import { confirm as confirm4 } from "@inquirer/prompts";
|
|
3190
|
+
function need6(value, flag) {
|
|
2777
3191
|
if (value === void 0) {
|
|
2778
3192
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2779
3193
|
}
|
|
@@ -2808,9 +3222,9 @@ function registerCancelCommand(parent, deps) {
|
|
|
2808
3222
|
message: "API Key:",
|
|
2809
3223
|
type: "password"
|
|
2810
3224
|
});
|
|
2811
|
-
const orderId =
|
|
3225
|
+
const orderId = need6(opts.orderId, "order-id");
|
|
2812
3226
|
if (!isYes) {
|
|
2813
|
-
const confirmed = await
|
|
3227
|
+
const confirmed = await confirm4({
|
|
2814
3228
|
message: `Cancel ride ${orderId}? This may incur a fee.`,
|
|
2815
3229
|
default: false
|
|
2816
3230
|
});
|
|
@@ -2844,14 +3258,14 @@ function registerCancelCommand(parent, deps) {
|
|
|
2844
3258
|
}
|
|
2845
3259
|
|
|
2846
3260
|
// src/ride-elife/update.ts
|
|
2847
|
-
import { confirm as
|
|
2848
|
-
function
|
|
3261
|
+
import { confirm as confirm5 } from "@inquirer/prompts";
|
|
3262
|
+
function need7(value, flag) {
|
|
2849
3263
|
if (value === void 0) {
|
|
2850
3264
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
2851
3265
|
}
|
|
2852
3266
|
return value;
|
|
2853
3267
|
}
|
|
2854
|
-
function
|
|
3268
|
+
function num4(value, flag) {
|
|
2855
3269
|
if (value === void 0) return void 0;
|
|
2856
3270
|
const parsed = Number(value);
|
|
2857
3271
|
if (!Number.isFinite(parsed)) {
|
|
@@ -2860,7 +3274,7 @@ function num3(value, flag) {
|
|
|
2860
3274
|
return parsed;
|
|
2861
3275
|
}
|
|
2862
3276
|
function int(value, flag) {
|
|
2863
|
-
const parsed =
|
|
3277
|
+
const parsed = num4(value, flag);
|
|
2864
3278
|
if (parsed === void 0) return void 0;
|
|
2865
3279
|
if (!Number.isInteger(parsed)) {
|
|
2866
3280
|
throw new CliError("PARAM_INVALID", `--${flag} must be an integer.`);
|
|
@@ -2885,8 +3299,8 @@ function location(lat, lng, name, side) {
|
|
|
2885
3299
|
);
|
|
2886
3300
|
}
|
|
2887
3301
|
return {
|
|
2888
|
-
lat:
|
|
2889
|
-
lng:
|
|
3302
|
+
lat: num4(lat, `${side}-lat`),
|
|
3303
|
+
lng: num4(lng, `${side}-lng`),
|
|
2890
3304
|
name
|
|
2891
3305
|
};
|
|
2892
3306
|
}
|
|
@@ -2912,7 +3326,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2912
3326
|
message: "API Key:",
|
|
2913
3327
|
type: "password"
|
|
2914
3328
|
});
|
|
2915
|
-
const orderId =
|
|
3329
|
+
const orderId = need7(opts.orderId, "order-id");
|
|
2916
3330
|
const mgTouched = process.argv.some(
|
|
2917
3331
|
(a) => a === "--meet-and-greet" || a === "--no-meet-and-greet"
|
|
2918
3332
|
);
|
|
@@ -2922,7 +3336,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2922
3336
|
};
|
|
2923
3337
|
set("quote_id", opts.quoteId);
|
|
2924
3338
|
set("vehicle_class", opts.vehicleClass);
|
|
2925
|
-
set("price_amount",
|
|
3339
|
+
set("price_amount", num4(opts.priceAmount, "price-amount"));
|
|
2926
3340
|
set("price_currency", opts.priceCurrency);
|
|
2927
3341
|
set(
|
|
2928
3342
|
"pickup",
|
|
@@ -2969,7 +3383,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
2969
3383
|
);
|
|
2970
3384
|
}
|
|
2971
3385
|
if (!isYes) {
|
|
2972
|
-
const confirmed = await
|
|
3386
|
+
const confirmed = await confirm5({
|
|
2973
3387
|
message: `Apply ${Object.keys(body).length} change(s) to ride ${orderId}? The fare may change.`,
|
|
2974
3388
|
default: false
|
|
2975
3389
|
});
|
|
@@ -3003,7 +3417,7 @@ function registerRideUpdateCommand(parent, deps) {
|
|
|
3003
3417
|
}
|
|
3004
3418
|
|
|
3005
3419
|
// src/ride-elife/trip-status.ts
|
|
3006
|
-
function
|
|
3420
|
+
function need8(value, flag) {
|
|
3007
3421
|
if (value === void 0) {
|
|
3008
3422
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3009
3423
|
}
|
|
@@ -3041,7 +3455,7 @@ function registerRideTripStatusCommand(parent, deps) {
|
|
|
3041
3455
|
message: "API Key:",
|
|
3042
3456
|
type: "password"
|
|
3043
3457
|
});
|
|
3044
|
-
const orderId =
|
|
3458
|
+
const orderId = need8(opts.orderId, "order-id");
|
|
3045
3459
|
const leg = tripNo(opts.tripNo);
|
|
3046
3460
|
const spinner = format === "json" ? null : createSpinner("Fetching trip status...");
|
|
3047
3461
|
const result = await deps.apiClient.get(
|
|
@@ -3478,6 +3892,17 @@ function positiveInt2(value, flag) {
|
|
|
3478
3892
|
}
|
|
3479
3893
|
return String(n);
|
|
3480
3894
|
}
|
|
3895
|
+
function assertCompatibleOptions(opts) {
|
|
3896
|
+
if (opts.orderType !== void 0 && opts.orderTypes !== void 0) {
|
|
3897
|
+
throw new CliError("PARAM_INVALID", "--order-type and --order-types cannot be used together.");
|
|
3898
|
+
}
|
|
3899
|
+
if (opts.status !== void 0 && opts.statuses !== void 0) {
|
|
3900
|
+
throw new CliError("PARAM_INVALID", "--status and --statuses cannot be used together.");
|
|
3901
|
+
}
|
|
3902
|
+
if (opts.cursor !== void 0 && Number(opts.page ?? DEFAULT_PAGE2) !== 1) {
|
|
3903
|
+
throw new CliError("PARAM_INVALID", "--cursor cannot be combined with --page greater than 1.");
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3481
3906
|
function formatOrders2(data) {
|
|
3482
3907
|
const orders = data.orders ?? [];
|
|
3483
3908
|
if (orders.length === 0) {
|
|
@@ -3496,14 +3921,17 @@ function formatOrders2(data) {
|
|
|
3496
3921
|
["Page", String(data.page ?? "-")],
|
|
3497
3922
|
["Page size", String(data.page_size ?? "-")]
|
|
3498
3923
|
];
|
|
3924
|
+
if (data.has_more !== void 0) summary.push(["Has more", String(data.has_more)]);
|
|
3925
|
+
if (data.next_cursor) summary.push(["Next cursor", data.next_cursor]);
|
|
3499
3926
|
return `${Formatter.table(headers, rows)}
|
|
3500
3927
|
${Formatter.keyValue(summary)}`;
|
|
3501
3928
|
}
|
|
3502
3929
|
function registerOrdersListCommand(parent, deps) {
|
|
3503
|
-
const cmd = parent.command("list").description("List orders across ALL providers (ride + hotel), with
|
|
3930
|
+
const cmd = parent.command("list").description("List orders across ALL providers (ride + hotel + flight), with filters and pagination").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-type <type>", "Legacy single order type filter: ride | hotel | flight").option("--order-types <types>", "Comma-separated order types: ride,hotel,flight").option("--status <status>", "Legacy single normalized status filter").option("--statuses <statuses>", "Comma-separated statuses: PENDING,CONFIRMED,COMPLETED,CANCELLED,FAILED").option("--created-from <datetime>", "Created at or after this ISO 8601 datetime (inclusive)").option("--created-to <datetime>", "Created before this ISO 8601 datetime (exclusive)").option("--cursor <cursor>", "Opaque cursor returned by the previous page").option("--page <page>", "Legacy 1-based page number", DEFAULT_PAGE2).option("--page-size <size>", "Page size", DEFAULT_PAGE_SIZE2).option("--member <id>", MEMBER_OPTION_DESCRIPTION);
|
|
3504
3931
|
attachSchemaHelp(cmd, unifiedOrdersListSchema);
|
|
3505
3932
|
cmd.action(async () => {
|
|
3506
3933
|
const opts = cmd.optsWithGlobals();
|
|
3934
|
+
assertCompatibleOptions(opts);
|
|
3507
3935
|
const format = resolveFormat(opts.format);
|
|
3508
3936
|
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
3509
3937
|
message: "API Key:",
|
|
@@ -3514,7 +3942,12 @@ function registerOrdersListCommand(parent, deps) {
|
|
|
3514
3942
|
page_size: positiveInt2(opts.pageSize ?? DEFAULT_PAGE_SIZE2, "page-size")
|
|
3515
3943
|
};
|
|
3516
3944
|
if (opts.orderType !== void 0) params.order_type = opts.orderType;
|
|
3945
|
+
if (opts.orderTypes !== void 0) params.order_types = opts.orderTypes;
|
|
3517
3946
|
if (opts.status !== void 0) params.status = opts.status;
|
|
3947
|
+
if (opts.statuses !== void 0) params.statuses = opts.statuses;
|
|
3948
|
+
if (opts.createdFrom !== void 0) params.created_from = opts.createdFrom;
|
|
3949
|
+
if (opts.createdTo !== void 0) params.created_to = opts.createdTo;
|
|
3950
|
+
if (opts.cursor !== void 0) params.cursor = opts.cursor;
|
|
3518
3951
|
const member = memberIdOf(opts);
|
|
3519
3952
|
if (member !== void 0) params.member_id = member;
|
|
3520
3953
|
const spinner = format === "json" ? null : createSpinner("Fetching orders...");
|
|
@@ -3539,7 +3972,7 @@ function registerOrdersListCommand(parent, deps) {
|
|
|
3539
3972
|
|
|
3540
3973
|
// src/orders/get.ts
|
|
3541
3974
|
function registerOrdersGetCommand(parent, deps) {
|
|
3542
|
-
const cmd = parent.command("get").description("Get a single order detail by id, regardless of provider (ride/hotel)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").requiredOption("--order-id <id>", "Order id (e.g. rio_
|
|
3975
|
+
const cmd = parent.command("get").description("Get a single order detail by id, regardless of provider (ride/hotel/flight)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").requiredOption("--order-id <id>", "Order id (e.g. rio_..., hho_..., or ffo_...)");
|
|
3543
3976
|
attachSchemaHelp(cmd, unifiedOrdersGetSchema);
|
|
3544
3977
|
cmd.action(async () => {
|
|
3545
3978
|
const opts = cmd.optsWithGlobals();
|
|
@@ -3570,28 +4003,28 @@ function registerOrdersGetCommand(parent, deps) {
|
|
|
3570
4003
|
}
|
|
3571
4004
|
|
|
3572
4005
|
// src/hotel-redaug/search.ts
|
|
3573
|
-
function
|
|
4006
|
+
function need9(value, flag) {
|
|
3574
4007
|
if (value === void 0) {
|
|
3575
4008
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3576
4009
|
}
|
|
3577
4010
|
return value;
|
|
3578
4011
|
}
|
|
3579
|
-
function
|
|
3580
|
-
const n = Number(
|
|
4012
|
+
function num5(value, flag) {
|
|
4013
|
+
const n = Number(need9(value, flag));
|
|
3581
4014
|
if (!Number.isFinite(n)) {
|
|
3582
4015
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3583
4016
|
}
|
|
3584
4017
|
return n;
|
|
3585
4018
|
}
|
|
3586
4019
|
function coord(value, flag, min, max) {
|
|
3587
|
-
const n =
|
|
4020
|
+
const n = num5(value, flag);
|
|
3588
4021
|
if (n < min || n > max) {
|
|
3589
4022
|
throw new CliError("PARAM_INVALID", `--${flag} must be between ${min} and ${max}.`);
|
|
3590
4023
|
}
|
|
3591
4024
|
return n;
|
|
3592
4025
|
}
|
|
3593
4026
|
function positiveInt3(value, flag) {
|
|
3594
|
-
const n =
|
|
4027
|
+
const n = num5(value, flag);
|
|
3595
4028
|
if (!Number.isInteger(n) || n <= 0) {
|
|
3596
4029
|
throw new CliError("PARAM_INVALID", `--${flag} must be a positive integer.`);
|
|
3597
4030
|
}
|
|
@@ -3599,7 +4032,7 @@ function positiveInt3(value, flag) {
|
|
|
3599
4032
|
}
|
|
3600
4033
|
var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3601
4034
|
function stayDate(value, flag) {
|
|
3602
|
-
const raw =
|
|
4035
|
+
const raw = need9(value, flag);
|
|
3603
4036
|
if (!YMD_RE.test(raw)) {
|
|
3604
4037
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3605
4038
|
}
|
|
@@ -3671,21 +4104,21 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
3671
4104
|
const pageSize = positiveInt3(opts.pageSize, "page-size");
|
|
3672
4105
|
const body = {};
|
|
3673
4106
|
if (hasDestination) {
|
|
3674
|
-
body.destination_id =
|
|
4107
|
+
body.destination_id = need9(opts.destinationId, "destination-id");
|
|
3675
4108
|
} else {
|
|
3676
4109
|
body.lat = coord(opts.lat, "lat", -90, 90);
|
|
3677
4110
|
body.lng = coord(opts.lng, "lng", -180, 180);
|
|
3678
4111
|
}
|
|
3679
|
-
body.distance =
|
|
4112
|
+
body.distance = num5(opts.distance, "distance");
|
|
3680
4113
|
body.check_in = checkIn;
|
|
3681
4114
|
body.check_out = checkOut;
|
|
3682
|
-
body.adults =
|
|
3683
|
-
body.children =
|
|
3684
|
-
body.room_num =
|
|
3685
|
-
if (opts.star !== void 0) body.star =
|
|
4115
|
+
body.adults = num5(opts.adults, "adults");
|
|
4116
|
+
body.children = num5(opts.children, "children");
|
|
4117
|
+
body.room_num = num5(opts.roomNum, "room-num");
|
|
4118
|
+
if (opts.star !== void 0) body.star = num5(opts.star, "star");
|
|
3686
4119
|
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 =
|
|
4120
|
+
if (opts.priceMin !== void 0) body.price_min = num5(opts.priceMin, "price-min");
|
|
4121
|
+
if (opts.priceMax !== void 0) body.price_max = num5(opts.priceMax, "price-max");
|
|
3689
4122
|
if (opts.sortBy !== void 0) body.sort_by = opts.sortBy;
|
|
3690
4123
|
body.page = page;
|
|
3691
4124
|
body.page_size = pageSize;
|
|
@@ -3714,14 +4147,14 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
3714
4147
|
}
|
|
3715
4148
|
|
|
3716
4149
|
// src/hotel-redaug/quote.ts
|
|
3717
|
-
function
|
|
4150
|
+
function need10(value, flag) {
|
|
3718
4151
|
if (value === void 0) {
|
|
3719
4152
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3720
4153
|
}
|
|
3721
4154
|
return value;
|
|
3722
4155
|
}
|
|
3723
|
-
function
|
|
3724
|
-
const n = Number(
|
|
4156
|
+
function num6(value, flag) {
|
|
4157
|
+
const n = Number(need10(value, flag));
|
|
3725
4158
|
if (!Number.isFinite(n)) {
|
|
3726
4159
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3727
4160
|
}
|
|
@@ -3729,7 +4162,7 @@ function num5(value, flag) {
|
|
|
3729
4162
|
}
|
|
3730
4163
|
var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3731
4164
|
function stayDate2(value, flag) {
|
|
3732
|
-
const raw =
|
|
4165
|
+
const raw = need10(value, flag);
|
|
3733
4166
|
if (!YMD_RE2.test(raw)) {
|
|
3734
4167
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3735
4168
|
}
|
|
@@ -3769,7 +4202,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3769
4202
|
message: "API Key:",
|
|
3770
4203
|
type: "password"
|
|
3771
4204
|
});
|
|
3772
|
-
const hotelId =
|
|
4205
|
+
const hotelId = need10(opts.hotelId, "hotel-id");
|
|
3773
4206
|
const checkIn = stayDate2(opts.checkIn, "check-in");
|
|
3774
4207
|
const checkOut = stayDate2(opts.checkOut, "check-out");
|
|
3775
4208
|
if (!(checkOut > checkIn)) {
|
|
@@ -3779,9 +4212,9 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3779
4212
|
hotel_id: hotelId,
|
|
3780
4213
|
check_in: checkIn,
|
|
3781
4214
|
check_out: checkOut,
|
|
3782
|
-
adults:
|
|
3783
|
-
children:
|
|
3784
|
-
room_num:
|
|
4215
|
+
adults: num6(opts.adults, "adults"),
|
|
4216
|
+
children: num6(opts.children, "children"),
|
|
4217
|
+
room_num: num6(opts.roomNum, "room-num"),
|
|
3785
4218
|
nationality: opts.nationality
|
|
3786
4219
|
};
|
|
3787
4220
|
const result = await deps.apiClient.post(
|
|
@@ -3803,7 +4236,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
3803
4236
|
}
|
|
3804
4237
|
|
|
3805
4238
|
// src/hotel-redaug/create-order.ts
|
|
3806
|
-
import { confirm as
|
|
4239
|
+
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
3807
4240
|
function parsePriceItems(raw) {
|
|
3808
4241
|
const INVALID = "--price-items must be a JSON array of {sale_date (string), sale_price (number), breakfast_num (number)}.";
|
|
3809
4242
|
let parsed;
|
|
@@ -3861,14 +4294,14 @@ function parseCancellation(raw) {
|
|
|
3861
4294
|
}
|
|
3862
4295
|
return parsed;
|
|
3863
4296
|
}
|
|
3864
|
-
function
|
|
4297
|
+
function need11(value, flag) {
|
|
3865
4298
|
if (value === void 0) {
|
|
3866
4299
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
3867
4300
|
}
|
|
3868
4301
|
return value;
|
|
3869
4302
|
}
|
|
3870
|
-
function
|
|
3871
|
-
const n = Number(
|
|
4303
|
+
function num7(value, flag) {
|
|
4304
|
+
const n = Number(need11(value, flag));
|
|
3872
4305
|
if (!Number.isFinite(n)) {
|
|
3873
4306
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
3874
4307
|
}
|
|
@@ -3876,7 +4309,7 @@ function num6(value, flag) {
|
|
|
3876
4309
|
}
|
|
3877
4310
|
var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3878
4311
|
function stayDate3(value, flag) {
|
|
3879
|
-
const raw =
|
|
4312
|
+
const raw = need11(value, flag);
|
|
3880
4313
|
if (!YMD_RE3.test(raw)) {
|
|
3881
4314
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
3882
4315
|
}
|
|
@@ -3887,7 +4320,7 @@ function stayDate3(value, flag) {
|
|
|
3887
4320
|
}
|
|
3888
4321
|
return raw;
|
|
3889
4322
|
}
|
|
3890
|
-
function
|
|
4323
|
+
function formatCreateOrder2(data) {
|
|
3891
4324
|
const lines = [
|
|
3892
4325
|
["Order ID", String(data.order_id ?? "-")],
|
|
3893
4326
|
["FC order code", String(data.fc_order_code ?? "-")],
|
|
@@ -3945,18 +4378,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3945
4378
|
message: "API Key:",
|
|
3946
4379
|
type: "password"
|
|
3947
4380
|
});
|
|
3948
|
-
const productToken =
|
|
3949
|
-
const totalAmount =
|
|
3950
|
-
const currency =
|
|
3951
|
-
const priceItems = parsePriceItems(
|
|
4381
|
+
const productToken = need11(opts.productToken, "product-token");
|
|
4382
|
+
const totalAmount = num7(opts.totalAmount, "total-amount");
|
|
4383
|
+
const currency = need11(opts.currency, "currency");
|
|
4384
|
+
const priceItems = parsePriceItems(need11(opts.priceItems, "price-items"));
|
|
3952
4385
|
const checkIn = stayDate3(opts.checkIn, "check-in");
|
|
3953
4386
|
const checkOut = stayDate3(opts.checkOut, "check-out");
|
|
3954
4387
|
if (!(checkOut > checkIn)) {
|
|
3955
4388
|
throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
|
|
3956
4389
|
}
|
|
3957
|
-
const guestName =
|
|
3958
|
-
const contactName =
|
|
3959
|
-
const contactPhone =
|
|
4390
|
+
const guestName = need11(opts.guestName, "guest-name");
|
|
4391
|
+
const contactName = need11(opts.contactName, "contact-name");
|
|
4392
|
+
const contactPhone = need11(opts.contactPhone, "contact-phone");
|
|
3960
4393
|
const body = {
|
|
3961
4394
|
product_token: productToken,
|
|
3962
4395
|
total_amount: totalAmount,
|
|
@@ -3964,9 +4397,9 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3964
4397
|
price_items: priceItems,
|
|
3965
4398
|
check_in: checkIn,
|
|
3966
4399
|
check_out: checkOut,
|
|
3967
|
-
room_num:
|
|
3968
|
-
adults:
|
|
3969
|
-
children:
|
|
4400
|
+
room_num: num7(opts.roomNum, "room-num"),
|
|
4401
|
+
adults: num7(opts.adults, "adults"),
|
|
4402
|
+
children: num7(opts.children, "children"),
|
|
3970
4403
|
nationality: opts.nationality,
|
|
3971
4404
|
guest_name: guestName,
|
|
3972
4405
|
contact_name: contactName,
|
|
@@ -3990,7 +4423,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3990
4423
|
if (member !== void 0) body.member_id = member;
|
|
3991
4424
|
if (!isYes) {
|
|
3992
4425
|
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
|
|
4426
|
+
const confirmed = await confirm6({
|
|
3994
4427
|
message: `Create this hotel order for ${totalAmount} ${currency} (check-in ${checkIn}, check-out ${checkOut})? ${chargeNote}`,
|
|
3995
4428
|
default: false
|
|
3996
4429
|
});
|
|
@@ -4017,14 +4450,14 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4017
4450
|
const configManager = new ConfigManager();
|
|
4018
4451
|
const commandResult = {
|
|
4019
4452
|
data,
|
|
4020
|
-
text: () =>
|
|
4453
|
+
text: () => formatCreateOrder2(data)
|
|
4021
4454
|
};
|
|
4022
4455
|
await renderWithContext(commandResult, { format }, configManager);
|
|
4023
4456
|
});
|
|
4024
4457
|
}
|
|
4025
4458
|
|
|
4026
4459
|
// src/hotel-redaug/pay-order.ts
|
|
4027
|
-
import { confirm as
|
|
4460
|
+
import { confirm as confirm7 } from "@inquirer/prompts";
|
|
4028
4461
|
|
|
4029
4462
|
// src/hotel-redaug/watch.ts
|
|
4030
4463
|
var DEFAULT_ORDER_WATCH_INTERVAL_SECONDS = 5;
|
|
@@ -4147,7 +4580,7 @@ async function watchCheckoutStatus(apiClient, apiKey, taskOrderCode, opts) {
|
|
|
4147
4580
|
// src/hotel-redaug/pay-order.ts
|
|
4148
4581
|
var DEFAULT_PAY_WATCH_INTERVAL_SECONDS = 5;
|
|
4149
4582
|
var DEFAULT_PAY_WATCH_TIMEOUT_SECONDS = 300;
|
|
4150
|
-
function
|
|
4583
|
+
function formatPayOrder2(data) {
|
|
4151
4584
|
const lines = [
|
|
4152
4585
|
["Order ID", String(data.order_id ?? "-")],
|
|
4153
4586
|
["Order status", String(data.order_status ?? "-")]
|
|
@@ -4169,6 +4602,9 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4169
4602
|
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
4603
|
"--authorized-merchant-trans-id <id>",
|
|
4171
4604
|
"Resume a 3DS challenge: merchant trans id of an already-authorised preauth"
|
|
4605
|
+
).option(
|
|
4606
|
+
"--evo-explicit",
|
|
4607
|
+
"[\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
4608
|
).option(
|
|
4173
4609
|
"--idempotency-key <key>",
|
|
4174
4610
|
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
@@ -4207,8 +4643,9 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4207
4643
|
if (opts.authorizedMerchantTransId !== void 0) {
|
|
4208
4644
|
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
4209
4645
|
}
|
|
4646
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
4210
4647
|
if (!isYes) {
|
|
4211
|
-
const confirmed = await
|
|
4648
|
+
const confirmed = await confirm7({
|
|
4212
4649
|
message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
|
|
4213
4650
|
default: false
|
|
4214
4651
|
});
|
|
@@ -4235,7 +4672,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4235
4672
|
const configManager = new ConfigManager();
|
|
4236
4673
|
const commandResult = {
|
|
4237
4674
|
data,
|
|
4238
|
-
text: () =>
|
|
4675
|
+
text: () => formatPayOrder2(data)
|
|
4239
4676
|
};
|
|
4240
4677
|
await renderWithContext(commandResult, { format }, configManager);
|
|
4241
4678
|
} else {
|
|
@@ -4286,7 +4723,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4286
4723
|
}
|
|
4287
4724
|
|
|
4288
4725
|
// src/hotel-redaug/get.ts
|
|
4289
|
-
function
|
|
4726
|
+
function need12(value, flag) {
|
|
4290
4727
|
if (value === void 0) {
|
|
4291
4728
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4292
4729
|
}
|
|
@@ -4324,8 +4761,8 @@ function formatGetOrder2(data) {
|
|
|
4324
4761
|
}
|
|
4325
4762
|
if (data.guest?.name) lines.push(["Guest", String(data.guest.name)]);
|
|
4326
4763
|
if (data.contact?.name) {
|
|
4327
|
-
const
|
|
4328
|
-
lines.push(["Contact", `${data.contact.name}${
|
|
4764
|
+
const phone3 = data.contact.phone ? ` (+${data.contact.country_code ?? ""} ${data.contact.phone})` : "";
|
|
4765
|
+
lines.push(["Contact", `${data.contact.name}${phone3}`]);
|
|
4329
4766
|
}
|
|
4330
4767
|
if (data.arrive_time) lines.push(["Arrive time", String(data.arrive_time)]);
|
|
4331
4768
|
if (data.special_requests) lines.push(["Special requests", String(data.special_requests)]);
|
|
@@ -4350,7 +4787,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4350
4787
|
message: "API Key:",
|
|
4351
4788
|
type: "password"
|
|
4352
4789
|
});
|
|
4353
|
-
const orderId =
|
|
4790
|
+
const orderId = need12(opts.orderId, "order-id");
|
|
4354
4791
|
if (opts.watch) {
|
|
4355
4792
|
await watchOrderStatus(deps.apiClient, apiKey, orderId, {
|
|
4356
4793
|
intervalSeconds: resolveSeconds(
|
|
@@ -4384,7 +4821,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4384
4821
|
}
|
|
4385
4822
|
|
|
4386
4823
|
// src/hotel-redaug/cancel.ts
|
|
4387
|
-
function
|
|
4824
|
+
function need13(value, flag) {
|
|
4388
4825
|
if (value === void 0) {
|
|
4389
4826
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4390
4827
|
}
|
|
@@ -4437,8 +4874,8 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4437
4874
|
message: "API Key:",
|
|
4438
4875
|
type: "password"
|
|
4439
4876
|
});
|
|
4440
|
-
const orderId =
|
|
4441
|
-
const fcOrderCode =
|
|
4877
|
+
const orderId = need13(opts.orderId, "order-id");
|
|
4878
|
+
const fcOrderCode = need13(opts.fcOrderCode, "fc-order-code");
|
|
4442
4879
|
const body = { fc_order_code: fcOrderCode };
|
|
4443
4880
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
4444
4881
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -4467,15 +4904,15 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4467
4904
|
}
|
|
4468
4905
|
|
|
4469
4906
|
// src/hotel-redaug/checkout.ts
|
|
4470
|
-
import { confirm as
|
|
4471
|
-
function
|
|
4907
|
+
import { confirm as confirm8 } from "@inquirer/prompts";
|
|
4908
|
+
function need14(value, flag) {
|
|
4472
4909
|
if (value === void 0) {
|
|
4473
4910
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4474
4911
|
}
|
|
4475
4912
|
return value;
|
|
4476
4913
|
}
|
|
4477
|
-
function
|
|
4478
|
-
const n = Number(
|
|
4914
|
+
function num8(value, flag) {
|
|
4915
|
+
const n = Number(need14(value, flag));
|
|
4479
4916
|
if (!Number.isFinite(n)) {
|
|
4480
4917
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4481
4918
|
}
|
|
@@ -4541,11 +4978,11 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4541
4978
|
message: "API Key:",
|
|
4542
4979
|
type: "password"
|
|
4543
4980
|
});
|
|
4544
|
-
const orderId =
|
|
4545
|
-
const fcOrderCode =
|
|
4546
|
-
const reason =
|
|
4547
|
-
const checkoutRooms = parseCheckoutRooms(
|
|
4548
|
-
const refundType =
|
|
4981
|
+
const orderId = need14(opts.orderId, "order-id");
|
|
4982
|
+
const fcOrderCode = need14(opts.fcOrderCode, "fc-order-code");
|
|
4983
|
+
const reason = need14(opts.reason, "reason");
|
|
4984
|
+
const checkoutRooms = parseCheckoutRooms(need14(opts.checkoutRooms, "checkout-rooms"));
|
|
4985
|
+
const refundType = num8(opts.refundType, "refund-type");
|
|
4549
4986
|
const body = {
|
|
4550
4987
|
fc_order_code: fcOrderCode,
|
|
4551
4988
|
reason,
|
|
@@ -4553,7 +4990,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4553
4990
|
checkout_rooms: checkoutRooms
|
|
4554
4991
|
};
|
|
4555
4992
|
if (!isYes) {
|
|
4556
|
-
const confirmed = await
|
|
4993
|
+
const confirmed = await confirm8({
|
|
4557
4994
|
message: `Request check-out / out-of-policy cancellation for order ${orderId} (${checkoutRooms.length} room(s))? The property must approve and charges may apply.`,
|
|
4558
4995
|
default: false
|
|
4559
4996
|
});
|
|
@@ -4587,7 +5024,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4587
5024
|
}
|
|
4588
5025
|
|
|
4589
5026
|
// src/hotel-redaug/get-checkout.ts
|
|
4590
|
-
function
|
|
5027
|
+
function need15(value, flag) {
|
|
4591
5028
|
if (value === void 0) {
|
|
4592
5029
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4593
5030
|
}
|
|
@@ -4623,7 +5060,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
|
|
|
4623
5060
|
message: "API Key:",
|
|
4624
5061
|
type: "password"
|
|
4625
5062
|
});
|
|
4626
|
-
const taskOrderCode =
|
|
5063
|
+
const taskOrderCode = need15(opts.taskOrderCode, "task-order-code");
|
|
4627
5064
|
if (opts.watch) {
|
|
4628
5065
|
await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
|
|
4629
5066
|
intervalSeconds: resolveSeconds(
|
|
@@ -4727,7 +5164,7 @@ function registerHotelListOrdersCommand(parent, deps) {
|
|
|
4727
5164
|
}
|
|
4728
5165
|
|
|
4729
5166
|
// src/hotel-redaug/find-destination.ts
|
|
4730
|
-
function
|
|
5167
|
+
function need16(value, flag) {
|
|
4731
5168
|
if (value === void 0 || value.trim() === "") {
|
|
4732
5169
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4733
5170
|
}
|
|
@@ -4761,7 +5198,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
4761
5198
|
message: "API Key:",
|
|
4762
5199
|
type: "password"
|
|
4763
5200
|
});
|
|
4764
|
-
const keyword =
|
|
5201
|
+
const keyword = need16(opts.keyword, "keyword");
|
|
4765
5202
|
const body = { keyword };
|
|
4766
5203
|
if (opts.dataType !== void 0) {
|
|
4767
5204
|
body.data_type = opts.dataType;
|
|
@@ -4785,21 +5222,21 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
4785
5222
|
}
|
|
4786
5223
|
|
|
4787
5224
|
// src/hotel-redaug/hotel-filters.ts
|
|
4788
|
-
function
|
|
5225
|
+
function need17(value, flag) {
|
|
4789
5226
|
if (value === void 0 || value.trim() === "") {
|
|
4790
5227
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4791
5228
|
}
|
|
4792
5229
|
return value;
|
|
4793
5230
|
}
|
|
4794
|
-
function
|
|
4795
|
-
const n = Number(
|
|
5231
|
+
function num9(value, flag) {
|
|
5232
|
+
const n = Number(need17(value, flag));
|
|
4796
5233
|
if (!Number.isFinite(n)) {
|
|
4797
5234
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4798
5235
|
}
|
|
4799
5236
|
return n;
|
|
4800
5237
|
}
|
|
4801
5238
|
function coord2(value, flag, min, max) {
|
|
4802
|
-
const n =
|
|
5239
|
+
const n = num9(value, flag);
|
|
4803
5240
|
if (n < min || n > max) {
|
|
4804
5241
|
throw new CliError("PARAM_INVALID", `--${flag} must be between ${min} and ${max}.`);
|
|
4805
5242
|
}
|
|
@@ -4872,12 +5309,12 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
4872
5309
|
}
|
|
4873
5310
|
const body = {};
|
|
4874
5311
|
if (hasDestination) {
|
|
4875
|
-
body.destination_id =
|
|
5312
|
+
body.destination_id = need17(opts.destinationId, "destination-id");
|
|
4876
5313
|
} else {
|
|
4877
5314
|
body.lat = coord2(opts.lat, "lat", -90, 90);
|
|
4878
5315
|
body.lng = coord2(opts.lng, "lng", -180, 180);
|
|
4879
5316
|
}
|
|
4880
|
-
body.distance =
|
|
5317
|
+
body.distance = num9(opts.distance, "distance");
|
|
4881
5318
|
const result = await deps.apiClient.post(
|
|
4882
5319
|
"/hotel/filters",
|
|
4883
5320
|
{ type: "api-key", key: apiKey },
|
|
@@ -4897,7 +5334,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
4897
5334
|
}
|
|
4898
5335
|
|
|
4899
5336
|
// src/hotel-redaug/list-cities.ts
|
|
4900
|
-
function
|
|
5337
|
+
function need18(value, flag) {
|
|
4901
5338
|
if (value === void 0 || value.trim() === "") {
|
|
4902
5339
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4903
5340
|
}
|
|
@@ -4930,7 +5367,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
4930
5367
|
message: "API Key:",
|
|
4931
5368
|
type: "password"
|
|
4932
5369
|
});
|
|
4933
|
-
const country =
|
|
5370
|
+
const country = need18(opts.country, "country");
|
|
4934
5371
|
const body = { country_code: country };
|
|
4935
5372
|
const result = await deps.apiClient.post(
|
|
4936
5373
|
"/hotel/cities",
|
|
@@ -4951,7 +5388,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
4951
5388
|
}
|
|
4952
5389
|
|
|
4953
5390
|
// src/hotel-redaug/hotel-detail.ts
|
|
4954
|
-
function
|
|
5391
|
+
function need19(value, flag) {
|
|
4955
5392
|
if (value === void 0 || value.trim() === "") {
|
|
4956
5393
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4957
5394
|
}
|
|
@@ -5098,7 +5535,7 @@ function registerHotelDetailCommand(parent, deps) {
|
|
|
5098
5535
|
message: "API Key:",
|
|
5099
5536
|
type: "password"
|
|
5100
5537
|
});
|
|
5101
|
-
const hotelId =
|
|
5538
|
+
const hotelId = need19(opts.hotelId, "hotel-id");
|
|
5102
5539
|
const rawWithImages = opts.withImages;
|
|
5103
5540
|
const withImages = rawWithImages !== "false" && rawWithImages !== false;
|
|
5104
5541
|
const settings = parseSettings(opts.settings);
|
|
@@ -5306,14 +5743,14 @@ function registerHotelSkillCommand(parent) {
|
|
|
5306
5743
|
}
|
|
5307
5744
|
|
|
5308
5745
|
// src/flight-flink/_helpers.ts
|
|
5309
|
-
function
|
|
5746
|
+
function need20(value, flag) {
|
|
5310
5747
|
if (value === void 0) {
|
|
5311
5748
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5312
5749
|
}
|
|
5313
5750
|
return value;
|
|
5314
5751
|
}
|
|
5315
|
-
function
|
|
5316
|
-
const n = Number(
|
|
5752
|
+
function num10(value, flag) {
|
|
5753
|
+
const n = Number(need20(value, flag));
|
|
5317
5754
|
if (!Number.isFinite(n)) {
|
|
5318
5755
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5319
5756
|
}
|
|
@@ -5348,7 +5785,7 @@ function registerFindAirportCommand(parent, deps) {
|
|
|
5348
5785
|
const opts = cmd.optsWithGlobals();
|
|
5349
5786
|
const format = resolveFormat(opts.format);
|
|
5350
5787
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5351
|
-
const keyword =
|
|
5788
|
+
const keyword = need20(opts.keyword, "keyword");
|
|
5352
5789
|
const spinner = format === "json" ? null : createSpinner("Resolving airports...");
|
|
5353
5790
|
const result = await deps.apiClient.post(
|
|
5354
5791
|
"/flight/find-airport",
|
|
@@ -5374,8 +5811,8 @@ function registerListAirportsCommand(parent, deps) {
|
|
|
5374
5811
|
const format = resolveFormat(opts.format);
|
|
5375
5812
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5376
5813
|
const body = {
|
|
5377
|
-
page:
|
|
5378
|
-
page_size:
|
|
5814
|
+
page: num10(opts.page, "page"),
|
|
5815
|
+
page_size: num10(opts.pageSize, "page-size")
|
|
5379
5816
|
};
|
|
5380
5817
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
5381
5818
|
const spinner = format === "json" ? null : createSpinner("Fetching airports...");
|
|
@@ -5399,8 +5836,8 @@ function registerListAirlinesCommand(parent, deps) {
|
|
|
5399
5836
|
const format = resolveFormat(opts.format);
|
|
5400
5837
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5401
5838
|
const body = {
|
|
5402
|
-
page:
|
|
5403
|
-
page_size:
|
|
5839
|
+
page: num10(opts.page, "page"),
|
|
5840
|
+
page_size: num10(opts.pageSize, "page-size")
|
|
5404
5841
|
};
|
|
5405
5842
|
if (opts.keyword !== void 0) body.keyword = opts.keyword;
|
|
5406
5843
|
const spinner = format === "json" ? null : createSpinner("Fetching airlines...");
|
|
@@ -5444,13 +5881,13 @@ function registerSearchCommand(parent, deps) {
|
|
|
5444
5881
|
const format = resolveFormat(opts.format);
|
|
5445
5882
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5446
5883
|
const body = {
|
|
5447
|
-
trip_type:
|
|
5448
|
-
journeys: jsonArray(
|
|
5884
|
+
trip_type: num10(opts.tripType, "trip-type"),
|
|
5885
|
+
journeys: jsonArray(need20(opts.journeys, "journeys"), "journeys"),
|
|
5449
5886
|
cabin_class: opts.cabinClass,
|
|
5450
|
-
adult_num:
|
|
5451
|
-
child_num:
|
|
5452
|
-
infant_num:
|
|
5453
|
-
transfer_number:
|
|
5887
|
+
adult_num: num10(opts.adultNum, "adult-num"),
|
|
5888
|
+
child_num: num10(opts.childNum, "child-num"),
|
|
5889
|
+
infant_num: num10(opts.infantNum, "infant-num"),
|
|
5890
|
+
transfer_number: num10(opts.transferNumber, "transfer-number")
|
|
5454
5891
|
};
|
|
5455
5892
|
if (opts.airline !== void 0) body.airline = opts.airline;
|
|
5456
5893
|
if (opts.journeyId !== void 0) {
|
|
@@ -5476,7 +5913,7 @@ function registerMoreOffersCommand(parent, deps) {
|
|
|
5476
5913
|
const opts = cmd.optsWithGlobals();
|
|
5477
5914
|
const format = resolveFormat(opts.format);
|
|
5478
5915
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5479
|
-
const productToken =
|
|
5916
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5480
5917
|
const spinner = format === "json" ? null : createSpinner("Fetching offers...");
|
|
5481
5918
|
const result = await deps.apiClient.post(
|
|
5482
5919
|
"/flight/more-offers",
|
|
@@ -5497,7 +5934,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5497
5934
|
const opts = cmd.optsWithGlobals();
|
|
5498
5935
|
const format = resolveFormat(opts.format);
|
|
5499
5936
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5500
|
-
const productToken =
|
|
5937
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5501
5938
|
const spinner = format === "json" ? null : createSpinner("Verifying price...");
|
|
5502
5939
|
const result = await deps.apiClient.post(
|
|
5503
5940
|
"/flight/verify",
|
|
@@ -5519,7 +5956,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5519
5956
|
}
|
|
5520
5957
|
|
|
5521
5958
|
// src/flight-flink/create-order.ts
|
|
5522
|
-
import { confirm as
|
|
5959
|
+
import { confirm as confirm9 } from "@inquirer/prompts";
|
|
5523
5960
|
function registerCreateOrderCommand(parent, deps) {
|
|
5524
5961
|
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
5962
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5531,19 +5968,19 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5531
5968
|
const format = resolveFormat(opts.format);
|
|
5532
5969
|
const isYes = Boolean(opts.yes);
|
|
5533
5970
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5534
|
-
const productToken =
|
|
5535
|
-
const totalAmount =
|
|
5536
|
-
const currency =
|
|
5971
|
+
const productToken = need20(opts.productToken, "product-token");
|
|
5972
|
+
const totalAmount = num10(opts.totalAmount, "total-amount");
|
|
5973
|
+
const currency = need20(opts.currency, "currency");
|
|
5537
5974
|
const body = {
|
|
5538
5975
|
product_token: productToken,
|
|
5539
5976
|
total_amount: totalAmount,
|
|
5540
5977
|
currency,
|
|
5541
|
-
trip_type:
|
|
5542
|
-
contact_name:
|
|
5543
|
-
contact_region:
|
|
5544
|
-
contact_phone:
|
|
5545
|
-
contact_email:
|
|
5546
|
-
passengers: jsonArray(
|
|
5978
|
+
trip_type: num10(opts.tripType, "trip-type"),
|
|
5979
|
+
contact_name: need20(opts.contactName, "contact-name"),
|
|
5980
|
+
contact_region: need20(opts.contactRegion, "contact-region"),
|
|
5981
|
+
contact_phone: need20(opts.contactPhone, "contact-phone"),
|
|
5982
|
+
contact_email: need20(opts.contactEmail, "contact-email"),
|
|
5983
|
+
passengers: jsonArray(need20(opts.passengers, "passengers"), "passengers")
|
|
5547
5984
|
};
|
|
5548
5985
|
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
5549
5986
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
@@ -5553,7 +5990,7 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5553
5990
|
const member = memberIdOf(opts);
|
|
5554
5991
|
if (member !== void 0) body.member_id = member;
|
|
5555
5992
|
if (!isYes) {
|
|
5556
|
-
const ok = await
|
|
5993
|
+
const ok = await confirm9({
|
|
5557
5994
|
message: `Create this flight order for ${totalAmount} ${currency}? This locks the fare but does NOT charge yet.`,
|
|
5558
5995
|
default: false
|
|
5559
5996
|
});
|
|
@@ -5592,11 +6029,14 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5592
6029
|
}
|
|
5593
6030
|
|
|
5594
6031
|
// src/flight-flink/pay-order.ts
|
|
5595
|
-
import { confirm as
|
|
6032
|
+
import { confirm as confirm10 } from "@inquirer/prompts";
|
|
5596
6033
|
function registerPayOrderCommand(parent, deps) {
|
|
5597
6034
|
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
6035
|
"--authorized-merchant-trans-id <id>",
|
|
5599
6036
|
"Resume a 3DS challenge: merchant trans id of an already-authorised preauth"
|
|
6037
|
+
).option(
|
|
6038
|
+
"--evo-explicit",
|
|
6039
|
+
"[\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
6040
|
).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
|
|
5601
6041
|
attachSchemaHelp(cmd, flightPayOrderSchema);
|
|
5602
6042
|
cmd.action(async () => {
|
|
@@ -5604,9 +6044,9 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
5604
6044
|
const format = resolveFormat(opts.format);
|
|
5605
6045
|
const isYes = Boolean(opts.yes);
|
|
5606
6046
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5607
|
-
const orderNo =
|
|
6047
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5608
6048
|
if (!isYes) {
|
|
5609
|
-
const ok = await
|
|
6049
|
+
const ok = await confirm10({
|
|
5610
6050
|
message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
|
|
5611
6051
|
default: false
|
|
5612
6052
|
});
|
|
@@ -5623,6 +6063,7 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
5623
6063
|
if (opts.authorizedMerchantTransId !== void 0) {
|
|
5624
6064
|
body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
|
|
5625
6065
|
}
|
|
6066
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
5626
6067
|
const result = await deps.apiClient.post(
|
|
5627
6068
|
`/flight/${encodeURIComponent(orderNo)}/pay`,
|
|
5628
6069
|
{ type: "api-key", key: apiKey },
|
|
@@ -5655,12 +6096,12 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
5655
6096
|
const opts = cmd.optsWithGlobals();
|
|
5656
6097
|
const format = resolveFormat(opts.format);
|
|
5657
6098
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5658
|
-
const orderNo =
|
|
6099
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5659
6100
|
const path = `/flight/${encodeURIComponent(orderNo)}/status`;
|
|
5660
6101
|
const auth = { type: "api-key", key: apiKey };
|
|
5661
6102
|
if (opts.watch) {
|
|
5662
|
-
const interval =
|
|
5663
|
-
const timeoutMs =
|
|
6103
|
+
const interval = num10(opts.watchInterval, "watch-interval") * 1e3;
|
|
6104
|
+
const timeoutMs = num10(opts.watchTimeout, "watch-timeout") * 1e3;
|
|
5664
6105
|
const deadline = Date.now() + timeoutMs;
|
|
5665
6106
|
for (; ; ) {
|
|
5666
6107
|
const r = await deps.apiClient.get(path, auth);
|
|
@@ -5695,7 +6136,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
5695
6136
|
}
|
|
5696
6137
|
|
|
5697
6138
|
// src/flight-flink/cancel-order.ts
|
|
5698
|
-
import { confirm as
|
|
6139
|
+
import { confirm as confirm11 } from "@inquirer/prompts";
|
|
5699
6140
|
function registerCancelOrderCommand(parent, deps) {
|
|
5700
6141
|
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
6142
|
attachSchemaHelp(cmd, flightCancelOrderSchema);
|
|
@@ -5704,9 +6145,9 @@ function registerCancelOrderCommand(parent, deps) {
|
|
|
5704
6145
|
const format = resolveFormat(opts.format);
|
|
5705
6146
|
const isYes = Boolean(opts.yes);
|
|
5706
6147
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5707
|
-
const orderNo =
|
|
6148
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
5708
6149
|
if (!isYes) {
|
|
5709
|
-
const ok = await
|
|
6150
|
+
const ok = await confirm11({
|
|
5710
6151
|
message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
|
|
5711
6152
|
default: false
|
|
5712
6153
|
});
|
|
@@ -5751,8 +6192,8 @@ function registerListOrdersCommand2(parent, deps) {
|
|
|
5751
6192
|
if (opts.status !== void 0) params.set("status", opts.status);
|
|
5752
6193
|
const member = memberIdOf(opts);
|
|
5753
6194
|
if (member !== void 0) params.set("member_id", member);
|
|
5754
|
-
params.set("page", String(
|
|
5755
|
-
params.set("page_size", String(
|
|
6195
|
+
params.set("page", String(num10(opts.page, "page")));
|
|
6196
|
+
params.set("page_size", String(num10(opts.pageSize, "page-size")));
|
|
5756
6197
|
const spinner = format === "json" ? null : createSpinner("Fetching flight orders...");
|
|
5757
6198
|
const result = await deps.apiClient.get(
|
|
5758
6199
|
`/flight/orders?${params.toString()}`,
|
|
@@ -5780,10 +6221,10 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
5780
6221
|
const format = resolveFormat(opts.format);
|
|
5781
6222
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5782
6223
|
const body = {
|
|
5783
|
-
order_no:
|
|
5784
|
-
date:
|
|
5785
|
-
passenger:
|
|
5786
|
-
segment_id:
|
|
6224
|
+
order_no: need20(opts.orderNo, "order-no"),
|
|
6225
|
+
date: need20(opts.date, "date"),
|
|
6226
|
+
passenger: need20(opts.passenger, "passenger"),
|
|
6227
|
+
segment_id: need20(opts.segmentId, "segment-id"),
|
|
5787
6228
|
cabin_class: opts.cabinClass
|
|
5788
6229
|
};
|
|
5789
6230
|
const spinner = format === "json" ? null : createSpinner("Searching change options...");
|
|
@@ -5799,7 +6240,7 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
5799
6240
|
}
|
|
5800
6241
|
|
|
5801
6242
|
// src/flight-flink/change-apply.ts
|
|
5802
|
-
import { confirm as
|
|
6243
|
+
import { confirm as confirm12 } from "@inquirer/prompts";
|
|
5803
6244
|
function registerChangeApplyCommand(parent, deps) {
|
|
5804
6245
|
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
6246
|
attachSchemaHelp(cmd, flightChangeApplySchema);
|
|
@@ -5809,17 +6250,17 @@ function registerChangeApplyCommand(parent, deps) {
|
|
|
5809
6250
|
const isYes = Boolean(opts.yes);
|
|
5810
6251
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5811
6252
|
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:
|
|
6253
|
+
order_no: need20(opts.orderNo, "order-no"),
|
|
6254
|
+
passenger: need20(opts.passenger, "passenger"),
|
|
6255
|
+
segment_id: need20(opts.segmentId, "segment-id"),
|
|
6256
|
+
product_token: need20(opts.productToken, "product-token"),
|
|
6257
|
+
contact_name: need20(opts.contactName, "contact-name"),
|
|
6258
|
+
contact_region: need20(opts.contactRegion, "contact-region"),
|
|
6259
|
+
contact_phone: need20(opts.contactPhone, "contact-phone"),
|
|
6260
|
+
contact_email: need20(opts.contactEmail, "contact-email")
|
|
5820
6261
|
};
|
|
5821
6262
|
if (!isYes) {
|
|
5822
|
-
const ok = await
|
|
6263
|
+
const ok = await confirm12({
|
|
5823
6264
|
message: `Submit a change request for order ${body.order_no}?`,
|
|
5824
6265
|
default: false
|
|
5825
6266
|
});
|
|
@@ -5850,7 +6291,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
5850
6291
|
const opts = cmd.optsWithGlobals();
|
|
5851
6292
|
const format = resolveFormat(opts.format);
|
|
5852
6293
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5853
|
-
const changeOrderNo =
|
|
6294
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
5854
6295
|
const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
|
|
5855
6296
|
const result = await deps.apiClient.get(
|
|
5856
6297
|
`/flight/change/${encodeURIComponent(changeOrderNo)}`,
|
|
@@ -5863,7 +6304,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
5863
6304
|
}
|
|
5864
6305
|
|
|
5865
6306
|
// src/flight-flink/change-cancel.ts
|
|
5866
|
-
import { confirm as
|
|
6307
|
+
import { confirm as confirm13 } from "@inquirer/prompts";
|
|
5867
6308
|
function registerChangeCancelCommand(parent, deps) {
|
|
5868
6309
|
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
6310
|
attachSchemaHelp(cmd, flightChangeCancelSchema);
|
|
@@ -5872,9 +6313,9 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
5872
6313
|
const format = resolveFormat(opts.format);
|
|
5873
6314
|
const isYes = Boolean(opts.yes);
|
|
5874
6315
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5875
|
-
const changeOrderNo =
|
|
6316
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
5876
6317
|
if (!isYes) {
|
|
5877
|
-
const ok = await
|
|
6318
|
+
const ok = await confirm13({ message: `Cancel change request ${changeOrderNo}?`, default: false });
|
|
5878
6319
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
|
|
5879
6320
|
}
|
|
5880
6321
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5895,7 +6336,7 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
5895
6336
|
}
|
|
5896
6337
|
|
|
5897
6338
|
// src/flight-flink/change-pay.ts
|
|
5898
|
-
import { confirm as
|
|
6339
|
+
import { confirm as confirm14 } from "@inquirer/prompts";
|
|
5899
6340
|
function registerChangePayCommand(parent, deps) {
|
|
5900
6341
|
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
6342
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5907,10 +6348,10 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5907
6348
|
const format = resolveFormat(opts.format);
|
|
5908
6349
|
const isYes = Boolean(opts.yes);
|
|
5909
6350
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5910
|
-
const changeOrderNo =
|
|
5911
|
-
const orderNo =
|
|
5912
|
-
const amount =
|
|
5913
|
-
const currency =
|
|
6351
|
+
const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
|
|
6352
|
+
const orderNo = need20(opts.orderNo, "order-no");
|
|
6353
|
+
const amount = num10(opts.amount, "amount");
|
|
6354
|
+
const currency = need20(opts.currency, "currency");
|
|
5914
6355
|
const body = {
|
|
5915
6356
|
order_no: orderNo,
|
|
5916
6357
|
amount,
|
|
@@ -5924,7 +6365,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5924
6365
|
if (!isYes) {
|
|
5925
6366
|
const isResume = opts.authorizedMerchantTransId !== void 0;
|
|
5926
6367
|
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
|
|
6368
|
+
const ok = await confirm14({ message, default: false });
|
|
5928
6369
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change payment aborted by user.");
|
|
5929
6370
|
}
|
|
5930
6371
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -5971,7 +6412,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
5971
6412
|
}
|
|
5972
6413
|
|
|
5973
6414
|
// src/flight-flink/refund-apply.ts
|
|
5974
|
-
import { confirm as
|
|
6415
|
+
import { confirm as confirm15 } from "@inquirer/prompts";
|
|
5975
6416
|
function registerRefundApplyCommand(parent, deps) {
|
|
5976
6417
|
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
6418
|
attachSchemaHelp(cmd, flightRefundApplySchema);
|
|
@@ -5981,18 +6422,18 @@ function registerRefundApplyCommand(parent, deps) {
|
|
|
5981
6422
|
const isYes = Boolean(opts.yes);
|
|
5982
6423
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5983
6424
|
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:
|
|
6425
|
+
order_no: need20(opts.orderNo, "order-no"),
|
|
6426
|
+
passenger: need20(opts.passenger, "passenger"),
|
|
6427
|
+
segment_id: need20(opts.segmentId, "segment-id"),
|
|
6428
|
+
reason_type: num10(opts.reasonType, "reason-type"),
|
|
6429
|
+
contact_name: need20(opts.contactName, "contact-name"),
|
|
6430
|
+
contact_region: need20(opts.contactRegion, "contact-region"),
|
|
6431
|
+
contact_phone: need20(opts.contactPhone, "contact-phone"),
|
|
6432
|
+
contact_email: need20(opts.contactEmail, "contact-email")
|
|
5992
6433
|
};
|
|
5993
6434
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
5994
6435
|
if (!isYes) {
|
|
5995
|
-
const ok = await
|
|
6436
|
+
const ok = await confirm15({
|
|
5996
6437
|
message: `Submit a refund request for order ${body.order_no}?`,
|
|
5997
6438
|
default: false
|
|
5998
6439
|
});
|
|
@@ -6023,7 +6464,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6023
6464
|
const opts = cmd.optsWithGlobals();
|
|
6024
6465
|
const format = resolveFormat(opts.format);
|
|
6025
6466
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6026
|
-
const refundOrderNo =
|
|
6467
|
+
const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
|
|
6027
6468
|
const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
|
|
6028
6469
|
const result = await deps.apiClient.get(
|
|
6029
6470
|
`/flight/refund/${encodeURIComponent(refundOrderNo)}`,
|
|
@@ -6036,7 +6477,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6036
6477
|
}
|
|
6037
6478
|
|
|
6038
6479
|
// src/flight-flink/refund-confirm.ts
|
|
6039
|
-
import { confirm as
|
|
6480
|
+
import { confirm as confirm16 } from "@inquirer/prompts";
|
|
6040
6481
|
function registerRefundConfirmCommand(parent, deps) {
|
|
6041
6482
|
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
6483
|
attachSchemaHelp(cmd, flightRefundConfirmSchema);
|
|
@@ -6045,14 +6486,14 @@ function registerRefundConfirmCommand(parent, deps) {
|
|
|
6045
6486
|
const format = resolveFormat(opts.format);
|
|
6046
6487
|
const isYes = Boolean(opts.yes);
|
|
6047
6488
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6048
|
-
const refundOrderNo =
|
|
6049
|
-
const confirmFlag =
|
|
6489
|
+
const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
|
|
6490
|
+
const confirmFlag = need20(opts.confirm, "confirm");
|
|
6050
6491
|
if (confirmFlag !== "1" && confirmFlag !== "2") {
|
|
6051
6492
|
throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
|
|
6052
6493
|
}
|
|
6053
6494
|
if (!isYes) {
|
|
6054
6495
|
const action = confirmFlag === "1" ? "confirm" : "cancel";
|
|
6055
|
-
const ok = await
|
|
6496
|
+
const ok = await confirm16({ message: `${action} refund ${refundOrderNo}?`, default: false });
|
|
6056
6497
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Refund confirmation aborted by user.");
|
|
6057
6498
|
}
|
|
6058
6499
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -6215,6 +6656,8 @@ Key notes:
|
|
|
6215
6656
|
);
|
|
6216
6657
|
registerQuoteCommand(rideCmd, deps);
|
|
6217
6658
|
registerBookCommand(rideCmd, deps);
|
|
6659
|
+
registerRideCreateOrderCommand(rideCmd, deps);
|
|
6660
|
+
registerRidePayOrderCommand(rideCmd, deps);
|
|
6218
6661
|
registerRideGetCommand(rideCmd, deps);
|
|
6219
6662
|
registerCancelCommand(rideCmd, deps);
|
|
6220
6663
|
registerRideUpdateCommand(rideCmd, deps);
|
|
@@ -6224,7 +6667,7 @@ Key notes:
|
|
|
6224
6667
|
registerServicesListCommand(servicesCmd, { discoveryClient, program });
|
|
6225
6668
|
registerServiceGetCommand(servicesCmd, { discoveryClient, program });
|
|
6226
6669
|
const ordersCmd = program.command("orders").description(
|
|
6227
|
-
|
|
6670
|
+
"Unified cross-provider order index (ride + hotel + flight). Use for order history, common filters, and stable pagination."
|
|
6228
6671
|
);
|
|
6229
6672
|
registerOrdersListCommand(ordersCmd, deps);
|
|
6230
6673
|
registerOrdersGetCommand(ordersCmd, deps);
|