@final-commerce/command-frame 0.2.0-beta.6 → 0.3.0-beta.5

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.
Files changed (126) hide show
  1. package/README.md +24 -0
  2. package/dist/CommonTypes.d.ts +73 -622
  3. package/dist/CommonTypes.js +5 -65
  4. package/dist/actions/add-cart-discount/mock.js +6 -3
  5. package/dist/actions/add-cart-fee/mock.js +6 -6
  6. package/dist/actions/add-custom-sale/mock.js +7 -2
  7. package/dist/actions/add-order-note/mock.js +3 -1
  8. package/dist/actions/add-product/mock.js +1 -1
  9. package/dist/actions/add-product-discount/mock.js +5 -5
  10. package/dist/actions/add-product-fee/mock.js +6 -6
  11. package/dist/actions/apply-transition/action.d.ts +2 -0
  12. package/dist/actions/apply-transition/action.js +4 -0
  13. package/dist/actions/apply-transition/mock.d.ts +6 -0
  14. package/dist/actions/apply-transition/mock.js +33 -0
  15. package/dist/actions/apply-transition/types.d.ts +17 -0
  16. package/dist/actions/cash-payment/mock.js +12 -18
  17. package/dist/actions/delete-parked-order/mock.js +3 -1
  18. package/dist/actions/edit-product/mock.js +1 -1
  19. package/dist/actions/extension-payment/types.d.ts +4 -0
  20. package/dist/actions/get-context/mock.js +1 -1
  21. package/dist/actions/get-orders/mock.js +3 -3
  22. package/dist/actions/get-products/mock.js +9 -4
  23. package/dist/actions/get-products/types.d.ts +2 -0
  24. package/dist/actions/get-roles/mock.js +35 -41
  25. package/dist/actions/get-smart-grid-layout/action.d.ts +2 -0
  26. package/dist/actions/get-smart-grid-layout/action.js +4 -0
  27. package/dist/actions/get-smart-grid-layout/mock.d.ts +2 -0
  28. package/dist/actions/get-smart-grid-layout/mock.js +9 -0
  29. package/dist/actions/get-smart-grid-layout/types.d.ts +10 -0
  30. package/dist/actions/get-users/mock.js +16 -25
  31. package/dist/actions/integration-payment/action.d.ts +5 -0
  32. package/dist/actions/integration-payment/action.js +7 -0
  33. package/dist/actions/integration-payment/mock.d.ts +2 -0
  34. package/dist/actions/integration-payment/mock.js +4 -0
  35. package/dist/actions/integration-payment/types.d.ts +56 -0
  36. package/dist/actions/open-extension-overlay/action.d.ts +2 -0
  37. package/dist/actions/open-extension-overlay/action.js +4 -0
  38. package/dist/actions/open-extension-overlay/mock.d.ts +2 -0
  39. package/dist/actions/open-extension-overlay/mock.js +1 -0
  40. package/dist/actions/open-extension-overlay/types.d.ts +9 -0
  41. package/dist/actions/park-order/mock.js +4 -1
  42. package/dist/actions/partial-payment/mock.js +21 -3
  43. package/dist/actions/redeem-payment/types.d.ts +9 -5
  44. package/dist/actions/remove-custom-sale/mock.d.ts +2 -0
  45. package/dist/actions/remove-custom-sale/mock.js +29 -0
  46. package/dist/actions/remove-customer-from-cart/mock.js +3 -1
  47. package/dist/actions/remove-order-note/mock.d.ts +2 -0
  48. package/dist/actions/remove-order-note/mock.js +12 -0
  49. package/dist/actions/remove-product-discount/mock.d.ts +2 -0
  50. package/dist/actions/remove-product-discount/mock.js +17 -0
  51. package/dist/actions/remove-product-fee/mock.d.ts +2 -0
  52. package/dist/actions/remove-product-fee/mock.js +17 -0
  53. package/dist/actions/remove-product-from-cart/mock.js +5 -5
  54. package/dist/actions/resolve-extension-overlay/action.d.ts +2 -0
  55. package/dist/actions/resolve-extension-overlay/action.js +4 -0
  56. package/dist/actions/resolve-extension-overlay/mock.d.ts +2 -0
  57. package/dist/actions/resolve-extension-overlay/mock.js +1 -0
  58. package/dist/actions/resolve-extension-overlay/types.d.ts +9 -0
  59. package/dist/actions/resolve-extension-overlay/types.js +1 -0
  60. package/dist/actions/resume-parked-order/mock.js +5 -2
  61. package/dist/actions/save-smart-grid-layout/action.d.ts +2 -0
  62. package/dist/actions/save-smart-grid-layout/action.js +4 -0
  63. package/dist/actions/save-smart-grid-layout/mock.d.ts +2 -0
  64. package/dist/actions/save-smart-grid-layout/mock.js +10 -0
  65. package/dist/actions/save-smart-grid-layout/types.d.ts +10 -0
  66. package/dist/actions/save-smart-grid-layout/types.js +1 -0
  67. package/dist/actions/set-active-product-discount/mock.js +1 -1
  68. package/dist/actions/set-active-product-fee/mock.js +1 -1
  69. package/dist/actions/tap-to-pay-payment/mock.js +5 -3
  70. package/dist/actions/terminal-payment/mock.js +4 -5
  71. package/dist/actions/update-cart-item-quantity/mock.js +9 -9
  72. package/dist/demo/database.d.ts +33 -22
  73. package/dist/demo/database.js +191 -21
  74. package/dist/index.d.ts +116 -115
  75. package/dist/index.js +15 -13
  76. package/dist/interceptors/index.d.ts +21 -0
  77. package/dist/interceptors/index.js +53 -0
  78. package/dist/interceptors/types.d.ts +26 -0
  79. package/dist/interceptors/types.js +1 -0
  80. package/dist/projects/render/mocks.js +19 -15
  81. package/dist/projects/render/types.d.ts +8 -6
  82. package/dist/pubsub/topics/products/product-get-active/types.d.ts +6 -2
  83. package/dist/pubsub/topics/split-payments/index.d.ts +12 -0
  84. package/dist/pubsub/topics/split-payments/index.js +22 -0
  85. package/dist/pubsub/topics/split-payments/split-payment-updated/types.d.ts +16 -0
  86. package/dist/pubsub/topics/split-payments/split-payment-updated/types.js +1 -0
  87. package/dist/pubsub/topics/split-payments/types.d.ts +10 -0
  88. package/dist/pubsub/topics/split-payments/types.js +5 -0
  89. package/dist/pubsub/topics/types.d.ts +2 -0
  90. package/package.json +17 -14
  91. package/dist/actions/extension-refund/constants.d.ts +0 -2
  92. package/dist/actions/extension-refund/constants.js +0 -2
  93. package/dist/actions/extension-refund/extension-refund-listener.d.ts +0 -11
  94. package/dist/actions/extension-refund/extension-refund-listener.js +0 -60
  95. package/dist/actions/extension-refund/types.d.ts +0 -32
  96. package/dist/actions/extension-refund/types.js +0 -5
  97. package/dist/actions/set-active-outlet/action.d.ts +0 -2
  98. package/dist/actions/set-active-outlet/action.js +0 -4
  99. package/dist/actions/set-active-outlet/mock.d.ts +0 -2
  100. package/dist/actions/set-active-outlet/mock.js +0 -16
  101. package/dist/actions/set-active-outlet/types.d.ts +0 -10
  102. package/dist/actions/set-active-session/action.d.ts +0 -2
  103. package/dist/actions/set-active-session/action.js +0 -4
  104. package/dist/actions/set-active-session/mock.d.ts +0 -2
  105. package/dist/actions/set-active-session/mock.js +0 -15
  106. package/dist/actions/set-active-session/types.d.ts +0 -10
  107. package/dist/actions/set-active-station/action.d.ts +0 -2
  108. package/dist/actions/set-active-station/action.js +0 -4
  109. package/dist/actions/set-active-station/mock.d.ts +0 -2
  110. package/dist/actions/set-active-station/mock.js +0 -16
  111. package/dist/actions/set-active-station/types.d.ts +0 -10
  112. package/dist/actions/trigger-webhook/action.d.ts +0 -6
  113. package/dist/actions/trigger-webhook/action.js +0 -8
  114. package/dist/actions/trigger-webhook/mock.d.ts +0 -2
  115. package/dist/actions/trigger-webhook/mock.js +0 -8
  116. package/dist/actions/trigger-webhook/types.d.ts +0 -21
  117. package/dist/actions/trigger-webhook/types.js +0 -2
  118. package/dist/actions/trigger-zapier-webhook/action.d.ts +0 -6
  119. package/dist/actions/trigger-zapier-webhook/action.js +0 -8
  120. package/dist/actions/trigger-zapier-webhook/mock.d.ts +0 -2
  121. package/dist/actions/trigger-zapier-webhook/mock.js +0 -8
  122. package/dist/actions/trigger-zapier-webhook/types.d.ts +0 -9
  123. /package/dist/actions/{set-active-outlet → apply-transition}/types.js +0 -0
  124. /package/dist/actions/{set-active-session → get-smart-grid-layout}/types.js +0 -0
  125. /package/dist/actions/{set-active-station → integration-payment}/types.js +0 -0
  126. /package/dist/actions/{trigger-zapier-webhook → open-extension-overlay}/types.js +0 -0
