@final-commerce/command-frame 0.5.0 → 0.6.0-staging.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.
Files changed (69) hide show
  1. package/README.md +5 -5
  2. package/dist/CommonTypes.d.ts +6 -6
  3. package/dist/CommonTypes.js +2 -2
  4. package/dist/actions/add-cart-discount/mock.d.ts +1 -1
  5. package/dist/actions/add-cart-discount/mock.js +8 -8
  6. package/dist/actions/add-cart-fee/mock.d.ts +1 -1
  7. package/dist/actions/add-cart-fee/mock.js +8 -8
  8. package/dist/actions/add-product-to-cart/mock.d.ts +1 -1
  9. package/dist/actions/add-product-to-cart/mock.js +24 -10
  10. package/dist/actions/add-product-to-cart/types.d.ts +13 -1
  11. package/dist/actions/adjust-inventory/mock.d.ts +1 -1
  12. package/dist/actions/adjust-inventory/mock.js +6 -6
  13. package/dist/actions/apply-transition/mock.d.ts +1 -1
  14. package/dist/actions/apply-transition/mock.js +8 -8
  15. package/dist/actions/apply-transition/types.d.ts +1 -1
  16. package/dist/actions/authenticate-user/mock.d.ts +1 -1
  17. package/dist/actions/authenticate-user/mock.js +3 -3
  18. package/dist/actions/calculate-refund-total/action.d.ts +1 -1
  19. package/dist/actions/calculate-refund-total/action.js +2 -2
  20. package/dist/actions/can-transition/types.d.ts +1 -1
  21. package/dist/actions/cash-payment/mock.d.ts +1 -1
  22. package/dist/actions/cash-payment/mock.js +10 -10
  23. package/dist/actions/cash-payment/types.d.ts +1 -1
  24. package/dist/actions/extension-payment/mock.d.ts +1 -1
  25. package/dist/actions/extension-payment/mock.js +3 -3
  26. package/dist/actions/extension-payment/types.d.ts +1 -1
  27. package/dist/actions/get-available-transitions/mock.d.ts +1 -1
  28. package/dist/actions/get-available-transitions/mock.js +19 -19
  29. package/dist/actions/get-final-context/mock.d.ts +1 -1
  30. package/dist/actions/get-final-context/mock.js +2 -2
  31. package/dist/actions/get-products/mock.d.ts +1 -1
  32. package/dist/actions/get-products/mock.js +26 -9
  33. package/dist/actions/get-refunds/types.d.ts +1 -1
  34. package/dist/actions/get-remaining-refundable-quantities/action.d.ts +1 -1
  35. package/dist/actions/get-remaining-refundable-quantities/action.js +2 -2
  36. package/dist/actions/get-remaining-refundable-quantities/mock.d.ts +1 -1
  37. package/dist/actions/get-remaining-refundable-quantities/mock.js +2 -2
  38. package/dist/actions/integration-payment/types.d.ts +1 -1
  39. package/dist/actions/park-order/types.d.ts +1 -1
  40. package/dist/actions/partial-payment/mock.d.ts +1 -1
  41. package/dist/actions/partial-payment/mock.js +8 -8
  42. package/dist/actions/partial-payment/types.d.ts +1 -1
  43. package/dist/actions/print/mock.d.ts +1 -1
  44. package/dist/actions/print/mock.js +9 -9
  45. package/dist/actions/print/types.d.ts +6 -6
  46. package/dist/actions/redeem-payment/types.d.ts +1 -1
  47. package/dist/actions/remove-cart-fee/mock.d.ts +1 -1
  48. package/dist/actions/remove-cart-fee/mock.js +7 -7
  49. package/dist/actions/remove-product-from-cart/mock.d.ts +1 -1
  50. package/dist/actions/remove-product-from-cart/mock.js +11 -8
  51. package/dist/actions/resume-parked-order/types.d.ts +1 -1
  52. package/dist/actions/select-all-refund-items/action.d.ts +1 -1
  53. package/dist/actions/select-all-refund-items/action.js +2 -2
  54. package/dist/actions/set-active-product/mock.d.ts +1 -1
  55. package/dist/actions/set-active-product/mock.js +19 -14
  56. package/dist/actions/set-active-refund/types.d.ts +1 -1
  57. package/dist/actions/tap-to-pay-payment/mock.d.ts +1 -1
  58. package/dist/actions/tap-to-pay-payment/mock.js +6 -6
  59. package/dist/actions/tap-to-pay-payment/types.d.ts +1 -1
  60. package/dist/actions/terminal-payment/mock.d.ts +1 -1
  61. package/dist/actions/terminal-payment/mock.js +6 -6
  62. package/dist/actions/terminal-payment/types.d.ts +2 -2
  63. package/dist/actions/update-cart-item-quantity/mock.d.ts +1 -1
  64. package/dist/actions/update-cart-item-quantity/mock.js +23 -15
  65. package/dist/actions/update-cart-item-quantity/types.d.ts +8 -1
  66. package/dist/actions/upsert-custom-table-data/mock.d.ts +1 -1
  67. package/dist/actions/upsert-custom-table-data/mock.js +3 -3
  68. package/dist/demo/database.js +30 -4
  69. package/package.json +2 -2
