@agenzo/merchant-cli 0.8.4 → 0.8.6
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 +61 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -314,6 +314,25 @@ function compareVersions(a, b) {
|
|
|
314
314
|
function isBelow(current, minimum) {
|
|
315
315
|
return compareVersions(current, minimum) < 0;
|
|
316
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
|
+
}
|
|
317
336
|
var ApiClient = class {
|
|
318
337
|
baseUrl;
|
|
319
338
|
timeout;
|
|
@@ -329,16 +348,43 @@ var ApiClient = class {
|
|
|
329
348
|
* a single trace_id server-side and can be followed as one chain in logs.
|
|
330
349
|
*/
|
|
331
350
|
requestId;
|
|
351
|
+
/**
|
|
352
|
+
* 上游给的剩余预算(毫秒),来自 `DEADLINE_MS`;未注入时为 null。
|
|
353
|
+
*
|
|
354
|
+
* 进程启动时读一次而不是每请求读:一次 CLI 调用就是链路上的一跳,预算属于这一跳
|
|
355
|
+
* 整体。每请求重读会让多步流程(如 `payment-methods add` 的 create + poll + get)
|
|
356
|
+
* 各自拿到完整预算,等于凭空放大了本跳的时间上限。
|
|
357
|
+
*/
|
|
358
|
+
deadlineMs;
|
|
359
|
+
/** 本进程开始时刻(单调时钟),用于算已用时间。 */
|
|
360
|
+
startedAt;
|
|
332
361
|
constructor(config) {
|
|
333
362
|
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
334
|
-
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));
|
|
335
367
|
this.requestId = crypto.randomUUID();
|
|
336
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
|
+
}
|
|
337
375
|
buildHeaders(auth) {
|
|
338
376
|
const headers = {
|
|
339
377
|
"User-Agent": `agenzo-admin-cli/${getCurrentVersion()}`,
|
|
340
378
|
"X-Request-Id": this.requestId
|
|
341
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
|
+
}
|
|
342
388
|
if (auth.type === "bearer") {
|
|
343
389
|
headers["Authorization"] = `Bearer ${auth.token}`;
|
|
344
390
|
} else if (auth.type === "api-key") {
|
|
@@ -483,12 +529,12 @@ var DEFAULT_API_PATH = "/api/admin/v1";
|
|
|
483
529
|
var DEFAULT_CONFIG = {
|
|
484
530
|
active_org: null,
|
|
485
531
|
active_developer_id: null,
|
|
486
|
-
api_host: "https://agent.
|
|
532
|
+
api_host: "https://agent.agenzo.com",
|
|
487
533
|
api_path: DEFAULT_API_PATH
|
|
488
534
|
};
|
|
489
535
|
var BUILTIN_PROFILES = {
|
|
490
|
-
production: "https://agent.
|
|
491
|
-
testing: "https://agent-
|
|
536
|
+
production: "https://agent.agenzo.com",
|
|
537
|
+
testing: "https://agent-dev.agenzo.com"
|
|
492
538
|
};
|
|
493
539
|
function resolveApiHost(host) {
|
|
494
540
|
if (BUILTIN_PROFILES[host]) {
|
|
@@ -1291,6 +1337,11 @@ var hotelCreateOrderSchema = {
|
|
|
1291
1337
|
required: false,
|
|
1292
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."
|
|
1293
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
|
+
},
|
|
1294
1345
|
"payment-token-id": {
|
|
1295
1346
|
type: "string",
|
|
1296
1347
|
required: false,
|
|
@@ -2785,6 +2836,7 @@ var SERVICE_REGISTRY = [
|
|
|
2785
2836
|
"change-search",
|
|
2786
2837
|
"change-apply",
|
|
2787
2838
|
"change-detail",
|
|
2839
|
+
"change-pay",
|
|
2788
2840
|
"change-cancel",
|
|
2789
2841
|
"refund-apply",
|
|
2790
2842
|
"refund-detail",
|
|
@@ -2806,6 +2858,7 @@ var SERVICE_REGISTRY = [
|
|
|
2806
2858
|
"change-search": "Search rebook-eligible flights.",
|
|
2807
2859
|
"change-apply": "Submit a change request (pending review).",
|
|
2808
2860
|
"change-detail": "Change request detail.",
|
|
2861
|
+
"change-pay": "Pay the change fee and trigger change ticketing.",
|
|
2809
2862
|
"change-cancel": "Cancel a change request (immediate terminal).",
|
|
2810
2863
|
"refund-apply": "Submit a refund request (pending review).",
|
|
2811
2864
|
"refund-detail": "Refund request detail.",
|
|
@@ -3380,19 +3433,6 @@ function parseTips(raw) {
|
|
|
3380
3433
|
}
|
|
3381
3434
|
return parsed;
|
|
3382
3435
|
}
|
|
3383
|
-
function parseCancellation(raw) {
|
|
3384
|
-
const INVALID = "--cancellation must be a JSON object.";
|
|
3385
|
-
let parsed;
|
|
3386
|
-
try {
|
|
3387
|
-
parsed = JSON.parse(raw);
|
|
3388
|
-
} catch {
|
|
3389
|
-
throw new CliError("PARAM_INVALID", INVALID);
|
|
3390
|
-
}
|
|
3391
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
3392
|
-
throw new CliError("PARAM_INVALID", INVALID);
|
|
3393
|
-
}
|
|
3394
|
-
return parsed;
|
|
3395
|
-
}
|
|
3396
3436
|
function need7(value, flag) {
|
|
3397
3437
|
if (value === void 0) {
|
|
3398
3438
|
throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
|
|
@@ -3447,14 +3487,11 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3447
3487
|
"--tips <json>",
|
|
3448
3488
|
"\u5BA2\u6237\u81EA\u6D4B\u70B95 \u63D0\u793A\u4FE1\u606F: the chosen quote rate's tips as a JSON array [{title,text}]. Stored on the order for the order-detail page ONLY \u2014 platform-local, not sent upstream."
|
|
3449
3489
|
).option("--hotel-name <name>", "Hotel name (display-only, stored for order summary)").option(
|
|
3450
|
-
"--cancellation <json>",
|
|
3451
|
-
"Cancellation policy JSON from the chosen rate ({restriction_type,restriction_day,restriction_time,penalties[]}); stored on the order for cancellation gating and free-cancel deadline display. Not sent upstream."
|
|
3452
|
-
).option(
|
|
3453
|
-
"--hotel-timezone <tz>",
|
|
3454
|
-
"Hotel timezone from quote (e.g. 'UTC-5'); stored to compute the free-cancellation deadline in hotel-local time."
|
|
3455
|
-
).option(
|
|
3456
3490
|
"--bed-type <code>",
|
|
3457
3491
|
"Product bed-type code from the chosen quote rate's beds[].code (e.g. 'L000000' King / '1000000' Queen); forwarded verbatim to upstream createOrder bedType."
|
|
3492
|
+
).option(
|
|
3493
|
+
"--payment-method-id <id>",
|
|
3494
|
+
"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."
|
|
3458
3495
|
).option(
|
|
3459
3496
|
"--payment-token-id <id>",
|
|
3460
3497
|
"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)."
|
|
@@ -3503,10 +3540,9 @@ function registerHotelCreateOrderCommand(parent, deps) {
|
|
|
3503
3540
|
if (opts.arriveTime !== void 0) body.arrive_time = opts.arriveTime;
|
|
3504
3541
|
if (opts.specialRequests !== void 0) body.special_requests = opts.specialRequests;
|
|
3505
3542
|
if (opts.tips !== void 0) body.tips = parseTips(opts.tips);
|
|
3506
|
-
if (opts.cancellation !== void 0) body.cancellation = parseCancellation(opts.cancellation);
|
|
3507
|
-
if (opts.hotelTimezone !== void 0) body.hotel_timezone = opts.hotelTimezone;
|
|
3508
3543
|
if (opts.hotelName !== void 0) body.hotel_name = opts.hotelName;
|
|
3509
3544
|
if (opts.bedType !== void 0) body.bed_type = opts.bedType;
|
|
3545
|
+
if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
|
|
3510
3546
|
if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
|
|
3511
3547
|
if (!isYes) {
|
|
3512
3548
|
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.";
|