@hachej/boring-core 0.1.69 → 0.1.71

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.
@@ -154,13 +154,17 @@ interface CreditLedgerEntry {
154
154
  /** Format SIGNED credit micros as a currency string with an explicit +/− sign.
155
155
  * `currency` is the configured display currency (1 credit-unit = 1 major unit); defaults
156
156
  * to EUR for callers without a configured purchase currency. */
157
- declare function formatSignedCreditMicros(micros: number, currency?: string, locale?: string): string;
157
+ interface CreditFormatOptions {
158
+ /** Show sub-cent/sub-rappen/sub-credit usage instead of rounding tiny amounts to 0.00. */
159
+ highPrecision?: boolean;
160
+ }
161
+ declare function formatSignedCreditMicros(micros: number, currency?: string, locale?: string, options?: CreditFormatOptions): string;
158
162
  /** Format a minor-unit price (e.g. cents) in its currency for pack labels/buttons. */
159
163
  declare function formatMinorPrice(priceMinor: number, currency: string, locale?: string): string;
160
164
  /** Format credit micros as a currency string. 1 credit-unit = 1 major unit of the
161
165
  * configured display `currency` (µ/1e6). Defaults to EUR for callers without a
162
166
  * configured purchase currency (e.g. a consumption-only deployment). */
163
- declare function formatCreditMicros(micros: number, currency?: string, locale?: string): string;
167
+ declare function formatCreditMicros(micros: number, currency?: string, locale?: string, options?: CreditFormatOptions): string;
164
168
  /** True when the remaining balance is at or below the low-balance threshold. */
165
169
  declare function isLowBalance(micros: number, thresholdMicros?: number): boolean;
166
170
  /** Stable server error code for an out-of-credits rejection (mirrors the agent's
@@ -916,19 +916,26 @@ function creditNetMicros(balance) {
916
916
  const debt = Number.isFinite(balance.debtMicros) ? balance.debtMicros : 0;
917
917
  return remaining - debt;
918
918
  }
919
- function formatSignedCreditMicros(micros, currency = "EUR", locale) {
919
+ function creditFractionDigits(major, options) {
920
+ if (!options?.highPrecision) return {};
921
+ return {
922
+ minimumFractionDigits: 2,
923
+ maximumFractionDigits: Math.abs(major) > 0 && Math.abs(major) < 0.01 ? 6 : 2
924
+ };
925
+ }
926
+ function formatSignedCreditMicros(micros, currency = "EUR", locale, options) {
920
927
  const major = (Number.isFinite(micros) ? micros : 0) / 1e6;
921
928
  const sign = major > 0 ? "+" : major < 0 ? "\u2212" : "";
922
- const abs = new Intl.NumberFormat(locale, { style: "currency", currency }).format(Math.abs(major));
929
+ const abs = new Intl.NumberFormat(locale, { style: "currency", currency, ...creditFractionDigits(major, options) }).format(Math.abs(major));
923
930
  return `${sign}${abs}`;
924
931
  }
925
932
  function formatMinorPrice(priceMinor, currency, locale) {
926
933
  const major = (Number.isFinite(priceMinor) ? priceMinor : 0) / 100;
927
934
  return new Intl.NumberFormat(locale, { style: "currency", currency, maximumFractionDigits: major % 1 === 0 ? 0 : 2 }).format(major);
928
935
  }
929
- function formatCreditMicros(micros, currency = "EUR", locale) {
936
+ function formatCreditMicros(micros, currency = "EUR", locale, options) {
930
937
  const major = (Number.isFinite(micros) ? Math.max(0, micros) : 0) / 1e6;
931
- return new Intl.NumberFormat(locale, { style: "currency", currency }).format(major);
938
+ return new Intl.NumberFormat(locale, { style: "currency", currency, ...creditFractionDigits(major, options) }).format(major);
932
939
  }
933
940
  function isLowBalance(micros, thresholdMicros = 5e5) {
934
941
  return Number.isFinite(micros) && micros <= thresholdMicros;
@@ -1253,7 +1260,7 @@ function CreditsSettingsPanel({ apiBaseUrl = "", locale }) {
1253
1260
  inDebt ? `\u2212${formatCreditMicros(balance.debtMicros, currency, locale)}` : formatCreditMicros(balance.remainingMicros, currency, locale),
1254
1261
  updating && /* @__PURE__ */ jsx7("span", { className: "ml-2 text-[11px] font-normal text-muted-foreground", "aria-live": "polite", children: "Updating\u2026" })
1255
1262
  ] }) }),
