@agenzo/merchant-cli 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +343 -343
- package/dist/index.js +58 -1
- package/dist/index.js.map +1 -1
- package/package.json +28 -28
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ var CODE_NUM = {
|
|
|
59
59
|
CHECKOUT_TASK_NOT_FOUND: 4307,
|
|
60
60
|
PAY_PER_CALL_NOT_AVAILABLE: 4308,
|
|
61
61
|
HOTEL_NOT_FOUND: 4309,
|
|
62
|
+
BOOKING_RESTRICTED: 4310,
|
|
62
63
|
RATE_LIMITED: 5001,
|
|
63
64
|
UPSTREAM_ERROR: 5101,
|
|
64
65
|
INTERNAL_ERROR: 5201,
|
|
@@ -239,6 +240,7 @@ var STABLE_MESSAGE = {
|
|
|
239
240
|
CHECKOUT_TASK_NOT_FOUND: "Check-out application not found.",
|
|
240
241
|
PAY_PER_CALL_NOT_AVAILABLE: "Pay-per-call billing is not available; use monthly_settlement.",
|
|
241
242
|
HOTEL_NOT_FOUND: "This hotel is no longer available from the supplier.",
|
|
243
|
+
BOOKING_RESTRICTED: "This room has a booking condition that your request doesn't meet. Please check the room's booking rules and adjust your request.",
|
|
242
244
|
NOT_IMPLEMENTED: "This operation is not implemented yet."
|
|
243
245
|
};
|
|
244
246
|
function toErrorEnvelope(error) {
|
|
@@ -312,6 +314,25 @@ function compareVersions(a, b) {
|
|
|
312
314
|
function isBelow(current, minimum) {
|
|
313
315
|
return compareVersions(current, minimum) < 0;
|
|
314
316
|
}
|
|
317
|
+
var TRACEPARENT_PATTERN = /^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$/;
|
|
318
|
+
var DEFAULT_HTTP_TIMEOUT_MS = 7e4;
|
|
319
|
+
function httpTimeoutFromEnv(env = process.env) {
|
|
320
|
+
const raw = env.AGENZO_CLI_HTTP_TIMEOUT_MS;
|
|
321
|
+
if (raw === void 0 || raw.trim() === "") return null;
|
|
322
|
+
const parsed = Number(raw);
|
|
323
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
324
|
+
return parsed;
|
|
325
|
+
}
|
|
326
|
+
var DEADLINE_HEADER = "x-deadline-ms";
|
|
327
|
+
var DEADLINE_RESERVE_MS = 200;
|
|
328
|
+
function deadlineFromEnv(env = process.env) {
|
|
329
|
+
const raw = env.DEADLINE_MS;
|
|
330
|
+
if (raw === void 0 || raw.trim() === "") return null;
|
|
331
|
+
if (!/^\d+$/.test(raw.trim())) return null;
|
|
332
|
+
const parsed = Number(raw);
|
|
333
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
334
|
+
return parsed;
|
|
335
|
+
}
|
|
315
336
|
var ApiClient = class {
|
|
316
337
|
baseUrl;
|
|
317
338
|
timeout;
|
|
@@ -327,16 +348,43 @@ var ApiClient = class {
|
|
|
327
348
|
* a single trace_id server-side and can be followed as one chain in logs.
|
|
328
349
|
*/
|
|
329
350
|
requestId;
|
|
351
|
+
/**
|
|
352
|
+
* 上游给的剩余预算(毫秒),来自 `DEADLINE_MS`;未注入时为 null。
|
|
353
|
+
*
|
|
354
|
+
* 进程启动时读一次而不是每请求读:一次 CLI 调用就是链路上的一跳,预算属于这一跳
|
|
355
|
+
* 整体。每请求重读会让多步流程(如 `payment-methods add` 的 create + poll + get)
|
|
356
|
+
* 各自拿到完整预算,等于凭空放大了本跳的时间上限。
|
|
357
|
+
*/
|
|
358
|
+
deadlineMs;
|
|
359
|
+
/** 本进程开始时刻(单调时钟),用于算已用时间。 */
|
|
360
|
+
startedAt;
|
|
330
361
|
constructor(config) {
|
|
331
362
|
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
332
|
-
this.
|
|
363
|
+
this.deadlineMs = deadlineFromEnv();
|
|
364
|
+
this.startedAt = performance.now();
|
|
365
|
+
const configured = config.timeout ?? httpTimeoutFromEnv() ?? DEFAULT_HTTP_TIMEOUT_MS;
|
|
366
|
+
this.timeout = this.deadlineMs === null ? configured : Math.min(configured, Math.max(1, this.deadlineMs - DEADLINE_RESERVE_MS));
|
|
333
367
|
this.requestId = crypto.randomUUID();
|
|
334
368
|
}
|
|
369
|
+
/** 交给下游的剩余毫秒:扣掉本进程已用时间与回程预留;无预算时返回 null。 */
|
|
370
|
+
remainingDeadlineMs() {
|
|
371
|
+
if (this.deadlineMs === null) return null;
|
|
372
|
+
const elapsed = performance.now() - this.startedAt;
|
|
373
|
+
return Math.max(0, Math.round(this.deadlineMs - elapsed - DEADLINE_RESERVE_MS));
|
|
374
|
+
}
|
|
335
375
|
buildHeaders(auth) {
|
|
336
376
|
const headers = {
|
|
337
377
|
"User-Agent": `agenzo-admin-cli/${getCurrentVersion()}`,
|
|
338
378
|
"X-Request-Id": this.requestId
|
|
339
379
|
};
|
|
380
|
+
const remaining = this.remainingDeadlineMs();
|
|
381
|
+
if (remaining !== null) {
|
|
382
|
+
headers[DEADLINE_HEADER] = String(remaining);
|
|
383
|
+
}
|
|
384
|
+
const traceparent = process.env.TRACEPARENT;
|
|
385
|
+
if (traceparent && TRACEPARENT_PATTERN.test(traceparent.trim())) {
|
|
386
|
+
headers["traceparent"] = traceparent.trim();
|
|
387
|
+
}
|
|
340
388
|
if (auth.type === "bearer") {
|
|
341
389
|
headers["Authorization"] = `Bearer ${auth.token}`;
|
|
342
390
|
} else if (auth.type === "api-key") {
|
|
@@ -1289,6 +1337,11 @@ var hotelCreateOrderSchema = {
|
|
|
1289
1337
|
required: false,
|
|
1290
1338
|
description: "Product bed-type code from the chosen quote rate's beds[].code (e.g. 'L000000' King / '1000000' Queen). Forwarded verbatim to upstream createOrder bedType; upstream recommends passing the product-dimension bed type at booking."
|
|
1291
1339
|
},
|
|
1340
|
+
"payment-method-id": {
|
|
1341
|
+
type: "string",
|
|
1342
|
+
required: false,
|
|
1343
|
+
description: "Optional bound-card id (pay_per_call / EVO path). When set, the platform settles this order by pre-authorizing + capturing on that specific bound card; omit to let billing_mode decide."
|
|
1344
|
+
},
|
|
1292
1345
|
"payment-token-id": {
|
|
1293
1346
|
type: "string",
|
|
1294
1347
|
required: false,
|
|
@@ -3434,6 +3487,9 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3434
3487
|
).option("--hotel-name <name>", "Hotel name (display-only, stored for order summary)").option(
|
|
3435
3488
|
"--bed-type <code>",
|
|
3436
3489
|
"Product bed-type code from the chosen quote rate's beds[].code (e.g. 'L000000' King / '1000000' Queen); forwarded verbatim to upstream createOrder bedType."
|
|
3490
|
+
).option(
|
|
3491
|
+
"--payment-method-id <id>",
|
|
3492
|
+
"Optional bound-card id (pay_per_call / EVO path). When set, the platform settles this order by pre-authorizing + capturing on that specific bound card. Omit to let the platform pick by billing_mode."
|
|
3437
3493
|
).option(
|
|
3438
3494
|
"--payment-token-id <id>",
|
|
3439
3495
|
"UPI Agent Pay: payment token id from an already-completed UnionPay network-token capture. When set, the platform skips EVO preauth/capture and only locks the order + records this credential (funds already charged)."
|
|
@@ -3484,6 +3540,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3484
3540
|
if (opts.tips !== void 0) body.tips = parseTips(opts.tips);
|
|
3485
3541
|
if (opts.hotelName !== void 0) body.hotel_name = opts.hotelName;
|
|
3486
3542
|
if (opts.bedType !== void 0) body.bed_type = opts.bedType;
|
|
3543
|
+
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
3487
3544
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
3488
3545
|
if (!isYes) {
|
|
3489
3546
|
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.";
|