@final-commerce/common 2.2.0-beta.2 → 2.2.0-staging.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/index.d.mts CHANGED
@@ -189,7 +189,8 @@ declare enum Platform {
189
189
  }
190
190
  declare enum OrderPlatform {
191
191
  POS = "in-store",
192
- WOO_COMMERCE = "woo-commerce"
192
+ WOO_COMMERCE = "woo-commerce",
193
+ PUBLIC_API = "public-api"
193
194
  }
194
195
  declare enum CustomerPlatform {
195
196
  POS = "in-store",
@@ -1030,6 +1031,40 @@ declare function setOrderState(order: OrderStateWritable, paymentState: PaymentS
1030
1031
 
1031
1032
  declare function inferStatesFromLegacyStatus(order: OrderLikeForLegacyInference): StatePair;
1032
1033
 
1034
+ interface OrderMutationData extends OrderStateWritable {
1035
+ total?: number;
1036
+ balance?: number;
1037
+ paymentMethods?: {
1038
+ amount?: number;
1039
+ [key: string]: unknown;
1040
+ }[];
1041
+ refunds?: {
1042
+ quantity?: number;
1043
+ [key: string]: unknown;
1044
+ }[];
1045
+ refund?: {
1046
+ quantity?: number;
1047
+ [key: string]: unknown;
1048
+ }[];
1049
+ lineItems?: {
1050
+ quantity?: number;
1051
+ fulfilledQuantity?: number;
1052
+ returnedQuantity?: number;
1053
+ [key: string]: unknown;
1054
+ }[];
1055
+ }
1056
+ interface OrderWriteStrategy {
1057
+ applyState(order: OrderMutationData): void;
1058
+ }
1059
+ declare class LegacyWriteStrategy implements OrderWriteStrategy {
1060
+ applyState(_order: OrderMutationData): void;
1061
+ }
1062
+ declare class DualWriteStrategy implements OrderWriteStrategy {
1063
+ private readonly config;
1064
+ constructor(config: StoredStateConfig);
1065
+ applyState(order: OrderMutationData): void;
1066
+ }
1067
+
1033
1068
  interface ResolveTemplateResult {
1034
1069
  fragment: StateConfigFragment;
1035
1070
  resolvedValues: Record<string, unknown>;
@@ -1145,40 +1180,6 @@ interface ConfigUpdatedPayload {
1145
1180
  }
1146
1181
  type OrderStateEventPayload = StateTransitionCompletedPayload | StateTransitionBlockedPayload | ConfigUpdatedPayload;
1147
1182
 
1148
- interface OrderMutationData extends OrderStateWritable {
1149
- total?: number;
1150
- balance?: number;
1151
- paymentMethods?: {
1152
- amount?: number;
1153
- [key: string]: unknown;
1154
- }[];
1155
- refunds?: {
1156
- quantity?: number;
1157
- [key: string]: unknown;
1158
- }[];
1159
- refund?: {
1160
- quantity?: number;
1161
- [key: string]: unknown;
1162
- }[];
1163
- lineItems?: {
1164
- quantity?: number;
1165
- fulfilledQuantity?: number;
1166
- returnedQuantity?: number;
1167
- [key: string]: unknown;
1168
- }[];
1169
- }
1170
- interface OrderWriteStrategy {
1171
- applyState(order: OrderMutationData): void;
1172
- }
1173
- declare class LegacyWriteStrategy implements OrderWriteStrategy {
1174
- applyState(_order: OrderMutationData): void;
1175
- }
1176
- declare class DualWriteStrategy implements OrderWriteStrategy {
1177
- private readonly config;
1178
- constructor(config: StoredStateConfig);
1179
- applyState(order: OrderMutationData): void;
1180
- }
1181
-
1182
1183
  interface CurrencyRate {
1183
1184
  rate: number;
1184
1185
  country: string;
package/dist/index.d.ts CHANGED
@@ -189,7 +189,8 @@ declare enum Platform {
189
189
  }
190
190
  declare enum OrderPlatform {
191
191
  POS = "in-store",
192
- WOO_COMMERCE = "woo-commerce"
192
+ WOO_COMMERCE = "woo-commerce",
193
+ PUBLIC_API = "public-api"
193
194
  }
194
195
  declare enum CustomerPlatform {
195
196
  POS = "in-store",
@@ -1030,6 +1031,40 @@ declare function setOrderState(order: OrderStateWritable, paymentState: PaymentS
1030
1031
 
1031
1032
  declare function inferStatesFromLegacyStatus(order: OrderLikeForLegacyInference): StatePair;
1032
1033
 
1034
+ interface OrderMutationData extends OrderStateWritable {
1035
+ total?: number;
1036
+ balance?: number;
1037
+ paymentMethods?: {
1038
+ amount?: number;
1039
+ [key: string]: unknown;
1040
+ }[];
1041
+ refunds?: {
1042
+ quantity?: number;
1043
+ [key: string]: unknown;
1044
+ }[];
1045
+ refund?: {
1046
+ quantity?: number;
1047
+ [key: string]: unknown;
1048
+ }[];
1049
+ lineItems?: {
1050
+ quantity?: number;
1051
+ fulfilledQuantity?: number;
1052
+ returnedQuantity?: number;
1053
+ [key: string]: unknown;
1054
+ }[];
1055
+ }
1056
+ interface OrderWriteStrategy {
1057
+ applyState(order: OrderMutationData): void;
1058
+ }
1059
+ declare class LegacyWriteStrategy implements OrderWriteStrategy {
1060
+ applyState(_order: OrderMutationData): void;
1061
+ }
1062
+ declare class DualWriteStrategy implements OrderWriteStrategy {
1063
+ private readonly config;
1064
+ constructor(config: StoredStateConfig);
1065
+ applyState(order: OrderMutationData): void;
1066
+ }
1067
+
1033
1068
  interface ResolveTemplateResult {
1034
1069
  fragment: StateConfigFragment;
1035
1070
  resolvedValues: Record<string, unknown>;
@@ -1145,40 +1180,6 @@ interface ConfigUpdatedPayload {
1145
1180
  }
1146
1181
  type OrderStateEventPayload = StateTransitionCompletedPayload | StateTransitionBlockedPayload | ConfigUpdatedPayload;
1147
1182
 
1148
- interface OrderMutationData extends OrderStateWritable {
1149
- total?: number;
1150
- balance?: number;
1151
- paymentMethods?: {
1152
- amount?: number;
1153
- [key: string]: unknown;
1154
- }[];
1155
- refunds?: {
1156
- quantity?: number;
1157
- [key: string]: unknown;
1158
- }[];
1159
- refund?: {
1160
- quantity?: number;
1161
- [key: string]: unknown;
1162
- }[];
1163
- lineItems?: {
1164
- quantity?: number;
1165
- fulfilledQuantity?: number;
1166
- returnedQuantity?: number;
1167
- [key: string]: unknown;
1168
- }[];
1169
- }
1170
- interface OrderWriteStrategy {
1171
- applyState(order: OrderMutationData): void;
1172
- }
1173
- declare class LegacyWriteStrategy implements OrderWriteStrategy {
1174
- applyState(_order: OrderMutationData): void;
1175
- }
1176
- declare class DualWriteStrategy implements OrderWriteStrategy {
1177
- private readonly config;
1178
- constructor(config: StoredStateConfig);
1179
- applyState(order: OrderMutationData): void;
1180
- }
1181
-
1182
1183
  interface CurrencyRate {
1183
1184
  rate: number;
1184
1185
  country: string;
package/dist/index.js CHANGED
@@ -369,6 +369,7 @@ var Platform = /* @__PURE__ */ ((Platform2) => {
369
369
  var OrderPlatform = /* @__PURE__ */ ((OrderPlatform2) => {
370
370
  OrderPlatform2["POS"] = "in-store";
371
371
  OrderPlatform2["WOO_COMMERCE"] = "woo-commerce";
372
+ OrderPlatform2["PUBLIC_API"] = "public-api";
372
373
  return OrderPlatform2;
373
374
  })(OrderPlatform || {});
374
375
  var CustomerPlatform = /* @__PURE__ */ ((CustomerPlatform2) => {
@@ -1446,10 +1447,7 @@ function negateAtPaths(value, path, paths) {
1446
1447
  function padHex(value, length) {
1447
1448
  return value.toString(16).padStart(length, "0");
1448
1449
  }
1449
- var PROCESS_RANDOM = Array.from(
1450
- { length: 5 },
1451
- () => padHex(Math.floor(Math.random() * 256), 2)
1452
- ).join("");
1450
+ var PROCESS_RANDOM = Array.from({ length: 5 }, () => padHex(Math.floor(Math.random() * 256), 2)).join("");
1453
1451
  var objectIdCounter = Math.floor(Math.random() * 16777215);
1454
1452
  function generateMongoID() {
1455
1453
  const timestamp = padHex(Math.floor(Date.now() / 1e3), 8);
@@ -1594,6 +1592,8 @@ var STATE_SCHEMA = Object.freeze({
1594
1592
  // order-state-machine/financial-invariants.ts
1595
1593
  var REFUND_ALLOWED_FULFILLMENT = /* @__PURE__ */ new Set(["fulfilled", "returned", "partially_returned", "cancelled"]);
1596
1594
  var PAYMENT_COLLECTION_ORDER = ["unpaid", "partially_paid", "paid"];
1595
+ var UNRETURNED_MONEY_STATES = /* @__PURE__ */ new Set(["partially_paid", "paid", "partially_refunded"]);
1596
+ var REFUNDED_FULFILLMENT_LANDINGS = /* @__PURE__ */ new Set(["returned", "cancelled"]);
1597
1597
  var FINANCIAL_INVARIANTS = [
1598
1598
  {
1599
1599
  id: "no-leave-refunded",
@@ -1624,6 +1624,26 @@ var FINANCIAL_INVARIANTS = [
1624
1624
  const toIdx = PAYMENT_COLLECTION_ORDER.indexOf(to.payment);
1625
1625
  return fromIdx !== -1 && toIdx !== -1 && fromIdx > toIdx;
1626
1626
  }
1627
+ },
1628
+ {
1629
+ id: "no-cancel-with-unreturned-payments",
1630
+ description: "Fulfillment cannot enter cancelled while the payment state carries unreturned captured money (paid / partially_paid / partially_refunded) \u2014 return the money first: a full refund of an unfulfilled order lands refunded \xD7 cancelled, a void lands voided \xD7 cancelled. Scoped to the cancelling MOVE (from.fulfillment !== cancelled) so payment-axis edges evaluated against an already-cancelled fulfillment do not trip it",
1631
+ check: (from, to) => from !== null && from.fulfillment !== "cancelled" && to.fulfillment === "cancelled" && UNRETURNED_MONEY_STATES.has(to.payment)
1632
+ },
1633
+ {
1634
+ id: "no-draft-regression-with-captured-payments",
1635
+ description: "Fulfillment cannot regress to draft once money has been captured \u2014 a money-carrying order is no longer a cart (bug #31: resume lands deposit orders on in_progress for the same reason). New orders and draft-to-draft moves are exempt, so partially_paid \xD7 draft remains declarable as an initial state",
1636
+ check: (from, to) => from !== null && from.fulfillment !== "draft" && to.fulfillment === "draft" && to.payment !== "unpaid"
1637
+ },
1638
+ {
1639
+ id: "no-reopen-voided-fulfillment",
1640
+ description: "A voided order exists only at cancelled fulfillment: a voided order cannot re-enter fulfillment, and a voided \xD7 non-cancelled pair cannot be materialized from nothing (complements no-leave-voided, which only freezes the payment axis). Moves INTO voided from a live payment state are the void flow\u2019s concern, not this rule\u2019s",
1641
+ check: (from, to) => (from === null || from.payment === "voided") && to.payment === "voided" && to.fulfillment !== "cancelled"
1642
+ },
1643
+ {
1644
+ id: "no-reopen-refunded-fulfillment",
1645
+ description: "A fully refunded order cannot re-enter fulfillment \u2014 it may only relabel between its canonical landings, returned and cancelled (complements no-leave-refunded, which only freezes the payment axis)",
1646
+ check: (from, to) => from?.payment === "refunded" && !REFUNDED_FULFILLMENT_LANDINGS.has(to.fulfillment)
1627
1647
  }
1628
1648
  ];
1629
1649
  function getFinancialInvariantViolations(from, to) {
@@ -1711,24 +1731,17 @@ var DISPLAY_LABEL_OVERRIDES = {
1711
1731
  "paid|on_hold": "Parked - Paid",
1712
1732
  "paid|fulfilled": "Completed",
1713
1733
  "partially_refunded|fulfilled": "Partially Refunded",
1714
- "partially_refunded|partially_returned": "Partially Refunded",
1715
- "refunded|fulfilled": "Refunded",
1716
- "refunded|returned": "Refunded",
1717
- // Full refund of a never-fulfilled order (kaching refund op lands on
1718
- // cancelled when nothing was delivered). Terminal payment states emit no
1719
- // generic rows, so without this the pair fell through to the raw
1720
- // "refunded / cancelled" engine fallback.
1721
- "refunded|cancelled": "Refunded",
1722
- "voided|cancelled": "Cancelled"
1734
+ "partially_refunded|partially_returned": "Partially Refunded"
1735
+ };
1736
+ var TERMINAL_LABEL_OVERRIDES = {
1737
+ voided: "Cancelled"
1723
1738
  };
1724
1739
  function buildDefaultDisplayStateMap() {
1725
1740
  const rules = [];
1726
1741
  for (const p of PAYMENT_STATES) {
1742
+ const terminalLabel = TERMINAL_PAYMENT_STATES.has(p) ? TERMINAL_LABEL_OVERRIDES[p] ?? PAYMENT_LABELS.get(p) : void 0;
1727
1743
  for (const f of FULFILLMENT_STATES) {
1728
- const key = `${p}|${f}`;
1729
- const override = DISPLAY_LABEL_OVERRIDES[key];
1730
- if (TERMINAL_PAYMENT_STATES.has(p) && !override) continue;
1731
- const label = override ?? `${PAYMENT_LABELS.get(p)} / ${FULFILLMENT_LABELS.get(f)}`;
1744
+ const label = DISPLAY_LABEL_OVERRIDES[`${p}|${f}`] ?? terminalLabel ?? `${PAYMENT_LABELS.get(p)} / ${FULFILLMENT_LABELS.get(f)}`;
1732
1745
  rules.push({ paymentState: p, fulfillmentState: f, label });
1733
1746
  }
1734
1747
  }
@@ -1851,6 +1864,9 @@ function buildOrderContext(order, extras) {
1851
1864
  }
1852
1865
 
1853
1866
  // order-state-machine/display-state.ts
1867
+ function atomLabel(atom, defs) {
1868
+ return defs.find((d) => d.id === atom)?.label ?? atom;
1869
+ }
1854
1870
  function matchesOptional(actual, rule) {
1855
1871
  if (rule === void 0) return true;
1856
1872
  return Array.isArray(rule) ? rule.includes(actual) : rule === actual;
@@ -1861,7 +1877,9 @@ function deriveDisplayState(payment, fulfillment, config) {
1861
1877
  return { label: rule.label, color: rule.color, icon: rule.icon };
1862
1878
  }
1863
1879
  }
1864
- return { label: `${payment} / ${fulfillment}` };
1880
+ return {
1881
+ label: `${atomLabel(payment, STATE_SCHEMA.paymentStates)} / ${atomLabel(fulfillment, STATE_SCHEMA.fulfillmentStates)}`
1882
+ };
1865
1883
  }
1866
1884
  function displayRuleMatchesPair(rule, payment, fulfillment) {
1867
1885
  return matchesOptional(payment, rule.paymentState) && matchesOptional(fulfillment, rule.fulfillmentState);
@@ -2097,13 +2115,11 @@ function labelForFulfillment(id, config) {
2097
2115
  return config.fulfillmentStates.find((s) => s.id === id)?.label ?? id;
2098
2116
  }
2099
2117
  function transitionDisplayLabel(to, config) {
2100
- const pay = labelForPayment(to.payment, config);
2101
- const ful = labelForFulfillment(to.fulfillment, config);
2102
2118
  const derived = deriveDisplayState(to.payment, to.fulfillment, config).label;
2103
- if (derived && derived !== `${to.payment} / ${to.fulfillment}`) {
2119
+ if (derived) {
2104
2120
  return derived;
2105
2121
  }
2106
- return `${pay} \xB7 ${ful}`;
2122
+ return `${labelForPayment(to.payment, config)} \xB7 ${labelForFulfillment(to.fulfillment, config)}`;
2107
2123
  }
2108
2124
  function conditionMetLines(config, from, to, context) {
2109
2125
  const lines = [];
@@ -2132,20 +2148,12 @@ function conditionMetLines(config, from, to, context) {
2132
2148
  }
2133
2149
  function getAvailableTransitions(current, config, context) {
2134
2150
  const candidates = [];
2135
- for (const s of config.paymentStates) {
2136
- if (s.id === current.payment) continue;
2137
- candidates.push({ payment: s.id, fulfillment: current.fulfillment });
2138
- }
2139
2151
  for (const s of config.fulfillmentStates) {
2140
2152
  if (s.id === current.fulfillment) continue;
2141
2153
  candidates.push({ payment: current.payment, fulfillment: s.id });
2142
2154
  }
2143
2155
  const out = [];
2144
- const seen = /* @__PURE__ */ new Set();
2145
2156
  for (const to of candidates) {
2146
- const key = `${to.payment}:${to.fulfillment}`;
2147
- if (seen.has(key)) continue;
2148
- seen.add(key);
2149
2157
  const result = canTransition({
2150
2158
  from: current,
2151
2159
  to,
@@ -2594,6 +2602,27 @@ function inferStatesFromLegacyStatus(order) {
2594
2602
  return { payment: "unpaid", fulfillment: "pending" };
2595
2603
  }
2596
2604
 
2605
+ // order-state-machine/write-strategy.ts
2606
+ var LegacyWriteStrategy = class {
2607
+ applyState(_order) {
2608
+ }
2609
+ };
2610
+ var DualWriteStrategy = class {
2611
+ constructor(config) {
2612
+ this.config = config;
2613
+ }
2614
+ applyState(order) {
2615
+ if (order.paymentState && order.fulfillmentState) {
2616
+ setOrderState(order, order.paymentState, order.fulfillmentState, this.config);
2617
+ return;
2618
+ }
2619
+ if (order.status) {
2620
+ const inferred = inferStatesFromLegacyStatus(order);
2621
+ setOrderState(order, inferred.payment, inferred.fulfillment, this.config);
2622
+ }
2623
+ }
2624
+ };
2625
+
2597
2626
  // order-state-machine/resolve-template.ts
2598
2627
  function resolveTemplate(templateJson, params, values = {}) {
2599
2628
  const resolvedValues = {};
@@ -2895,27 +2924,6 @@ var ORDER_STATE_EVENTS = {
2895
2924
  stateTransitionBlocked: "state-transition-blocked",
2896
2925
  configUpdated: "config-updated"
2897
2926
  };
2898
-
2899
- // order-state-machine/write-strategy.ts
2900
- var LegacyWriteStrategy = class {
2901
- applyState(_order) {
2902
- }
2903
- };
2904
- var DualWriteStrategy = class {
2905
- constructor(config) {
2906
- this.config = config;
2907
- }
2908
- applyState(order) {
2909
- if (order.paymentState && order.fulfillmentState) {
2910
- setOrderState(order, order.paymentState, order.fulfillmentState, this.config);
2911
- return;
2912
- }
2913
- if (order.status) {
2914
- const inferred = inferStatesFromLegacyStatus(order);
2915
- setOrderState(order, inferred.payment, inferred.fulfillment, this.config);
2916
- }
2917
- }
2918
- };
2919
2927
  // Annotate the CommonJS export names for ESM import in node:
2920
2928
  0 && (module.exports = {
2921
2929
  AttributeType,