@final-commerce/command-frame 0.1.61 → 0.1.63
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/README.md +5 -1
- package/dist/CommonTypes.d.ts +1 -0
- package/dist/actions/add-customer-note/mock.js +1 -0
- package/dist/actions/remove-cart-fee/mock.d.ts +2 -0
- package/dist/actions/remove-cart-fee/mock.js +35 -0
- package/dist/actions/remove-customer-note/action.d.ts +6 -0
- package/dist/actions/remove-customer-note/action.js +8 -0
- package/dist/actions/remove-customer-note/mock.d.ts +2 -0
- package/dist/actions/remove-customer-note/mock.js +13 -0
- package/dist/actions/remove-customer-note/types.d.ts +9 -0
- package/dist/actions/remove-customer-note/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/projects/render/mocks.js +12 -7
- package/dist/projects/render/types.d.ts +3 -1
- package/package.json +24 -2
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@ A TypeScript library for type-safe communication between iframes and their paren
|
|
|
6
6
|
|
|
7
7
|
Command Frame provides a structured way to build integrations that run inside Final Commerce applications (like Render POS or Manage Dashboard). It handles the underlying `postMessage` communication while enforcing strict type safety for both the host application (Provider) and the embedded app (Client).
|
|
8
8
|
|
|
9
|
+
`RenderClient` and `ManageClient` extend `CommandFrameClient`: dynamic methods such as `getProducts()` map to `postMessage` actions named after the method (camelCase), with typed params and responses per project.
|
|
10
|
+
|
|
9
11
|
The library provides three main capabilities:
|
|
10
12
|
|
|
11
13
|
| Capability | Purpose | Scope |
|
|
@@ -15,6 +17,8 @@ The library provides three main capabilities:
|
|
|
15
17
|
| **Hooks** | Register business-logic callbacks that persist across all pages | Session-scoped (survives page navigation) |
|
|
16
18
|
| **Host → iframe refunds** | Render asks the extension to reverse redeem / gift-card payments before completing a POS refund | Parent `postMessage` + `requestId` (see below) |
|
|
17
19
|
|
|
20
|
+
Domain models (orders, cart, customers, products, and related types) are documented in **[Types reference](./src/types/README.md)**.
|
|
21
|
+
|
|
18
22
|
## Installation
|
|
19
23
|
|
|
20
24
|
### From npm (public registry)
|
|
@@ -75,7 +79,7 @@ const context = await client.getContext();
|
|
|
75
79
|
The pub/sub system allows iframe extensions to subscribe to topics and receive real-time events published by the host (Render). Subscriptions are **page-scoped** -- they fire only while the iframe is mounted on the current page.
|
|
76
80
|
|
|
77
81
|
- **[Pub/Sub Documentation](./src/pubsub/README.md)**
|
|
78
|
-
- **Topics:** Cart (
|
|
82
|
+
- **Topics:** Cart (16), Customers (8), Orders (4), Payments (2), Products (4), Refunds (4), Print (3), Custom Tables (3), Outlet (2), Station (2), Session (2), Users (2).
|
|
79
83
|
|
|
80
84
|
```typescript
|
|
81
85
|
import { topics } from '@final-commerce/command-frame';
|
package/dist/CommonTypes.d.ts
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MOCK_CART, mockPublishEvent } from "../../demo/database";
|
|
2
|
+
function feeContributionToTotal(fee, subtotal) {
|
|
3
|
+
if (fee.isPercent) {
|
|
4
|
+
return subtotal * (fee.amount / 100);
|
|
5
|
+
}
|
|
6
|
+
return fee.amount;
|
|
7
|
+
}
|
|
8
|
+
export const mockRemoveCartFee = (params) => {
|
|
9
|
+
console.log("[Mock] removeCartFee called", params);
|
|
10
|
+
const { index } = params;
|
|
11
|
+
if (typeof index !== "number" || !Number.isInteger(index) || index < 0) {
|
|
12
|
+
throw new Error("removeCartFee requires a non-negative integer index");
|
|
13
|
+
}
|
|
14
|
+
const fees = MOCK_CART.customFee;
|
|
15
|
+
if (!fees?.length) {
|
|
16
|
+
throw new Error("Cart has no fees to remove");
|
|
17
|
+
}
|
|
18
|
+
if (index >= fees.length) {
|
|
19
|
+
throw new Error(`Cart fee index ${index} is out of range (0–${fees.length - 1})`);
|
|
20
|
+
}
|
|
21
|
+
const removed = fees[index];
|
|
22
|
+
const delta = feeContributionToTotal(removed, MOCK_CART.subtotal);
|
|
23
|
+
fees.splice(index, 1);
|
|
24
|
+
if (fees.length === 0) {
|
|
25
|
+
MOCK_CART.customFee = undefined;
|
|
26
|
+
}
|
|
27
|
+
MOCK_CART.total -= delta;
|
|
28
|
+
MOCK_CART.amountToBeCharged = MOCK_CART.total;
|
|
29
|
+
MOCK_CART.remainingBalance = MOCK_CART.total;
|
|
30
|
+
mockPublishEvent("cart", "cart-fee-removed", { feeIndex: index });
|
|
31
|
+
return Promise.resolve({
|
|
32
|
+
success: true,
|
|
33
|
+
timestamp: new Date().toISOString()
|
|
34
|
+
});
|
|
35
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove customer note action
|
|
3
|
+
* Calls the removeCustomerNote action on the parent window
|
|
4
|
+
*/
|
|
5
|
+
import { commandFrameClient } from "../../client";
|
|
6
|
+
export const removeCustomerNote = async (params) => {
|
|
7
|
+
return await commandFrameClient.call("removeCustomerNote", params);
|
|
8
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const mockRemoveCustomerNote = async (params) => {
|
|
2
|
+
console.log("[Mock] removeCustomerNote called", params);
|
|
3
|
+
const noteId = params?.noteId ?? "";
|
|
4
|
+
const timestamp = new Date().toISOString();
|
|
5
|
+
if (!noteId) {
|
|
6
|
+
return { success: false, noteId, timestamp };
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
success: true,
|
|
10
|
+
noteId,
|
|
11
|
+
timestamp
|
|
12
|
+
};
|
|
13
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface RemoveCustomerNoteParams {
|
|
2
|
+
noteId: string;
|
|
3
|
+
}
|
|
4
|
+
export interface RemoveCustomerNoteResponse {
|
|
5
|
+
success: boolean;
|
|
6
|
+
noteId: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
}
|
|
9
|
+
export type RemoveCustomerNote = (params?: RemoveCustomerNoteParams) => Promise<RemoveCustomerNoteResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare const command: {
|
|
|
39
39
|
readonly extensionPayment: import("./actions/extension-payment/types").ExtensionPayment;
|
|
40
40
|
readonly redeemPayment: import("./actions/redeem-payment/types").RedeemPayment;
|
|
41
41
|
readonly addCustomerNote: import("./actions/add-customer-note/types").AddCustomerNote;
|
|
42
|
+
readonly removeCustomerNote: import("./actions/remove-customer-note/types").RemoveCustomerNote;
|
|
42
43
|
readonly removeCustomerFromCart: import("./actions/remove-customer-from-cart/types").RemoveCustomerFromCart;
|
|
43
44
|
readonly removeCartDiscount: import("./actions/remove-cart-discount/types").RemoveCartDiscount;
|
|
44
45
|
readonly goToStationHome: import("./actions/go-to-station-home/types").GoToStationHome;
|
|
@@ -160,6 +161,7 @@ export { EXTENSION_REFUND_REQUEST_ACTION } from "./actions/extension-refund/cons
|
|
|
160
161
|
export { installExtensionRefundListener } from "./actions/extension-refund/extension-refund-listener";
|
|
161
162
|
export type { ExtensionRefundParams, ExtensionRefundResponse } from "./actions/extension-refund/types";
|
|
162
163
|
export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse } from "./actions/add-customer-note/types";
|
|
164
|
+
export type { RemoveCustomerNote, RemoveCustomerNoteParams, RemoveCustomerNoteResponse } from "./actions/remove-customer-note/types";
|
|
163
165
|
export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from "./actions/remove-customer-from-cart/types";
|
|
164
166
|
export type { RemoveCartDiscount, RemoveCartDiscountResponse } from "./actions/remove-cart-discount/types";
|
|
165
167
|
export type { GoToStationHome, GoToStationHomeResponse } from "./actions/go-to-station-home/types";
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ import { extensionPayment } from "./actions/extension-payment/action";
|
|
|
40
40
|
import { redeemPayment } from "./actions/redeem-payment/action";
|
|
41
41
|
// Customer Actions
|
|
42
42
|
import { addCustomerNote } from "./actions/add-customer-note/action";
|
|
43
|
+
import { removeCustomerNote } from "./actions/remove-customer-note/action";
|
|
43
44
|
import { removeCustomerFromCart } from "./actions/remove-customer-from-cart/action";
|
|
44
45
|
import { removeCartDiscount } from "./actions/remove-cart-discount/action";
|
|
45
46
|
// System Actions
|
|
@@ -161,6 +162,7 @@ export const command = {
|
|
|
161
162
|
redeemPayment,
|
|
162
163
|
// Customer Actions
|
|
163
164
|
addCustomerNote,
|
|
165
|
+
removeCustomerNote,
|
|
164
166
|
removeCustomerFromCart,
|
|
165
167
|
removeCartDiscount,
|
|
166
168
|
// System Actions
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { mockAddCartDiscount } from "../../actions/add-cart-discount/mock";
|
|
2
2
|
import { mockAddCartFee } from "../../actions/add-cart-fee/mock";
|
|
3
|
+
import { mockRemoveCartFee } from "../../actions/remove-cart-fee/mock";
|
|
3
4
|
import { mockAddCustomSale } from "../../actions/add-custom-sale/mock";
|
|
4
5
|
import { mockAddCustomer } from "../../actions/add-customer/mock";
|
|
5
6
|
import { mockAddCustomerNote } from "../../actions/add-customer-note/mock";
|
|
7
|
+
import { mockRemoveCustomerNote } from "../../actions/remove-customer-note/mock";
|
|
6
8
|
import { mockEditCustomer } from "../../actions/edit-customer/mock";
|
|
7
9
|
import { mockAddOrderNote } from "../../actions/add-order-note/mock";
|
|
8
10
|
import { mockAddProductDiscount } from "../../actions/add-product-discount/mock";
|
|
@@ -31,6 +33,7 @@ import { mockGetCustomers } from "../../actions/get-customers/mock";
|
|
|
31
33
|
import { mockGetOrders } from "../../actions/get-orders/mock";
|
|
32
34
|
import { mockGetProducts } from "../../actions/get-products/mock";
|
|
33
35
|
import { mockGetRefunds } from "../../actions/get-refunds/mock";
|
|
36
|
+
import { mockGetTaxTables } from "../../actions/get-tax-tables/mock";
|
|
34
37
|
import { mockGetRemainingRefundableQuantities } from "../../actions/get-remaining-refundable-quantities/mock";
|
|
35
38
|
import { mockGoToStationHome } from "../../actions/go-to-station-home/mock";
|
|
36
39
|
import { mockInitiateRefund } from "../../actions/initiate-refund/mock";
|
|
@@ -89,6 +92,7 @@ export const RENDER_MOCKS = {
|
|
|
89
92
|
addCustomer: mockAddCustomer,
|
|
90
93
|
editCustomer: mockEditCustomer,
|
|
91
94
|
addCustomerNote: mockAddCustomerNote,
|
|
95
|
+
removeCustomerNote: mockRemoveCustomerNote,
|
|
92
96
|
addOrderNote: mockAddOrderNote,
|
|
93
97
|
addProductDiscount: mockAddProductDiscount,
|
|
94
98
|
addProductFee: mockAddProductFee,
|
|
@@ -115,6 +119,7 @@ export const RENDER_MOCKS = {
|
|
|
115
119
|
getOrders: mockGetOrders,
|
|
116
120
|
getProducts: mockGetProducts,
|
|
117
121
|
getRefunds: mockGetRefunds,
|
|
122
|
+
getTaxTables: mockGetTaxTables,
|
|
118
123
|
getRemainingRefundableQuantities: mockGetRemainingRefundableQuantities,
|
|
119
124
|
goToStationHome: mockGoToStationHome,
|
|
120
125
|
initiateRefund: mockInitiateRefund,
|
|
@@ -167,11 +172,11 @@ export const RENDER_MOCKS = {
|
|
|
167
172
|
getActiveUser: mockGetActiveUser,
|
|
168
173
|
setActiveUser: mockSetActiveUser,
|
|
169
174
|
setActiveRefund: mockSetActiveRefund,
|
|
170
|
-
removeProductDiscount:
|
|
171
|
-
removeProductFee:
|
|
172
|
-
removeProductNote:
|
|
173
|
-
removeCartFee:
|
|
174
|
-
removeOrderNote:
|
|
175
|
-
removeCustomSale:
|
|
176
|
-
removeNonRevenueItem:
|
|
175
|
+
removeProductDiscount: () => Promise.resolve({ success: true, timestamp: new Date().toISOString() }),
|
|
176
|
+
removeProductFee: () => Promise.resolve({ success: true, timestamp: new Date().toISOString() }),
|
|
177
|
+
removeProductNote: () => Promise.resolve({ success: true, timestamp: new Date().toISOString() }),
|
|
178
|
+
removeCartFee: mockRemoveCartFee,
|
|
179
|
+
removeOrderNote: () => Promise.resolve({ success: true, timestamp: new Date().toISOString() }),
|
|
180
|
+
removeCustomSale: params => Promise.resolve({ success: true, id: params.id, timestamp: new Date().toISOString() }),
|
|
181
|
+
removeNonRevenueItem: params => Promise.resolve({ success: true, externalId: params.externalId, timestamp: new Date().toISOString() })
|
|
177
182
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExampleFunction, GetProducts, AddCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, 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, GetActiveOrder, GetActiveCustomer, SetActiveCustomer, GetActiveOutlet, SetActiveOutlet, GetActiveStation, SetActiveStation, GetActiveSession, SetActiveSession, GetActiveUser, SetActiveUser, SetActiveRefund, RemoveProductDiscount, RemoveProductFee, RemoveProductNote, RemoveCartFee, RemoveOrderNote, RemoveCustomSale, RemoveNonRevenueItem } from "../../index";
|
|
1
|
+
import type { ExampleFunction, GetProducts, AddCustomSale, GetCustomers, AssignCustomer, AddCustomer, EditCustomer, GetCategories, GetOrders, GetRefunds, GetTaxTables, AddProductDiscount, AddProductToCart, RemoveProductFromCart, UpdateCartItemQuantity, AddCartDiscount, GetContext, GetFinalContext, AddProductNote, AddProductFee, SetActiveProductFee, SetActiveProductDiscount, GetActiveProduct, SetActiveProduct, AdjustInventory, AddOrderNote, AddCartFee, ClearCart, ParkOrder, ResumeParkedOrder, DeleteParkedOrder, InitiateRefund, CashPayment, TapToPayPayment, TerminalPayment, VendaraPayment, ExtensionPayment, RedeemPayment, AddNonRevenueItem, AddCustomerNote, RemoveCustomerNote, 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, GetActiveOrder, GetActiveCustomer, SetActiveCustomer, GetActiveOutlet, SetActiveOutlet, GetActiveStation, SetActiveStation, GetActiveSession, SetActiveSession, GetActiveUser, SetActiveUser, SetActiveRefund, RemoveProductDiscount, RemoveProductFee, RemoveProductNote, RemoveCartFee, RemoveOrderNote, RemoveCustomSale, RemoveNonRevenueItem } from "../../index";
|
|
2
2
|
export interface RenderProviderActions {
|
|
3
3
|
exampleFunction: ExampleFunction;
|
|
4
4
|
getProducts: GetProducts;
|
|
@@ -10,6 +10,7 @@ export interface RenderProviderActions {
|
|
|
10
10
|
getCategories: GetCategories;
|
|
11
11
|
getOrders: GetOrders;
|
|
12
12
|
getRefunds: GetRefunds;
|
|
13
|
+
getTaxTables: GetTaxTables;
|
|
13
14
|
addProductDiscount: AddProductDiscount;
|
|
14
15
|
addProductToCart: AddProductToCart;
|
|
15
16
|
removeProductFromCart: RemoveProductFromCart;
|
|
@@ -39,6 +40,7 @@ export interface RenderProviderActions {
|
|
|
39
40
|
redeemPayment: RedeemPayment;
|
|
40
41
|
addNonRevenueItem: AddNonRevenueItem;
|
|
41
42
|
addCustomerNote: AddCustomerNote;
|
|
43
|
+
removeCustomerNote: RemoveCustomerNote;
|
|
42
44
|
removeCustomerFromCart: RemoveCustomerFromCart;
|
|
43
45
|
removeCartDiscount: RemoveCartDiscount;
|
|
44
46
|
goToStationHome: GoToStationHome;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@final-commerce/command-frame",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.63",
|
|
4
4
|
"description": "Commands Frame library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"test": "vitest",
|
|
18
18
|
"test:run": "vitest run",
|
|
19
19
|
"prepublishOnly": "npm run build",
|
|
20
|
-
"prepare": "npm run build",
|
|
20
|
+
"prepare": "husky && npm run build",
|
|
21
|
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives",
|
|
21
22
|
"format": "prettier --write .",
|
|
22
23
|
"format:check": "prettier --check .",
|
|
23
24
|
"publish:npm": "npm publish --registry=https://registry.npmjs.org",
|
|
@@ -41,9 +42,30 @@
|
|
|
41
42
|
"type": "git",
|
|
42
43
|
"url": "git+https://github.com/Final-Commerce/command-frame.git"
|
|
43
44
|
},
|
|
45
|
+
"lint-staged": {
|
|
46
|
+
"**/*.{ts,tsx,js,json,md}": [
|
|
47
|
+
"prettier --write"
|
|
48
|
+
],
|
|
49
|
+
"**/*.{ts,tsx}": [
|
|
50
|
+
"eslint --fix"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"jira-prepare-commit-msg": {
|
|
54
|
+
"messagePattern": "$M [$J]",
|
|
55
|
+
"jiraTicketPattern": "([A-Z]+-\\d+)",
|
|
56
|
+
"ignoredBranchesPattern": "^(main|master|develop|release-staging.*|pre-prod)$",
|
|
57
|
+
"ignoreBranchesMissingTickets": true
|
|
58
|
+
},
|
|
44
59
|
"devDependencies": {
|
|
45
60
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
46
61
|
"@typescript-eslint/parser": "^8.48.0",
|
|
62
|
+
"eslint": "^8.57.0",
|
|
63
|
+
"eslint-plugin-react": "^7.37.5",
|
|
64
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
65
|
+
"eslint-plugin-react-refresh": "^0.4.26",
|
|
66
|
+
"husky": "^9.1.7",
|
|
67
|
+
"jira-prepare-commit-msg": "^1.7.2",
|
|
68
|
+
"lint-staged": "^16.2.7",
|
|
47
69
|
"prettier": "^3.7.1",
|
|
48
70
|
"typescript": "^5.0.0",
|
|
49
71
|
"vitest": "^3.0.5"
|