@@ -1,36 +1,53 @@
1
- import { MOCK_PRODUCTS, safeSerialize } from "../../demo/database";
1
+ import { MOCK_PRODUCTS, safeSerialize } from '../../demo/database';
2
+ import { resolveUnit } from '@final-commerce/common';
2
3
  export const mockGetProducts = async (params) => {
3
- console.log("[Mock] getProducts called", params);
4
+ console.log('[Mock] getProducts called', params);
4
5
  // Simple filter simulation
5
6
  let products = MOCK_PRODUCTS;
6
7
  const query = params?.query || {};
7
8
  if (query.searchValue) {
8
9
  const search = String(query.searchValue).toLowerCase();
9
- products = products.filter(p => p.name.toLowerCase().includes(search) ||
10
- p.sku?.toLowerCase().includes(search));
10
+ products = products.filter((p) => p.name.toLowerCase().includes(search) || p.sku?.toLowerCase().includes(search));
11
11
  }
12
12
  if (query.categories) {
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 || []).some(c => c.name === 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.name)));
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 || []).some(c => c.name.includes(containsVal)));
24
+ products = products.filter((p) => (p.categories || []).some((c) => c.name.includes(containsVal)));
25
25
  }
26
26
  }
27
27
  const total = products.length;
28
28
  const offset = params?.offset ?? 0;
29
29
  const limit = params?.limit ?? 100;
30
30
  const paged = products.slice(offset, offset + limit);
31
+ // Mirror the real host's attachUnits: storage carries only `unitId`, the wire shape
32
+ // adds the RESOLVED unit (abbreviation, ratioToBase, precision) so a card can label
33
+ // stock and a quantity input can pick its step. Unresolvable ids pass through bare
34
+ // rather than killing the page — same stance as the host's per-variant catch.
35
+ const withUnits = safeSerialize(paged).map((product) => ({
36
+ ...product,
37
+ variants: (product.variants ?? []).map((variant) => {
38
+ if (!variant.unitId)
39
+ return variant;
40
+ try {
41
+ return { ...variant, unit: resolveUnit(variant.unitId) };
42
+ }
43
+ catch {
44
+ return variant;
45
+ }
46
+ }),
47
+ }));
31
48
  return {
32
- products: safeSerialize(paged),
49
+ products: withUnits,
33
50
  total,
34
- timestamp: new Date().toISOString()
51
+ timestamp: new Date().toISOString(),
35
52
  };
36
53
  };
