@final-commerce/command-frame 0.1.50 → 0.1.52

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.
@@ -1,9 +1,9 @@
1
1
  import type { ExtensionRefundParams, ExtensionRefundResponse } from "./types";
2
2
  /**
3
3
  * Install a message listener in the **extension iframe** so the host can request refunds.
4
- * Validates `event.source === window.parent` before handling.
4
+ * Validates `event.source === window.top` before handling.
5
5
  *
6
- * Replies with {@link PostMessageResponse}, using `event.origin` as the target origin when posting back to the parent.
6
+ * Replies with {@link PostMessageResponse}, using `event.origin` as the target origin when posting back to the host.
7
7
  *
8
8
  * @param handler - Perform the extension-side refund (API call, etc.)
9
9
  * @returns Unsubscribe function
@@ -4,9 +4,9 @@ function isRecord(value) {
4
4
  }
5
5
  /**
6
6
  * Install a message listener in the **extension iframe** so the host can request refunds.
7
- * Validates `event.source === window.parent` before handling.
7
+ * Validates `event.source === window.top` before handling.
8
8
  *
9
- * Replies with {@link PostMessageResponse}, using `event.origin` as the target origin when posting back to the parent.
9
+ * Replies with {@link PostMessageResponse}, using `event.origin` as the target origin when posting back to the host.
10
10
  *
11
11
  * @param handler - Perform the extension-side refund (API call, etc.)
12
12
  * @returns Unsubscribe function
@@ -21,7 +21,7 @@ export function installExtensionRefundListener(handler) {
21
21
  if (typeof requestId !== "string") {
22
22
  return;
23
23
  }
24
- if (event.source !== window.parent || !event.source) {
24
+ if (event.source !== window.top || !event.source) {
25
25
  return;
26
26
  }
27
27
  const source = event.source;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Remove cart discount action
3
+ * Calls the removeCartDiscount action on the parent window
4
+ */
5
+ import type { RemoveCartDiscount } from "./types";
6
+ export declare const removeCartDiscount: RemoveCartDiscount;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Remove cart discount action
3
+ * Calls the removeCartDiscount action on the parent window
4
+ */
5
+ import { commandFrameClient } from "../../client";
6
+ export const removeCartDiscount = async () => {
7
+ return await commandFrameClient.call("removeCartDiscount");
8
+ };
@@ -0,0 +1,2 @@
1
+ import { RemoveCartDiscount } from "./types";
2
+ export declare const mockRemoveCartDiscount: RemoveCartDiscount;
@@ -0,0 +1,15 @@
1
+ import { MOCK_CART, mockPublishEvent } from "../../demo/database";
2
+ export const mockRemoveCartDiscount = async () => {
3
+ console.log("[Mock] removeCartDiscount called");
4
+ if (MOCK_CART.discount) {
5
+ delete MOCK_CART.discount;
6
+ MOCK_CART.total = MOCK_CART.subtotal;
7
+ MOCK_CART.amountToBeCharged = MOCK_CART.subtotal;
8
+ MOCK_CART.remainingBalance = MOCK_CART.subtotal;
9
+ mockPublishEvent("cart", "cart-discount-removed", {});
10
+ }
11
+ return {
12
+ success: true,
13
+ timestamp: new Date().toISOString()
14
+ };
15
+ };
@@ -0,0 +1,5 @@
1
+ export interface RemoveCartDiscountResponse {
2
+ success: boolean;
3
+ timestamp: string;
4
+ }
5
+ export type RemoveCartDiscount = () => Promise<RemoveCartDiscountResponse>;
@@ -0,0 +1 @@
1
+ export {};
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Command Frame Client for iframe communication
3
- * Allows the iframe to call functions on the parent window via postMessage
3
+ * Allows the iframe to call functions on the host (top) window via postMessage
4
4
  */