1256
- /* @__PURE__ */ jsx7(DetailLine, { label: "Used so far", children: /* @__PURE__ */ jsx7("p", { style: { fontVariantNumeric: "tabular-nums" }, children: formatCreditMicros(balance.usedMicros, currency, locale) }) })
1263
+ /* @__PURE__ */ jsx7(DetailLine, { label: "Used so far", children: /* @__PURE__ */ jsx7("p", { style: { fontVariantNumeric: "tabular-nums" }, children: formatCreditMicros(balance.usedMicros, currency, locale, { highPrecision: true }) }) })
1257
1264
  ] }),
1258
1265
  showBuy && packs.length > 0 && /* @__PURE__ */ jsxs6("fieldset", { className: "space-y-2", children: [
1259
1266
  /* @__PURE__ */ jsx7("legend", { className: "text-[12px] font-medium text-foreground", children: "Buy credits" }),
@@ -1322,7 +1329,7 @@ function CreditsSettingsPanel({ apiBaseUrl = "", locale }) {
1322
1329
  {
1323
1330
  style: { fontVariantNumeric: "tabular-nums" },
1324
1331
  className: e.amountMicros >= 0 ? "text-foreground" : "text-muted-foreground",
1325
- children: formatSignedCreditMicros(e.amountMicros, currency, locale)
1332
+ children: formatSignedCreditMicros(e.amountMicros, currency, locale, e.kind === "usage" ? { highPrecision: true } : void 0)
1326
1333
  }
1327
1334
  )
1328
1335
  ] }, e.id)) })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-core",
3
- "version": "0.1.69",
3
+ "version": "0.1.71",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Foundation package for boring-ui-v2 apps: DB, auth, config, HTTP app factory, and frontend app shell.",
@@ -63,14 +63,14 @@
63
63
  "@zxcvbn-ts/core": "^4.1.2",
64
64
  "@zxcvbn-ts/language-common": "^4.1.2",
65
65
  "@zxcvbn-ts/language-en": "^4.1.1",
66
- "better-auth": "^1.6.22",
66
+ "better-auth": "^1.6.23",
67
67
  "close-with-grace": "^2.2.0",
68
68
  "drizzle-orm": "^0.45.2",
69
69
  "fastify": "^5.9.0",
70
70
  "fastify-plugin": "^6.0.0",
71
71
  "isomorphic-dompurify": "^3.18.0",
72
72
  "lucide-react": "^1.21.0",
73
- "nodemailer": "^9.0.1",
73
+ "nodemailer": "^9.0.3",
74
74
  "pino": "^10.3.1",
75
75
  "postgres": "^3.4.9",
76
76
  "posthog-node": "^5.38.5",
@@ -79,9 +79,9 @@
79
79
  "react-router-dom": "^7.18.0",
80
80
  "smol-toml": "^1.7.0",
81
81
  "zod": "^3.25.76",
82
- "@hachej/boring-ui-kit": "0.1.69",
83
- "@hachej/boring-agent": "0.1.69",
84
- "@hachej/boring-workspace": "0.1.69"
82
+ "@hachej/boring-agent": "0.1.71",
83
+ "@hachej/boring-ui-kit": "0.1.71",
84
+ "@hachej/boring-workspace": "0.1.71"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@testing-library/jest-dom": "^6.9.1",