@@ -1,66 +1,6 @@
1
1
  export * from "./common-types";
2
- export var CurrencyCode;
3
- (function (CurrencyCode) {
4
- CurrencyCode["USD"] = "USD";
5
- CurrencyCode["EUR"] = "EUR";
6
- CurrencyCode["GBP"] = "GBP";
7
- CurrencyCode["CAD"] = "CAD";
8
- CurrencyCode["AUD"] = "AUD";
9
- CurrencyCode["NZD"] = "NZD";
10
- CurrencyCode["CHF"] = "CHF";
11
- CurrencyCode["CNY"] = "CNY";
12
- CurrencyCode["INR"] = "INR";
13
- CurrencyCode["MXN"] = "MXN";
14
- CurrencyCode["BRL"] = "BRL";
15
- CurrencyCode["ZAR"] = "ZAR";
16
- CurrencyCode["SGD"] = "SGD";
17
- CurrencyCode["HKD"] = "HKD";
18
- CurrencyCode["SEK"] = "SEK";
19
- CurrencyCode["NOK"] = "NOK";
20
- CurrencyCode["DKK"] = "DKK";
21
- CurrencyCode["PLN"] = "PLN";
22
- CurrencyCode["THB"] = "THB";
23
- CurrencyCode["MYR"] = "MYR";
24
- CurrencyCode["PHP"] = "PHP";
25
- CurrencyCode["IDR"] = "IDR";
26
- CurrencyCode["AED"] = "AED";
27
- CurrencyCode["SAR"] = "SAR";
28
- CurrencyCode["ILS"] = "ILS";
29
- CurrencyCode["TRY"] = "TRY";
30
- CurrencyCode["RUB"] = "RUB";
31
- CurrencyCode["JPY"] = "JPY";
32
- CurrencyCode["KRW"] = "KRW";
33
- CurrencyCode["VND"] = "VND";
34
- CurrencyCode["CLP"] = "CLP";
35
- CurrencyCode["ISK"] = "ISK";
36
- CurrencyCode["HUF"] = "HUF";
37
- CurrencyCode["TWD"] = "TWD";
38
- CurrencyCode["KWD"] = "KWD";
39
- CurrencyCode["BHD"] = "BHD";
40
- CurrencyCode["OMR"] = "OMR";
41
- CurrencyCode["JOD"] = "JOD";
42
- CurrencyCode["TND"] = "TND";
43
- CurrencyCode["LYD"] = "LYD";
44
- CurrencyCode["IQD"] = "IQD";
45
- })(CurrencyCode || (CurrencyCode = {}));
46
- // Enums
47
- export var CFProductType;
48
- (function (CFProductType) {
49
- CFProductType["SIMPLE"] = "simple";
50
- CFProductType["VARIABLE"] = "variable";
51
- })(CFProductType || (CFProductType = {}));
52
- export var CFUserTypes;
53
- (function (CFUserTypes) {
54
- CFUserTypes["OWNER"] = "owner";
55
- CFUserTypes["ORG_USER"] = "organization_user";
56
- CFUserTypes["ORG_OWNER"] = "organization_owner";
57
- CFUserTypes["FINAL_USER"] = "final_user";
58
- CFUserTypes["FINAL_OWNER"] = "final_owner";
59
- CFUserTypes["EMPLOYEE"] = "employee";
60
- CFUserTypes["SUPER_ADMIN"] = "super_admin";
61
- CFUserTypes["MANAGER"] = "manager";
62
- CFUserTypes["ADMIN"] = "admin";
63
- CFUserTypes["ASSISTANT_MANAGER"] = "assistant";
64
- CFUserTypes["CASHIER"] = "cashier";
65
- CFUserTypes["RESELLER"] = "reseller";
66
- })(CFUserTypes || (CFUserTypes = {}));
2
+ // Enums — re-exported from common (single source). CurrencyCode keeps its name;
3
+ // CFProductType/CFUserTypes alias common's ProductType/UserTypes. Note: common's
4
+ // UserTypes uses `COMPANY_OWNER` where command-frame's enum previously had `OWNER`
5
+ // (same value `'owner'`).
6
+ export { CurrencyCode, ProductType as CFProductType, UserTypes as CFUserTypes } from "@final-commerce/common";
@@ -2,17 +2,20 @@ import { MOCK_CART, mockPublishEvent } from "../../demo/database";
2
2
  export const mockAddCartDiscount = async (params) => {
3
3
  console.log("[Mock] addCartDiscount called", params);
4
4
  if (params) {
5
+ // Mirror render: input is raw (50 = 50%, 5 = $5). Store percent as a
6
+ // fraction (0.5) and fixed as minor units (500), like the real handler.
7
+ const minorFactor = 10 ** (MOCK_CART.minorUnits ?? 2);
8
+ const value = params.isPercent ? params.amount / 100 : Math.round(params.amount * minorFactor);
5
9
  MOCK_CART.discount = {
6
- value: params.amount,
10
+ value,
7
11
  isPercent: params.isPercent,
8
12
  label: params.label
9
13
  };
10
- // Simple mock calc (not real logic)
11
14
  if (params.isPercent) {
12
15
  MOCK_CART.total = MOCK_CART.subtotal * (1 - params.amount / 100);
13
16
  }
14
17
  else {
15
- MOCK_CART.total = MOCK_CART.subtotal - params.amount;
18
+ MOCK_CART.total = MOCK_CART.subtotal - value;
16
19
  }
17
20
  MOCK_CART.amountToBeCharged = MOCK_CART.total;
18
21
  MOCK_CART.remainingBalance = MOCK_CART.total;
@@ -4,18 +4,18 @@ export const mockAddCartFee = async (params) => {
4
4
  if (params) {
5
5
  if (!MOCK_CART.customFee)
6
6
  MOCK_CART.customFee = [];
7
+ // Mirror render: input is raw (50 = 50%, 5 = $5). Store percent as a
8
+ // fraction (0.5) and fixed as minor units (500), like the real handler.
9
+ const minorFactor = 10 ** (MOCK_CART.minorUnits ?? 2);
10
+ const storedAmount = params.isPercent ? params.amount / 100 : Math.round(params.amount * minorFactor);
7
11
  MOCK_CART.customFee.push({
8
12
  label: params.label || "Fee",
9
- amount: params.amount,
13
+ amount: storedAmount,
10
14
  isPercent: params.isPercent || false,
11
15
  applyTaxes: params.applyTaxes || false,
12
16
  taxTableId: params.taxTableId
13
17
  });
14
- // Simple calc
15
- let feeAmount = params.amount;
16
- if (params.isPercent) {
17
- feeAmount = MOCK_CART.subtotal * (params.amount / 100);
18
- }
18
+ const feeAmount = params.isPercent ? MOCK_CART.subtotal * (params.amount / 100) : storedAmount;
19
19
  MOCK_CART.total += feeAmount;
20
20
  MOCK_CART.amountToBeCharged = MOCK_CART.total;
21
21
  MOCK_CART.remainingBalance = MOCK_CART.total;
@@ -1,11 +1,14 @@
1
- import { MOCK_CART } from "../../demo/database";
1
+ import { MOCK_CART, mockPublishEvent } from "../../demo/database";
2
2
  export const mockAddCustomSale = async (params) => {
3
3
  console.log("[Mock] addCustomSale called", params);
4
4
  if (!params)
5
5
  throw new Error("Params required");
6
6
  // Simple mock ID generation
7
7
  const mockId = 'sale_' + Math.random().toString(36).substr(2, 9);
8
- const price = Number(params.price);
8
+ // Mirror render: the flow sends raw dollars ($4); render does toMinorUnits.
9
+ // MOCK_CART tracks minor units, so convert here too.
10
+ const minorFactor = 10 ** (MOCK_CART.minorUnits ?? 2);
11
+ const price = Math.round(Number(params.price) * minorFactor);
9
12
  const quantity = 1; // Default to 1 for custom sale usually
10
13
  const customSale = {
11
14
  id: mockId,
@@ -24,6 +27,8 @@ export const mockAddCustomSale = async (params) => {
24
27
  MOCK_CART.total += price * quantity;
25
28
  MOCK_CART.amountToBeCharged = MOCK_CART.total;
26
29
  MOCK_CART.remainingBalance = MOCK_CART.total;
30
+ // Publish custom-sale-added event so cart subscribers refresh
31
+ mockPublishEvent('cart', 'custom-sale-added', { customSale });
27
32
  return {
28
33
  success: true,
29
34
  customSaleId: mockId,
@@ -1,4 +1,4 @@
1
- import { MOCK_CART } from "../../demo/database";
1
+ import { MOCK_CART, mockPublishEvent } from "../../demo/database";
2
2
  export const mockAddOrderNote = async (params) => {
3
3
  console.log("[Mock] addOrderNote called", params);
4
4
  // In Render, AddOrderNote usually adds a note to the active cart if it's not checked out yet.
@@ -9,6 +9,8 @@ export const mockAddOrderNote = async (params) => {
9
9
  else {
10
10
  MOCK_CART.orderNotes = params.note;
11
11
  }
12
+ // Publish order-note-added event so cart subscribers refresh.
13
+ mockPublishEvent("cart", "order-note-added", { note: params.note });
12
14
  }
13
15
  return {
14
16
  success: true,
@@ -12,7 +12,7 @@ export const mockAddProduct = async (params) => {
12
12
  minorUnits: 2,
13
13
  name: params.name,
14
14
  description: params.description,
15
- categories: params.categories || [],
15
+ categories: (params.categories || []).map((c) => ({ name: c, externalId: c })),
16
16
  taxTable: params.taxTable || "",
17
17
  images: params.images || [],
18
18
  status: params.status || "active",
@@ -10,11 +10,11 @@ export const mockAddProductDiscount = async (params) => {
10
10
  item = MOCK_CART.products[MOCK_CART.products.length - 1];
11
11
  }
12
12
  if (item) {
13
- item.discount = {
14
- value: params.amount,
15
- isPercent: params.isPercent || false,
16
- label: params.label
17
- };
13
+ item.discounts = [{
14
+ value: params.amount,
15
+ isPercent: params.isPercent || false,
16
+ label: params.label
17
+ }];
18
18
  // Recalculate cart totals (simplified)
19
19
  // Ideally, this should trigger a full recalculation function
20
20
  }
@@ -10,12 +10,12 @@ export const mockAddProductFee = async (params) => {
10
10
  item = MOCK_CART.products[MOCK_CART.products.length - 1];
11
11
  }
12
12
  if (item) {
13
- item.fee = {
14
- label: params.label || "Fee",
15
- amount: params.amount,
16
- isPercent: params.isPercent || false,
17
- applyTaxes: params.applyTaxes || false
18
- };
13
+ item.fees = [{
14
+ label: params.label || "Fee",
15
+ amount: params.amount,
16
+ isPercent: params.isPercent || false,
17
+ applyTaxes: params.applyTaxes || false
18
+ }];
19
19
  }
20
20
  }
21
21
  return {
@@ -0,0 +1,2 @@
1
+ import type { ApplyTransition } from "./types";
2
+ export declare const applyTransition: ApplyTransition;
@@ -0,0 +1,4 @@
1
+ import { commandFrameClient } from "../../client";
2
+ export const applyTransition = async (params) => {
3
+ return await commandFrameClient.call("applyTransition", params);
4
+ };
@@ -0,0 +1,6 @@
1
+ import type { ApplyTransitionParams, ApplyTransitionResponse } from "./types";
2
+ /**
3
+ * Mock implementation: applies all transitions except a few known-invalid ones
4
+ * so the demo app can show both successful and blocked responses.
5
+ */
6
+ export declare const applyTransitionMock: (params: ApplyTransitionParams) => Promise<ApplyTransitionResponse>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Mock implementation: applies all transitions except a few known-invalid ones
3
+ * so the demo app can show both successful and blocked responses.
4
+ */
5
+ export const applyTransitionMock = (params) => {
6
+ const { to } = params;
7
+ if (to.payment === "refunded" && to.fulfillment === "draft") {
8
+ return Promise.resolve({
9
+ result: {
10
+ allowed: false,
11
+ blockedBy: "financial_invariant",
12
+ guard: "no-refund-in-draft",
13
+ reason: "Cannot refund an order that is still in draft"
14
+ }
15
+ });
16
+ }
17
+ if (to.payment === "paid" && to.fulfillment === "cancelled") {
18
+ return Promise.resolve({
19
+ result: {
20
+ allowed: false,
21
+ blockedBy: "cross_axis_rule",
22
+ guard: "no-pay-cancelled",
23
+ reason: "Cannot mark a cancelled order as paid"
24
+ }
25
+ });
26
+ }
27
+ return Promise.resolve({
28
+ result: { allowed: true },
29
+ from: { payment: "unpaid", fulfillment: "draft" },
30
+ to,
31
+ displayState: `${to.payment} / ${to.fulfillment}`
32
+ });
33
+ };
@@ -0,0 +1,17 @@
1
+ import type { CFStatePair, CFTransitionResult } from "../../common-types/order-state";
2
+ export interface ApplyTransitionParams {
3
+ /** Order to transition. */
4
+ orderId: string;
5
+ /** Target state pair. */
6
+ to: CFStatePair;
7
+ }
8
+ export interface ApplyTransitionResponse {
9
+ result: CFTransitionResult;
10
+ /** Previous state — present only when the transition was applied. */
11
+ from?: CFStatePair;
12
+ /** New state — present only when the transition was applied. */
13
+ to?: CFStatePair;
14
+ /** Computed display label — present only when the transition was applied. */
15
+ displayState?: string;
16
+ }
17
+ export type ApplyTransition = (params: ApplyTransitionParams) => Promise<ApplyTransitionResponse>;
@@ -1,14 +1,14 @@
1
- import { createOrderFromCart, MOCK_CART, mockPublishEvent } from "../../demo/database";
1
+ import { applyMockPayment, MOCK_CART } from "../../demo/database";
2
2
  export const mockCashPayment = async (params) => {
3
3
  console.log("[Mock] cashPayment called", params);
4
- // Default to true to match action behavior
4
+ // Default to true to match action behavior.
5
5
  const openChangeCalculator = params?.openChangeCalculator ?? true;
6
- let amount = params?.amount || MOCK_CART.total;
6
+ // Amount due for THIS tender (the queued amount-to-be-charged), in minor units.
7
+ const due = params?.amount ?? MOCK_CART.amountToBeCharged ?? MOCK_CART.total;
7
8
  if (openChangeCalculator) {
8
9
  try {
9
- const input = window.prompt(`Total Due: $${MOCK_CART.total.toFixed(2)}\nEnter amount tendered:`, amount.toString());
10
+ const input = window.prompt(`Amount due: $${(due / 100).toFixed(2)}\nEnter amount tendered:`, (due / 100).toFixed(2));
10
11
  if (input === null) {
11
- // User cancelled
12
12
  return {
13
13
  success: false,
14
14
  amount: 0,
@@ -18,28 +18,22 @@ export const mockCashPayment = async (params) => {
18
18
  timestamp: new Date().toISOString()
19
19
  };
20
20
  }
21
- const tendered = parseFloat(input);
21
+ const tendered = parseFloat(input); // dollars
22
22
  if (!isNaN(tendered)) {
23
- amount = tendered;
24
- const change = tendered - MOCK_CART.total;
25
- if (change >= 0) {
26
- window.alert(`Change Due: $${change.toFixed(2)}`);
27
- }
28
- else {
29
- window.alert(`Warning: Tendered amount is less than total. Short by: $${Math.abs(change).toFixed(2)}`);
30
- }
23
+ const change = tendered - due / 100;
24
+ window.alert(change >= 0
25
+ ? `Change Due: $${change.toFixed(2)}`
26
+ : `Warning: Tendered is short by: $${Math.abs(change).toFixed(2)}`);
31
27
  }
32
28
  }
33
29
  catch (e) {
34
30
  console.warn("Could not open prompt/alert (possibly in non-interactive environment)", e);
35
31
  }
36
32
  }
37
- const order = createOrderFromCart("cash", amount, "cash");
38
- // Publish payment-done event
39
- mockPublishEvent('payments', 'payment-done', { order });
33
+ const order = applyMockPayment(due, "cash", "cash");
40
34
  return {
41
35
  success: true,
42
- amount,
36
+ amount: due,
43
37
  openChangeCalculator,
44
38
  paymentType: "cash",
45
39
  order,
@@ -1,10 +1,12 @@
1
- import { MOCK_PARKED_ORDERS } from "../../demo/database";
1
+ import { MOCK_PARKED_ORDERS, mockPublishEvent } from "../../demo/database";
2
2
  export const mockDeleteParkedOrder = async (params) => {
3
3
  console.log("[Mock] deleteParkedOrder called", params);
4
4
  if (params?.orderId) {
5
5
  const index = MOCK_PARKED_ORDERS.findIndex(o => o._id === params.orderId);
6
6
  if (index !== -1) {
7
7
  MOCK_PARKED_ORDERS.splice(index, 1);
8
+ // Refresh order lists (the parked-order modal reads getOrders).
9
+ mockPublishEvent("orders", "parked-order-deleted", { orderId: params.orderId });
8
10
  }
9
11
  }
10
12
  return {
@@ -10,7 +10,7 @@ export const mockEditProduct = async (params) => {
10
10
  minorUnits: 2,
11
11
  name: params.changes.name || "Updated Product",
12
12
  description: params.changes.description,
13
- categories: params.changes.categories || [],
13
+ categories: (params.changes.categories || []).map((c) => ({ name: c, externalId: c })),
14
14
  taxTable: params.changes.taxTable || "",
15
15
  images: params.changes.images || [],
16
16
  status: params.changes.status || "active",
@@ -11,6 +11,10 @@ export interface ExtensionPaymentParams {
11
11
  metadata?: Record<string, unknown>;
12
12
  /** Override the fulfillment state after full payment. Render resolves the cascade. */
13
13
  checkoutFulfillmentTarget?: string;
14
+ /** EMV data when the underlying payment carries one (typed as `IntegrationEmvData` by the integration wrapper). */
15
+ emvData?: unknown;
16
+ /** Processor fee in minor units; recorded on the order's paymentMethod.processorFee. */
17
+ processorFee?: number;
14
18
  }
15
19
  export interface ExtensionPaymentResponse {
16
20
  success: boolean;
@@ -24,7 +24,7 @@ export const mockGetContext = () => {
24
24
  thousandSeparator: ",",
25
25
  decimalSeparator: ".",
26
26
  user: null,
27
- company: null,
27
+ company: { _id: MOCK_COMPANY.id, name: MOCK_COMPANY.name, logo: MOCK_COMPANY.logo },
28
28
  station: null,
29
29
  outlet: null,
30
30
  timestamp: new Date().toISOString()
@@ -1,8 +1,8 @@
1
- import { MOCK_ORDERS, MOCK_USERS, MOCK_STATIONS, MOCK_OUTLETS, safeSerialize } from "../../demo/database";
1
+ import { MOCK_ORDERS, MOCK_PARKED_ORDERS, MOCK_USERS, MOCK_STATIONS, MOCK_OUTLETS, safeSerialize } from "../../demo/database";
2
2
  export const mockGetOrders = async (params) => {
3
3
  console.log("[Mock] getOrders called", params);
4
- // Start with a safe copy of mock orders
5
- let orders = safeSerialize(MOCK_ORDERS);
4
+ // Start with a safe copy of mock orders, including parked (status: "parked").
5
+ let orders = safeSerialize([...MOCK_ORDERS, ...MOCK_PARKED_ORDERS]);
6
6
  // Filter simulation
7
7
  if (params) {
8
8
  const { customerId, status, sessionId, searchValue, limit, offset, sortBy, sortDirection } = params;
@@ -13,19 +13,24 @@ export const mockGetProducts = async (params) => {
13
13
  // Handle categories filter: { $in: [...] } or direct string
14
14
  const catFilter = query.categories;
15
15
  if (typeof catFilter === 'string') {
16
- products = products.filter(p => (p.categories || []).includes(catFilter));
16
+ products = products.filter(p => (p.categories || []).some(c => c.name === catFilter));
17
17
  }
18
18
  else if (typeof catFilter === 'object' && '$in' in catFilter) {
19
19
  const inList = catFilter.$in;
20
- products = products.filter(p => (p.categories || []).some(c => inList.includes(c)));
20
+ products = products.filter(p => (p.categories || []).some(c => inList.includes(c.name)));
21
21
  }
22
22
  else if (typeof catFilter === 'object' && '$contains' in catFilter) {
23
23
  const containsVal = catFilter.$contains;
24
- products = products.filter(p => (p.categories || []).includes(containsVal));
24
+ products = products.filter(p => (p.categories || []).some(c => c.name.includes(containsVal)));
25
25
  }
26
26
  }
27
+ const total = products.length;
28
+ const offset = params?.offset ?? 0;
29
+ const limit = params?.limit ?? 100;
30
+ const paged = products.slice(offset, offset + limit);
27
31
  return {
28
- products: safeSerialize(products),
32
+ products: safeSerialize(paged),
33
+ total,
29
34
  timestamp: new Date().toISOString()
30
35
  };
31
36
  };
@@ -29,6 +29,8 @@ export interface GetProductsParams {
29
29
  }
30
30
  export interface GetProductsResponse {
31
31
  products: CFProduct[];
32
+ /** Total number of products matching the query, ignoring offset/limit. Optional — hosts that cannot cheaply compute the total may omit it. */
33
+ total?: number;
32
34
  timestamp: string;
33
35
  }
34
36
  export type GetProducts = (params?: GetProductsParams) => Promise<GetProductsResponse>;
@@ -4,61 +4,55 @@ export const mockGetRoles = async (params) => {
4
4
  roles: [
5
5
  {
6
6
  id: "691df9c6c478bada1fb23d0b",
7
- _id: "691df9c6c478bada1fb23d0b",
8
- companyId: "691df9c4c478bada1fb23bff",
9
7
  name: "Owner",
10
8
  permissions: [
11
- { category: "hub_access", name: "taxes", value: true, subCategory: "store_management", permissionId: "664759347eefffe8aba84476" },
12
- { category: "hub_access", name: "general", value: true, subCategory: "store_management", permissionId: "6647591d7eefffe8aba84475" },
13
- { category: "hub_access", name: "reports", value: true, subCategory: "store_management", permissionId: "6645f719ee8498efff5c49bb" },
14
- { category: "hub_access", name: "products", value: true, subCategory: "store_management", permissionId: "6645f719f00dc43caaeffe2b" },
15
- { category: "hub_access", name: "users", value: true, subCategory: "store_management", permissionId: "6647555b7eefffe8aba84473" },
16
- { category: "hub_access", name: "outlets", value: true, subCategory: "store_management", permissionId: "664759047eefffe8aba84474" },
17
- { category: "hub_access", name: "builder", value: true, subCategory: "builder_access", permissionId: "664779827eefffe8aba84477" },
18
- { category: "hub_access", name: "global_blocks", value: true, subCategory: "builder_access", permissionId: "6645f719f00dc43caaeffe47" },
19
- { category: "hub_access", name: "images", value: true, subCategory: "builder_access", permissionId: "6645f719ee8498efff5c49dc" },
20
- { category: "hub_access", name: "transactions", value: true, subCategory: "payments_access", permissionId: "6645f719ee8498efff5c4a6b" },
21
- { category: "hub_access", name: "payouts", value: true, subCategory: "payments_access", permissionId: "66477add7eefffe8aba84478" },
22
- { category: "hub_access", name: "terminals", value: true, subCategory: "payments_access", permissionId: "6645f71998735e68b2c45740" },
23
- { category: "hub_access", name: "billing", value: true, subCategory: "payments_access", permissionId: "66bbb00572999149fdd57866" },
24
- { category: "station_access", name: "give_discounts", value: true, subCategory: "pos_actions", permissionId: "6723b146ae5f176f7539d8a6" },
25
- { category: "station_access", name: "issue_refunds", value: true, subCategory: "pos_actions", permissionId: "6645f719ee8498efff5c4ae4" },
26
- { category: "station_access", name: "delete_customers", value: true, subCategory: "pos_actions", permissionId: "6645f71998735e68b2c457df" },
27
- { category: "station_access", name: "version_control", value: true, subCategory: "station_setting", permissionId: "66e050160d69015fbff9758a" },
28
- { category: "station_access", name: "session_reports", value: true, subCategory: "station_home", permissionId: "6723b271ae5f176f7539d8a7" },
29
- { category: "station_access", name: "cash_drawer", value: true, subCategory: "station_home", permissionId: "6723b2aeae5f176f7539d8a8" },
30
- { category: "station_access", name: "station_setting", value: true, subCategory: "station_home", permissionId: "6723b2c5ae5f176f7539d8a9" },
31
- { category: "station_access", name: "station_transactions", value: true, subCategory: "station_home", permissionId: "677eb109d2607a0169fdf7d5" },
9
+ { category: "hub_access", label: "taxes", name: "taxes", value: true },
10
+ { category: "hub_access", label: "general", name: "general", value: true },
11
+ { category: "hub_access", label: "reports", name: "reports", value: true },
12
+ { category: "hub_access", label: "products", name: "products", value: true },
13
+ { category: "hub_access", label: "users", name: "users", value: true },
14
+ { category: "hub_access", label: "outlets", name: "outlets", value: true },
15
+ { category: "hub_access", label: "builder", name: "builder", value: true },
16
+ { category: "hub_access", label: "global_blocks", name: "global_blocks", value: true },
17
+ { category: "hub_access", label: "images", name: "images", value: true },
18
+ { category: "hub_access", label: "transactions", name: "transactions", value: true },
19
+ { category: "hub_access", label: "payouts", name: "payouts", value: true },
20
+ { category: "hub_access", label: "terminals", name: "terminals", value: true },
21
+ { category: "hub_access", label: "billing", name: "billing", value: true },
22
+ { category: "station_access", label: "give_discounts", name: "give_discounts", value: true },
23
+ { category: "station_access", label: "issue_refunds", name: "issue_refunds", value: true },
24
+ { category: "station_access", label: "delete_customers", name: "delete_customers", value: true },
25
+ { category: "station_access", label: "version_control", name: "version_control", value: true },
26
+ { category: "station_access", label: "session_reports", name: "session_reports", value: true },
27
+ { category: "station_access", label: "cash_drawer", name: "cash_drawer", value: true },
28
+ { category: "station_access", label: "station_setting", name: "station_setting", value: true },
29
+ { category: "station_access", label: "station_transactions", name: "station_transactions", value: true },
32
30
  ]
33
31
  },
34
32
  {
35
33
  id: "691df9c6c478bada1fb23d0c",
36
- _id: "691df9c6c478bada1fb23d0c",
37
- companyId: "691df9c4c478bada1fb23bff",
38
34
  name: "admin",
39
35
  permissions: [
40
- { category: "hub_access", name: "taxes", value: true, subCategory: "store_management", permissionId: "664759347eefffe8aba84476" },
41
- { category: "hub_access", name: "general", value: true, subCategory: "store_management", permissionId: "6647591d7eefffe8aba84475" },
42
- { category: "hub_access", name: "reports", value: true, subCategory: "store_management", permissionId: "6645f719ee8498efff5c49bb" },
43
- { category: "hub_access", name: "products", value: true, subCategory: "store_management", permissionId: "6645f719f00dc43caaeffe2b" },
44
- { category: "hub_access", name: "users", value: true, subCategory: "store_management", permissionId: "6647555b7eefffe8aba84473" },
45
- { category: "hub_access", name: "transactions", value: true, subCategory: "payments_access", permissionId: "6645f719ee8498efff5c4a6b" },
46
- { category: "station_access", name: "give_discounts", value: true, subCategory: "pos_actions", permissionId: "6723b146ae5f176f7539d8a6" },
47
- { category: "station_access", name: "issue_refunds", value: true, subCategory: "pos_actions", permissionId: "6645f719ee8498efff5c4ae4" },
48
- { category: "station_access", name: "delete_customers", value: true, subCategory: "pos_actions", permissionId: "6645f71998735e68b2c457df" },
36
+ { category: "hub_access", label: "taxes", name: "taxes", value: true },
37
+ { category: "hub_access", label: "general", name: "general", value: true },
38
+ { category: "hub_access", label: "reports", name: "reports", value: true },
39
+ { category: "hub_access", label: "products", name: "products", value: true },
40
+ { category: "hub_access", label: "users", name: "users", value: true },
41
+ { category: "hub_access", label: "transactions", name: "transactions", value: true },
42
+ { category: "station_access", label: "give_discounts", name: "give_discounts", value: true },
43
+ { category: "station_access", label: "issue_refunds", name: "issue_refunds", value: true },
44
+ { category: "station_access", label: "delete_customers", name: "delete_customers", value: true },
49
45
  ]
50
46
  },
51
47
  {
52
48
  id: "691df9c6c478bada1fb23d0d",
53
- _id: "691df9c6c478bada1fb23d0d",
54
- companyId: "691df9c4c478bada1fb23bff",
55
49
  name: "cashier",
56
50
  permissions: [
57
- { category: "station_access", name: "give_discounts", value: false, subCategory: "pos_actions", permissionId: "6723b146ae5f176f7539d8a6" },
58
- { category: "station_access", name: "issue_refunds", value: false, subCategory: "pos_actions", permissionId: "6645f719ee8498efff5c4ae4" },
59
- { category: "station_access", name: "delete_customers", value: false, subCategory: "pos_actions", permissionId: "6645f71998735e68b2c457df" },
60
- { category: "station_access", name: "session_reports", value: true, subCategory: "station_home", permissionId: "6723b271ae5f176f7539d8a7" },
61
- { category: "station_access", name: "cash_drawer", value: true, subCategory: "station_home", permissionId: "6723b2aeae5f176f7539d8a8" },
51
+ { category: "station_access", label: "give_discounts", name: "give_discounts", value: false },
52
+ { category: "station_access", label: "issue_refunds", name: "issue_refunds", value: false },
53
+ { category: "station_access", label: "delete_customers", name: "delete_customers", value: false },
54
+ { category: "station_access", label: "session_reports", name: "session_reports", value: true },
55
+ { category: "station_access", label: "cash_drawer", name: "cash_drawer", value: true },
62
56
  ]
63
57
  }
64
58
  ],
@@ -0,0 +1,2 @@
1
+ import type { GetSmartGridLayout } from "./types";
2
+ export declare const getSmartGridLayout: GetSmartGridLayout;
@@ -0,0 +1,4 @@
1
+ import { commandFrameClient } from "../../client";
2
+ export const getSmartGridLayout = async (params) => {
3
+ return await commandFrameClient.call("getSmartGridLayout", params);
4
+ };
@@ -0,0 +1,2 @@
1
+ import { GetSmartGridLayout } from "./types";
2
+ export declare const mockGetSmartGridLayout: GetSmartGridLayout;
@@ -0,0 +1,9 @@
1
+ import { MOCK_SMART_GRID_LAYOUTS } from "../../demo/database";
2
+ export const mockGetSmartGridLayout = (params) => {
3
+ console.log("[Mock] getSmartGridLayout called", params);
4
+ return Promise.resolve({
5
+ success: true,
6
+ layout: MOCK_SMART_GRID_LAYOUTS[params.gridId] ?? null,
7
+ timestamp: new Date().toISOString()
8
+ });
9
+ };
@@ -0,0 +1,10 @@
1
+ import { CFSmartGridLayout } from "../../CommonTypes";
2
+ export interface GetSmartGridLayoutParams {
3
+ gridId: string;
4
+ }
5
+ export interface GetSmartGridLayoutResponse {
6
+ success: boolean;
7
+ layout: CFSmartGridLayout | null;
8
+ timestamp: string;
9
+ }
10
+ export type GetSmartGridLayout = (params: GetSmartGridLayoutParams) => Promise<GetSmartGridLayoutResponse>;