5
5
  export interface PostMessageRequest<T = any> {
6
6
  action: string;
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Command Frame Client for iframe communication
3
- * Allows the iframe to call functions on the parent window via postMessage
3
+ * Allows the iframe to call functions on the host (top) window via postMessage
4
4
  */
5
5
  export class CommandFrameClient {
6
6
  constructor(options = {}) {
@@ -14,7 +14,7 @@ export class CommandFrameClient {
14
14
  this.mockRegistry = options.mockRegistry || {};
15
15
  // If running standalone (no parent window), force Mock Mode immediately
16
16
  // This prevents the 2s delay and ensures immediate response in dev/standalone mode
17
- if (typeof window !== 'undefined' && (!window.parent || window.parent === window)) {
17
+ if (typeof window !== 'undefined' && (!window.top || window.top === window)) {
18
18
  if (this.isDebugEnabled()) {
19
19
  console.log("[ActionsClient] Standalone mode detected. Enabling Mock Mode immediately.");
20
20
  }
@@ -118,15 +118,15 @@ export class CommandFrameClient {
118
118
  timestamp: new Date().toISOString()
119
119
  });
120
120
  }
121
- if (typeof window !== 'undefined' && window.parent) {
122
- window.parent.postMessage(message, this.origin);
121
+ if (typeof window !== 'undefined' && window.top) {
122
+ window.top.postMessage(message, this.origin);
123
123
  }
124
124
  else {
125
125
  clearTimeout(timeoutHandle);
126
126
  this.pendingRequests.delete(requestId);
127
- const error = new Error("No parent window found. This app must run in an iframe.");
127
+ const error = new Error("No host window found. This app must run in an iframe.");
128
128
  if (this.isDebugEnabled()) {
129
- console.error("[ActionsClient] No parent window", error);
129
+ console.error("[ActionsClient] No host window", error);
130
130
  }
131
131
  reject(error);
132
132
  }
@@ -135,7 +135,7 @@ export class CommandFrameClient {
135
135
  // Private check to determine environment
136
136
  detectContext() {
137
137
  return new Promise((resolve) => {
138
- if (typeof window === 'undefined' || !window.parent || window.parent === window)
138
+ if (typeof window === 'undefined' || !window.top || window.top === window)
139
139
  return resolve(null);
140
140
  const requestId = this.generateRequestId();
141
141
  const timeout = setTimeout(() => {
@@ -148,7 +148,7 @@ export class CommandFrameClient {
148
148
  timeout
149
149
  });
150
150
  try {
151
- window.parent.postMessage({ action: "getFinalContext", requestId }, this.origin);
151
+ window.top.postMessage({ action: "getFinalContext", requestId }, this.origin);
152
152
  }
153
153
  catch {
154
154
  clearTimeout(timeout);
@@ -11,8 +11,8 @@ function getOrigin() {
11
11
  function register(topic, callback, options) {
12
12
  const hookId = options.hookId;
13
13
  const functionBody = callback.toString();
14
- if (typeof window !== "undefined" && window.parent && window.parent !== window) {
15
- window.parent.postMessage({
14
+ if (typeof window !== "undefined" && window.top && window.top !== window) {
15
+ window.top.postMessage({
16
16
  type: "hook-register",
17
17
  topic,
18
18
  functionBody,
@@ -26,8 +26,8 @@ function register(topic, callback, options) {
26
26
  * Unregister a hook by ID. Sends a message to the host to remove the hook.
27
27
  */
28
28
  function unregister(hookId) {
29
- if (typeof window !== "undefined" && window.parent && window.parent !== window) {
30
- window.parent.postMessage({
29
+ if (typeof window !== "undefined" && window.top && window.top !== window) {
30
+ window.top.postMessage({
31
31
  type: "hook-unregister",
32
32
  hookId
33
33
  }, getOrigin());
package/dist/index.d.ts CHANGED
@@ -35,6 +35,7 @@ export declare const command: {
35
35
  readonly redeemPayment: import("./actions/redeem-payment/types").RedeemPayment;
36
36
  readonly addCustomerNote: import("./actions/add-customer-note/types").AddCustomerNote;
37
37
  readonly removeCustomerFromCart: import("./actions/remove-customer-from-cart/types").RemoveCustomerFromCart;
38
+ readonly removeCartDiscount: import("./actions/remove-cart-discount/types").RemoveCartDiscount;
38
39
  readonly goToStationHome: import("./actions/go-to-station-home/types").GoToStationHome;
39
40
  readonly openCashDrawer: import("./actions/open-cash-drawer/types").OpenCashDrawer;
40
41
  readonly showNotification: import("./actions/show-notification/types").ShowNotification;
@@ -131,6 +132,7 @@ export { installExtensionRefundListener } from "./actions/extension-refund/exten
131
132
  export type { ExtensionRefundParams, ExtensionRefundResponse } from "./actions/extension-refund/types";
132
133
  export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse } from "./actions/add-customer-note/types";
133
134
  export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from "./actions/remove-customer-from-cart/types";
135
+ export type { RemoveCartDiscount, RemoveCartDiscountResponse } from "./actions/remove-cart-discount/types";
134
136
  export type { GoToStationHome, GoToStationHomeResponse } from "./actions/go-to-station-home/types";
135
137
  export type { OpenCashDrawer, OpenCashDrawerResponse } from "./actions/open-cash-drawer/types";
136
138
  export type { ShowNotification, ShowNotificationParams, ShowNotificationResponse } from "./actions/show-notification/types";
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ import { redeemPayment } from "./actions/redeem-payment/action";
36
36
  // Customer Actions
37
37
  import { addCustomerNote } from "./actions/add-customer-note/action";
38
38
  import { removeCustomerFromCart } from "./actions/remove-customer-from-cart/action";
39
+ import { removeCartDiscount } from "./actions/remove-cart-discount/action";
39
40
  // System Actions
40
41
  import { goToStationHome } from "./actions/go-to-station-home/action";
41
42
  import { openCashDrawer } from "./actions/open-cash-drawer/action";
@@ -131,6 +132,7 @@ export const command = {
131
132
  // Customer Actions
132
133
  addCustomerNote,
133
134
  removeCustomerFromCart,
135
+ removeCartDiscount,
134
136
  // System Actions
135
137
  goToStationHome,
136
138
  openCashDrawer,
@@ -9,6 +9,7 @@ import { mockAddProductFee } from "../../actions/add-product-fee/mock";
9
9
  import { mockAddProductNote } from "../../actions/add-product-note/mock";
10
10
  import { mockAddProductToCart } from "../../actions/add-product-to-cart/mock";
11
11
  import { mockRemoveProductFromCart } from "../../actions/remove-product-from-cart/mock";
12
+ import { mockRemoveCartDiscount } from "../../actions/remove-cart-discount/mock";
12
13
  import { mockUpdateCartItemQuantity } from "../../actions/update-cart-item-quantity/mock";
13
14
  import { mockAdjustInventory } from "../../actions/adjust-inventory/mock";
14
15
  import { mockAssignCustomer } from "../../actions/assign-customer/mock";
@@ -100,6 +101,7 @@ export const RENDER_MOCKS = {
100
101
  partialPayment: mockPartialPayment,
101
102
  processPartialRefund: mockProcessPartialRefund,
102
103
  removeCustomerFromCart: mockRemoveCustomerFromCart,
104
+ removeCartDiscount: mockRemoveCartDiscount,
103
105
  resetRefundDetails: mockResetRefundDetails,
104
106
  resumeParkedOrder: mockResumeParkedOrder,
105
107
  selectAllRefundItems: mockSelectAllRefundItems,
@@ -1,4 +1,4 @@
1
- import type { ExampleFunction, GetProducts, AddCustomSale, GetCustomers, AssignCustomer, AddCustomer, GetCategories, GetOrders, GetRefunds, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, AdjustInventory, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, InitiateRefund, CashPayment, TapToPayPayment, TerminalPayment, VendaraPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, TriggerWebhook, TriggerZapierWebhook, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, GetCurrentCart, Print, SetActiveOrder, GetCustomTables, GetCustomTableData, UpsertCustomTableData, DeleteCustomTableData, GetCustomExtensions, GetCurrentCompanyCustomExtensions, GetCustomExtensionCustomTables, GetCustomTableFields, GetSecretsKeys, GetSecretVal, SetSecretVal, GetUsers, GetRoles } from "../../index";
1
+ import type { ExampleFunction, GetProducts, AddCustomSale, GetCustomers, AssignCustomer, AddCustomer, GetCategories, GetOrders, GetRefunds, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, AdjustInventory, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, InitiateRefund, CashPayment, TapToPayPayment, TerminalPayment, VendaraPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerFromCart, GoToStationHome, OpenCashDrawer, ShowNotification, ShowConfirmation, AuthenticateUser, PartialPayment, SwitchUser, TriggerWebhook, TriggerZapierWebhook, SetRefundStockAction, SelectAllRefundItems, ResetRefundDetails, CalculateRefundTotal, GetRemainingRefundableQuantities, ProcessPartialRefund, GetCurrentCart, Print, SetActiveOrder, GetCustomTables, GetCustomTableData, UpsertCustomTableData, DeleteCustomTableData, GetCustomExtensions, GetCurrentCompanyCustomExtensions, GetCustomExtensionCustomTables, GetCustomTableFields, GetSecretsKeys, GetSecretVal, SetSecretVal, GetUsers, GetRoles, RemoveCartDiscount } from "../../index";
2
2
  export interface RenderProviderActions {
3
3
  exampleFunction: ExampleFunction;
4
4
  getProducts: GetProducts;
@@ -35,6 +35,7 @@ export interface RenderProviderActions {
35
35
  addNonRevenueItem: AddNonRevenueItem;
36
36
  addCustomerNote: AddCustomerNote;
37
37
  removeCustomerFromCart: RemoveCustomerFromCart;
38
+ removeCartDiscount: RemoveCartDiscount;
38
39
  goToStationHome: GoToStationHome;
39
40
  openCashDrawer: OpenCashDrawer;
40
41
  showNotification: ShowNotification;
@@ -12,8 +12,8 @@ export class TopicSubscriber {
12
12
  this.origin = options.origin || "*";
13
13
  this.debug = options.debug ?? false;
14
14
  this.useGlobalDebug = options.debug === undefined;
15
- // Detect standalone mode (no parent iframe)
16
- if (typeof window !== 'undefined' && (!window.parent || window.parent === window)) {
15
+ // Detect standalone mode (not inside any iframe)
16
+ if (typeof window !== 'undefined' && (!window.top || window.top === window)) {
17
17
  this.mockMode = true;
18
18
  if (this.isDebugEnabled()) {
19
19
  console.log("[TopicSubscriber] Mock Mode enabled (standalone mode detected)");
@@ -70,7 +70,7 @@ export class TopicSubscriber {
70
70
  * Request the list of available topics from the host
71
71
  */
72
72
  requestTopics() {
73
- if (typeof window !== "undefined" && window.parent && window.parent !== window) {
73
+ if (typeof window !== "undefined" && window.top && window.top !== window) {
74
74
  const message = {
75
75
  type: "pubsub-request-topics",
76
76
  requestId: `topics_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
@@ -78,7 +78,7 @@ export class TopicSubscriber {
78
78
  if (this.isDebugEnabled()) {
79
79
  console.log("[TopicSubscriber] Requesting topics list", message);
80
80
  }
81
- window.parent.postMessage(message, this.origin);
81
+ window.top.postMessage(message, this.origin);
82
82
  }
83
83
  }
84
84
  /**
@@ -177,7 +177,7 @@ export class TopicSubscriber {
177
177
  * Notify host about subscription changes
178
178
  */
179
179
  notifySubscription(topic, isSubscribed) {
180
- if (typeof window !== "undefined" && window.parent && window.parent !== window) {
180
+ if (typeof window !== "undefined" && window.top && window.top !== window) {
181
181
  const message = {
182
182
  type: isSubscribed ? "pubsub-subscribe" : "pubsub-unsubscribe",
183
183
  topic,
@@ -186,7 +186,7 @@ export class TopicSubscriber {
186
186
  if (this.isDebugEnabled()) {
187
187
  console.log("[TopicSubscriber] Notifying subscription change", message);
188
188
  }
189
- window.parent.postMessage(message, this.origin);
189
+ window.top.postMessage(message, this.origin);
190
190
  }
191
191
  }
192
192
  /**
@@ -203,7 +203,7 @@ export class TopicSubscriber {
203
203
  return;
204
204
  }
205
205
  const data = event.data;
206
- // Clear detection timeout on first valid message from parent
206
+ // Clear detection timeout on first valid message from host
207
207
  if (this.detectionTimeout && data && (data.type === "pubsub-event" || data.type === "pubsub-topics-list")) {
208
208
  clearTimeout(this.detectionTimeout);
209
209
  this.detectionTimeout = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@final-commerce/command-frame",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Commands Frame library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",