@final-commerce/common 2.1.0 → 2.2.0-beta.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.
package/dist/index.mjs CHANGED
@@ -228,6 +228,7 @@ var InventorySpecificActionType = /* @__PURE__ */ ((InventorySpecificActionType2
228
228
  InventorySpecificActionType2["REFUND_RESTOCK_RETURN"] = "REFUND_RESTOCK_RETURN";
229
229
  InventorySpecificActionType2["REFUND_DAMAGE"] = "REFUND_DAMAGE";
230
230
  InventorySpecificActionType2["SALE"] = "SALE";
231
+ InventorySpecificActionType2["COMPOSED_FOR_SALE"] = "COMPOSED_FOR_SALE";
231
232
  InventorySpecificActionType2["TRANSFER"] = "TRANSFER";
232
233
  InventorySpecificActionType2["BULK_RECOUNT"] = "BULK_RECOUNT";
233
234
  InventorySpecificActionType2["APPLIED_FROM_WOO"] = "APPLIED_FROM_WOO";
@@ -717,6 +718,252 @@ function amountToString(amount) {
717
718
  return majorValue.toFixed(amount.minorUnits);
718
719
  }
719
720
 
721
+ // units/system-units.ts
722
+ var SYSTEM_FAMILY_IDS = {
723
+ COUNT: "count",
724
+ WEIGHT: "weight-metric",
725
+ WEIGHT_IMPERIAL: "weight-imperial",
726
+ VOLUME: "volume-metric",
727
+ VOLUME_IMPERIAL: "volume-imperial",
728
+ LENGTH: "length-metric",
729
+ LENGTH_IMPERIAL: "length-imperial",
730
+ AREA: "area-metric",
731
+ AREA_IMPERIAL: "area-imperial"
732
+ };
733
+ var SYSTEM_UNIT_IDS = {
734
+ EACH: "EA",
735
+ GRAM: "GRM",
736
+ KILOGRAM: "KGM",
737
+ /** 100 g is a hectogram; the merchant-facing name stays "100 g". */
738
+ HECTOGRAM: "HGM",
739
+ MILLILITRE: "MLT",
740
+ LITRE: "LTR"
741
+ };
742
+ var SYSTEM_FAMILIES = [
743
+ {
744
+ familyId: SYSTEM_FAMILY_IDS.COUNT,
745
+ companyId: null,
746
+ name: "Count",
747
+ base: { name: "Piece", abbreviation: "ea", ratioToBase: 1, precision: 0 }
748
+ },
749
+ {
750
+ familyId: SYSTEM_FAMILY_IDS.WEIGHT,
751
+ companyId: null,
752
+ name: "Weight",
753
+ base: { name: "Gram", abbreviation: "g", ratioToBase: 1, precision: 0 }
754
+ },
755
+ {
756
+ familyId: SYSTEM_FAMILY_IDS.WEIGHT_IMPERIAL,
757
+ companyId: null,
758
+ name: "Weight (imperial)",
759
+ base: { name: "Hundred-thousandth of an ounce", abbreviation: "10\u207B\u2075 oz", ratioToBase: 1, precision: 0 }
760
+ },
761
+ {
762
+ familyId: SYSTEM_FAMILY_IDS.VOLUME,
763
+ companyId: null,
764
+ name: "Volume",
765
+ base: { name: "Millilitre", abbreviation: "ml", ratioToBase: 1, precision: 0 }
766
+ },
767
+ {
768
+ // Cubic inches, not fluid ounces: a US gallon is 231 in³ and 128 fl oz, and 231 = 3 × 7 × 11.
769
+ // With an ounce base the board foot lands on 6144000/77 — and lumber is the reason this family
770
+ // exists at all.
771
+ familyId: SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL,
772
+ companyId: null,
773
+ name: "Volume (imperial)",
774
+ base: { name: "1/128000 cubic inch", abbreviation: "\xB5in\xB3", ratioToBase: 1, precision: 0 }
775
+ },
776
+ {
777
+ familyId: SYSTEM_FAMILY_IDS.LENGTH,
778
+ companyId: null,
779
+ name: "Length",
780
+ base: { name: "Millimetre", abbreviation: "mm", ratioToBase: 1, precision: 0 }
781
+ },
782
+ {
783
+ familyId: SYSTEM_FAMILY_IDS.LENGTH_IMPERIAL,
784
+ companyId: null,
785
+ name: "Length (imperial)",
786
+ base: { name: "Millionth of an inch", abbreviation: "\xB5in", ratioToBase: 1, precision: 0 }
787
+ },
788
+ {
789
+ familyId: SYSTEM_FAMILY_IDS.AREA,
790
+ companyId: null,
791
+ name: "Area",
792
+ base: { name: "Square millimetre", abbreviation: "mm\xB2", ratioToBase: 1, precision: 0 }
793
+ },
794
+ {
795
+ familyId: SYSTEM_FAMILY_IDS.AREA_IMPERIAL,
796
+ companyId: null,
797
+ name: "Area (imperial)",
798
+ base: { name: "Thousandth of a square inch", abbreviation: "m-sq in", ratioToBase: 1, precision: 0 }
799
+ }
800
+ ];
801
+ var unit = (unitId, familyId, name, abbreviation, ratioToBase, precision) => ({ unitId, companyId: null, familyId, name, abbreviation, ratioToBase, precision });
802
+ var SELLABLE_UNITS = [
803
+ // ── Count ────────────────────────────────────────────────────────────────
804
+ unit("EA", SYSTEM_FAMILY_IDS.COUNT, "Each", "ea", 1, 0),
805
+ unit("PR", SYSTEM_FAMILY_IDS.COUNT, "Pair", "pr", 2, 0),
806
+ unit("DZN", SYSTEM_FAMILY_IDS.COUNT, "Dozen", "dz", 12, 0),
807
+ unit("GRO", SYSTEM_FAMILY_IDS.COUNT, "Gross", "gro", 144, 0),
808
+ unit("CEN", SYSTEM_FAMILY_IDS.COUNT, "Hundred", "C", 100, 0),
809
+ unit("MIL", SYSTEM_FAMILY_IDS.COUNT, "Thousand", "M", 1e3, 0),
810
+ // ── Weight, metric ───────────────────────────────────────────────────────
811
+ unit("GRM", SYSTEM_FAMILY_IDS.WEIGHT, "Gram", "g", 1, 0),
812
+ unit("HGM", SYSTEM_FAMILY_IDS.WEIGHT, "100 g", "100g", 100, 2),
813
+ unit("KGM", SYSTEM_FAMILY_IDS.WEIGHT, "Kilogram", "kg", 1e3, 3),
814
+ unit("TNE", SYSTEM_FAMILY_IDS.WEIGHT, "Tonne", "t", 1e6, 3),
815
+ // ── Weight, imperial ─────────────────────────────────────────────────────
816
+ unit("ONZ", SYSTEM_FAMILY_IDS.WEIGHT_IMPERIAL, "Ounce", "oz", 1e5, 2),
817
+ unit("LBR", SYSTEM_FAMILY_IDS.WEIGHT_IMPERIAL, "Pound", "lb", 16e5, 2),
818
+ unit("STI", SYSTEM_FAMILY_IDS.WEIGHT_IMPERIAL, "Stone", "st", 224e5, 2),
819
+ // `(US)` is not decoration: Rec 20 also carries `CWI`, the UK hundredweight, at 112 lb — 12 % more.
820
+ // The code here is the right one; an unqualified "cwt" on screen is what would be ambiguous.
821
+ unit("CWA", SYSTEM_FAMILY_IDS.WEIGHT_IMPERIAL, "Hundredweight (US)", "cwt (US)", 16e7, 2),
822
+ unit("STN", SYSTEM_FAMILY_IDS.WEIGHT_IMPERIAL, "Ton (short)", "tn", 32e8, 3),
823
+ // ── Volume, metric ───────────────────────────────────────────────────────
824
+ unit("MLT", SYSTEM_FAMILY_IDS.VOLUME, "Millilitre", "ml", 1, 0),
825
+ unit("CLT", SYSTEM_FAMILY_IDS.VOLUME, "Centilitre", "cl", 10, 1),
826
+ unit("LTR", SYSTEM_FAMILY_IDS.VOLUME, "Litre", "l", 1e3, 3),
827
+ unit("HLT", SYSTEM_FAMILY_IDS.VOLUME, "Hectolitre", "hl", 1e5, 3),
828
+ unit("MTQ", SYSTEM_FAMILY_IDS.VOLUME, "Cubic metre", "m\xB3", 1e6, 3),
829
+ // ── Volume, imperial ─────────────────────────────────────────────────────
830
+ unit("OZA", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Fluid ounce", "fl oz", 231e3, 2),
831
+ unit("PTL", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Pint", "pt", 3696e3, 2),
832
+ unit("QTL", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Quart", "qt", 7392e3, 2),
833
+ unit("GLL", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Gallon", "gal", 29568e3, 3),
834
+ unit("INQ", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Cubic inch", "in\xB3", 128e3, 2),
835
+ unit("BFT", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Board foot", "fbm", 18432e3, 2),
836
+ unit("FTQ", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Cubic foot", "ft\xB3", 221184e3, 3),
837
+ unit("YDQ", SYSTEM_FAMILY_IDS.VOLUME_IMPERIAL, "Cubic yard", "yd\xB3", 5971968e3, 3),
838
+ // ── Length, metric ───────────────────────────────────────────────────────
839
+ unit("MMT", SYSTEM_FAMILY_IDS.LENGTH, "Millimetre", "mm", 1, 0),
840
+ unit("CMT", SYSTEM_FAMILY_IDS.LENGTH, "Centimetre", "cm", 10, 1),
841
+ unit("MTR", SYSTEM_FAMILY_IDS.LENGTH, "Metre", "m", 1e3, 3),
842
+ unit("KMT", SYSTEM_FAMILY_IDS.LENGTH, "Kilometre", "km", 1e6, 3),
843
+ // ── Length, imperial ─────────────────────────────────────────────────────
844
+ // `INH` carries four decimals, not three: an eighth of an inch is 0.125 but a sixteenth is
845
+ // 0.0625, and sixteenths are the everyday fraction on a tape measure. A thirty-second needs five,
846
+ // which is the ceiling; a sixty-fourth has no decimal form at all and is a question about
847
+ // fraction input, not about precision.
848
+ unit("INH", SYSTEM_FAMILY_IDS.LENGTH_IMPERIAL, "Inch", "in", 1e6, 4),
849
+ unit("FOT", SYSTEM_FAMILY_IDS.LENGTH_IMPERIAL, "Foot", "ft", 12e6, 3),
850
+ unit("LF", SYSTEM_FAMILY_IDS.LENGTH_IMPERIAL, "Linear foot", "lin ft", 12e6, 2),
851
+ unit("YRD", SYSTEM_FAMILY_IDS.LENGTH_IMPERIAL, "Yard", "yd", 36e6, 3),
852
+ unit("SMI", SYSTEM_FAMILY_IDS.LENGTH_IMPERIAL, "Mile", "mi", 6336e7, 3),
853
+ // ── Area, metric ─────────────────────────────────────────────────────────
854
+ unit("MMK", SYSTEM_FAMILY_IDS.AREA, "Square millimetre", "mm\xB2", 1, 0),
855
+ unit("CMK", SYSTEM_FAMILY_IDS.AREA, "Square centimetre", "cm\xB2", 100, 2),
856
+ unit("MTK", SYSTEM_FAMILY_IDS.AREA, "Square metre", "m\xB2", 1e6, 3),
857
+ unit("HAR", SYSTEM_FAMILY_IDS.AREA, "Hectare", "ha", 1e10, 3),
858
+ // ── Area, imperial ───────────────────────────────────────────────────────
859
+ unit("INK", SYSTEM_FAMILY_IDS.AREA_IMPERIAL, "Square inch", "sq in", 1e3, 2),
860
+ unit("FTK", SYSTEM_FAMILY_IDS.AREA_IMPERIAL, "Square foot", "sq ft", 144e3, 2),
861
+ unit("YDK", SYSTEM_FAMILY_IDS.AREA_IMPERIAL, "Square yard", "sq yd", 1296e3, 2),
862
+ // A roofing square is exactly 100 square feet — a trade unit with a precise definition, which is
863
+ // why it is a real row and not a label.
864
+ unit("SQR", SYSTEM_FAMILY_IDS.AREA_IMPERIAL, "Square (roofing)", "sq", 144e5, 2),
865
+ unit("ACR", SYSTEM_FAMILY_IDS.AREA_IMPERIAL, "Acre", "ac", 627264e4, 2)
866
+ ];
867
+ var BASE_UNITS = SYSTEM_FAMILIES.filter(
868
+ (family) => !SELLABLE_UNITS.some((u) => u.familyId === family.familyId && u.ratioToBase === 1)
869
+ ).map((family) => ({
870
+ unitId: `${family.familyId}-base`,
871
+ companyId: null,
872
+ familyId: family.familyId,
873
+ name: family.base.name,
874
+ abbreviation: family.base.abbreviation,
875
+ ratioToBase: 1,
876
+ precision: 0,
877
+ sellable: false
878
+ }));
879
+ var SYSTEM_UNITS = [...SELLABLE_UNITS, ...BASE_UNITS];
880
+ var DEFAULT_UNIT_ID = SYSTEM_UNIT_IDS.EACH;
881
+
882
+ // units/convert.ts
883
+ var EPSILON = 1e-9;
884
+ function isWhole(value) {
885
+ return Math.abs(value - Math.round(value)) <= EPSILON * Math.max(1, Math.abs(value));
886
+ }
887
+ var MAX_PRECISION = 5;
888
+ function resolveUnit(unitId, companyUnits = []) {
889
+ const unit2 = SYSTEM_UNITS.find((u) => u.unitId === unitId) ?? companyUnits.find((u) => u.unitId === unitId);
890
+ if (!unit2) throw new Error(`Unknown measurement unit: ${unitId}`);
891
+ return unit2;
892
+ }
893
+ function resolveFamily(familyId, companyFamilies = []) {
894
+ const family = SYSTEM_FAMILIES.find((f) => f.familyId === familyId) ?? companyFamilies.find((f) => f.familyId === familyId);
895
+ if (!family) throw new Error(`Unknown measurement unit family: ${familyId}`);
896
+ return family;
897
+ }
898
+ function baseOf(familyId, companyFamilies = []) {
899
+ return resolveFamily(familyId, companyFamilies).base;
900
+ }
901
+ function baseFor(unit2, companyFamilies = []) {
902
+ return baseOf(unit2.familyId, companyFamilies);
903
+ }
904
+ function sameFamily(a, b) {
905
+ return a.familyId === b.familyId;
906
+ }
907
+ function assertUnitSane(unit2) {
908
+ const { ratioToBase, precision, name } = unit2;
909
+ if (!Number.isInteger(ratioToBase) || ratioToBase < 1)
910
+ throw new Error(`Unit "${name}": ratioToBase must be a positive integer, got ${ratioToBase}`);
911
+ if (!Number.isInteger(precision) || precision < 0 || precision > MAX_PRECISION)
912
+ throw new Error(`Unit "${name}": precision must be an integer 0\u2013${MAX_PRECISION}, got ${precision}`);
913
+ if (ratioToBase % 10 ** precision !== 0)
914
+ throw new Error(
915
+ `Unit "${name}": precision ${precision} is finer than a ratio of ${ratioToBase} allows \u2014 at most ${maxPrecisionFor(ratioToBase)}. For anything finer the family needs a smaller base unit.`
916
+ );
917
+ }
918
+ function maxPrecisionFor(ratioToBase) {
919
+ if (!Number.isInteger(ratioToBase) || ratioToBase < 1)
920
+ throw new Error(`ratioToBase must be a positive integer, got ${ratioToBase}`);
921
+ let precision = 0;
922
+ while (precision < MAX_PRECISION && ratioToBase % 10 ** (precision + 1) === 0) precision++;
923
+ return precision;
924
+ }
925
+ function isValidQuantity(quantity, unit2) {
926
+ if (!Number.isFinite(quantity) || quantity < 0) return false;
927
+ return isWhole(quantity * 10 ** unit2.precision);
928
+ }
929
+ function toBase(quantity, unit2) {
930
+ const exact = quantity * unit2.ratioToBase;
931
+ const whole = Math.round(exact);
932
+ if (!isWhole(exact))
933
+ throw new Error(
934
+ `${quantity} ${unit2.abbreviation} is ${exact} base units \u2014 not whole. Check the quantity against precision ${unit2.precision}.`
935
+ );
936
+ return whole;
937
+ }
938
+ function fromBase(baseQuantity, unit2) {
939
+ return baseQuantity / unit2.ratioToBase;
940
+ }
941
+ function availableIn(baseQuantity, unit2) {
942
+ const step = unit2.ratioToBase / 10 ** unit2.precision;
943
+ return Math.floor(baseQuantity / step) / 10 ** unit2.precision;
944
+ }
945
+ function formatQuantity(baseQuantity, unit2) {
946
+ return fromBase(baseQuantity, unit2).toFixed(unit2.precision);
947
+ }
948
+ function formatInUnit(quantity, unit2) {
949
+ return quantity.toFixed(unit2.precision);
950
+ }
951
+ function roundToPrecision(quantity, precision) {
952
+ const scale = 10 ** precision;
953
+ return Math.round(quantity * scale) / scale;
954
+ }
955
+ function extendPrice(priceMinor, quantity) {
956
+ const scale = 10 ** MAX_PRECISION;
957
+ const scaled = BigInt(Math.round(priceMinor)) * BigInt(Math.round(quantity * scale));
958
+ const divisor = BigInt(scale);
959
+ return Number((scaled + divisor / 2n) / divisor);
960
+ }
961
+ function extendPriceFor(priceMinor, quantity, unit2) {
962
+ if (!isValidQuantity(quantity, unit2))
963
+ throw new Error(`${quantity} ${unit2.abbreviation} has more decimals than precision ${unit2.precision} allows.`);
964
+ return extendPrice(priceMinor, quantity);
965
+ }
966
+
720
967
  // utils/order-totals.util.ts
721
968
  function toMinorUnits2(value) {
722
969
  return Number(value) || 0;
@@ -734,7 +981,7 @@ function getSettlementTotal(payments, tipTotal) {
734
981
  return toMinorUnits2(payments?.cardTotal) + toMinorUnits2(payments?.cashTotal) + toMinorUnits2(payments?.customTotal) + toMinorUnits2(tipTotal);
735
982
  }
736
983
  function getLineSubtotal(price, quantity) {
737
- return toMinorUnits2(price) * toMinorUnits2(quantity);
984
+ return extendPrice(toMinorUnits2(price), toMinorUnits2(quantity));
738
985
  }
739
986
  function getGoodsPortion(total, totalTax) {
740
987
  return toMinorUnits2(total) - toMinorUnits2(totalTax);
@@ -1058,6 +1305,31 @@ function normalizeMongoIdString(value) {
1058
1305
  return null;
1059
1306
  }
1060
1307
 
1308
+ // units/family-code.ts
1309
+ var MAX_SLUG_LENGTH = 32;
1310
+ var FALLBACK_SLUG = "family";
1311
+ var SYSTEM_FAMILY_CODES = new Set(SYSTEM_FAMILIES.map((family) => family.familyId));
1312
+ function slugify(name) {
1313
+ const slug = name.normalize("NFKD").replace(/\p{Diacritic}/gu, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, MAX_SLUG_LENGTH).replace(/^-+|-+$/g, "");
1314
+ return slug || FALLBACK_SLUG;
1315
+ }
1316
+ function deriveFamilyCode(name, companyId, takenCodes = []) {
1317
+ if (!companyId) throw new Error(`Cannot derive a family code for "${name}" without a companyId.`);
1318
+ const taken = new Set(takenCodes);
1319
+ const slug = slugify(name);
1320
+ for (let attempt = 1; ; attempt++) {
1321
+ const code = attempt === 1 ? `${slug}-${companyId}` : `${slug}-${attempt}-${companyId}`;
1322
+ if (!taken.has(code) && !isSystemFamilyCode(code)) return code;
1323
+ }
1324
+ }
1325
+ function isSystemFamilyCode(code) {
1326
+ return SYSTEM_FAMILY_CODES.has(code);
1327
+ }
1328
+ function deriveUnitId(abbreviation, documentId) {
1329
+ if (!documentId) throw new Error(`Cannot derive a unit id for "${abbreviation}" without a document id.`);
1330
+ return `${slugify(abbreviation)}-${documentId}`;
1331
+ }
1332
+
1061
1333
  // order-state-machine/types.ts
1062
1334
  var PAYMENT_STATES = [
1063
1335
  "unpaid",
@@ -2453,6 +2725,27 @@ var ORDER_STATE_EVENTS = {
2453
2725
  stateTransitionBlocked: "state-transition-blocked",
2454
2726
  configUpdated: "config-updated"
2455
2727
  };
2728
+
2729
+ // order-state-machine/write-strategy.ts
2730
+ var LegacyWriteStrategy = class {
2731
+ applyState(_order) {
2732
+ }
2733
+ };
2734
+ var DualWriteStrategy = class {
2735
+ constructor(config) {
2736
+ this.config = config;
2737
+ }
2738
+ applyState(order) {
2739
+ if (order.paymentState && order.fulfillmentState) {
2740
+ setOrderState(order, order.paymentState, order.fulfillmentState, this.config);
2741
+ return;
2742
+ }
2743
+ if (order.status) {
2744
+ const inferred = inferStatesFromLegacyStatus(order);
2745
+ setOrderState(order, inferred.payment, inferred.fulfillment, this.config);
2746
+ }
2747
+ }
2748
+ };
2456
2749
  export {
2457
2750
  AttributeType,
2458
2751
  CONDITION_OPERATORS,
@@ -2466,6 +2759,8 @@ export {
2466
2759
  DEFAULT_CROSS_AXIS_RULES,
2467
2760
  DEFAULT_DISPLAY_STATE_MAP,
2468
2761
  DEFAULT_RESOLVED_CONFIG,
2762
+ DEFAULT_UNIT_ID,
2763
+ DualWriteStrategy,
2469
2764
  EUFixedRates,
2470
2765
  EUROPE,
2471
2766
  ExtensionCategory,
@@ -2475,7 +2770,9 @@ export {
2475
2770
  InventoryBaseActionEnum,
2476
2771
  InventorySpecificActionType,
2477
2772
  InvoiceStatus,
2773
+ LegacyWriteStrategy,
2478
2774
  LibraryItemType,
2775
+ MAX_PRECISION,
2479
2776
  MenuProject,
2480
2777
  NAFixedRates,
2481
2778
  NORTH_AMERICA,
@@ -2508,6 +2805,10 @@ export {
2508
2805
  ResidualStatus,
2509
2806
  STATE_SCHEMA,
2510
2807
  STRIPE_SUPPORTED_COUNTRIES,
2808
+ SYSTEM_FAMILIES,
2809
+ SYSTEM_FAMILY_IDS,
2810
+ SYSTEM_UNITS,
2811
+ SYSTEM_UNIT_IDS,
2511
2812
  StationStatus,
2512
2813
  StripeCurrencyCode,
2513
2814
  StripeStatus,
@@ -2516,7 +2817,11 @@ export {
2516
2817
  UserTypes,
2517
2818
  addAmounts,
2518
2819
  amountToString,
2820
+ assertUnitSane,
2821
+ availableIn,
2822
+ baseFor,
2519
2823
  baseFulfillmentDefinitions,
2824
+ baseOf,
2520
2825
  basePaymentDefinitions,
2521
2826
  buildOrderContext,
2522
2827
  buildPosPresetConfig,
@@ -2528,12 +2833,19 @@ export {
2528
2833
  createAmount,
2529
2834
  crossAxisRuleApplies,
2530
2835
  deriveDisplayState,
2836
+ deriveFamilyCode,
2837
+ deriveUnitId,
2531
2838
  displayRuleMatchesPair,
2532
2839
  divideAmount,
2533
2840
  evaluateCondition,
2534
2841
  evaluateConditionSet,
2842
+ extendPrice,
2843
+ extendPriceFor,
2535
2844
  formatCurrency,
2845
+ formatInUnit,
2536
2846
  formatMinorUnitsToString,
2847
+ formatQuantity,
2848
+ fromBase,
2537
2849
  fromMinorUnits,
2538
2850
  generateMongoID,
2539
2851
  getAvailableTransitions,
@@ -2555,7 +2867,11 @@ export {
2555
2867
  isFulfillmentState,
2556
2868
  isPaymentState,
2557
2869
  isSupportedCurrency,
2870
+ isSystemFamilyCode,
2871
+ isValidQuantity,
2872
+ isWhole,
2558
2873
  mapToLegacyStatus,
2874
+ maxPrecisionFor,
2559
2875
  mergeFragment,
2560
2876
  multiplyAmount,
2561
2877
  normalizeMongoIdString,
@@ -2563,11 +2879,16 @@ export {
2563
2879
  parseCurrencyCode,
2564
2880
  parseStripeCurrencyCode,
2565
2881
  removeFragment,
2882
+ resolveFamily,
2566
2883
  resolveTemplate,
2884
+ resolveUnit,
2885
+ roundToPrecision,
2886
+ sameFamily,
2567
2887
  setOrderState,
2568
2888
  signReportForDisplay,
2569
2889
  stringifyMinorUnits,
2570
2890
  subtractAmounts,
2891
+ toBase,
2571
2892
  toMinorUnits,
2572
2893
  validateConfig,
2573
2894
  validateFragmentCompatibility,