@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/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.timeout = config.timeout ?? 6e4;
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.";