@@ -1,4 +1,4 @@
1
- import { CFRefundItem } from "../../CommonTypes";
1
+ import { CFRefundItem } from '../../CommonTypes';
2
2
  export interface GetRefundsParams {
3
3
  orderId?: string;
4
4
  sessionId?: string;
@@ -2,5 +2,5 @@
2
2
  * Get remaining refundable quantities action
3
3
  * Calls the getRemainingRefundableQuantities action on the parent window
4
4
  */
5
- import type { GetRemainingRefundableQuantities } from "./types";
5
+ import type { GetRemainingRefundableQuantities } from './types';
6
6
  export declare const getRemainingRefundableQuantities: GetRemainingRefundableQuantities;
@@ -2,7 +2,7 @@
2
2
  * Get remaining refundable quantities action
3
3
  * Calls the getRemainingRefundableQuantities action on the parent window
4
4
  */
5
- import { commandFrameClient } from "../../client";
5
+ import { commandFrameClient } from '../../client';
6
6
  export const getRemainingRefundableQuantities = async (params) => {
7
- return await commandFrameClient.call("getRemainingRefundableQuantities", params);
7
+ return await commandFrameClient.call('getRemainingRefundableQuantities', params);
8
8
  };
@@ -1,2 +1,2 @@
1
- import { GetRemainingRefundableQuantities } from "./types";
1
+ import { GetRemainingRefundableQuantities } from './types';
2
2
  export declare const mockGetRemainingRefundableQuantities: GetRemainingRefundableQuantities;
@@ -1,11 +1,11 @@
1
1
  export const mockGetRemainingRefundableQuantities = async (_params) => {
2
- console.log("[Mock] getRemainingRefundableQuantities called", _params);
2
+ console.log('[Mock] getRemainingRefundableQuantities called', _params);
3
3
  return {
4
4
  success: true,
5
5
  lineItems: {},
6
6
  customSales: {},
7
7
  cartFees: {},
8
8
  tips: {},
9
- timestamp: new Date().toISOString()
9
+ timestamp: new Date().toISOString(),
10
10
  };
11
11
  };
@@ -1,4 +1,4 @@
1
- import type { ExtensionPaymentResponse } from "../extension-payment/types";
1
+ import type { ExtensionPaymentResponse } from '../extension-payment/types';
2
2
  /**
3
3
  * Card display fields for an integration payment.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { CFOrder } from "../../CommonTypes";
1
+ import { CFOrder } from '../../CommonTypes';
2
2
  export interface ParkOrderResponse {
3
3
  success: boolean;
4
4
  order: CFOrder;
@@ -1,2 +1,2 @@
1
- import { PartialPayment } from "./types";
1
+ import { PartialPayment } from './types';
2
2
  export declare const mockPartialPayment: PartialPayment;
@@ -1,18 +1,18 @@
1
- import { MOCK_CART, mockPublishEvent } from "../../demo/database";
2
- import { percentToFraction, requireMinorUnitsInteger } from "../../demo/units";
1
+ import { MOCK_CART, mockPublishEvent } from '../../demo/database';
2
+ import { percentToFraction, requireMinorUnitsInteger } from '../../demo/units';
3
3
  export const mockPartialPayment = async (params) => {
4
- console.log("[Mock] partialPayment called", params);
4
+ console.log('[Mock] partialPayment called', params);
5
5
  const openUI = params?.openUI ?? true;
6
6
  if (openUI) {
7
7
  // Split-payment UI is host-owned; nothing to simulate here.
8
- window.alert("Demo: Split Payment UI would open here.");
8
+ window.alert('Demo: Split Payment UI would open here.');
9
9
  return {
10
10
  success: true,
11
11
  amount: params?.amount,
12
12
  isPercent: params?.isPercent || false,
13
13
  openUI,
14
14
  order: null,
15
- timestamp: new Date().toISOString()
15
+ timestamp: new Date().toISOString(),
16
16
  };
17
17
  }
18
18
  // Queue a partial amount as the next tender. The remaining balance is left
@@ -23,15 +23,15 @@ export const mockPartialPayment = async (params) => {
23
23
  // directly; a percent is raw 0-100 against the remaining total.
24
24
  const charge = params?.isPercent
25
25
  ? Math.round(remaining * percentToFraction(raw))
26
- : requireMinorUnitsInteger(raw, "Payment amount");
26
+ : requireMinorUnitsInteger(raw, 'Payment amount');
27
27
  MOCK_CART.amountToBeCharged = Math.min(Math.max(0, charge), remaining);
28
- mockPublishEvent("cart", "partial-payment-set", { amountToBeCharged: MOCK_CART.amountToBeCharged });
28
+ mockPublishEvent('cart', 'partial-payment-set', { amountToBeCharged: MOCK_CART.amountToBeCharged });
29
29
  return {
30
30
  success: true,
31
31
  amount: params?.amount,
32
32
  isPercent: params?.isPercent || false,
33
33
  openUI,
34
34
  order: null,
35
- timestamp: new Date().toISOString()
35
+ timestamp: new Date().toISOString(),
36
36
  };
37
37
  };
@@ -1,4 +1,4 @@
1
- import { CFOrder } from "../../CommonTypes";
1
+ import { CFOrder } from '../../CommonTypes';
2
2
  export interface PartialPaymentParams {
3
3
  /** The payment amount in integer MINOR currency units (required if openUI is false). If isPercent is true, this is a percentage (0-100) instead. */
4
4
  amount?: number;
@@ -1,2 +1,2 @@
1
- import { Print } from "./types";
1
+ import { Print } from './types';
2
2
  export declare const mockPrint: Print;
@@ -1,25 +1,25 @@
1
1
  export const mockPrint = (params) => {
2
- console.log("[Mock] print called", params);
2
+ console.log('[Mock] print called', params);
3
3
  if (!params) {
4
- throw new Error("Print parameters are required");
4
+ throw new Error('Print parameters are required');
5
5
  }
6
6
  // Mock implementation - just log what would be printed
7
7
  switch (params.type) {
8
- case "image":
9
- console.log("[Mock] Would print image:", params.data.image?.substring(0, 50) + "...");
8
+ case 'image':
9
+ console.log('[Mock] Would print image:', params.data.image?.substring(0, 50) + '...');
10
10
  break;
11
- case "html":
11
+ case 'html':
12
12
  console.warn("[Mock] print type 'html' is DEPRECATED — rasterize and use type: 'image'.");
13
- console.log("[Mock] Would print HTML:", params.data.html?.substring(0, 100) + "...");
13
+ console.log('[Mock] Would print HTML:', params.data.html?.substring(0, 100) + '...');
14
14
  break;
15
- case "receipt":
15
+ case 'receipt':
16
16
  console.warn("[Mock] print type 'receipt' is DEPRECATED — rasterize and use type: 'image'.");
17
- console.log("[Mock] Would print receipt for order:", params.data.order);
17
+ console.log('[Mock] Would print receipt for order:', params.data.order);
18
18
  break;
19
19
  }
20
20
  return Promise.resolve({
21
21
  success: true,
22
22
  timestamp: new Date().toISOString(),
23
- type: params.type
23
+ type: params.type,
24
24
  });
25
25
  };
@@ -1,14 +1,14 @@
1
- import type { CFActiveOrder } from "../../CommonTypes";
2
- export type PrintType = "image" | "html" | "receipt";
1
+ import type { CFActiveOrder } from '../../CommonTypes';
2
+ export type PrintType = 'image' | 'html' | 'receipt';
3
3
  export type PrintParams = {
4
- type: "image";
4
+ type: 'image';
5
5
  data: {
6
6
  image: string;
7
7
  };
8
8
  options?: PrintOptions;
9
9
  } | {
10
10
  /** @deprecated Rasterize your HTML and use `type: "image"`. The native path posts raw HTML to the shell (no html2canvas/sanitization) and PrintOptions may be dropped. */
11
- type: "html";
11
+ type: 'html';
12
12
  data: {
13
13
  html: string;
14
14
  };
@@ -19,9 +19,9 @@ export type PrintParams = {
19
19
  * The station requires `order` (no active-order fallback), ignores
20
20
  * `globalBlockId`, and drops ALL PrintOptions (including tag routing).
21
21
  */
22
- type: "receipt";
22
+ type: 'receipt';
23
23
  data: {
24
- order?: Omit<CFActiveOrder, "_id">;
24
+ order?: Omit<CFActiveOrder, '_id'>;
25
25
  globalBlockId?: string;
26
26
  };
27
27
  options?: PrintOptions;
@@ -1,4 +1,4 @@
1
- import type { ExtensionPaymentResponse } from "../extension-payment/types";
1
+ import type { ExtensionPaymentResponse } from '../extension-payment/types';
2
2
  /**
3
3
  * Redeem (e.g. gift card) — always uses paymentType `"redeem"` on the wire.
4
4
  * `amount` is required so the persisted payment never silently falls back to the cart
@@ -1,2 +1,2 @@
1
- import type { RemoveCartFee } from "./types";
1
+ import type { RemoveCartFee } from './types';
2
2
  export declare const mockRemoveCartFee: RemoveCartFee;
@@ -1,4 +1,4 @@
1
- import { MOCK_CART, mockPublishEvent } from "../../demo/database";
1
+ import { MOCK_CART, mockPublishEvent } from '../../demo/database';
2
2
  function feeContributionToTotal(fee, subtotal) {
3
3
  // A percent fee is STORED as a fraction (10% -> 0.1), so it scales the
4
4
  // subtotal directly. Dividing by 100 again credited back a hundredth of the
@@ -9,14 +9,14 @@ function feeContributionToTotal(fee, subtotal) {
9
9
  return fee.amount;
10
10
  }
11
11
  export const mockRemoveCartFee = (params) => {
12
- console.log("[Mock] removeCartFee called", params);
12
+ console.log('[Mock] removeCartFee called', params);
13
13
  const { index } = params;
14
- if (typeof index !== "number" || !Number.isInteger(index) || index < 0) {
15
- throw new Error("removeCartFee requires a non-negative integer index");
14
+ if (typeof index !== 'number' || !Number.isInteger(index) || index < 0) {
15
+ throw new Error('removeCartFee requires a non-negative integer index');
16
16
  }
17
17
  const fees = MOCK_CART.customFee;
18
18
  if (!fees?.length) {
19
- throw new Error("Cart has no fees to remove");
19
+ throw new Error('Cart has no fees to remove');
20
20
  }
21
21
  if (index >= fees.length) {
22
22
  throw new Error(`Cart fee index ${index} is out of range (0–${fees.length - 1})`);
@@ -30,9 +30,9 @@ export const mockRemoveCartFee = (params) => {
30
30
  MOCK_CART.total -= delta;
31
31
  MOCK_CART.amountToBeCharged = MOCK_CART.total;
32
32
  MOCK_CART.remainingBalance = MOCK_CART.total;
33
- mockPublishEvent("cart", "cart-fee-removed", { feeIndex: index });
33
+ mockPublishEvent('cart', 'cart-fee-removed', { feeIndex: index });
34
34
  return Promise.resolve({
35
35
  success: true,
36
- timestamp: new Date().toISOString()
36
+ timestamp: new Date().toISOString(),
37
37
  });
38
38
  };
@@ -1,2 +1,2 @@
1
- import { RemoveProductFromCart } from "./types";
1
+ import { RemoveProductFromCart } from './types';
2
2
  export declare const mockRemoveProductFromCart: RemoveProductFromCart;
@@ -1,12 +1,13 @@
1
- import { MOCK_CART, mockPublishEvent } from "../../demo/database";
1
+ import { MOCK_CART, mockPublishEvent } from '../../demo/database';
2
+ import { extendPrice } from '@final-commerce/common';
2
3
  export const mockRemoveProductFromCart = (params) => {
3
- console.log("[Mock] removeProductFromCart called", params);
4
+ console.log('[Mock] removeProductFromCart called', params);
4
5
  if (!params?.internalId) {
5
- throw new Error("internalId is required");
6
+ throw new Error('internalId is required');
6
7
  }
7
8
  const { internalId } = params;
8
9
  // Find the product in the cart
9
- const productIndex = MOCK_CART.products.findIndex(p => p.internalId === internalId);
10
+ const productIndex = MOCK_CART.products.findIndex((p) => p.internalId === internalId);
10
11
  if (productIndex === -1) {
11
12
  throw new Error(`Cart item with internalId ${internalId} not found`);
12
13
  }
@@ -14,19 +15,21 @@ export const mockRemoveProductFromCart = (params) => {
14
15
  // Remove from cart
15
16
  MOCK_CART.products.splice(productIndex, 1);
16
17
  // Recalculate totals
17
- const lineTotal = product.price * product.quantity;
18
+ // The same rounded extension the add path put on: subtracting a raw multiply from a
19
+ // weighed line would leave the cent extendPrice rounded away stuck in the cart total.
20
+ const lineTotal = extendPrice(product.price, product.quantity);
18
21
  MOCK_CART.subtotal -= lineTotal;
19
22
  MOCK_CART.total -= lineTotal;
20
23
  MOCK_CART.amountToBeCharged = MOCK_CART.total;
21
24
  MOCK_CART.remainingBalance = MOCK_CART.total;
22
25
  // Publish product-deleted event
23
- mockPublishEvent("cart", "product-deleted", {
26
+ mockPublishEvent('cart', 'product-deleted', {
24
27
  product: product,
25
- internalId: internalId
28
+ internalId: internalId,
26
29
  });
27
30
  return Promise.resolve({
28
31
  success: true,
29
32
  internalId: internalId,
30
- timestamp: new Date().toISOString()
33
+ timestamp: new Date().toISOString(),
31
34
  });
32
35
  };
@@ -1,4 +1,4 @@
1
- import { CFOrder } from "../../CommonTypes";
1
+ import { CFOrder } from '../../CommonTypes';
2
2
  export interface ResumeParkedOrderParams {
3
3
  orderId: string;
4
4
  }
@@ -2,5 +2,5 @@
2
2
  * Select all refund items action
3
3
  * Calls the selectAllRefundItems action on the parent window
4
4
  */
5
- import type { SelectAllRefundItems } from "./types";
5
+ import type { SelectAllRefundItems } from './types';
6
6
  export declare const selectAllRefundItems: SelectAllRefundItems;
@@ -2,7 +2,7 @@
2
2
  * Select all refund items action
3
3
  * Calls the selectAllRefundItems action on the parent window
4
4
  */
5
- import { commandFrameClient } from "../../client";
5
+ import { commandFrameClient } from '../../client';
6
6
  export const selectAllRefundItems = async (params) => {
7
- return await commandFrameClient.call("selectAllRefundItems", params);
7
+ return await commandFrameClient.call('selectAllRefundItems', params);
8
8
  };
@@ -1,2 +1,2 @@
1
- import type { SetActiveProduct } from "./types";
1
+ import type { SetActiveProduct } from './types';
2
2
  export declare const mockSetActiveProduct: SetActiveProduct;
@@ -1,47 +1,52 @@
1
- import { MOCK_PRODUCTS, setMockActiveProduct } from "../../demo/database";
1
+ import { MOCK_PRODUCTS, setMockActiveProduct } from '../../demo/database';
2
+ import { resolveUnit } from '@final-commerce/common';
2
3
  export const mockSetActiveProduct = async (params) => {
3
- console.log("[Mock] setActiveProduct called", params);
4
+ console.log('[Mock] setActiveProduct called', params);
4
5
  if (!params?.variantId) {
5
- throw new Error("Variant ID is required");
6
+ throw new Error('Variant ID is required');
6
7
  }
7
8
  const { variantId } = params;
8
9
  let matchedProduct;
9
10
  let matchedVariant;
10
11
  for (const product of MOCK_PRODUCTS) {
11
- const variant = product.variants.find(v => v._id === variantId);
12
+ const variant = product.variants.find((v) => v._id === variantId);
12
13
  if (variant) {
13
14
  matchedProduct = product;
14
15
  matchedVariant = variant;
15
16
  break;
16
17
  }
17
18
  }
19
+ // The unit the variant sells in, resolved exactly as the add-to-cart mock does — the
20
+ // product card reads the ACTIVE product, and without this it cannot label "100" as kg.
21
+ const unit = matchedVariant?.unitId ? resolveUnit(matchedVariant.unitId) : undefined;
18
22
  const activeProduct = {
19
- id: matchedProduct?._id || "mock_product",
23
+ id: matchedProduct?._id || 'mock_product',
20
24
  internalId: `internal_${Date.now()}`,
21
- externalId: matchedVariant?.externalId || "mock_external_id",
22
- productExternalId: matchedProduct?.externalId || "mock_product_external_id",
25
+ externalId: matchedVariant?.externalId || 'mock_external_id',
26
+ productExternalId: matchedProduct?.externalId || 'mock_product_external_id',
23
27
  variantId: matchedVariant?._id || variantId,
24
- name: matchedProduct?.name || "Mock Product",
25
- sku: matchedVariant?.sku || "mock_sku",
28
+ name: matchedProduct?.name || 'Mock Product',
29
+ sku: matchedVariant?.sku || 'mock_sku',
26
30
  price: matchedVariant?.price || 100,
27
31
  images: matchedVariant?.images || matchedProduct?.images || [],
28
- taxTableId: matchedProduct?.taxTable || "mock_tax_table_id",
32
+ taxTableId: matchedProduct?.taxTable || 'mock_tax_table_id',
29
33
  quantity: 1,
30
34
  note: undefined,
31
35
  discount: undefined,
32
- description: matchedProduct?.description || "Mock Description",
33
- barcodeId: matchedVariant?.barcode || "mock_barcode_id",
36
+ description: matchedProduct?.description || 'Mock Description',
37
+ barcodeId: matchedVariant?.barcode || 'mock_barcode_id',
34
38
  stock: matchedVariant?.inventory?.[0]?.stock ?? 100,
39
+ ...(unit ? { unit } : {}),
35
40
  allowBackOrder: matchedVariant?.allowBackorder || false,
36
41
  fee: undefined,
37
42
  isUnlimited: !matchedVariant?.manageStock,
38
- attributes: matchedVariant?.attributes?.map(a => a.value).join(", ") || "",
43
+ attributes: matchedVariant?.attributes?.map((a) => a.value).join(', ') || '',
39
44
  localQuantity: 1,
40
45
  };
41
46
  setMockActiveProduct(activeProduct);
42
47
  return {
43
48
  success: true,
44
49
  product: activeProduct,
45
- timestamp: new Date().toISOString()
50
+ timestamp: new Date().toISOString(),
46
51
  };
47
52
  };
@@ -1,4 +1,4 @@
1
- import { CFActiveRefundDetails } from "../../CommonTypes";
1
+ import { CFActiveRefundDetails } from '../../CommonTypes';
2
2
  export interface SetActiveRefundParams {
3
3
  orderId: string;
4
4
  }
@@ -1,2 +1,2 @@
1
- import { TapToPayPayment } from "./types";
1
+ import { TapToPayPayment } from './types';
2
2
  export declare const mockTapToPayPayment: TapToPayPayment;
@@ -1,19 +1,19 @@
1
- import { applyMockPayment, MOCK_CART } from "../../demo/database";
1
+ import { applyMockPayment, MOCK_CART } from '../../demo/database';
2
2
  export const mockTapToPayPayment = async (params) => {
3
- console.log("[Mock] tapToPayPayment called", params);
3
+ console.log('[Mock] tapToPayPayment called', params);
4
4
  // Simulate Tap to Pay interaction
5
- window.alert("Demo: Processing Tap to Pay...\n(Please tap card or device on screen)");
5
+ window.alert('Demo: Processing Tap to Pay...\n(Please tap card or device on screen)');
6
6
  const due = params?.amount ?? MOCK_CART.amountToBeCharged ?? MOCK_CART.total;
7
- const order = applyMockPayment(due, "card", "tapToPay");
7
+ const order = applyMockPayment(due, 'card', 'tapToPay');
8
8
  return {
9
9
  success: true,
10
10
  amount: due,
11
- paymentType: "tapToPay",
11
+ paymentType: 'tapToPay',
12
12
  order,
13
13
  timestamp: new Date().toISOString(),
14
14
  change: 0,
15
15
  cashRounding: 0,
16
16
  saleFinalized: true,
17
- remainingBalance: 0
17
+ remainingBalance: 0,
18
18
  };
19
19
  };
@@ -1,4 +1,4 @@
1
- import { CFOrder } from "../../CommonTypes";
1
+ import { CFOrder } from '../../CommonTypes';
2
2
  export interface TapToPayPaymentParams {
3
3
  /**
4
4
  * The amount to pay with this tender, in integer MINOR currency units
@@ -1,2 +1,2 @@
1
- import { TerminalPayment } from "./types";
1
+ import { TerminalPayment } from './types';
2
2
  export declare const mockTerminalPayment: TerminalPayment;
@@ -1,20 +1,20 @@
1
- import { applyMockPayment, MOCK_CART } from "../../demo/database";
1
+ import { applyMockPayment, MOCK_CART } from '../../demo/database';
2
2
  export const mockTerminalPayment = async (params) => {
3
- console.log("[Mock] terminalPayment called", params);
4
- const connectionType = params?.paymentType || "Cloud";
3
+ console.log('[Mock] terminalPayment called', params);
4
+ const connectionType = params?.paymentType || 'Cloud';
5
5
  // Simulate terminal interaction
6
6
  window.alert(`Demo: Processing ${connectionType} Terminal Payment...\n(Please tap, insert, or swipe card on terminal)`);
7
7
  const due = params?.amount ?? MOCK_CART.amountToBeCharged ?? MOCK_CART.total;
8
- const order = applyMockPayment(due, "card", "stripe_terminal");
8
+ const order = applyMockPayment(due, 'card', 'stripe_terminal');
9
9
  return {
10
10
  success: true,
11
11
  amount: due,
12
- paymentType: "terminal",
12
+ paymentType: 'terminal',
13
13
  order,
14
14
  timestamp: new Date().toISOString(),
15
15
  change: 0,
16
16
  cashRounding: 0,
17
17
  saleFinalized: true,
18
- remainingBalance: 0
18
+ remainingBalance: 0,
19
19
  };
20
20
  };
@@ -1,4 +1,4 @@
1
- import { CFOrder } from "../../CommonTypes";
1
+ import { CFOrder } from '../../CommonTypes';
2
2
  export interface TerminalPaymentParams {
3
3
  /**
4
4
  * The amount to pay with this tender, in integer MINOR currency units
@@ -11,7 +11,7 @@ export interface TerminalPaymentParams {
11
11
  */
12
12
  amount: number;
13
13
  /** "Bluetooth" or "Cloud". Only "Cloud" routes to the cloud processor; omitted or "Bluetooth" uses the native card reader. */
14
- paymentType?: "Bluetooth" | "Cloud";
14
+ paymentType?: 'Bluetooth' | 'Cloud';
15
15
  /** Override the fulfillment state the order lands in on full payment (validated against the fulfillment state machine; invalid values throw). Omitted: preserve advanced fulfillment, auto-fulfill from draft/pending/on_hold. */
16
16
  checkoutFulfillmentTarget?: string;
17
17
  }
@@ -1,2 +1,2 @@
1
- import { UpdateCartItemQuantity } from "./types";
1
+ import { UpdateCartItemQuantity } from './types';
2
2
  export declare const mockUpdateCartItemQuantity: UpdateCartItemQuantity;