@agenzo/merchant-cli 0.8.6 → 0.8.8

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
@@ -3,7 +3,7 @@
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
5
 
6
- // ../../packages/cli-core/dist/index.js
6
+ // ../../../agenzo-cli/packages/cli-core/dist/index.js
7
7
  import { readFileSync } from "fs";
8
8
  import { dirname, join } from "path";
9
9
  import { fileURLToPath } from "url";
@@ -60,6 +60,8 @@ var CODE_NUM = {
60
60
  PAY_PER_CALL_NOT_AVAILABLE: 4308,
61
61
  HOTEL_NOT_FOUND: 4309,
62
62
  BOOKING_RESTRICTED: 4310,
63
+ PAYORDER_FAILED: 4311,
64
+ PAYORDER_FAILED_AFTER_PAYMENT: 4312,
63
65
  RATE_LIMITED: 5001,
64
66
  UPSTREAM_ERROR: 5101,
65
67
  INTERNAL_ERROR: 5201,
@@ -77,13 +79,14 @@ function codeNum(code) {
77
79
  return CODE_NUM[code];
78
80
  }
79
81
  var CliError = class _CliError extends Error {
80
- constructor(code, message, statusCode, requestId, upstream, backendMessage) {
82
+ constructor(code, message, statusCode, requestId, upstream, backendMessage, data) {
81
83
  super(message);
82
84
  this.code = code;
83
85
  this.statusCode = statusCode;
84
86
  this.requestId = requestId;
85
87
  this.upstream = upstream;
86
88
  this.backendMessage = backendMessage;
89
+ this.data = data;
87
90
  this.name = "CliError";
88
91
  }
89
92
  code;
@@ -91,6 +94,7 @@ var CliError = class _CliError extends Error {
91
94
  requestId;
92
95
  upstream;
93
96
  backendMessage;
97
+ data;
94
98
  /**
95
99
  * Map a backend ApiError to a CLI-facing code (§8.5 transitional mapping).
96
100
  * Backend numeric codes / HTTP status are translated to §8.4 string codes.
@@ -124,7 +128,8 @@ var CliError = class _CliError extends Error {
124
128
  error.statusCode,
125
129
  error.requestId,
126
130
  error.upstream,
127
- error.errorMessage
131
+ error.errorMessage,
132
+ error.data
128
133
  );
129
134
  }
130
135
  const status = error.statusCode;
@@ -142,7 +147,8 @@ var CliError = class _CliError extends Error {
142
147
  status,
143
148
  error.requestId,
144
149
  error.upstream,
145
- error.errorMessage
150
+ error.errorMessage,
151
+ error.data
146
152
  );
147
153
  }
148
154
  };
@@ -241,8 +247,15 @@ var STABLE_MESSAGE = {
241
247
  PAY_PER_CALL_NOT_AVAILABLE: "Pay-per-call billing is not available; use monthly_settlement.",
242
248
  HOTEL_NOT_FOUND: "This hotel is no longer available from the supplier.",
243
249
  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.",
250
+ PAYORDER_FAILED: "The hotel order was created, but payment failed. Retry payment for the existing order.",
251
+ PAYORDER_FAILED_AFTER_PAYMENT: "Payment was received, but hotel confirmation failed. Contact support for reconciliation.",
244
252
  NOT_IMPLEMENTED: "This operation is not implemented yet."
245
253
  };
254
+ function errorDetailLines(envelope) {
255
+ const orderId = envelope.error.data?.order_id;
256
+ if (typeof orderId !== "string" || orderId.length === 0) return [];
257
+ return [` Order: ${orderId}`];
258
+ }
246
259
  function toErrorEnvelope(error) {
247
260
  if (error instanceof CliError) {
248
261
  const stableMessage = error.message || "Unknown error";
@@ -254,7 +267,8 @@ function toErrorEnvelope(error) {
254
267
  message: stableMessage,
255
268
  ...error.requestId ? { request_id: error.requestId } : {},
256
269
  ...error.upstream ? { upstream: error.upstream } : {},
257
- ...backendMessage ? { backend_message: backendMessage } : {}
270
+ ...backendMessage ? { backend_message: backendMessage } : {},
271
+ ...error.data ? { data: error.data } : {}
258
272
  }
259
273
  };
260
274
  }
@@ -472,7 +486,8 @@ var ApiClient = class {
472
486
  }
473
487
  }
474
488
  const errorCodeStr = responseBody.error_code;
475
- const rawData = responseBody.data;
489
+ const dataValue = responseBody.data;
490
+ const rawData = dataValue && typeof dataValue === "object" && !Array.isArray(dataValue) ? dataValue : void 0;
476
491
  const upstream = rawData?.upstream && typeof rawData.upstream === "object" ? rawData.upstream : void 0;
477
492
  return {
478
493
  success: false,
@@ -481,6 +496,7 @@ var ApiClient = class {
481
496
  statusCode: response.status,
482
497
  ...errorCodeStr ? { code: errorCodeStr } : typeof code === "string" && code ? { code } : {},
483
498
  requestId: responseBody.request_id ?? responseBody.requestId,
499
+ ...rawData ? { data: rawData } : {},
484
500
  ...upstream ? { upstream } : {}
485
501
  };
486
502
  } catch (error) {
@@ -1010,6 +1026,11 @@ var bookSchema = {
1010
1026
  required: "conditional",
1011
1027
  description: "Required when billing_mode=pay_per_call (a PAID payment order). Forbidden when billing_mode=monthly_settlement"
1012
1028
  },
1029
+ "payment-method-id": {
1030
+ type: "string",
1031
+ required: false,
1032
+ description: "Bound payment method id to charge (pay_per_call only). Opaque id from `token payment-methods list`; ignored for monthly_settlement"
1033
+ },
1013
1034
  "passenger-name": { type: "string", required: true, description: "Passenger full name" },
1014
1035
  "passenger-phone": { type: "string", required: true, description: "Passenger phone in E.164 format (e.g. +14155551234)" },
1015
1036
  "passenger-email": { type: "string", required: true, description: "Passenger email (required by eLife for booking)" },
@@ -1332,6 +1353,17 @@ var hotelCreateOrderSchema = {
1332
1353
  "arrive-time": { type: "string", required: false, description: "Expected arrival time", constraints: "HH:mm, hotel local time" },
1333
1354
  "special-requests": { type: "string", required: false, description: "Free-text special requests (non-binding)" },
1334
1355
  tips: { type: "string", required: false, description: "FCG \u5BA2\u6237\u81EA\u6D4B\u70B95 \u63D0\u793A\u4FE1\u606F: the chosen quote rate's tips (tips[].tipsDetails[]) as a JSON array [{title,text}], captured at booking. Stored on the order for the order-detail page only; platform-local, not sent upstream", constraints: "JSON array of {title (string, optional), text (string, optional)}; else PARAM_INVALID" },
1356
+ cancellation: {
1357
+ type: "string",
1358
+ required: false,
1359
+ description: "Cancellation policy snapshot copied from the selected quote rate and stored on the order.",
1360
+ constraints: "JSON object; else PARAM_INVALID"
1361
+ },
1362
+ "hotel-timezone": {
1363
+ type: "string",
1364
+ required: false,
1365
+ description: "Hotel timezone from quote (for example 'UTC+8'), used to evaluate cancellation deadlines."
1366
+ },
1335
1367
  "bed-type": {
1336
1368
  type: "string",
1337
1369
  required: false,
@@ -2389,7 +2421,10 @@ function formatBook(data) {
2389
2421
  return Formatter.keyValue(lines);
2390
2422
  }
2391
2423
  function registerBookCommand(parent, deps) {
2392
- const cmd = parent.command("book").description("Book a ride using a quote_id returned by quote").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("--payment-order-id <id>", "Paid payment order id (pay_per_call mode only)").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(
2424
+ const cmd = parent.command("book").description("Book a ride using a quote_id returned by quote").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("--payment-order-id <id>", "Paid payment order id (pay_per_call mode only)").option(
2425
+ "--payment-method-id <id>",
2426
+ "Bound payment method id to charge (pay_per_call mode only)"
2427
+ ).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(
2393
2428
  "--idempotency-key <key>",
2394
2429
  "Idempotency key forwarded verbatim as the Idempotency-Key header"
2395
2430
  );
@@ -2412,6 +2447,7 @@ function registerBookCommand(parent, deps) {
2412
2447
  passenger_phone: phone(opts.passengerPhone, "passenger-phone")
2413
2448
  };
2414
2449
  if (opts.paymentOrderId) body.payment_order_id = opts.paymentOrderId;
2450
+ if (opts.paymentMethodId) body.payment_method_id = opts.paymentMethodId;
2415
2451
  if (opts.passengerEmail) body.passenger_email = opts.passengerEmail;
2416
2452
  if (opts.luggageCount !== void 0) {
2417
2453
  body.luggage_count = num2(opts.luggageCount, "luggage-count");
@@ -3433,6 +3469,19 @@ function parseTips(raw) {
3433
3469
  }
3434
3470
  return parsed;
3435
3471
  }
3472
+ function parseCancellation(raw) {
3473
+ const invalid = "--cancellation must be a JSON object.";
3474
+ let parsed;
3475
+ try {
3476
+ parsed = JSON.parse(raw);
3477
+ } catch {
3478
+ throw new CliError("PARAM_INVALID", invalid);
3479
+ }
3480
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
3481
+ throw new CliError("PARAM_INVALID", invalid);
3482
+ }
3483
+ return parsed;
3484
+ }
3436
3485
  function need7(value, flag) {
3437
3486
  if (value === void 0) {
3438
3487
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
@@ -3487,6 +3536,12 @@ function registerHotelCreateOrderCommand(parent, deps) {
3487
3536
  "--tips <json>",
3488
3537
  "\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."
3489
3538
  ).option("--hotel-name <name>", "Hotel name (display-only, stored for order summary)").option(
3539
+ "--cancellation <json>",
3540
+ "Cancellation policy JSON from the chosen rate; stored on the order for cancellation gating and deadline display."
3541
+ ).option(
3542
+ "--hotel-timezone <tz>",
3543
+ "Hotel timezone from quote (for example 'UTC+8'); stored to evaluate cancellation deadlines in hotel-local time."
3544
+ ).option(
3490
3545
  "--bed-type <code>",
3491
3546
  "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
3547
  ).option(
@@ -3540,6 +3595,8 @@ function registerHotelCreateOrderCommand(parent, deps) {
3540
3595
  if (opts.arriveTime !== void 0) body.arrive_time = opts.arriveTime;
3541
3596
  if (opts.specialRequests !== void 0) body.special_requests = opts.specialRequests;
3542
3597
  if (opts.tips !== void 0) body.tips = parseTips(opts.tips);
3598
+ if (opts.cancellation !== void 0) body.cancellation = parseCancellation(opts.cancellation);
3599
+ if (opts.hotelTimezone !== void 0) body.hotel_timezone = opts.hotelTimezone;
3543
3600
  if (opts.hotelName !== void 0) body.hotel_name = opts.hotelName;
3544
3601
  if (opts.bedType !== void 0) body.bed_type = opts.bedType;
3545
3602
  if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
@@ -5833,6 +5890,9 @@ function reportError(error) {
5833
5890
  console.error(
5834
5891
  Formatter.status("error", `[${envelope.error.code_num}] ${envelope.error.message}`)
5835
5892
  );
5893
+ for (const line of errorDetailLines(envelope)) {
5894
+ console.error(line);
5895
+ }
5836
5896
  if (envelope.error.upstream) {
5837
5897
  console.error(` \u21B3 [${envelope.error.upstream.code}] ${envelope.error.upstream.message}`);
5838
5898
  }