@softure-ai/core 0.1.9 → 0.1.10

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/CHANGELOG.md CHANGED
@@ -4,6 +4,11 @@ Newest first. Each version lists what changed for an app that uses `@softure-ai/
4
4
  production, the version gets a line `verified in: <app>@<commit>` ([docs/05](../../docs/05-adoption-playbook.md),
5
5
  "Definition of done"). Versions before the first one below are described in their GitHub Releases (`core@x.y.z`).
6
6
 
7
+ ## 0.1.10
8
+
9
+ - `formatMoney` never puts a minus on zero: a negative zero, or an amount that rounds to zero under `rounded` or
10
+ `compact`, shows as `PLN 0.00` / `PLN 0` instead of `-PLN 0.00` (#375).
11
+
7
12
  ## 0.1.9
8
13
 
9
14
  - Day arithmetic on `YYYY-MM-DD` days with documented semantics: `isCalendarDay`, `addCalendarDays`,
package/README.md CHANGED
@@ -321,6 +321,7 @@ formatPercent(1250, "en"); // "12.5%" (basis points, at most two fraction digits
321
321
  A day is formatted at UTC midnight in UTC, so no zone moves it; the Polish long style names the month in
322
322
  the genitive. `formatMoney` takes the amount in the currency's minor unit, read from the pinned ISO 4217
323
323
  table `CURRENCY_MINOR_UNIT_DIGITS` (a code outside it gets `Intl`'s digits), and always groups thousands.
324
+ Zero never carries a sign: a negative zero (`Math.round(-0.4)`) or an amount that rounds to zero shows as `PLN 0.00`.
324
325
 
325
326
  ## 10. Hooks
326
327
 
package/dist/format.d.ts CHANGED
@@ -4,7 +4,7 @@ export type CalendarDayStyle = "long" | "medium" | "numeric";
4
4
  export interface FormatMoneyOptions {
5
5
  /** Whole units only, rounded half away from zero: PLN 1,235 for 1234.56. */
6
6
  readonly rounded?: boolean;
7
- /** A `+` before a positive amount (a `-` before a negative one is always there); zero has neither. */
7
+ /** A `+` before a positive amount (a `-` before a negative one is always there). Zero has neither in any mode, also a negative zero or an amount that rounds to zero. */
8
8
  readonly signed?: boolean;
9
9
  /** The locale's short notation for large amounts: PLN 1.2M. */
10
10
  readonly compact?: boolean;
@@ -13,7 +13,8 @@ export interface FormatMoneyOptions {
13
13
  export declare function formatCalendarDay(day: string, locale: Locale, style?: CalendarDayStyle): string;
14
14
  /**
15
15
  * An amount in the currency's minor unit (2900 PLN = PLN 29.00) in `locale`'s notation, thousands always
16
- * grouped (pl writes 1 234,56 where its default would leave four digits together). The minor unit is the pinned ISO
16
+ * grouped (pl writes 1 234,56 where its default would leave four digits together), and zero is never signed (`-0`
17
+ * and an amount that rounds to zero show as zero). The minor unit is the pinned ISO
17
18
  * 4217 one (`CURRENCY_MINOR_UNIT_DIGITS`); a code outside the table gets `Intl`'s digits. Throws a
18
19
  * `RangeError` for an amount that is not a whole number of minor units, or a code `Intl` refuses.
19
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,mIAAmI;AACnI,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,sGAAsG;IACtG,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAcD,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,gBAAyB,GAAG,MAAM,CASvG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,CAarH;AAED,0IAA0I;AAC1I,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIzE"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,mIAAmI;AACnI,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,yKAAyK;IACzK,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAcD,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,gBAAyB,GAAG,MAAM,CASvG;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,CAarH;AAED,0IAA0I;AAC1I,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIzE"}
package/dist/format.js CHANGED
@@ -25,7 +25,8 @@ export function formatCalendarDay(day, locale, style = "long") {
25
25
  }
26
26
  /**
27
27
  * An amount in the currency's minor unit (2900 PLN = PLN 29.00) in `locale`'s notation, thousands always
28
- * grouped (pl writes 1 234,56 where its default would leave four digits together). The minor unit is the pinned ISO
28
+ * grouped (pl writes 1 234,56 where its default would leave four digits together), and zero is never signed (`-0`
29
+ * and an amount that rounds to zero show as zero). The minor unit is the pinned ISO
29
30
  * 4217 one (`CURRENCY_MINOR_UNIT_DIGITS`); a code outside the table gets `Intl`'s digits. Throws a
30
31
  * `RangeError` for an amount that is not a whole number of minor units, or a code `Intl` refuses.
31
32
  */
@@ -39,7 +40,7 @@ export function formatMoney(minor, currency, locale, options = {}) {
39
40
  style: "currency",
40
41
  currency,
41
42
  useGrouping: "always",
42
- signDisplay: options.signed === true ? "exceptZero" : "auto",
43
+ signDisplay: options.signed === true ? "exceptZero" : "negative",
43
44
  ...(options.compact === true ? { notation: "compact" } : { minimumFractionDigits: shownDigits, maximumFractionDigits: shownDigits }),
44
45
  });
45
46
  return format.format(minor / 10 ** digits);
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softure-ai/core",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "The SOFTURE AI module contract: app config, module definitions, Result, Clock and messages.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/format.ts CHANGED
@@ -10,7 +10,7 @@ export type CalendarDayStyle = "long" | "medium" | "numeric";
10
10
  export interface FormatMoneyOptions {
11
11
  /** Whole units only, rounded half away from zero: PLN 1,235 for 1234.56. */
12
12
  readonly rounded?: boolean;
13
- /** A `+` before a positive amount (a `-` before a negative one is always there); zero has neither. */
13
+ /** A `+` before a positive amount (a `-` before a negative one is always there). Zero has neither in any mode, also a negative zero or an amount that rounds to zero. */
14
14
  readonly signed?: boolean;
15
15
  /** The locale's short notation for large amounts: PLN 1.2M. */
16
16
  readonly compact?: boolean;
@@ -42,7 +42,8 @@ export function formatCalendarDay(day: string, locale: Locale, style: CalendarDa
42
42
 
43
43
  /**
44
44
  * An amount in the currency's minor unit (2900 PLN = PLN 29.00) in `locale`'s notation, thousands always
45
- * grouped (pl writes 1 234,56 where its default would leave four digits together). The minor unit is the pinned ISO
45
+ * grouped (pl writes 1 234,56 where its default would leave four digits together), and zero is never signed (`-0`
46
+ * and an amount that rounds to zero show as zero). The minor unit is the pinned ISO
46
47
  * 4217 one (`CURRENCY_MINOR_UNIT_DIGITS`); a code outside the table gets `Intl`'s digits. Throws a
47
48
  * `RangeError` for an amount that is not a whole number of minor units, or a code `Intl` refuses.
48
49
  */
@@ -55,7 +56,7 @@ export function formatMoney(minor: number, currency: string, locale: Locale, opt
55
56
  style: "currency",
56
57
  currency,
57
58
  useGrouping: "always",
58
- signDisplay: options.signed === true ? "exceptZero" : "auto",
59
+ signDisplay: options.signed === true ? "exceptZero" : "negative",
59
60
  ...(options.compact === true ? { notation: "compact" } : { minimumFractionDigits: shownDigits, maximumFractionDigits: shownDigits }),
60
61
  });
61
62
  return format.format(minor / 10 ** digits);