@agenzo/merchant-cli 0.8.17 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +343 -343
- package/dist/index.js +383 -105
- package/dist/index.js.map +1 -1
- package/package.json +28 -28
package/dist/index.js
CHANGED
|
@@ -2231,6 +2231,97 @@ var unifiedOrdersGetSchema = {
|
|
|
2231
2231
|
INTERNAL_ERROR: "The order's provider detail lookup is temporarily unavailable. Retry once after a short delay."
|
|
2232
2232
|
}
|
|
2233
2233
|
};
|
|
2234
|
+
var ordersPayBatchSchema = {
|
|
2235
|
+
cli: CLI_NAME,
|
|
2236
|
+
noun: ORDERS_NOUN,
|
|
2237
|
+
verb: "pay-batch",
|
|
2238
|
+
description: "Settle a batch of orders (may mix ride/hotel/flight \u2014 hho_/ffo_/rio_) in ONE aggregate payment via a single payment credential. Physical landing point of the logical write tool orders__aggregate__pay-batch, invoked by the trip-aggregate pay-orders write verb through UniversalGateway (executed only after the single confirmation gate; never exposed to the LLM). Amounts are NOT passed here \u2014 the platform sums each order's locked authoritative price. Provide the aggregate total via one rail: --payment-token-id (\u8F68A: network-token minted for the aggregate total, external_transaction_id bound to this payment_group \u2014 one UnionPay/Visa passkey) OR --payment-method-id (\u8F68B: EVO bound card \u2014 one 3DS challenge); both may be omitted (monthly_settlement / platform default card). On EVO cardholder authentication the response is AUTHENTICATION_REQUIRED with a three_ds_url + merchant_trans_id; finish it out-of-band, then an idempotent replay settles. On success the batch becomes settled / partially_settled (upstream-confirmation-failed orders are refunded). Supports --watch to poll until a terminal batch status.",
|
|
2239
|
+
flags: {
|
|
2240
|
+
"order-ids": {
|
|
2241
|
+
type: "string",
|
|
2242
|
+
required: true,
|
|
2243
|
+
description: `Ordered order ids to settle together \u2014 comma-separated (hho_1,ffo_2,rio_3) or a JSON array (["hho_1","ffo_2"]). May mix hho_/ffo_/rio_ domains. Amounts come from each order's locked authoritative price (NOT passed here).`
|
|
2244
|
+
},
|
|
2245
|
+
"payment-token-id": {
|
|
2246
|
+
type: "string",
|
|
2247
|
+
required: false,
|
|
2248
|
+
description: "[\u8F68A] Network-token id (UnionPay/Visa) minted for the aggregate total with external_transaction_id bound to this payment_group (direct-charge main path). Mutually exclusive with --payment-method-id; both may be omitted for monthly_settlement / platform default."
|
|
2249
|
+
},
|
|
2250
|
+
"payment-method-id": {
|
|
2251
|
+
type: "string",
|
|
2252
|
+
required: false,
|
|
2253
|
+
description: "[\u8F68B] EVO bound-card id to settle the aggregate total via one 3DS challenge (explicit/fallback rail). Mutually exclusive with --payment-token-id."
|
|
2254
|
+
},
|
|
2255
|
+
"evo-explicit": {
|
|
2256
|
+
type: "bool",
|
|
2257
|
+
required: false,
|
|
2258
|
+
default: false,
|
|
2259
|
+
description: "[\u8F68B \u786C\u95E8\u69DB] Explicit opt-in to settle via the EVO bound-card rail. Set true ONLY when the user explicitly chose EVO; forwarded to the body as evo_explicit=true. Omit on the payment-token-id direct-charge path."
|
|
2260
|
+
},
|
|
2261
|
+
"payment-group-id": {
|
|
2262
|
+
type: "string",
|
|
2263
|
+
required: false,
|
|
2264
|
+
description: "Optional caller-pre-generated payment group id; omit to let the platform generate one. The whole batch is associated with this group for cross-provider reconciliation."
|
|
2265
|
+
},
|
|
2266
|
+
member: MEMBER_FLAG_SCHEMA,
|
|
2267
|
+
"idempotency-key": {
|
|
2268
|
+
type: "string",
|
|
2269
|
+
required: true,
|
|
2270
|
+
description: "Unique key forwarded verbatim as the Idempotency-Key header; never auto-generated. The SAME key + the SAME ordered order_ids replays as the same batch (dedup re-check, no double charge); any change to order_ids yields a new batch.",
|
|
2271
|
+
constraints: "1-128 chars [A-Za-z0-9_-]"
|
|
2272
|
+
},
|
|
2273
|
+
watch: {
|
|
2274
|
+
type: "bool",
|
|
2275
|
+
required: false,
|
|
2276
|
+
default: false,
|
|
2277
|
+
description: "Poll until a terminal batch status (settled / partially_settled / failed) or timeout, emitting one NDJSON line per poll. Non-terminal states (authorizing/capturing, AUTHENTICATION_REQUIRED) keep polling \u2014 after the user finishes 3DS out-of-band, the next idempotent replay settles."
|
|
2278
|
+
},
|
|
2279
|
+
// watch 默认值与 pay-batch.ts 的 DEFAULT_PAY_BATCH_WATCH_* 常量一致;此处内联字面量
|
|
2280
|
+
// 以避免 verb-schema.ts ↔ pay-batch.ts 循环依赖(pay-batch.ts 反向依赖本模块的 schema)。
|
|
2281
|
+
"watch-interval": {
|
|
2282
|
+
type: "int",
|
|
2283
|
+
required: false,
|
|
2284
|
+
default: 5,
|
|
2285
|
+
description: "Seconds between polls when --watch is set"
|
|
2286
|
+
},
|
|
2287
|
+
"watch-timeout": {
|
|
2288
|
+
type: "int",
|
|
2289
|
+
required: false,
|
|
2290
|
+
default: 300,
|
|
2291
|
+
description: "Max seconds to poll before giving up"
|
|
2292
|
+
}
|
|
2293
|
+
},
|
|
2294
|
+
response: {
|
|
2295
|
+
payment_group_id: { type: "string", description: "The payment group this batch settled under (echoes --payment-group-id when supplied, else server-generated)." },
|
|
2296
|
+
status: { type: "string", description: "settled | partially_settled | failed | AUTHENTICATION_REQUIRED (3DS challenge body)." },
|
|
2297
|
+
currency: { type: "string", description: "ISO 4217 currency of the aggregate settlement (all orders share one currency)." },
|
|
2298
|
+
total_amount: { type: "float", description: "Aggregate total in DECIMAL units = sum of each order's authoritative price (computed by the platform, NOT sent by the caller)." },
|
|
2299
|
+
orders: {
|
|
2300
|
+
type: "array",
|
|
2301
|
+
description: "Per-order final result after upstream confirmation.",
|
|
2302
|
+
items: {
|
|
2303
|
+
order_id: { type: "string", description: "hho_/ffo_/rio_ order id." },
|
|
2304
|
+
status: { type: "string", description: "confirmed | refunded | failed." },
|
|
2305
|
+
amount: { type: "float", description: "That order's authoritative amount." },
|
|
2306
|
+
refunded_amount: { type: "float", description: "Amount refunded when upstream confirmation failed for this order." }
|
|
2307
|
+
}
|
|
2308
|
+
},
|
|
2309
|
+
three_ds_url: { type: "string", description: "[AUTHENTICATION_REQUIRED only] EVO 3DS challenge URL \u2014 complete out-of-band, then replay to settle." },
|
|
2310
|
+
merchant_trans_id: { type: "string", description: "[AUTHENTICATION_REQUIRED only] merchant trans id of the batch preauth." },
|
|
2311
|
+
amount: { type: "float", description: "[AUTHENTICATION_REQUIRED only] challenge amount = aggregate total." }
|
|
2312
|
+
},
|
|
2313
|
+
example: {
|
|
2314
|
+
command: "agenzo-merchant-cli orders pay-batch --order-ids hho_01K...,ffo_01K...,rio_01K... --payment-token-id ntk_01J2ABC --idempotency-key trip-pay-1",
|
|
2315
|
+
output_summary: "Settles all listed orders in one charge (banks/EVO see one transaction). Returns {payment_group_id, status, total_amount, currency, orders[]}. Use --watch to poll until settled / partially_settled / failed; upstream-confirmation-failed orders are refunded."
|
|
2316
|
+
},
|
|
2317
|
+
error_recovery: {
|
|
2318
|
+
PARAM_INVALID: "Fix --order-ids (a non-empty comma-separated list or JSON array of order ids) and ensure --idempotency-key is present, then retry.",
|
|
2319
|
+
ORDER_NOT_PAYABLE: "One of the order_ids is not in AWAITING_PAYMENT (the error names the specific order_id). Remove/replace it and retry with a NEW idempotency-key.",
|
|
2320
|
+
CURRENCY_MISMATCH: "The batch mixes currencies \u2014 orders in one pay-batch must share a single currency. Split by currency and settle each group separately.",
|
|
2321
|
+
TOKEN_ORDER_MISMATCH: "The token external_transaction_id is not bound to this payment_group. Mint a token for the aggregate total bound to THIS payment_group_id and retry; no funds moved.",
|
|
2322
|
+
AUTHENTICATION_REQUIRED: "EVO requires cardholder 3DS: open three_ds_url, finish authentication, then replay pay-batch with the SAME idempotency-key (or use --watch to poll automatically)."
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2234
2325
|
function flightSchema(verb, description, flags, response, example, extra = {}) {
|
|
2235
2326
|
return { cli: CLI_NAME, noun: FLIGHT_NOUN, verb, description, flags, response, example, ...extra };
|
|
2236
2327
|
}
|
|
@@ -4002,15 +4093,201 @@ function registerOrdersGetCommand(parent, deps) {
|
|
|
4002
4093
|
});
|
|
4003
4094
|
}
|
|
4004
4095
|
|
|
4005
|
-
// src/
|
|
4096
|
+
// src/orders/pay-batch.ts
|
|
4097
|
+
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
4098
|
+
var DEFAULT_PAY_BATCH_WATCH_INTERVAL_SECONDS = 5;
|
|
4099
|
+
var DEFAULT_PAY_BATCH_WATCH_TIMEOUT_SECONDS = 300;
|
|
4100
|
+
var PAY_BATCH_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
4101
|
+
"settled",
|
|
4102
|
+
"partially_settled",
|
|
4103
|
+
"failed"
|
|
4104
|
+
]);
|
|
4105
|
+
function parseOrderIds(raw) {
|
|
4106
|
+
const INVALID = '--order-ids must be a comma-separated list OR a JSON array of order ids (e.g. "hho_1,ffo_2,rio_3" or ["hho_1","ffo_2"]).';
|
|
4107
|
+
const trimmed = raw.trim();
|
|
4108
|
+
let ids;
|
|
4109
|
+
if (trimmed.startsWith("[")) {
|
|
4110
|
+
let parsed;
|
|
4111
|
+
try {
|
|
4112
|
+
parsed = JSON.parse(trimmed);
|
|
4113
|
+
} catch {
|
|
4114
|
+
throw new CliError("PARAM_INVALID", INVALID);
|
|
4115
|
+
}
|
|
4116
|
+
if (!Array.isArray(parsed)) {
|
|
4117
|
+
throw new CliError("PARAM_INVALID", INVALID);
|
|
4118
|
+
}
|
|
4119
|
+
if (!parsed.every((el) => typeof el === "string")) {
|
|
4120
|
+
throw new CliError("PARAM_INVALID", INVALID);
|
|
4121
|
+
}
|
|
4122
|
+
ids = parsed.map((s) => s.trim());
|
|
4123
|
+
} else {
|
|
4124
|
+
ids = trimmed.split(",").map((s) => s.trim());
|
|
4125
|
+
}
|
|
4126
|
+
ids = ids.filter((s) => s.length > 0);
|
|
4127
|
+
if (ids.length === 0) {
|
|
4128
|
+
throw new CliError("PARAM_INVALID", INVALID);
|
|
4129
|
+
}
|
|
4130
|
+
return ids;
|
|
4131
|
+
}
|
|
4132
|
+
function formatPayBatch(data) {
|
|
4133
|
+
const lines = [
|
|
4134
|
+
["Payment group", String(data.payment_group_id ?? "-")],
|
|
4135
|
+
["Status", String(data.status ?? "-")]
|
|
4136
|
+
];
|
|
4137
|
+
if (data.total_amount != null && data.currency) {
|
|
4138
|
+
lines.push(["Total", `${data.total_amount} ${data.currency}`]);
|
|
4139
|
+
}
|
|
4140
|
+
if (data.status === "AUTHENTICATION_REQUIRED") {
|
|
4141
|
+
if (data.three_ds_url) lines.push(["3DS URL", String(data.three_ds_url)]);
|
|
4142
|
+
if (data.merchant_trans_id) lines.push(["Merchant trans ID", String(data.merchant_trans_id)]);
|
|
4143
|
+
if (data.amount != null && data.currency) {
|
|
4144
|
+
lines.push(["Challenge amount", `${data.amount} ${data.currency}`]);
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4147
|
+
const out = [Formatter.keyValue(lines)];
|
|
4148
|
+
const perOrder = data.per_order ?? [];
|
|
4149
|
+
if (perOrder.length > 0) {
|
|
4150
|
+
const headers = ["Order ID", "Domain", "Status", "Amount", "Refunded"];
|
|
4151
|
+
const rows = perOrder.map((o) => [
|
|
4152
|
+
String(o.order_id ?? "-"),
|
|
4153
|
+
String(o.domain ?? "-"),
|
|
4154
|
+
String(o.status ?? "-"),
|
|
4155
|
+
String(o.amount ?? "-"),
|
|
4156
|
+
String(o.refunded_amount ?? "-")
|
|
4157
|
+
]);
|
|
4158
|
+
out.push("", Formatter.table(headers, rows));
|
|
4159
|
+
}
|
|
4160
|
+
return out.join("\n");
|
|
4161
|
+
}
|
|
4162
|
+
function isBatchTerminal(record) {
|
|
4163
|
+
const status = record.status;
|
|
4164
|
+
return typeof status === "string" && PAY_BATCH_TERMINAL_STATUSES.has(status);
|
|
4165
|
+
}
|
|
4166
|
+
function registerOrdersPayBatchCommand(parent, deps) {
|
|
4167
|
+
const cmd = parent.command("pay-batch").description(
|
|
4168
|
+
"Settle a batch of orders (may mix ride/hotel/flight) in one aggregate payment via a single payment credential"
|
|
4169
|
+
).option("--api-key <key>", "API Key for authentication (X-Api-Key)").option(
|
|
4170
|
+
"--order-ids <ids>",
|
|
4171
|
+
"Ordered order ids to settle together \u2014 comma-separated (hho_1,ffo_2,rio_3) or a JSON array. May mix hho_/ffo_/rio_ domains. Amounts come from each order's locked authoritative price (not passed here)."
|
|
4172
|
+
).option(
|
|
4173
|
+
"--payment-token-id <id>",
|
|
4174
|
+
"[\u8F68 A] Network-token id minted for the aggregate total and bound to this payment_group (unionpay/visa charge path)"
|
|
4175
|
+
).option(
|
|
4176
|
+
"--payment-method-id <id>",
|
|
4177
|
+
"[\u8F68 B] EVO bound-card id to settle the aggregate total (one 3DS challenge)"
|
|
4178
|
+
).option(
|
|
4179
|
+
"--evo-explicit",
|
|
4180
|
+
"[\u8F68 B \u786C\u95E8\u69DB] Explicit opt-in to settle via the EVO bound-card rail. Set ONLY when the user explicitly chose EVO; forwarded to the body as evo_explicit=true."
|
|
4181
|
+
).option(
|
|
4182
|
+
"--payment-group-id <id>",
|
|
4183
|
+
"Optional caller-pre-generated payment group id; omit to let the platform generate one"
|
|
4184
|
+
).option("--member <id>", MEMBER_OPTION_DESCRIPTION).option(
|
|
4185
|
+
"--idempotency-key <key>",
|
|
4186
|
+
"Idempotency key forwarded verbatim as the Idempotency-Key header"
|
|
4187
|
+
).option("--watch", "Poll until a terminal batch status or timeout (NDJSON output)", false).option(
|
|
4188
|
+
"--watch-interval <seconds>",
|
|
4189
|
+
"Seconds between polls when --watch is set",
|
|
4190
|
+
String(DEFAULT_PAY_BATCH_WATCH_INTERVAL_SECONDS)
|
|
4191
|
+
).option(
|
|
4192
|
+
"--watch-timeout <seconds>",
|
|
4193
|
+
"Max seconds to poll before giving up",
|
|
4194
|
+
String(DEFAULT_PAY_BATCH_WATCH_TIMEOUT_SECONDS)
|
|
4195
|
+
);
|
|
4196
|
+
attachSchemaHelp(cmd, ordersPayBatchSchema);
|
|
4197
|
+
cmd.action(async () => {
|
|
4198
|
+
const opts = cmd.optsWithGlobals();
|
|
4199
|
+
const format = resolveFormat(opts.format);
|
|
4200
|
+
const isYes = Boolean(opts.yes);
|
|
4201
|
+
const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
|
|
4202
|
+
message: "API Key:",
|
|
4203
|
+
type: "password"
|
|
4204
|
+
});
|
|
4205
|
+
const orderIds = parseOrderIds(need9(opts.orderIds, "order-ids"));
|
|
4206
|
+
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
4207
|
+
yes: isYes,
|
|
4208
|
+
commandPath: "orders pay-batch"
|
|
4209
|
+
});
|
|
4210
|
+
const watchEnabled = Boolean(opts.watch);
|
|
4211
|
+
const watchInterval = resolveSeconds(opts.watchInterval, DEFAULT_PAY_BATCH_WATCH_INTERVAL_SECONDS);
|
|
4212
|
+
const watchTimeout = resolveSeconds(opts.watchTimeout, DEFAULT_PAY_BATCH_WATCH_TIMEOUT_SECONDS);
|
|
4213
|
+
const body = { order_ids: orderIds };
|
|
4214
|
+
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
4215
|
+
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
4216
|
+
if (opts.evoExplicit) body.evo_explicit = true;
|
|
4217
|
+
if (opts.paymentGroupId !== void 0) body.payment_group_id = opts.paymentGroupId;
|
|
4218
|
+
const member = memberIdOf(opts);
|
|
4219
|
+
if (member !== void 0) body.member_id = member;
|
|
4220
|
+
if (!isYes) {
|
|
4221
|
+
const confirmed = await confirm6({
|
|
4222
|
+
message: `Settle ${orderIds.length} order(s) in one aggregate payment? This moves money \u2014 a single charge covers the authoritative total of all listed orders (banks/EVO see one transaction).`,
|
|
4223
|
+
default: false
|
|
4224
|
+
});
|
|
4225
|
+
if (!confirmed) {
|
|
4226
|
+
throw new CliError("CLIENT_ABORTED", "Aggregate payment aborted by user.");
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
const path = "/orders/pay-batch";
|
|
4230
|
+
const headers = { "Idempotency-Key": idempotencyKey };
|
|
4231
|
+
const auth = { type: "api-key", key: apiKey };
|
|
4232
|
+
if (!watchEnabled) {
|
|
4233
|
+
const spinner = format === "json" ? null : createSpinner("Settling order batch...");
|
|
4234
|
+
const result = await deps.apiClient.post(path, auth, body, headers);
|
|
4235
|
+
spinner?.stop();
|
|
4236
|
+
if (!result.success) {
|
|
4237
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
4238
|
+
}
|
|
4239
|
+
const data = result.data;
|
|
4240
|
+
const configManager = new ConfigManager();
|
|
4241
|
+
const commandResult = {
|
|
4242
|
+
data,
|
|
4243
|
+
text: () => formatPayBatch(data)
|
|
4244
|
+
};
|
|
4245
|
+
await renderWithContext(commandResult, { format }, configManager);
|
|
4246
|
+
} else {
|
|
4247
|
+
const deadline = Date.now() + watchTimeout * 1e3;
|
|
4248
|
+
let lastRecord = null;
|
|
4249
|
+
for (; ; ) {
|
|
4250
|
+
const result = await deps.apiClient.post(path, auth, body, headers);
|
|
4251
|
+
if (result.success) {
|
|
4252
|
+
const data = result.data;
|
|
4253
|
+
lastRecord = data;
|
|
4254
|
+
ndjsonWriteLine(data);
|
|
4255
|
+
if (isBatchTerminal(data)) {
|
|
4256
|
+
return;
|
|
4257
|
+
}
|
|
4258
|
+
} else {
|
|
4259
|
+
throw CliError.fromApi(result, { auth: "api-key" });
|
|
4260
|
+
}
|
|
4261
|
+
if (Date.now() + watchInterval * 1e3 >= deadline) {
|
|
4262
|
+
const timeoutLine = {
|
|
4263
|
+
watch_status: "timeout",
|
|
4264
|
+
message: `Polling stopped after ${watchTimeout}s without reaching a terminal batch status.`,
|
|
4265
|
+
last_status: lastRecord
|
|
4266
|
+
};
|
|
4267
|
+
ndjsonWriteLine(timeoutLine);
|
|
4268
|
+
return;
|
|
4269
|
+
}
|
|
4270
|
+
await realSleep(watchInterval * 1e3);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
});
|
|
4274
|
+
}
|
|
4006
4275
|
function need9(value, flag) {
|
|
4007
4276
|
if (value === void 0) {
|
|
4008
4277
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4009
4278
|
}
|
|
4010
4279
|
return value;
|
|
4011
4280
|
}
|
|
4281
|
+
|
|
4282
|
+
// src/hotel-redaug/search.ts
|
|
4283
|
+
function need10(value, flag) {
|
|
4284
|
+
if (value === void 0) {
|
|
4285
|
+
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4286
|
+
}
|
|
4287
|
+
return value;
|
|
4288
|
+
}
|
|
4012
4289
|
function num5(value, flag) {
|
|
4013
|
-
const n = Number(
|
|
4290
|
+
const n = Number(need10(value, flag));
|
|
4014
4291
|
if (!Number.isFinite(n)) {
|
|
4015
4292
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4016
4293
|
}
|
|
@@ -4032,7 +4309,7 @@ function positiveInt3(value, flag) {
|
|
|
4032
4309
|
}
|
|
4033
4310
|
var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
4034
4311
|
function stayDate(value, flag) {
|
|
4035
|
-
const raw =
|
|
4312
|
+
const raw = need10(value, flag);
|
|
4036
4313
|
if (!YMD_RE.test(raw)) {
|
|
4037
4314
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
4038
4315
|
}
|
|
@@ -4104,7 +4381,7 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
4104
4381
|
const pageSize = positiveInt3(opts.pageSize, "page-size");
|
|
4105
4382
|
const body = {};
|
|
4106
4383
|
if (hasDestination) {
|
|
4107
|
-
body.destination_id =
|
|
4384
|
+
body.destination_id = need10(opts.destinationId, "destination-id");
|
|
4108
4385
|
} else {
|
|
4109
4386
|
body.lat = coord(opts.lat, "lat", -90, 90);
|
|
4110
4387
|
body.lng = coord(opts.lng, "lng", -180, 180);
|
|
@@ -4147,14 +4424,14 @@ function registerHotelSearchCommand(parent, deps) {
|
|
|
4147
4424
|
}
|
|
4148
4425
|
|
|
4149
4426
|
// src/hotel-redaug/quote.ts
|
|
4150
|
-
function
|
|
4427
|
+
function need11(value, flag) {
|
|
4151
4428
|
if (value === void 0) {
|
|
4152
4429
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4153
4430
|
}
|
|
4154
4431
|
return value;
|
|
4155
4432
|
}
|
|
4156
4433
|
function num6(value, flag) {
|
|
4157
|
-
const n = Number(
|
|
4434
|
+
const n = Number(need11(value, flag));
|
|
4158
4435
|
if (!Number.isFinite(n)) {
|
|
4159
4436
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4160
4437
|
}
|
|
@@ -4162,7 +4439,7 @@ function num6(value, flag) {
|
|
|
4162
4439
|
}
|
|
4163
4440
|
var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
4164
4441
|
function stayDate2(value, flag) {
|
|
4165
|
-
const raw =
|
|
4442
|
+
const raw = need11(value, flag);
|
|
4166
4443
|
if (!YMD_RE2.test(raw)) {
|
|
4167
4444
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
4168
4445
|
}
|
|
@@ -4202,7 +4479,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
4202
4479
|
message: "API Key:",
|
|
4203
4480
|
type: "password"
|
|
4204
4481
|
});
|
|
4205
|
-
const hotelId =
|
|
4482
|
+
const hotelId = need11(opts.hotelId, "hotel-id");
|
|
4206
4483
|
const checkIn = stayDate2(opts.checkIn, "check-in");
|
|
4207
4484
|
const checkOut = stayDate2(opts.checkOut, "check-out");
|
|
4208
4485
|
if (!(checkOut > checkIn)) {
|
|
@@ -4236,7 +4513,7 @@ function registerHotelQuoteCommand(parent, deps) {
|
|
|
4236
4513
|
}
|
|
4237
4514
|
|
|
4238
4515
|
// src/hotel-redaug/create-order.ts
|
|
4239
|
-
import { confirm as
|
|
4516
|
+
import { confirm as confirm7 } from "@inquirer/prompts";
|
|
4240
4517
|
function parsePriceItems(raw) {
|
|
4241
4518
|
const INVALID = "--price-items must be a JSON array of {sale_date (string), sale_price (number), breakfast_num (number)}.";
|
|
4242
4519
|
let parsed;
|
|
@@ -4294,14 +4571,14 @@ function parseCancellation(raw) {
|
|
|
4294
4571
|
}
|
|
4295
4572
|
return parsed;
|
|
4296
4573
|
}
|
|
4297
|
-
function
|
|
4574
|
+
function need12(value, flag) {
|
|
4298
4575
|
if (value === void 0) {
|
|
4299
4576
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4300
4577
|
}
|
|
4301
4578
|
return value;
|
|
4302
4579
|
}
|
|
4303
4580
|
function num7(value, flag) {
|
|
4304
|
-
const n = Number(
|
|
4581
|
+
const n = Number(need12(value, flag));
|
|
4305
4582
|
if (!Number.isFinite(n)) {
|
|
4306
4583
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4307
4584
|
}
|
|
@@ -4309,7 +4586,7 @@ function num7(value, flag) {
|
|
|
4309
4586
|
}
|
|
4310
4587
|
var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
|
|
4311
4588
|
function stayDate3(value, flag) {
|
|
4312
|
-
const raw =
|
|
4589
|
+
const raw = need12(value, flag);
|
|
4313
4590
|
if (!YMD_RE3.test(raw)) {
|
|
4314
4591
|
throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
|
|
4315
4592
|
}
|
|
@@ -4378,18 +4655,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4378
4655
|
message: "API Key:",
|
|
4379
4656
|
type: "password"
|
|
4380
4657
|
});
|
|
4381
|
-
const productToken =
|
|
4658
|
+
const productToken = need12(opts.productToken, "product-token");
|
|
4382
4659
|
const totalAmount = num7(opts.totalAmount, "total-amount");
|
|
4383
|
-
const currency =
|
|
4384
|
-
const priceItems = parsePriceItems(
|
|
4660
|
+
const currency = need12(opts.currency, "currency");
|
|
4661
|
+
const priceItems = parsePriceItems(need12(opts.priceItems, "price-items"));
|
|
4385
4662
|
const checkIn = stayDate3(opts.checkIn, "check-in");
|
|
4386
4663
|
const checkOut = stayDate3(opts.checkOut, "check-out");
|
|
4387
4664
|
if (!(checkOut > checkIn)) {
|
|
4388
4665
|
throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
|
|
4389
4666
|
}
|
|
4390
|
-
const guestName =
|
|
4391
|
-
const contactName =
|
|
4392
|
-
const contactPhone =
|
|
4667
|
+
const guestName = need12(opts.guestName, "guest-name");
|
|
4668
|
+
const contactName = need12(opts.contactName, "contact-name");
|
|
4669
|
+
const contactPhone = need12(opts.contactPhone, "contact-phone");
|
|
4393
4670
|
const body = {
|
|
4394
4671
|
product_token: productToken,
|
|
4395
4672
|
total_amount: totalAmount,
|
|
@@ -4423,7 +4700,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4423
4700
|
if (member !== void 0) body.member_id = member;
|
|
4424
4701
|
if (!isYes) {
|
|
4425
4702
|
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.";
|
|
4426
|
-
const confirmed = await
|
|
4703
|
+
const confirmed = await confirm7({
|
|
4427
4704
|
message: `Create this hotel order for ${totalAmount} ${currency} (check-in ${checkIn}, check-out ${checkOut})? ${chargeNote}`,
|
|
4428
4705
|
default: false
|
|
4429
4706
|
});
|
|
@@ -4457,7 +4734,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
4457
4734
|
}
|
|
4458
4735
|
|
|
4459
4736
|
// src/hotel-redaug/pay-order.ts
|
|
4460
|
-
import { confirm as
|
|
4737
|
+
import { confirm as confirm8 } from "@inquirer/prompts";
|
|
4461
4738
|
|
|
4462
4739
|
// src/hotel-redaug/watch.ts
|
|
4463
4740
|
var DEFAULT_ORDER_WATCH_INTERVAL_SECONDS = 5;
|
|
@@ -4645,7 +4922,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4645
4922
|
}
|
|
4646
4923
|
if (opts.evoExplicit) body.evo_explicit = true;
|
|
4647
4924
|
if (!isYes) {
|
|
4648
|
-
const confirmed = await
|
|
4925
|
+
const confirmed = await confirm8({
|
|
4649
4926
|
message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
|
|
4650
4927
|
default: false
|
|
4651
4928
|
});
|
|
@@ -4723,7 +5000,7 @@ function registerHotelPayOrderCommand(parent, deps) {
|
|
|
4723
5000
|
}
|
|
4724
5001
|
|
|
4725
5002
|
// src/hotel-redaug/get.ts
|
|
4726
|
-
function
|
|
5003
|
+
function need13(value, flag) {
|
|
4727
5004
|
if (value === void 0) {
|
|
4728
5005
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4729
5006
|
}
|
|
@@ -4787,7 +5064,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4787
5064
|
message: "API Key:",
|
|
4788
5065
|
type: "password"
|
|
4789
5066
|
});
|
|
4790
|
-
const orderId =
|
|
5067
|
+
const orderId = need13(opts.orderId, "order-id");
|
|
4791
5068
|
if (opts.watch) {
|
|
4792
5069
|
await watchOrderStatus(deps.apiClient, apiKey, orderId, {
|
|
4793
5070
|
intervalSeconds: resolveSeconds(
|
|
@@ -4821,7 +5098,7 @@ function registerHotelGetCommand(parent, deps) {
|
|
|
4821
5098
|
}
|
|
4822
5099
|
|
|
4823
5100
|
// src/hotel-redaug/cancel.ts
|
|
4824
|
-
function
|
|
5101
|
+
function need14(value, flag) {
|
|
4825
5102
|
if (value === void 0) {
|
|
4826
5103
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4827
5104
|
}
|
|
@@ -4874,8 +5151,8 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4874
5151
|
message: "API Key:",
|
|
4875
5152
|
type: "password"
|
|
4876
5153
|
});
|
|
4877
|
-
const orderId =
|
|
4878
|
-
const fcOrderCode =
|
|
5154
|
+
const orderId = need14(opts.orderId, "order-id");
|
|
5155
|
+
const fcOrderCode = need14(opts.fcOrderCode, "fc-order-code");
|
|
4879
5156
|
const body = { fc_order_code: fcOrderCode };
|
|
4880
5157
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
4881
5158
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -4904,15 +5181,15 @@ function registerHotelCancelCommand(parent, deps) {
|
|
|
4904
5181
|
}
|
|
4905
5182
|
|
|
4906
5183
|
// src/hotel-redaug/checkout.ts
|
|
4907
|
-
import { confirm as
|
|
4908
|
-
function
|
|
5184
|
+
import { confirm as confirm9 } from "@inquirer/prompts";
|
|
5185
|
+
function need15(value, flag) {
|
|
4909
5186
|
if (value === void 0) {
|
|
4910
5187
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
4911
5188
|
}
|
|
4912
5189
|
return value;
|
|
4913
5190
|
}
|
|
4914
5191
|
function num8(value, flag) {
|
|
4915
|
-
const n = Number(
|
|
5192
|
+
const n = Number(need15(value, flag));
|
|
4916
5193
|
if (!Number.isFinite(n)) {
|
|
4917
5194
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
4918
5195
|
}
|
|
@@ -4978,10 +5255,10 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4978
5255
|
message: "API Key:",
|
|
4979
5256
|
type: "password"
|
|
4980
5257
|
});
|
|
4981
|
-
const orderId =
|
|
4982
|
-
const fcOrderCode =
|
|
4983
|
-
const reason =
|
|
4984
|
-
const checkoutRooms = parseCheckoutRooms(
|
|
5258
|
+
const orderId = need15(opts.orderId, "order-id");
|
|
5259
|
+
const fcOrderCode = need15(opts.fcOrderCode, "fc-order-code");
|
|
5260
|
+
const reason = need15(opts.reason, "reason");
|
|
5261
|
+
const checkoutRooms = parseCheckoutRooms(need15(opts.checkoutRooms, "checkout-rooms"));
|
|
4985
5262
|
const refundType = num8(opts.refundType, "refund-type");
|
|
4986
5263
|
const body = {
|
|
4987
5264
|
fc_order_code: fcOrderCode,
|
|
@@ -4990,7 +5267,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
4990
5267
|
checkout_rooms: checkoutRooms
|
|
4991
5268
|
};
|
|
4992
5269
|
if (!isYes) {
|
|
4993
|
-
const confirmed = await
|
|
5270
|
+
const confirmed = await confirm9({
|
|
4994
5271
|
message: `Request check-out / out-of-policy cancellation for order ${orderId} (${checkoutRooms.length} room(s))? The property must approve and charges may apply.`,
|
|
4995
5272
|
default: false
|
|
4996
5273
|
});
|
|
@@ -5024,7 +5301,7 @@ function registerHotelCheckoutCommand(parent, deps) {
|
|
|
5024
5301
|
}
|
|
5025
5302
|
|
|
5026
5303
|
// src/hotel-redaug/get-checkout.ts
|
|
5027
|
-
function
|
|
5304
|
+
function need16(value, flag) {
|
|
5028
5305
|
if (value === void 0) {
|
|
5029
5306
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5030
5307
|
}
|
|
@@ -5060,7 +5337,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
|
|
|
5060
5337
|
message: "API Key:",
|
|
5061
5338
|
type: "password"
|
|
5062
5339
|
});
|
|
5063
|
-
const taskOrderCode =
|
|
5340
|
+
const taskOrderCode = need16(opts.taskOrderCode, "task-order-code");
|
|
5064
5341
|
if (opts.watch) {
|
|
5065
5342
|
await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
|
|
5066
5343
|
intervalSeconds: resolveSeconds(
|
|
@@ -5164,7 +5441,7 @@ function registerHotelListOrdersCommand(parent, deps) {
|
|
|
5164
5441
|
}
|
|
5165
5442
|
|
|
5166
5443
|
// src/hotel-redaug/find-destination.ts
|
|
5167
|
-
function
|
|
5444
|
+
function need17(value, flag) {
|
|
5168
5445
|
if (value === void 0 || value.trim() === "") {
|
|
5169
5446
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5170
5447
|
}
|
|
@@ -5198,7 +5475,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
5198
5475
|
message: "API Key:",
|
|
5199
5476
|
type: "password"
|
|
5200
5477
|
});
|
|
5201
|
-
const keyword =
|
|
5478
|
+
const keyword = need17(opts.keyword, "keyword");
|
|
5202
5479
|
const body = { keyword };
|
|
5203
5480
|
if (opts.dataType !== void 0) {
|
|
5204
5481
|
body.data_type = opts.dataType;
|
|
@@ -5222,14 +5499,14 @@ function registerHotelFindDestinationCommand(parent, deps) {
|
|
|
5222
5499
|
}
|
|
5223
5500
|
|
|
5224
5501
|
// src/hotel-redaug/hotel-filters.ts
|
|
5225
|
-
function
|
|
5502
|
+
function need18(value, flag) {
|
|
5226
5503
|
if (value === void 0 || value.trim() === "") {
|
|
5227
5504
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5228
5505
|
}
|
|
5229
5506
|
return value;
|
|
5230
5507
|
}
|
|
5231
5508
|
function num9(value, flag) {
|
|
5232
|
-
const n = Number(
|
|
5509
|
+
const n = Number(need18(value, flag));
|
|
5233
5510
|
if (!Number.isFinite(n)) {
|
|
5234
5511
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5235
5512
|
}
|
|
@@ -5309,7 +5586,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
5309
5586
|
}
|
|
5310
5587
|
const body = {};
|
|
5311
5588
|
if (hasDestination) {
|
|
5312
|
-
body.destination_id =
|
|
5589
|
+
body.destination_id = need18(opts.destinationId, "destination-id");
|
|
5313
5590
|
} else {
|
|
5314
5591
|
body.lat = coord2(opts.lat, "lat", -90, 90);
|
|
5315
5592
|
body.lng = coord2(opts.lng, "lng", -180, 180);
|
|
@@ -5334,7 +5611,7 @@ function registerHotelFiltersCommand(parent, deps) {
|
|
|
5334
5611
|
}
|
|
5335
5612
|
|
|
5336
5613
|
// src/hotel-redaug/list-cities.ts
|
|
5337
|
-
function
|
|
5614
|
+
function need19(value, flag) {
|
|
5338
5615
|
if (value === void 0 || value.trim() === "") {
|
|
5339
5616
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5340
5617
|
}
|
|
@@ -5367,7 +5644,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
5367
5644
|
message: "API Key:",
|
|
5368
5645
|
type: "password"
|
|
5369
5646
|
});
|
|
5370
|
-
const country =
|
|
5647
|
+
const country = need19(opts.country, "country");
|
|
5371
5648
|
const body = { country_code: country };
|
|
5372
5649
|
const result = await deps.apiClient.post(
|
|
5373
5650
|
"/hotel/cities",
|
|
@@ -5388,7 +5665,7 @@ function registerHotelListCitiesCommand(parent, deps) {
|
|
|
5388
5665
|
}
|
|
5389
5666
|
|
|
5390
5667
|
// src/hotel-redaug/hotel-detail.ts
|
|
5391
|
-
function
|
|
5668
|
+
function need20(value, flag) {
|
|
5392
5669
|
if (value === void 0 || value.trim() === "") {
|
|
5393
5670
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5394
5671
|
}
|
|
@@ -5535,7 +5812,7 @@ function registerHotelDetailCommand(parent, deps) {
|
|
|
5535
5812
|
message: "API Key:",
|
|
5536
5813
|
type: "password"
|
|
5537
5814
|
});
|
|
5538
|
-
const hotelId =
|
|
5815
|
+
const hotelId = need20(opts.hotelId, "hotel-id");
|
|
5539
5816
|
const rawWithImages = opts.withImages;
|
|
5540
5817
|
const withImages = rawWithImages !== "false" && rawWithImages !== false;
|
|
5541
5818
|
const settings = parseSettings(opts.settings);
|
|
@@ -5743,14 +6020,14 @@ function registerHotelSkillCommand(parent) {
|
|
|
5743
6020
|
}
|
|
5744
6021
|
|
|
5745
6022
|
// src/flight-flink/_helpers.ts
|
|
5746
|
-
function
|
|
6023
|
+
function need21(value, flag) {
|
|
5747
6024
|
if (value === void 0) {
|
|
5748
6025
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
5749
6026
|
}
|
|
5750
6027
|
return value;
|
|
5751
6028
|
}
|
|
5752
6029
|
function num10(value, flag) {
|
|
5753
|
-
const n = Number(
|
|
6030
|
+
const n = Number(need21(value, flag));
|
|
5754
6031
|
if (!Number.isFinite(n)) {
|
|
5755
6032
|
throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
|
|
5756
6033
|
}
|
|
@@ -5785,7 +6062,7 @@ function registerFindAirportCommand(parent, deps) {
|
|
|
5785
6062
|
const opts = cmd.optsWithGlobals();
|
|
5786
6063
|
const format = resolveFormat(opts.format);
|
|
5787
6064
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5788
|
-
const keyword =
|
|
6065
|
+
const keyword = need21(opts.keyword, "keyword");
|
|
5789
6066
|
const spinner = format === "json" ? null : createSpinner("Resolving airports...");
|
|
5790
6067
|
const result = await deps.apiClient.post(
|
|
5791
6068
|
"/flight/find-airport",
|
|
@@ -5882,7 +6159,7 @@ function registerSearchCommand(parent, deps) {
|
|
|
5882
6159
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5883
6160
|
const body = {
|
|
5884
6161
|
trip_type: num10(opts.tripType, "trip-type"),
|
|
5885
|
-
journeys: jsonArray(
|
|
6162
|
+
journeys: jsonArray(need21(opts.journeys, "journeys"), "journeys"),
|
|
5886
6163
|
cabin_class: opts.cabinClass,
|
|
5887
6164
|
adult_num: num10(opts.adultNum, "adult-num"),
|
|
5888
6165
|
child_num: num10(opts.childNum, "child-num"),
|
|
@@ -5913,7 +6190,7 @@ function registerMoreOffersCommand(parent, deps) {
|
|
|
5913
6190
|
const opts = cmd.optsWithGlobals();
|
|
5914
6191
|
const format = resolveFormat(opts.format);
|
|
5915
6192
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5916
|
-
const productToken =
|
|
6193
|
+
const productToken = need21(opts.productToken, "product-token");
|
|
5917
6194
|
const spinner = format === "json" ? null : createSpinner("Fetching offers...");
|
|
5918
6195
|
const result = await deps.apiClient.post(
|
|
5919
6196
|
"/flight/more-offers",
|
|
@@ -5934,7 +6211,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5934
6211
|
const opts = cmd.optsWithGlobals();
|
|
5935
6212
|
const format = resolveFormat(opts.format);
|
|
5936
6213
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5937
|
-
const productToken =
|
|
6214
|
+
const productToken = need21(opts.productToken, "product-token");
|
|
5938
6215
|
const spinner = format === "json" ? null : createSpinner("Verifying price...");
|
|
5939
6216
|
const result = await deps.apiClient.post(
|
|
5940
6217
|
"/flight/verify",
|
|
@@ -5956,7 +6233,7 @@ function registerVerifyCommand(parent, deps) {
|
|
|
5956
6233
|
}
|
|
5957
6234
|
|
|
5958
6235
|
// src/flight-flink/create-order.ts
|
|
5959
|
-
import { confirm as
|
|
6236
|
+
import { confirm as confirm10 } from "@inquirer/prompts";
|
|
5960
6237
|
function registerCreateOrderCommand(parent, deps) {
|
|
5961
6238
|
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(
|
|
5962
6239
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -5968,19 +6245,19 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5968
6245
|
const format = resolveFormat(opts.format);
|
|
5969
6246
|
const isYes = Boolean(opts.yes);
|
|
5970
6247
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
5971
|
-
const productToken =
|
|
6248
|
+
const productToken = need21(opts.productToken, "product-token");
|
|
5972
6249
|
const totalAmount = num10(opts.totalAmount, "total-amount");
|
|
5973
|
-
const currency =
|
|
6250
|
+
const currency = need21(opts.currency, "currency");
|
|
5974
6251
|
const body = {
|
|
5975
6252
|
product_token: productToken,
|
|
5976
6253
|
total_amount: totalAmount,
|
|
5977
6254
|
currency,
|
|
5978
6255
|
trip_type: num10(opts.tripType, "trip-type"),
|
|
5979
|
-
contact_name:
|
|
5980
|
-
contact_region:
|
|
5981
|
-
contact_phone:
|
|
5982
|
-
contact_email:
|
|
5983
|
-
passengers: jsonArray(
|
|
6256
|
+
contact_name: need21(opts.contactName, "contact-name"),
|
|
6257
|
+
contact_region: need21(opts.contactRegion, "contact-region"),
|
|
6258
|
+
contact_phone: need21(opts.contactPhone, "contact-phone"),
|
|
6259
|
+
contact_email: need21(opts.contactEmail, "contact-email"),
|
|
6260
|
+
passengers: jsonArray(need21(opts.passengers, "passengers"), "passengers")
|
|
5984
6261
|
};
|
|
5985
6262
|
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
5986
6263
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
@@ -5990,7 +6267,7 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
5990
6267
|
const member = memberIdOf(opts);
|
|
5991
6268
|
if (member !== void 0) body.member_id = member;
|
|
5992
6269
|
if (!isYes) {
|
|
5993
|
-
const ok = await
|
|
6270
|
+
const ok = await confirm10({
|
|
5994
6271
|
message: `Create this flight order for ${totalAmount} ${currency}? This locks the fare but does NOT charge yet.`,
|
|
5995
6272
|
default: false
|
|
5996
6273
|
});
|
|
@@ -6029,7 +6306,7 @@ function registerCreateOrderCommand(parent, deps) {
|
|
|
6029
6306
|
}
|
|
6030
6307
|
|
|
6031
6308
|
// src/flight-flink/pay-order.ts
|
|
6032
|
-
import { confirm as
|
|
6309
|
+
import { confirm as confirm11 } from "@inquirer/prompts";
|
|
6033
6310
|
function registerPayOrderCommand(parent, deps) {
|
|
6034
6311
|
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(
|
|
6035
6312
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -6044,9 +6321,9 @@ function registerPayOrderCommand(parent, deps) {
|
|
|
6044
6321
|
const format = resolveFormat(opts.format);
|
|
6045
6322
|
const isYes = Boolean(opts.yes);
|
|
6046
6323
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6047
|
-
const orderNo =
|
|
6324
|
+
const orderNo = need21(opts.orderNo, "order-no");
|
|
6048
6325
|
if (!isYes) {
|
|
6049
|
-
const ok = await
|
|
6326
|
+
const ok = await confirm11({
|
|
6050
6327
|
message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
|
|
6051
6328
|
default: false
|
|
6052
6329
|
});
|
|
@@ -6096,7 +6373,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
6096
6373
|
const opts = cmd.optsWithGlobals();
|
|
6097
6374
|
const format = resolveFormat(opts.format);
|
|
6098
6375
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6099
|
-
const orderNo =
|
|
6376
|
+
const orderNo = need21(opts.orderNo, "order-no");
|
|
6100
6377
|
const path = `/flight/${encodeURIComponent(orderNo)}/status`;
|
|
6101
6378
|
const auth = { type: "api-key", key: apiKey };
|
|
6102
6379
|
if (opts.watch) {
|
|
@@ -6136,7 +6413,7 @@ function registerGetOrderCommand(parent, deps) {
|
|
|
6136
6413
|
}
|
|
6137
6414
|
|
|
6138
6415
|
// src/flight-flink/cancel-order.ts
|
|
6139
|
-
import { confirm as
|
|
6416
|
+
import { confirm as confirm12 } from "@inquirer/prompts";
|
|
6140
6417
|
function registerCancelOrderCommand(parent, deps) {
|
|
6141
6418
|
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");
|
|
6142
6419
|
attachSchemaHelp(cmd, flightCancelOrderSchema);
|
|
@@ -6145,9 +6422,9 @@ function registerCancelOrderCommand(parent, deps) {
|
|
|
6145
6422
|
const format = resolveFormat(opts.format);
|
|
6146
6423
|
const isYes = Boolean(opts.yes);
|
|
6147
6424
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6148
|
-
const orderNo =
|
|
6425
|
+
const orderNo = need21(opts.orderNo, "order-no");
|
|
6149
6426
|
if (!isYes) {
|
|
6150
|
-
const ok = await
|
|
6427
|
+
const ok = await confirm12({
|
|
6151
6428
|
message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
|
|
6152
6429
|
default: false
|
|
6153
6430
|
});
|
|
@@ -6221,10 +6498,10 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
6221
6498
|
const format = resolveFormat(opts.format);
|
|
6222
6499
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6223
6500
|
const body = {
|
|
6224
|
-
order_no:
|
|
6225
|
-
date:
|
|
6226
|
-
passenger:
|
|
6227
|
-
segment_id:
|
|
6501
|
+
order_no: need21(opts.orderNo, "order-no"),
|
|
6502
|
+
date: need21(opts.date, "date"),
|
|
6503
|
+
passenger: need21(opts.passenger, "passenger"),
|
|
6504
|
+
segment_id: need21(opts.segmentId, "segment-id"),
|
|
6228
6505
|
cabin_class: opts.cabinClass
|
|
6229
6506
|
};
|
|
6230
6507
|
const spinner = format === "json" ? null : createSpinner("Searching change options...");
|
|
@@ -6240,7 +6517,7 @@ function registerChangeSearchCommand(parent, deps) {
|
|
|
6240
6517
|
}
|
|
6241
6518
|
|
|
6242
6519
|
// src/flight-flink/change-apply.ts
|
|
6243
|
-
import { confirm as
|
|
6520
|
+
import { confirm as confirm13 } from "@inquirer/prompts";
|
|
6244
6521
|
function registerChangeApplyCommand(parent, deps) {
|
|
6245
6522
|
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");
|
|
6246
6523
|
attachSchemaHelp(cmd, flightChangeApplySchema);
|
|
@@ -6250,17 +6527,17 @@ function registerChangeApplyCommand(parent, deps) {
|
|
|
6250
6527
|
const isYes = Boolean(opts.yes);
|
|
6251
6528
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6252
6529
|
const body = {
|
|
6253
|
-
order_no:
|
|
6254
|
-
passenger:
|
|
6255
|
-
segment_id:
|
|
6256
|
-
product_token:
|
|
6257
|
-
contact_name:
|
|
6258
|
-
contact_region:
|
|
6259
|
-
contact_phone:
|
|
6260
|
-
contact_email:
|
|
6530
|
+
order_no: need21(opts.orderNo, "order-no"),
|
|
6531
|
+
passenger: need21(opts.passenger, "passenger"),
|
|
6532
|
+
segment_id: need21(opts.segmentId, "segment-id"),
|
|
6533
|
+
product_token: need21(opts.productToken, "product-token"),
|
|
6534
|
+
contact_name: need21(opts.contactName, "contact-name"),
|
|
6535
|
+
contact_region: need21(opts.contactRegion, "contact-region"),
|
|
6536
|
+
contact_phone: need21(opts.contactPhone, "contact-phone"),
|
|
6537
|
+
contact_email: need21(opts.contactEmail, "contact-email")
|
|
6261
6538
|
};
|
|
6262
6539
|
if (!isYes) {
|
|
6263
|
-
const ok = await
|
|
6540
|
+
const ok = await confirm13({
|
|
6264
6541
|
message: `Submit a change request for order ${body.order_no}?`,
|
|
6265
6542
|
default: false
|
|
6266
6543
|
});
|
|
@@ -6291,7 +6568,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
6291
6568
|
const opts = cmd.optsWithGlobals();
|
|
6292
6569
|
const format = resolveFormat(opts.format);
|
|
6293
6570
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6294
|
-
const changeOrderNo =
|
|
6571
|
+
const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
|
|
6295
6572
|
const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
|
|
6296
6573
|
const result = await deps.apiClient.get(
|
|
6297
6574
|
`/flight/change/${encodeURIComponent(changeOrderNo)}`,
|
|
@@ -6304,7 +6581,7 @@ function registerChangeDetailCommand(parent, deps) {
|
|
|
6304
6581
|
}
|
|
6305
6582
|
|
|
6306
6583
|
// src/flight-flink/change-cancel.ts
|
|
6307
|
-
import { confirm as
|
|
6584
|
+
import { confirm as confirm14 } from "@inquirer/prompts";
|
|
6308
6585
|
function registerChangeCancelCommand(parent, deps) {
|
|
6309
6586
|
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");
|
|
6310
6587
|
attachSchemaHelp(cmd, flightChangeCancelSchema);
|
|
@@ -6313,9 +6590,9 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
6313
6590
|
const format = resolveFormat(opts.format);
|
|
6314
6591
|
const isYes = Boolean(opts.yes);
|
|
6315
6592
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6316
|
-
const changeOrderNo =
|
|
6593
|
+
const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
|
|
6317
6594
|
if (!isYes) {
|
|
6318
|
-
const ok = await
|
|
6595
|
+
const ok = await confirm14({ message: `Cancel change request ${changeOrderNo}?`, default: false });
|
|
6319
6596
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
|
|
6320
6597
|
}
|
|
6321
6598
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -6336,7 +6613,7 @@ function registerChangeCancelCommand(parent, deps) {
|
|
|
6336
6613
|
}
|
|
6337
6614
|
|
|
6338
6615
|
// src/flight-flink/change-pay.ts
|
|
6339
|
-
import { confirm as
|
|
6616
|
+
import { confirm as confirm15 } from "@inquirer/prompts";
|
|
6340
6617
|
function registerChangePayCommand(parent, deps) {
|
|
6341
6618
|
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(
|
|
6342
6619
|
"--authorized-merchant-trans-id <id>",
|
|
@@ -6348,10 +6625,10 @@ function registerChangePayCommand(parent, deps) {
|
|
|
6348
6625
|
const format = resolveFormat(opts.format);
|
|
6349
6626
|
const isYes = Boolean(opts.yes);
|
|
6350
6627
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6351
|
-
const changeOrderNo =
|
|
6352
|
-
const orderNo =
|
|
6628
|
+
const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
|
|
6629
|
+
const orderNo = need21(opts.orderNo, "order-no");
|
|
6353
6630
|
const amount = num10(opts.amount, "amount");
|
|
6354
|
-
const currency =
|
|
6631
|
+
const currency = need21(opts.currency, "currency");
|
|
6355
6632
|
const body = {
|
|
6356
6633
|
order_no: orderNo,
|
|
6357
6634
|
amount,
|
|
@@ -6365,7 +6642,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
6365
6642
|
if (!isYes) {
|
|
6366
6643
|
const isResume = opts.authorizedMerchantTransId !== void 0;
|
|
6367
6644
|
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.`;
|
|
6368
|
-
const ok = await
|
|
6645
|
+
const ok = await confirm15({ message, default: false });
|
|
6369
6646
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Change payment aborted by user.");
|
|
6370
6647
|
}
|
|
6371
6648
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -6412,7 +6689,7 @@ function registerChangePayCommand(parent, deps) {
|
|
|
6412
6689
|
}
|
|
6413
6690
|
|
|
6414
6691
|
// src/flight-flink/refund-apply.ts
|
|
6415
|
-
import { confirm as
|
|
6692
|
+
import { confirm as confirm16 } from "@inquirer/prompts";
|
|
6416
6693
|
function registerRefundApplyCommand(parent, deps) {
|
|
6417
6694
|
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");
|
|
6418
6695
|
attachSchemaHelp(cmd, flightRefundApplySchema);
|
|
@@ -6422,18 +6699,18 @@ function registerRefundApplyCommand(parent, deps) {
|
|
|
6422
6699
|
const isYes = Boolean(opts.yes);
|
|
6423
6700
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6424
6701
|
const body = {
|
|
6425
|
-
order_no:
|
|
6426
|
-
passenger:
|
|
6427
|
-
segment_id:
|
|
6702
|
+
order_no: need21(opts.orderNo, "order-no"),
|
|
6703
|
+
passenger: need21(opts.passenger, "passenger"),
|
|
6704
|
+
segment_id: need21(opts.segmentId, "segment-id"),
|
|
6428
6705
|
reason_type: num10(opts.reasonType, "reason-type"),
|
|
6429
|
-
contact_name:
|
|
6430
|
-
contact_region:
|
|
6431
|
-
contact_phone:
|
|
6432
|
-
contact_email:
|
|
6706
|
+
contact_name: need21(opts.contactName, "contact-name"),
|
|
6707
|
+
contact_region: need21(opts.contactRegion, "contact-region"),
|
|
6708
|
+
contact_phone: need21(opts.contactPhone, "contact-phone"),
|
|
6709
|
+
contact_email: need21(opts.contactEmail, "contact-email")
|
|
6433
6710
|
};
|
|
6434
6711
|
if (opts.reason !== void 0) body.reason = opts.reason;
|
|
6435
6712
|
if (!isYes) {
|
|
6436
|
-
const ok = await
|
|
6713
|
+
const ok = await confirm16({
|
|
6437
6714
|
message: `Submit a refund request for order ${body.order_no}?`,
|
|
6438
6715
|
default: false
|
|
6439
6716
|
});
|
|
@@ -6464,7 +6741,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6464
6741
|
const opts = cmd.optsWithGlobals();
|
|
6465
6742
|
const format = resolveFormat(opts.format);
|
|
6466
6743
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6467
|
-
const refundOrderNo =
|
|
6744
|
+
const refundOrderNo = need21(opts.refundOrderNo, "refund-order-no");
|
|
6468
6745
|
const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
|
|
6469
6746
|
const result = await deps.apiClient.get(
|
|
6470
6747
|
`/flight/refund/${encodeURIComponent(refundOrderNo)}`,
|
|
@@ -6477,7 +6754,7 @@ function registerRefundDetailCommand(parent, deps) {
|
|
|
6477
6754
|
}
|
|
6478
6755
|
|
|
6479
6756
|
// src/flight-flink/refund-confirm.ts
|
|
6480
|
-
import { confirm as
|
|
6757
|
+
import { confirm as confirm17 } from "@inquirer/prompts";
|
|
6481
6758
|
function registerRefundConfirmCommand(parent, deps) {
|
|
6482
6759
|
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");
|
|
6483
6760
|
attachSchemaHelp(cmd, flightRefundConfirmSchema);
|
|
@@ -6486,14 +6763,14 @@ function registerRefundConfirmCommand(parent, deps) {
|
|
|
6486
6763
|
const format = resolveFormat(opts.format);
|
|
6487
6764
|
const isYes = Boolean(opts.yes);
|
|
6488
6765
|
const apiKey = await resolveApiKey(opts.apiKey);
|
|
6489
|
-
const refundOrderNo =
|
|
6490
|
-
const confirmFlag =
|
|
6766
|
+
const refundOrderNo = need21(opts.refundOrderNo, "refund-order-no");
|
|
6767
|
+
const confirmFlag = need21(opts.confirm, "confirm");
|
|
6491
6768
|
if (confirmFlag !== "1" && confirmFlag !== "2") {
|
|
6492
6769
|
throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
|
|
6493
6770
|
}
|
|
6494
6771
|
if (!isYes) {
|
|
6495
6772
|
const action = confirmFlag === "1" ? "confirm" : "cancel";
|
|
6496
|
-
const ok = await
|
|
6773
|
+
const ok = await confirm17({ message: `${action} refund ${refundOrderNo}?`, default: false });
|
|
6497
6774
|
if (!ok) throw new CliError("CLIENT_ABORTED", "Refund confirmation aborted by user.");
|
|
6498
6775
|
}
|
|
6499
6776
|
const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
|
|
@@ -6667,10 +6944,11 @@ Key notes:
|
|
|
6667
6944
|
registerServicesListCommand(servicesCmd, { discoveryClient, program });
|
|
6668
6945
|
registerServiceGetCommand(servicesCmd, { discoveryClient, program });
|
|
6669
6946
|
const ordersCmd = program.command("orders").description(
|
|
6670
|
-
|
|
6947
|
+
'Unified cross-provider order index (spans ride + hotel + flight). Use list/get for generic "my orders" requests (use ride-elife/hotel-redaug/flight-flink commands once the business is known); pay-batch settles a batch of AWAITING_PAYMENT orders in one aggregate payment (trip checkout).'
|
|
6671
6948
|
);
|
|
6672
6949
|
registerOrdersListCommand(ordersCmd, deps);
|
|
6673
6950
|
registerOrdersGetCommand(ordersCmd, deps);
|
|
6951
|
+
registerOrdersPayBatchCommand(ordersCmd, deps);
|
|
6674
6952
|
const hotelCmd = program.command("hotel-redaug").description(
|
|
6675
6953
|
`Hotel booking (Redaug) \u2014 international hotel search, quote, create-order, pay-order, cancel, and check-out.
|
|
6676
6954
|
|