@agenzo/merchant-cli 0.9.1 → 0.9.3

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
@@ -329,6 +329,8 @@ function isBelow(current, minimum) {
329
329
  return compareVersions(current, minimum) < 0;
330
330
  }
331
331
  var TRACEPARENT_PATTERN = /^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$/;
332
+ var FLOW_ID_BAGGAGE_KEY = "agenzo.flow_id";
333
+ var FLOW_ID_PATTERN = /^flw_[A-Za-z0-9_-]{8,60}$/;
332
334
  var DEFAULT_HTTP_TIMEOUT_MS = 7e4;
333
335
  function httpTimeoutFromEnv(env = process.env) {
334
336
  const raw = env.AGENZO_CLI_HTTP_TIMEOUT_MS;
@@ -338,6 +340,25 @@ function httpTimeoutFromEnv(env = process.env) {
338
340
  return parsed;
339
341
  }
340
342
  var DEADLINE_HEADER = "x-deadline-ms";
343
+ var BAGGAGE_HEADER = "baggage";
344
+ function baggageFromEnv(env = process.env) {
345
+ const raw = env.BAGGAGE;
346
+ if (raw === void 0 || raw.trim() === "") return null;
347
+ for (const member of raw.split(",")) {
348
+ const pair = member.split(";", 1)[0] ?? "";
349
+ const eq = pair.indexOf("=");
350
+ if (eq < 0) continue;
351
+ if (pair.slice(0, eq).trim() !== FLOW_ID_BAGGAGE_KEY) continue;
352
+ let value = pair.slice(eq + 1).trim();
353
+ try {
354
+ value = decodeURIComponent(value);
355
+ } catch {
356
+ return null;
357
+ }
358
+ return FLOW_ID_PATTERN.test(value) ? `${FLOW_ID_BAGGAGE_KEY}=${encodeURIComponent(value)}` : null;
359
+ }
360
+ return null;
361
+ }
341
362
  var DEADLINE_RESERVE_MS = 200;
342
363
  function deadlineFromEnv(env = process.env) {
343
364
  const raw = env.DEADLINE_MS;
@@ -399,6 +420,10 @@ var ApiClient = class {
399
420
  if (traceparent && TRACEPARENT_PATTERN.test(traceparent.trim())) {
400
421
  headers["traceparent"] = traceparent.trim();
401
422
  }
423
+ const baggage = baggageFromEnv();
424
+ if (baggage !== null) {
425
+ headers[BAGGAGE_HEADER] = baggage;
426
+ }
402
427
  if (auth.type === "bearer") {
403
428
  headers["Authorization"] = `Bearer ${auth.token}`;
404
429
  } else if (auth.type === "api-key") {
@@ -1590,6 +1615,7 @@ var hotelCreateOrderSchema = {
1590
1615
  children: { type: "int", required: false, default: 0, description: "Children per room (match quote)", constraints: "0-10" },
1591
1616
  nationality: { type: "string", required: false, default: "CN", description: "Guest nationality (match quote)" },
1592
1617
  "guest-name": { type: "string", required: true, description: "Primary guest name", constraints: "Use the name as the user gives it. If a supplier returns NAME_FORMAT_INVALID, re-collect in Latin letters and retry" },
1618
+ "room-guests": { type: "string", required: false, description: "Per-room primary guests, listed in room order, for booking several rooms under different names. Omit it and every room reuses guest-name (backward compatible); guest-name stays required either way", constraints: "JSON array of {guest_name (non-empty string)}; room_index is optional and filled in from the array position (1-based, validated against room-num by the platform) \u2014 pass it explicitly only to override; else PARAM_INVALID" },
1593
1619
  "contact-name": { type: "string", required: true, description: "Booking contact name (may equal guest-name)" },
1594
1620
  "contact-phone": { type: "string", required: true, description: "Booking contact phone number", constraints: "Digits; collect country code separately in --contact-country-code" },
1595
1621
  "contact-country-code": { type: "string", required: false, default: "86", description: "Phone country calling code without '+'" },
@@ -4606,6 +4632,34 @@ function parsePriceItems(raw) {
4606
4632
  }
4607
4633
  return parsed;
4608
4634
  }
4635
+ function parseRoomGuests(raw) {
4636
+ const INVALID = "--room-guests must be a JSON array of {guest_name (non-empty string), room_index (optional 1-based integer)}.";
4637
+ let parsed;
4638
+ try {
4639
+ parsed = JSON.parse(raw);
4640
+ } catch {
4641
+ throw new CliError("PARAM_INVALID", INVALID);
4642
+ }
4643
+ if (!Array.isArray(parsed) || parsed.length === 0) {
4644
+ throw new CliError("PARAM_INVALID", INVALID);
4645
+ }
4646
+ return parsed.map((el, i) => {
4647
+ if (typeof el !== "object" || el === null || Array.isArray(el)) {
4648
+ throw new CliError("PARAM_INVALID", INVALID);
4649
+ }
4650
+ const item = el;
4651
+ if (typeof item.guest_name !== "string" || item.guest_name.trim() === "") {
4652
+ throw new CliError("PARAM_INVALID", INVALID);
4653
+ }
4654
+ if (item.room_index === void 0) {
4655
+ return { ...item, room_index: i + 1 };
4656
+ }
4657
+ if (!Number.isInteger(item.room_index) || item.room_index < 1) {
4658
+ throw new CliError("PARAM_INVALID", INVALID);
4659
+ }
4660
+ return item;
4661
+ });
4662
+ }
4609
4663
  function parseTips(raw) {
4610
4664
  const INVALID = "--tips must be a JSON array of {title (string, optional), text (string, optional)}.";
4611
4665
  let parsed;
@@ -4691,7 +4745,10 @@ function formatCreateOrder2(data) {
4691
4745
  return out.join("\n");
4692
4746
  }
4693
4747
  function registerHotelCreateOrderCommand(parent, deps) {
4694
- const cmd = parent.command("create-order").description("Create a hotel order without charging (lock inventory, await payment)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Chosen rate token from quote (rates[].product_token)").option("--total-amount <amount>", "Total stay price in decimal currency units (not cents)").option("--currency <currency>", "ISO 4217 currency code from the chosen rate").option("--price-items <json>", "Per-night price breakdown JSON array (copied verbatim from quote)").option("--check-in <date>", "Check-in date (YYYY-MM-DD, match quote)").option("--check-out <date>", "Check-out date (YYYY-MM-DD, strictly after check-in)").option("--room-num <n>", "Number of rooms (match quote)", "1").option("--adults <n>", "Adults per room (match quote)", "2").option("--children <n>", "Children per room (match quote)", "0").option("--nationality <code>", "Guest nationality (ISO country code)", "CN").option("--guest-name <name>", "Primary guest name").option("--contact-name <name>", "Booking contact name (may equal guest-name)").option("--contact-phone <phone>", "Booking contact phone number (digits)").option("--contact-country-code <code>", "Phone country calling code without '+'", "86").option("--contact-email <email>", "Booking contact email").option("--arrive-time <time>", "Expected arrival time (HH:mm, hotel local time)").option("--special-requests <text>", "Free-text special requests (non-binding)").option(
4748
+ const cmd = parent.command("create-order").description("Create a hotel order without charging (lock inventory, await payment)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Chosen rate token from quote (rates[].product_token)").option("--total-amount <amount>", "Total stay price in decimal currency units (not cents)").option("--currency <currency>", "ISO 4217 currency code from the chosen rate").option("--price-items <json>", "Per-night price breakdown JSON array (copied verbatim from quote)").option("--check-in <date>", "Check-in date (YYYY-MM-DD, match quote)").option("--check-out <date>", "Check-out date (YYYY-MM-DD, strictly after check-in)").option("--room-num <n>", "Number of rooms (match quote)", "1").option("--adults <n>", "Adults per room (match quote)", "2").option("--children <n>", "Children per room (match quote)", "0").option("--nationality <code>", "Guest nationality (ISO country code)", "CN").option("--guest-name <name>", "Primary guest name").option(
4749
+ "--room-guests <json>",
4750
+ "Optional per-room primary guests as a JSON array [{guest_name}], listed in room order, for booking several rooms under different names. room_index is filled in from the array position (1-based); pass it explicitly to override. Omit the flag and every room reuses --guest-name."
4751
+ ).option("--contact-name <name>", "Booking contact name (may equal guest-name)").option("--contact-phone <phone>", "Booking contact phone number (digits)").option("--contact-country-code <code>", "Phone country calling code without '+'", "86").option("--contact-email <email>", "Booking contact email").option("--arrive-time <time>", "Expected arrival time (HH:mm, hotel local time)").option("--special-requests <text>", "Free-text special requests (non-binding)").option(
4695
4752
  "--tips <json>",
4696
4753
  "\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."
4697
4754
  ).option("--hotel-name <name>", "Hotel name (display-only, stored for order summary)").option(
@@ -4753,6 +4810,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
4753
4810
  contact_phone: contactPhone,
4754
4811
  contact_country_code: opts.contactCountryCode
4755
4812
  };
4813
+ if (opts.roomGuests !== void 0) body.room_guests = parseRoomGuests(opts.roomGuests);
4756
4814
  if (opts.contactEmail !== void 0) body.contact_email = opts.contactEmail;
4757
4815
  if (opts.arriveTime !== void 0) body.arrive_time = opts.arriveTime;
4758
4816
  if (opts.specialRequests !== void 0) body.special_requests = opts.specialRequests;