@harbortouch/skytab-analytics-report-utils 0.6.2 → 0.7.1

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ import type { FieldType } from './types';
2
+ export type TimeFormat = '00:00' | '00:00:00' | '00:00-24H';
3
+ export interface LocaleOption {
4
+ currency: string;
5
+ locale: string;
6
+ }
7
+ export interface FormatDateOptions {
8
+ locale?: string;
9
+ timeZone?: string;
10
+ format?: TimeFormat;
11
+ }
12
+ export interface FormatTimeOptions {
13
+ locale?: string;
14
+ timeZone?: string;
15
+ format: TimeFormat;
16
+ }
17
+ export interface FormatMoneyOptions {
18
+ locale?: string;
19
+ currency?: string;
20
+ decimals?: number;
21
+ }
22
+ export declare const formatDate: (date: Date, options?: FormatDateOptions) => string;
23
+ export declare const formatTime: (date: Date | string | number, options: FormatTimeOptions) => string;
24
+ export declare const formatMoney: (amount: number, options?: FormatMoneyOptions) => string;
25
+ export declare const formatPercent: (value: number, decimals?: number) => string;
26
+ export declare const formatInteger: (value: number) => string;
27
+ export declare const formatFixedNumber: (value: number, decimals?: number) => string;
28
+ export declare const formatString: (value: unknown) => string;
29
+ export declare const getNumberToFormat: (value: unknown) => number;
30
+ export declare const getDateToFormat: (value?: unknown) => Date | null;
31
+ export declare const formatMoneyWithoutSymbol: (amount: number, options?: FormatMoneyOptions) => string;
32
+ export declare const getReportFormattingLocaleOptions: (locations: {
33
+ currency: string;
34
+ countryCode: string;
35
+ language: string;
36
+ }[]) => LocaleOption[];
37
+ export declare const formatFieldValue: (value: unknown, type: FieldType, localeOptions: LocaleOption) => string;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.cjs CHANGED
@@ -59,10 +59,22 @@ __export(index_exports, {
59
59
  dailySalesTaxesConfig: () => dailySalesTaxesConfig,
60
60
  dailySalesTrendsConfig: () => dailySalesTrendsConfig,
61
61
  employeeTimecardConfig: () => employeeTimecardConfig,
62
+ formatDate: () => formatDate,
63
+ formatFieldValue: () => formatFieldValue,
64
+ formatFixedNumber: () => formatFixedNumber,
65
+ formatInteger: () => formatInteger,
66
+ formatMoney: () => formatMoney,
67
+ formatMoneyWithoutSymbol: () => formatMoneyWithoutSymbol,
68
+ formatPercent: () => formatPercent,
69
+ formatString: () => formatString,
70
+ formatTime: () => formatTime,
62
71
  getColumnAlignment: () => getColumnAlignment,
63
72
  getColumnExportHeaderLabel: () => getColumnExportHeaderLabel,
64
73
  getColumnMetadata: () => getColumnMetadata,
74
+ getDateToFormat: () => getDateToFormat,
75
+ getNumberToFormat: () => getNumberToFormat,
65
76
  getReportConfig: () => getReportConfig,
77
+ getReportFormattingLocaleOptions: () => getReportFormattingLocaleOptions,
66
78
  isNumericType: () => isNumericType,
67
79
  itemTaxConfig: () => itemTaxConfig,
68
80
  modifierMixConfig: () => modifierMixConfig,
@@ -1587,6 +1599,112 @@ var dailySalesTaxesConfig = {
1587
1599
  availableColumns: DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1588
1600
  defaultVisibleColumns: DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS
1589
1601
  };
1602
+
1603
+ // src/formatting.ts
1604
+ var formatDate = (date, options = {}) => {
1605
+ const { locale = "en-US", timeZone = "UTC" } = options;
1606
+ const d = new Date(date);
1607
+ return new Intl.DateTimeFormat(locale, {
1608
+ dateStyle: "short",
1609
+ timeZone
1610
+ }).format(d);
1611
+ };
1612
+ var formatTime = (date, options) => {
1613
+ const { locale = "en-US", timeZone = "UTC", format } = options;
1614
+ const d = new Date(date);
1615
+ if (format === "00:00") {
1616
+ return new Intl.DateTimeFormat(locale, {
1617
+ hour: "2-digit",
1618
+ minute: "2-digit",
1619
+ timeZone
1620
+ }).format(d);
1621
+ }
1622
+ if (format === "00:00-24H") {
1623
+ return new Intl.DateTimeFormat(locale, {
1624
+ hour: "2-digit",
1625
+ minute: "2-digit",
1626
+ hour12: false,
1627
+ hourCycle: "h23",
1628
+ timeZone
1629
+ }).format(d);
1630
+ }
1631
+ return new Intl.DateTimeFormat(locale, {
1632
+ hour: "2-digit",
1633
+ minute: "2-digit",
1634
+ second: "2-digit",
1635
+ timeZone
1636
+ }).format(d);
1637
+ };
1638
+ var formatMoney = (amount, options = {}) => {
1639
+ const { locale = "en-US", currency = "USD", decimals = 2 } = options;
1640
+ return new Intl.NumberFormat(locale, {
1641
+ style: "currency",
1642
+ currency,
1643
+ minimumFractionDigits: decimals,
1644
+ maximumFractionDigits: decimals
1645
+ }).format(amount);
1646
+ };
1647
+ var formatPercent = (value, decimals = 2) => `${value.toFixed(decimals)}%`;
1648
+ var formatInteger = (value) => Math.round(value).toString();
1649
+ var formatFixedNumber = (value, decimals = 2) => value.toFixed(decimals);
1650
+ var formatString = (value) => {
1651
+ return value == null ? "" : typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : "";
1652
+ };
1653
+ var getNumberToFormat = (value) => typeof value === "number" ? value : 0;
1654
+ var getDateToFormat = (value) => {
1655
+ if (value instanceof Date) {
1656
+ return isNaN(value.getTime()) ? null : value;
1657
+ }
1658
+ if (typeof value === "string" || typeof value === "number") {
1659
+ const d = new Date(value);
1660
+ return isNaN(d.getTime()) ? null : d;
1661
+ }
1662
+ return null;
1663
+ };
1664
+ var formatMoneyWithoutSymbol = (amount, options = {}) => {
1665
+ const { locale = "en-US", decimals = 2 } = options;
1666
+ return new Intl.NumberFormat(locale, {
1667
+ minimumFractionDigits: decimals,
1668
+ maximumFractionDigits: decimals
1669
+ }).format(amount);
1670
+ };
1671
+ var getReportFormattingLocaleOptions = (locations) => {
1672
+ if (locations.length === 0) {
1673
+ return [{ currency: "USD", locale: "en-US" }];
1674
+ }
1675
+ return Array.from(
1676
+ new Map(
1677
+ locations.map((loc) => ({
1678
+ currency: loc.currency,
1679
+ locale: `${loc.language ?? "en"}-${loc.countryCode}`
1680
+ })).map((item) => [`${item.currency}-${item.locale}`, item])
1681
+ ).values()
1682
+ );
1683
+ };
1684
+ var formatFieldValue = (value, type, localeOptions) => {
1685
+ const { currency, locale } = localeOptions;
1686
+ switch (type) {
1687
+ case "string":
1688
+ return formatString(value);
1689
+ case "money":
1690
+ return formatMoney(getNumberToFormat(value), { currency, locale });
1691
+ case "percent":
1692
+ return formatPercent(getNumberToFormat(value) * 100);
1693
+ case "fixedNumber":
1694
+ return formatFixedNumber(getNumberToFormat(value));
1695
+ case "date": {
1696
+ const d = getDateToFormat(value);
1697
+ return d ? formatDate(d, { locale }) : "";
1698
+ }
1699
+ case "time": {
1700
+ const d = getDateToFormat(value);
1701
+ return d ? formatTime(d, { locale, format: "00:00:00" }) : "";
1702
+ }
1703
+ case "number":
1704
+ default:
1705
+ return String(getNumberToFormat(value));
1706
+ }
1707
+ };
1590
1708
  // Annotate the CommonJS export names for ESM import in node:
1591
1709
  0 && (module.exports = {
1592
1710
  COLUMN_REGISTRY,
@@ -1628,10 +1746,22 @@ var dailySalesTaxesConfig = {
1628
1746
  dailySalesTaxesConfig,
1629
1747
  dailySalesTrendsConfig,
1630
1748
  employeeTimecardConfig,
1749
+ formatDate,
1750
+ formatFieldValue,
1751
+ formatFixedNumber,
1752
+ formatInteger,
1753
+ formatMoney,
1754
+ formatMoneyWithoutSymbol,
1755
+ formatPercent,
1756
+ formatString,
1757
+ formatTime,
1631
1758
  getColumnAlignment,
1632
1759
  getColumnExportHeaderLabel,
1633
1760
  getColumnMetadata,
1761
+ getDateToFormat,
1762
+ getNumberToFormat,
1634
1763
  getReportConfig,
1764
+ getReportFormattingLocaleOptions,
1635
1765
  isNumericType,
1636
1766
  itemTaxConfig,
1637
1767
  modifierMixConfig,
package/dist/index.d.ts CHANGED
@@ -17,3 +17,5 @@ export { dailySalesRefundsVoidsConfig, DAILY_SALES_REFUNDS_VOIDS_AVAILABLE_COLUM
17
17
  export { dailySalesTaxesConfig, DAILY_SALES_TAXES_AVAILABLE_COLUMNS, DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS, } from './reports/dailySalesTaxes';
18
18
  export { employeeTimecardConfig, EMPLOYEE_TIMECARD_AVAILABLE_COLUMNS, EMPLOYEE_TIMECARD_DEFAULT_VISIBLE_COLUMNS, } from './reports/employeeTimecard';
19
19
  export { salesByItemDetailConfig, SALES_BY_ITEM_DETAIL_AVAILABLE_COLUMNS, SALES_BY_ITEM_DETAIL_DEFAULT_VISIBLE_COLUMNS, } from './reports/salesByItemDetail';
20
+ export type { FormatDateOptions, FormatTimeOptions, FormatMoneyOptions, LocaleOption, TimeFormat } from './formatting';
21
+ export { formatDate, formatTime, formatMoney, formatPercent, formatInteger, formatFixedNumber, formatString, getNumberToFormat, getDateToFormat, getReportFormattingLocaleOptions, formatMoneyWithoutSymbol, formatFieldValue, } from './formatting';
package/dist/index.js CHANGED
@@ -1511,6 +1511,112 @@ var dailySalesTaxesConfig = {
1511
1511
  availableColumns: DAILY_SALES_TAXES_AVAILABLE_COLUMNS,
1512
1512
  defaultVisibleColumns: DAILY_SALES_TAXES_DEFAULT_VISIBLE_COLUMNS
1513
1513
  };
1514
+
1515
+ // src/formatting.ts
1516
+ var formatDate = (date, options = {}) => {
1517
+ const { locale = "en-US", timeZone = "UTC" } = options;
1518
+ const d = new Date(date);
1519
+ return new Intl.DateTimeFormat(locale, {
1520
+ dateStyle: "short",
1521
+ timeZone
1522
+ }).format(d);
1523
+ };
1524
+ var formatTime = (date, options) => {
1525
+ const { locale = "en-US", timeZone = "UTC", format } = options;
1526
+ const d = new Date(date);
1527
+ if (format === "00:00") {
1528
+ return new Intl.DateTimeFormat(locale, {
1529
+ hour: "2-digit",
1530
+ minute: "2-digit",
1531
+ timeZone
1532
+ }).format(d);
1533
+ }
1534
+ if (format === "00:00-24H") {
1535
+ return new Intl.DateTimeFormat(locale, {
1536
+ hour: "2-digit",
1537
+ minute: "2-digit",
1538
+ hour12: false,
1539
+ hourCycle: "h23",
1540
+ timeZone
1541
+ }).format(d);
1542
+ }
1543
+ return new Intl.DateTimeFormat(locale, {
1544
+ hour: "2-digit",
1545
+ minute: "2-digit",
1546
+ second: "2-digit",
1547
+ timeZone
1548
+ }).format(d);
1549
+ };
1550
+ var formatMoney = (amount, options = {}) => {
1551
+ const { locale = "en-US", currency = "USD", decimals = 2 } = options;
1552
+ return new Intl.NumberFormat(locale, {
1553
+ style: "currency",
1554
+ currency,
1555
+ minimumFractionDigits: decimals,
1556
+ maximumFractionDigits: decimals
1557
+ }).format(amount);
1558
+ };
1559
+ var formatPercent = (value, decimals = 2) => `${value.toFixed(decimals)}%`;
1560
+ var formatInteger = (value) => Math.round(value).toString();
1561
+ var formatFixedNumber = (value, decimals = 2) => value.toFixed(decimals);
1562
+ var formatString = (value) => {
1563
+ return value == null ? "" : typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : "";
1564
+ };
1565
+ var getNumberToFormat = (value) => typeof value === "number" ? value : 0;
1566
+ var getDateToFormat = (value) => {
1567
+ if (value instanceof Date) {
1568
+ return isNaN(value.getTime()) ? null : value;
1569
+ }
1570
+ if (typeof value === "string" || typeof value === "number") {
1571
+ const d = new Date(value);
1572
+ return isNaN(d.getTime()) ? null : d;
1573
+ }
1574
+ return null;
1575
+ };
1576
+ var formatMoneyWithoutSymbol = (amount, options = {}) => {
1577
+ const { locale = "en-US", decimals = 2 } = options;
1578
+ return new Intl.NumberFormat(locale, {
1579
+ minimumFractionDigits: decimals,
1580
+ maximumFractionDigits: decimals
1581
+ }).format(amount);
1582
+ };
1583
+ var getReportFormattingLocaleOptions = (locations) => {
1584
+ if (locations.length === 0) {
1585
+ return [{ currency: "USD", locale: "en-US" }];
1586
+ }
1587
+ return Array.from(
1588
+ new Map(
1589
+ locations.map((loc) => ({
1590
+ currency: loc.currency,
1591
+ locale: `${loc.language ?? "en"}-${loc.countryCode}`
1592
+ })).map((item) => [`${item.currency}-${item.locale}`, item])
1593
+ ).values()
1594
+ );
1595
+ };
1596
+ var formatFieldValue = (value, type, localeOptions) => {
1597
+ const { currency, locale } = localeOptions;
1598
+ switch (type) {
1599
+ case "string":
1600
+ return formatString(value);
1601
+ case "money":
1602
+ return formatMoney(getNumberToFormat(value), { currency, locale });
1603
+ case "percent":
1604
+ return formatPercent(getNumberToFormat(value) * 100);
1605
+ case "fixedNumber":
1606
+ return formatFixedNumber(getNumberToFormat(value));
1607
+ case "date": {
1608
+ const d = getDateToFormat(value);
1609
+ return d ? formatDate(d, { locale }) : "";
1610
+ }
1611
+ case "time": {
1612
+ const d = getDateToFormat(value);
1613
+ return d ? formatTime(d, { locale, format: "00:00:00" }) : "";
1614
+ }
1615
+ case "number":
1616
+ default:
1617
+ return String(getNumberToFormat(value));
1618
+ }
1619
+ };
1514
1620
  export {
1515
1621
  COLUMN_REGISTRY,
1516
1622
  DAILY_SALES_AVAILABLE_COLUMNS,
@@ -1551,10 +1657,22 @@ export {
1551
1657
  dailySalesTaxesConfig,
1552
1658
  dailySalesTrendsConfig,
1553
1659
  employeeTimecardConfig,
1660
+ formatDate,
1661
+ formatFieldValue,
1662
+ formatFixedNumber,
1663
+ formatInteger,
1664
+ formatMoney,
1665
+ formatMoneyWithoutSymbol,
1666
+ formatPercent,
1667
+ formatString,
1668
+ formatTime,
1554
1669
  getColumnAlignment,
1555
1670
  getColumnExportHeaderLabel,
1556
1671
  getColumnMetadata,
1672
+ getDateToFormat,
1673
+ getNumberToFormat,
1557
1674
  getReportConfig,
1675
+ getReportFormattingLocaleOptions,
1558
1676
  isNumericType,
1559
1677
  itemTaxConfig,
1560
1678
  modifierMixConfig,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harbortouch/skytab-analytics-report-utils",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "description": "Centralized report column presentation configuration for SkyTab Analytics",
5
5
  "engines": {
6
6
  "node": ">=22.6.0",
@@ -26,6 +26,7 @@
26
26
  "lint:js": "eslint src",
27
27
  "lint:js:fix": "eslint src --fix",
28
28
  "lint:types": "tsc --noEmit",
29
+ "test": "vitest run",
29
30
  "typecheck": "tsc --noEmit",
30
31
  "prepare": "husky"
31
32
  },
@@ -41,7 +42,8 @@
41
42
  "pretty-quick": "^4.2.2",
42
43
  "tsup": "^8.0.0",
43
44
  "typescript": "^5.9.3",
44
- "typescript-eslint": "^8.53.1"
45
+ "typescript-eslint": "^8.53.1",
46
+ "vitest": "^4.1.5"
45
47
  },
46
48
  "packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
47
49
  }