@binaryandthread/cli 0.3.0 → 0.3.2

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/bin.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  forgetConfig,
6
6
  loadConfig,
7
7
  saveConfig
8
- } from "./chunk-OVG37IIX.js";
8
+ } from "./chunk-RGFMXWD5.js";
9
9
  import {
10
10
  makePrompts
11
11
  } from "./chunk-AAN4VWP3.js";
@@ -53,7 +53,7 @@ import {
53
53
  versionLine,
54
54
  warn,
55
55
  working
56
- } from "./chunk-RDJJLYXB.js";
56
+ } from "./chunk-BFMH7VCE.js";
57
57
  import {
58
58
  __require
59
59
  } from "./chunk-7OCVIDC7.js";
@@ -62,6 +62,26 @@ import {
62
62
  import { spawn } from "child_process";
63
63
  import { Command } from "commander";
64
64
 
65
+ // src/locale.ts
66
+ function detectRegionFromLocale(env) {
67
+ const raw = (env.LC_ALL || env.LC_MESSAGES || env.LANG || "").trim();
68
+ const m = /^[A-Za-z]{2,3}[_-]([A-Za-z]{2})(?:[.@]|$)/.exec(raw);
69
+ return m ? m[1].toLowerCase() : null;
70
+ }
71
+ function resolveEffectiveRegion(flag, saved, env) {
72
+ if (flag && flag.trim()) {
73
+ return { region: flag.trim().toLowerCase(), source: "flag" };
74
+ }
75
+ if (saved && saved.trim()) {
76
+ return { region: saved.trim().toLowerCase(), source: "config" };
77
+ }
78
+ const fromLocale = detectRegionFromLocale(env);
79
+ if (fromLocale) {
80
+ return { region: fromLocale, source: "locale" };
81
+ }
82
+ return { region: void 0, source: void 0 };
83
+ }
84
+
65
85
  // src/client-config.ts
66
86
  function resolveClientConfig(env = process.env) {
67
87
  const baseUrl = env.BT_API_URL || env.MEDUSA_BACKEND_URL || BT_DEFAULT_STORE_URL;
@@ -82,7 +102,7 @@ function makeLogger(debug, write = (s) => process.stderr.write(s)) {
82
102
  }
83
103
 
84
104
  // src/version.ts
85
- var VERSION = "0.3.0";
105
+ var VERSION = "0.3.2";
86
106
 
87
107
  // src/eggs.ts
88
108
  function teapot() {
@@ -223,6 +243,7 @@ import * as fs from "fs";
223
243
  import * as path from "path";
224
244
  var CACHE_FILE = "update-check.json";
225
245
  var CHECK_INTERVAL_MS = 6 * 60 * 60 * 1e3;
246
+ var NOTICE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
226
247
  var REGISTRY_LATEST = "https://registry.npmjs.org/@binaryandthread/cli/latest";
227
248
  var FETCH_TIMEOUT_MS = 2e3;
228
249
  function parseSemver(v) {
@@ -254,9 +275,14 @@ function maybeNotifyUpdate(deps) {
254
275
  const now = deps.now ?? Date.now();
255
276
  const read = deps.readCache ?? readUpdateCache;
256
277
  const refresh = deps.refresh ?? ((n) => void fetchLatestIntoCache(n));
278
+ const markNotified = deps.markNotified ?? markNotifiedInCache;
257
279
  const cache = read();
258
280
  const line = updateNoticeLine(deps.current, cache?.latest);
259
- if (line) deps.write(line + "\n");
281
+ const canNotify = cache?.lastNotified === void 0 || now - cache.lastNotified >= NOTICE_INTERVAL_MS;
282
+ if (line && canNotify) {
283
+ deps.write(line + "\n");
284
+ markNotified(now);
285
+ }
260
286
  if (!cache || now - cache.lastCheck > CHECK_INTERVAL_MS) {
261
287
  refresh(now);
262
288
  }
@@ -268,12 +294,22 @@ function readUpdateCache() {
268
294
  try {
269
295
  const j = JSON.parse(fs.readFileSync(cachePath(), "utf8"));
270
296
  if (j && typeof j.latest === "string" && typeof j.lastCheck === "number") {
271
- return { latest: j.latest, lastCheck: j.lastCheck };
297
+ const cache = { latest: j.latest, lastCheck: j.lastCheck };
298
+ if (typeof j.lastNotified === "number") {
299
+ cache.lastNotified = j.lastNotified;
300
+ }
301
+ return cache;
272
302
  }
273
303
  } catch {
274
304
  }
275
305
  return null;
276
306
  }
307
+ function markNotifiedInCache(now) {
308
+ const cache = readUpdateCache();
309
+ if (cache) {
310
+ writeUpdateCache({ ...cache, lastNotified: now });
311
+ }
312
+ }
277
313
  function writeUpdateCache(c) {
278
314
  try {
279
315
  fs.mkdirSync(configDir(), { recursive: true });
@@ -439,7 +475,7 @@ async function runBrowse(client, config, args) {
439
475
  lines.push(" peek at next \u2192 bt browse --branch=next");
440
476
  } else {
441
477
  lines.push(header(style, "bt browse \u2014 in stock"));
442
- lines.push(regionLine(rr, style));
478
+ lines.push(regionLine(rr, style, config.region_source));
443
479
  lines.push(...layoutRows(rows, style));
444
480
  for (const d of drops) {
445
481
  const dt = (d.title ?? d.handle ?? d.id).toString();
@@ -478,7 +514,7 @@ function registerBrowse(program, makeClient2, loadConfig2) {
478
514
  program.command("browse").alias("ls").description("list what's in stock on a branch.").option("--branch <branch>", "main (live) or next (terminal-only drops)").option("--pick", "opt into the arrow-key picker (default is the numbered table \u2014 use bt stage <n>)").option("--plain", "force the static table (the default; kept for back-compat)").action(async (opts) => {
479
515
  const { json, brand } = resolveOutput(program);
480
516
  if (opts.pick && !json && brand.color && process.stdout.isTTY && process.stdin.isTTY) {
481
- const { runInteractiveBrowse } = await import("./interactive-DJXIUVBM.js");
517
+ const { runInteractiveBrowse } = await import("./interactive-BOS6VMRJ.js");
482
518
  const handled = await runInteractiveBrowse(makeClient2(), loadConfig2(), { branch: opts.branch, brand });
483
519
  if (handled) return;
484
520
  }
@@ -891,10 +927,16 @@ async function runCheckout(client, config, args, deps) {
891
927
  lines.push(ok("deploy successful."));
892
928
  lines.push(` committed to wardrobe@main`);
893
929
  lines.push(` order #${displayId}`);
894
- if (mint.discount && mint.discount.amount > 0) {
930
+ const settled = outcome.summary;
931
+ const finalTotal = settled?.total ?? mint.total ?? shippedCart?.total ?? cart.total;
932
+ const finalCurrency = settled?.currency_code ?? currency;
933
+ if (settled?.discount_total) {
934
+ const codes = settled.discount_codes.length ? ` (${settled.discount_codes.join(", ")})` : "";
935
+ lines.push(dim(style, ` discount${codes} \u2212${fmtPrice(settled.discount_total, finalCurrency)}`));
936
+ } else if (mint.discount && mint.discount.amount > 0) {
895
937
  lines.push(dim(style, ` dev channel \u2212${fmtPrice(mint.discount.amount, currency)} (${mint.discount.pct}% \u2014 the terminal's cut for you)`));
896
938
  }
897
- lines.push(` total ${cyan(style, totalLine)}${taxIncl ? " (incl. VAT)" : ""}`);
939
+ lines.push(` total ${cyan(style, fmtPrice(finalTotal, finalCurrency))}${taxIncl ? " (incl. VAT)" : ""}`);
898
940
  if (shipsTo) {
899
941
  lines.push(` ships to ${shipsTo} \xB7 ~3\u20136 working days`);
900
942
  } else {
@@ -911,11 +953,13 @@ async function runCheckout(client, config, args, deps) {
911
953
  status: "placed",
912
954
  order_id: outcome.order_id,
913
955
  display_id: displayId,
914
- // A2 — the SHIPPING-INCLUSIVE, dev-channel-discounted total the buyer consented to (same
915
- // figure as the review), so a --json / bt buy consumer has the real amount, not just a status.
916
- total: mint.total ?? shippedCart?.total ?? cart.total ?? null,
917
- currency: mint.currency ?? cart.currency_code ?? region.currency_code ?? null,
918
- discount: mint.discount ?? null
956
+ // A2/ENG-39 — the REAL settled total (every discount applied, incl. at payment); fall back
957
+ // to the mint estimate for an older backend. A --json / bt buy consumer gets the true amount.
958
+ total: settled?.total ?? mint.total ?? shippedCart?.total ?? cart.total ?? null,
959
+ currency: settled?.currency_code ?? mint.currency ?? cart.currency_code ?? region.currency_code ?? null,
960
+ discount: mint.discount ?? null,
961
+ // The full settled summary (subtotal, discount_total, promo codes, line items) when available.
962
+ summary: settled ?? null
919
963
  } : void 0
920
964
  };
921
965
  }
@@ -972,8 +1016,8 @@ function registerCheckout(program, makeClient2, loadConfig2) {
972
1016
  const { json, brand } = resolveOutput(program);
973
1017
  const { makePrompts: makePrompts2 } = await import("./prompts-DDVV5RE6.js");
974
1018
  const { openCheckout } = await import("./browser-WCNC4AWS.js");
975
- const { pollUntilPlaced } = await import("./poll-O3VUD5WV.js");
976
- const { saveConfig: saveConfig2 } = await import("./config-FXGCWC6Y.js");
1019
+ const { pollUntilPlaced } = await import("./poll-II3TVJLK.js");
1020
+ const { saveConfig: saveConfig2 } = await import("./config-WV4DTQXU.js");
977
1021
  const client = makeClient2();
978
1022
  const print = json ? () => {
979
1023
  } : (line) => process.stdout.write(line + "\n");
@@ -1747,8 +1791,8 @@ function registerBuy(program, makeClient2, loadConfig2) {
1747
1791
  const { json, brand } = resolveOutput(program);
1748
1792
  const { makePrompts: makePrompts2 } = await import("./prompts-DDVV5RE6.js");
1749
1793
  const { openCheckout } = await import("./browser-WCNC4AWS.js");
1750
- const { pollUntilPlaced } = await import("./poll-O3VUD5WV.js");
1751
- const { saveConfig: saveConfig2 } = await import("./config-FXGCWC6Y.js");
1794
+ const { pollUntilPlaced } = await import("./poll-II3TVJLK.js");
1795
+ const { saveConfig: saveConfig2 } = await import("./config-WV4DTQXU.js");
1752
1796
  const client = makeClient2();
1753
1797
  const print = json ? () => {
1754
1798
  } : (line) => process.stdout.write(line + "\n");
@@ -1808,7 +1852,7 @@ function runConfig(args, deps) {
1808
1852
  function registerConfig(program) {
1809
1853
  program.command("config").argument("[sub]", "get | set", "get").argument("[key]", "config key").argument("[value]", "value (for set)").description("view or set local prefs (email, region, defaults). the auth token is never stored here.").action(async (sub, key, value) => {
1810
1854
  const { json } = resolveOutput(program);
1811
- const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await import("./config-FXGCWC6Y.js");
1855
+ const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await import("./config-WV4DTQXU.js");
1812
1856
  const res = runConfig({ sub, key, value, json }, { load: loadConfig2, save: saveConfig2 });
1813
1857
  printResult(res, json);
1814
1858
  });
@@ -2010,7 +2054,8 @@ function registerCommands(program) {
2010
2054
  const effectiveConfig = () => {
2011
2055
  const saved = loadConfig();
2012
2056
  const flag = program.opts().region;
2013
- return flag ? { ...saved, region: flag.trim().toLowerCase() } : saved;
2057
+ const { region, source } = resolveEffectiveRegion(flag, saved.region, process.env);
2058
+ return { ...saved, region, region_source: source };
2014
2059
  };
2015
2060
  registerInit(program);
2016
2061
  registerBrowse(program, makeClient, effectiveConfig);