@final-commerce/command-frame 0.1.72 → 0.1.74

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 (88) hide show
  1. package/README.md +50 -28
  2. package/dist/CommonTypes.d.ts +143 -7
  3. package/dist/CommonTypes.js +112 -0
  4. package/dist/actions/apply-transition/action.d.ts +2 -0
  5. package/dist/actions/apply-transition/action.js +4 -0
  6. package/dist/actions/apply-transition/mock.d.ts +6 -0
  7. package/dist/actions/apply-transition/mock.js +33 -0
  8. package/dist/actions/apply-transition/types.d.ts +17 -0
  9. package/dist/actions/apply-transition/types.js +1 -0
  10. package/dist/actions/can-transition/action.d.ts +2 -0
  11. package/dist/actions/can-transition/action.js +4 -0
  12. package/dist/actions/can-transition/mock.d.ts +6 -0
  13. package/dist/actions/can-transition/mock.js +28 -0
  14. package/dist/actions/can-transition/types.d.ts +11 -0
  15. package/dist/actions/can-transition/types.js +1 -0
  16. package/dist/actions/cash-payment/types.d.ts +5 -0
  17. package/dist/actions/delete-parked-order/types.d.ts +3 -0
  18. package/dist/actions/extension-payment/types.d.ts +5 -0
  19. package/dist/actions/get-available-transitions/action.d.ts +2 -0
  20. package/dist/actions/get-available-transitions/action.js +4 -0
  21. package/dist/actions/get-available-transitions/mock.d.ts +6 -0
  22. package/dist/actions/get-available-transitions/mock.js +26 -0
  23. package/dist/actions/get-available-transitions/types.d.ts +9 -0
  24. package/dist/actions/get-available-transitions/types.js +1 -0
  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-smart-grid-layout/types.js +1 -0
  31. package/dist/actions/initiate-refund/types.d.ts +3 -0
  32. package/dist/actions/open-extension-overlay/mock.d.ts +2 -0
  33. package/dist/actions/open-extension-overlay/mock.js +1 -0
  34. package/dist/actions/open-extension-overlay/types.d.ts +9 -0
  35. package/dist/actions/open-extension-overlay/types.js +1 -0
  36. package/dist/actions/park-order/types.d.ts +3 -0
  37. package/dist/actions/partial-payment/types.d.ts +5 -0
  38. package/dist/actions/process-partial-refund/types.d.ts +3 -0
  39. package/dist/actions/remove-product-from-cart/mock.js +5 -5
  40. package/dist/actions/resolve-extension-overlay/mock.d.ts +2 -0
  41. package/dist/actions/resolve-extension-overlay/mock.js +1 -0
  42. package/dist/actions/resolve-extension-overlay/types.d.ts +9 -0
  43. package/dist/actions/resolve-extension-overlay/types.js +1 -0
  44. package/dist/actions/resume-parked-order/types.d.ts +3 -0
  45. package/dist/actions/save-smart-grid-layout/action.d.ts +2 -0
  46. package/dist/actions/save-smart-grid-layout/action.js +4 -0
  47. package/dist/actions/save-smart-grid-layout/mock.d.ts +2 -0
  48. package/dist/actions/save-smart-grid-layout/mock.js +10 -0
  49. package/dist/actions/save-smart-grid-layout/types.d.ts +10 -0
  50. package/dist/actions/save-smart-grid-layout/types.js +1 -0
  51. package/dist/actions/tap-to-pay-payment/types.d.ts +5 -0
  52. package/dist/actions/terminal-payment/types.d.ts +5 -0
  53. package/dist/actions/update-cart-item-quantity/mock.js +9 -9
  54. package/dist/actions/vendara-payment/types.d.ts +5 -0
  55. package/dist/common-types/index.d.ts +1 -0
  56. package/dist/common-types/index.js +1 -0
  57. package/dist/common-types/order-state.d.ts +32 -0
  58. package/dist/common-types/order-state.js +6 -0
  59. package/dist/common-types/state-fragment.d.ts +77 -0
  60. package/dist/common-types/state-fragment.js +10 -0
  61. package/dist/demo/database.d.ts +2 -1
  62. package/dist/demo/database.js +13 -0
  63. package/dist/fragments/index.d.ts +1 -0
  64. package/dist/fragments/index.js +1 -0
  65. package/dist/fragments/preorder-no-deposit.d.ts +26 -0
  66. package/dist/fragments/preorder-no-deposit.js +166 -0
  67. package/dist/index.d.ts +18 -4
  68. package/dist/index.js +19 -3
  69. package/dist/interceptors/index.d.ts +21 -0
  70. package/dist/interceptors/index.js +53 -0
  71. package/dist/interceptors/types.d.ts +26 -0
  72. package/dist/interceptors/types.js +1 -0
  73. package/dist/projects/render/mocks.js +13 -1
  74. package/dist/projects/render/types.d.ts +9 -1
  75. package/dist/pubsub/topics/orders/index.js +10 -0
  76. package/dist/pubsub/topics/orders/state-transition-blocked/types.d.ts +16 -0
  77. package/dist/pubsub/topics/orders/state-transition-blocked/types.js +1 -0
  78. package/dist/pubsub/topics/orders/state-transition-completed/types.d.ts +15 -0
  79. package/dist/pubsub/topics/orders/state-transition-completed/types.js +1 -0
  80. package/dist/pubsub/topics/orders/types.d.ts +6 -2
  81. package/dist/pubsub/topics/orders/types.js +2 -0
  82. package/package.json +1 -1
  83. package/dist/actions/extension-refund/constants.d.ts +0 -2
  84. package/dist/actions/extension-refund/constants.js +0 -2
  85. package/dist/actions/extension-refund/extension-refund-listener.d.ts +0 -11
  86. package/dist/actions/extension-refund/extension-refund-listener.js +0 -60
  87. package/dist/actions/extension-refund/types.d.ts +0 -32
  88. package/dist/actions/extension-refund/types.js +0 -5
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Pre-order fragment — no deposit required.
3
+ *
4
+ * Mirrors preorder-with-deposit but removes the cross-axis rule that gates
5
+ * `on_hold` on payment state. An order can be placed on hold while still
6
+ * `unpaid` — payment is collected later (pay-at-pickup, BOPIS, COD, etc.).
7
+ *
8
+ * State flow:
9
+ *
10
+ * unpaid|on_hold → (cashier collects payment) → paid|on_hold
11
+ * ↓
12
+ * (progress fulfillment)
13
+ * ↓
14
+ * paid|in_progress
15
+ *
16
+ * Key difference from preorder-with-deposit:
17
+ * - No cross-axis rule blocking `on_hold` when unpaid. The cashier can
18
+ * confirm the pre-order without collecting a deposit first.
19
+ * - `unpaid|on_hold` is whitelisted as a valid first-save state pair.
20
+ * - `in_progress` still requires at least a partial payment (you must pay
21
+ * before the merchant starts fulfilling).
22
+ *
23
+ * Prefix all IDs with your extension id before merging to avoid collisions.
24
+ */
25
+ export const preorderNoDepositFragment = {
26
+ paymentPaths: [
27
+ {
28
+ from: "unpaid",
29
+ to: "partially_paid",
30
+ conditionSetId: "require-payment-recorded"
31
+ },
32
+ {
33
+ from: "unpaid",
34
+ to: "paid",
35
+ conditionSetId: "require-full-payment"
36
+ },
37
+ {
38
+ from: "partially_paid",
39
+ to: "paid",
40
+ conditionSetId: "require-full-payment"
41
+ }
42
+ ],
43
+ fulfillmentPaths: [
44
+ {
45
+ from: "draft",
46
+ to: "on_hold",
47
+ conditionSetId: "preorder-no-deposit-require-items"
48
+ },
49
+ {
50
+ from: "on_hold",
51
+ to: "cancelled",
52
+ conditionSetId: "preorder-no-deposit-cancel-before-progress"
53
+ }
54
+ ],
55
+ transitionConditions: [
56
+ {
57
+ id: "preorder-no-deposit-require-items",
58
+ label: "Require at least one item to place pre-order",
59
+ groups: [
60
+ {
61
+ conditions: [
62
+ {
63
+ field: "computed.itemCount",
64
+ operator: "gte",
65
+ value: 1
66
+ }
67
+ ]
68
+ }
69
+ ]
70
+ },
71
+ {
72
+ id: "preorder-no-deposit-cancel-before-progress",
73
+ label: "Can only cancel pre-order before fulfillment begins",
74
+ groups: [
75
+ {
76
+ conditions: [
77
+ {
78
+ field: "computed.fulfilledItemCount",
79
+ operator: "eq",
80
+ value: 0
81
+ }
82
+ ]
83
+ }
84
+ ]
85
+ },
86
+ {
87
+ id: "require-payment-recorded",
88
+ label: "Require at least one payment before marking partially paid",
89
+ groups: [
90
+ {
91
+ conditions: [
92
+ {
93
+ field: "computed.totalPaid",
94
+ operator: "gt",
95
+ value: 0
96
+ }
97
+ ]
98
+ }
99
+ ]
100
+ },
101
+ {
102
+ id: "require-full-payment",
103
+ label: "Require full payment before marking as paid",
104
+ groups: [
105
+ {
106
+ conditions: [
107
+ {
108
+ field: "computed.totalPaid",
109
+ operator: "gte",
110
+ value: 1
111
+ },
112
+ {
113
+ field: "computed.balance",
114
+ operator: "lte",
115
+ value: 0
116
+ }
117
+ ]
118
+ }
119
+ ]
120
+ }
121
+ ],
122
+ crossAxisRules: [
123
+ {
124
+ id: "preorder-no-deposit-require-payment-before-confirm",
125
+ label: "Require payment before starting fulfillment",
126
+ description: "Fulfillment cannot move to in_progress unless at least a partial payment has been made",
127
+ enabled: true,
128
+ trigger: {
129
+ axis: "fulfillment",
130
+ to: ["in_progress"]
131
+ },
132
+ requires: {
133
+ axis: "payment",
134
+ states: ["partially_paid", "paid"]
135
+ }
136
+ }
137
+ ],
138
+ validInitialStates: [
139
+ { payment: "unpaid", fulfillment: "on_hold" },
140
+ { payment: "partially_paid", fulfillment: "on_hold" },
141
+ { payment: "paid", fulfillment: "on_hold" }
142
+ ],
143
+ displayStateMap: [
144
+ {
145
+ paymentState: ["unpaid"],
146
+ fulfillmentState: ["on_hold"],
147
+ label: "Pre-Order",
148
+ color: "#6366f1",
149
+ icon: "clock"
150
+ },
151
+ {
152
+ paymentState: ["partially_paid"],
153
+ fulfillmentState: ["on_hold"],
154
+ label: "Pre-Order (Deposit Received)",
155
+ color: "#f59e0b",
156
+ icon: "clock"
157
+ },
158
+ {
159
+ paymentState: ["paid"],
160
+ fulfillmentState: ["on_hold"],
161
+ label: "Pre-Order (Fully Paid)",
162
+ color: "#22c55e",
163
+ icon: "check-circle"
164
+ }
165
+ ]
166
+ };
package/dist/index.d.ts CHANGED
@@ -86,6 +86,8 @@ export declare const command: {
86
86
  readonly deleteProduct: import("./actions/delete-product/types").DeleteProduct;
87
87
  readonly getOutlets: import("./actions/get-outlets/types").GetOutlets;
88
88
  readonly getStations: import("./actions/get-stations/types").GetStations;
89
+ readonly getSmartGridLayout: import("./actions/get-smart-grid-layout/types").GetSmartGridLayout;
90
+ readonly saveSmartGridLayout: import("./actions/save-smart-grid-layout/types").SaveSmartGridLayout;
89
91
  readonly getCustomTables: import("./actions/get-custom-tables/types").GetCustomTables;
90
92
  readonly getCustomTableFields: import("./actions/get-custom-table-fields/types").GetCustomTableFields;
91
93
  readonly getCustomTableData: import("./actions/get-custom-table-data/types").GetCustomTableData;
@@ -105,6 +107,9 @@ export declare const command: {
105
107
  readonly uploadMedia: import("./actions/upload-media/types").UploadMedia;
106
108
  readonly getTaxTables: import("./actions/get-tax-tables/types").GetTaxTables;
107
109
  readonly getBranding: import("./actions/get-branding/types").GetBranding;
110
+ readonly canTransition: import("./actions/can-transition/types").CanTransition;
111
+ readonly getAvailableTransitions: import("./actions/get-available-transitions/types").GetAvailableTransitions;
112
+ readonly applyTransition: import("./actions/apply-transition/types").ApplyTransition;
108
113
  };
109
114
  export type { ExampleFunction, ExampleFunctionParams, ExampleFunctionResponse } from "./actions/example-function/types";
110
115
  export type { GenerateAPIKey, GenerateAPIKeyParams, GenerateAPIKeyResponse } from "./actions/generate-api-key/types";
@@ -122,6 +127,8 @@ export type { EditProductVariants, EditProductVariantsParams, EditProductVariant
122
127
  export type { DeleteProduct, DeleteProductParams, DeleteProductResponse } from "./actions/delete-product/types";
123
128
  export type { GetOutlets, GetOutletsResponse } from "./actions/get-outlets/types";
124
129
  export type { GetStations, GetStationsParams, GetStationsResponse } from "./actions/get-stations/types";
130
+ export type { GetSmartGridLayout, GetSmartGridLayoutParams, GetSmartGridLayoutResponse } from "./actions/get-smart-grid-layout/types";
131
+ export type { SaveSmartGridLayout, SaveSmartGridLayoutParams, SaveSmartGridLayoutResponse } from "./actions/save-smart-grid-layout/types";
125
132
  export type { GetOrders, GetOrdersParams, GetOrdersResponse } from "./actions/get-orders/types";
126
133
  export type { GetRefunds, GetRefundsParams, GetRefundsResponse } from "./actions/get-refunds/types";
127
134
  export type { SetRefundStockAction, SetRefundStockActionParams, SetRefundStockActionResponse } from "./actions/set-refund-stock-action/types";
@@ -131,6 +138,8 @@ export type { CalculateRefundTotal, CalculateRefundTotalParams, CalculateRefundT
131
138
  export type { GetRemainingRefundableQuantities, GetRemainingRefundableQuantitiesParams, GetRemainingRefundableQuantitiesResponse } from "./actions/get-remaining-refundable-quantities/types";
132
139
  export type { ProcessPartialRefund, ProcessPartialRefundParams, ProcessPartialRefundResponse } from "./actions/process-partial-refund/types";
133
140
  export type { InitiateRefund, InitiateRefundParams, InitiateRefundResponse } from "./actions/initiate-refund/types";
141
+ export type { OpenExtensionOverlay, OpenExtensionOverlayParams, OpenExtensionOverlayResponse } from "./actions/open-extension-overlay/types";
142
+ export type { ResolveExtensionOverlay, ResolveExtensionOverlayParams, ResolveExtensionOverlayResponse } from "./actions/resolve-extension-overlay/types";
134
143
  export type { GetCurrentCart, GetCurrentCartResponse } from "./actions/get-current-cart/types";
135
144
  export type { AddProductDiscount, AddProductDiscountParams, AddProductDiscountResponse } from "./actions/add-product-discount/types";
136
145
  export type { AddProductToCart, AddProductToCartParams, AddProductToCartResponse } from "./actions/add-product-to-cart/types";
@@ -159,9 +168,6 @@ export type { VendaraPayment, VendaraPaymentParams, VendaraPaymentResponse } fro
159
168
  export type { ExtensionPayment, ExtensionPaymentParams, ExtensionPaymentResponse } from "./actions/extension-payment/types";
160
169
  export type { RedeemPayment, RedeemPaymentParams, RedeemPaymentResponse } from "./actions/redeem-payment/types";
161
170
  export type { IntegrationPayment, IntegrationPaymentParams, IntegrationPaymentResponse, IntegrationEmvData } from "./actions/integration-payment/types";
162
- export { EXTENSION_REFUND_REQUEST_ACTION } from "./actions/extension-refund/constants";
163
- export { installExtensionRefundListener } from "./actions/extension-refund/extension-refund-listener";
164
- export type { ExtensionRefundParams, ExtensionRefundResponse } from "./actions/extension-refund/types";
165
171
  export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse } from "./actions/add-customer-note/types";
166
172
  export type { RemoveCustomerNote, RemoveCustomerNoteParams, RemoveCustomerNoteResponse } from "./actions/remove-customer-note/types";
167
173
  export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from "./actions/remove-customer-from-cart/types";
@@ -216,6 +222,8 @@ export type { TopicDefinition, TopicEvent, TopicEventType, TopicSubscriptionCall
216
222
  export type { TopicEventPayloadMap } from "./pubsub/topics/types";
217
223
  export { hooks } from "./hooks";
218
224
  export type { HookFunction, HookRegisterOptions } from "./hooks";
225
+ export { interceptors } from "./interceptors";
226
+ export type { InterceptorFunction, InterceptorPoint, InterceptorRegisterOptions, InterceptorReturn, InterceptorOverlayContext, InterceptorHostCommands } from "./interceptors";
219
227
  export { customersTopic } from "./pubsub/topics/customers";
220
228
  export { ordersTopic } from "./pubsub/topics/orders";
221
229
  export { refundsTopic } from "./pubsub/topics/refunds";
@@ -234,7 +242,7 @@ export { transactionsTopic } from "./pubsub/topics/transactions";
234
242
  export { categoriesTopic } from "./pubsub/topics/categories";
235
243
  export { attributesTopic } from "./pubsub/topics/attributes";
236
244
  export type { CustomerCreatedPayload, CustomerUpdatedPayload, CustomerNoteAddedPayload, CustomerNoteDeletedPayload, CustomerAssignedPayload, CustomerUnassignedPayload, CustomerActiveSetPayload, CustomerActiveGetPayload, CustomerCreatedEvent, CustomerUpdatedEvent, CustomerNoteAddedEvent, CustomerNoteDeletedEvent, CustomerAssignedEvent, CustomerUnassignedEvent, CustomerActiveSetEvent, CustomerActiveGetEvent, CustomersEventType, CustomersEventPayload } from "./pubsub/topics/customers/types";
237
- export type { OrderCreatedPayload, OrderUpdatedPayload, OrderActiveSetPayload, OrderActiveGetPayload, OrderCreatedEvent, OrderUpdatedEvent, OrderActiveSetEvent, OrderActiveGetEvent, OrdersEventType, OrdersEventPayload } from "./pubsub/topics/orders/types";
245
+ export type { OrderCreatedPayload, OrderUpdatedPayload, OrderActiveSetPayload, OrderActiveGetPayload, OrderCreatedEvent, OrderUpdatedEvent, OrderActiveSetEvent, OrderActiveGetEvent, OrderStateTransitionCompletedPayload, OrderStateTransitionBlockedPayload, OrderStateTransitionCompletedEvent, OrderStateTransitionBlockedEvent, OrdersEventType, OrdersEventPayload } from "./pubsub/topics/orders/types";
238
246
  export type { RefundCreatedPayload, RefundUpdatedPayload, RefundActiveSetPayload, RefundActiveGetPayload, RefundCreatedEvent, RefundUpdatedEvent, RefundActiveSetEvent, RefundActiveGetEvent, RefundsEventType, RefundsEventPayload } from "./pubsub/topics/refunds/types";
239
247
  export type { ProductCreatedPayload, ProductUpdatedPayload, ProductSetActivePayload, ProductGetActivePayload, ProductCreatedEvent, ProductUpdatedEvent, ProductSetActiveEvent, ProductGetActiveEvent, ProductsEventType, ProductsEventPayload } from "./pubsub/topics/products/types";
240
248
  export type { OutletActiveSetPayload, OutletActiveGetPayload, OutletActiveSetEvent, OutletActiveGetEvent, OutletEventType, OutletEventPayload } from "./pubsub/topics/outlet/types";
@@ -265,3 +273,9 @@ export type { GetSecretVal, GetSecretValParams, GetSecretValResponse } from "./a
265
273
  export type { SetSecretVal, SetSecretValParams, SetSecretValResponse } from "./actions/set-secret-val/types";
266
274
  export type { GetUsers, GetUsersParams, GetUsersResponse } from "./actions/get-users/types";
267
275
  export type { GetRoles, GetRolesParams, GetRolesResponse } from "./actions/get-roles/types";
276
+ export type { CFBlockedBy, CFStatePair, CFTransitionResult, CFFailedCondition, CFConditionStatus, CFAvailableTransition } from "./common-types/order-state";
277
+ export type { CFConditionOperator, CFCondition, CFConditionGroup, CFTransitionConditionSet, CFPaymentTransitionPath, CFFulfillmentTransitionPath, CFCrossAxisRule, CFDisplayStateRule, CFStateConfigFragment } from "./common-types/state-fragment";
278
+ export type { CanTransition, CanTransitionParams, CanTransitionResponse } from "./actions/can-transition/types";
279
+ export type { GetAvailableTransitions, GetAvailableTransitionsParams, GetAvailableTransitionsResponse } from "./actions/get-available-transitions/types";
280
+ export type { ApplyTransition, ApplyTransitionParams, ApplyTransitionResponse } from "./actions/apply-transition/types";
281
+ export { preorderNoDepositFragment } from "./fragments";
package/dist/index.js CHANGED
@@ -103,6 +103,10 @@ import { getSecretsKeys } from "./actions/get-secrets-keys/action";
103
103
  import { getSecretVal } from "./actions/get-secret-val/action";
104
104
  import { setSecretVal } from "./actions/set-secret-val/action";
105
105
  import { generateAPIKey } from "./actions/generate-api-key/action";
106
+ // State Machine Query Actions
107
+ import { canTransition } from "./actions/can-transition/action";
108
+ import { getAvailableTransitions } from "./actions/get-available-transitions/action";
109
+ import { applyTransition } from "./actions/apply-transition/action";
106
110
  // Product CRUD Actions
107
111
  import { addProduct } from "./actions/add-product/action";
108
112
  import { editProduct } from "./actions/edit-product/action";
@@ -111,6 +115,9 @@ import { deleteProduct } from "./actions/delete-product/action";
111
115
  // Entity Actions
112
116
  import { getOutlets } from "./actions/get-outlets/action";
113
117
  import { getStations } from "./actions/get-stations/action";
118
+ // SmartGrid Actions
119
+ import { getSmartGridLayout } from "./actions/get-smart-grid-layout/action";
120
+ import { saveSmartGridLayout } from "./actions/save-smart-grid-layout/action";
114
121
  // Manage extension actions (optional hosts: Deerlake, etc.)
115
122
  import { navigateTo } from "./actions/navigate-to/action";
116
123
  import { refreshResource } from "./actions/refresh-resource/action";
@@ -216,6 +223,9 @@ export const command = {
216
223
  // Entity Actions
217
224
  getOutlets,
218
225
  getStations,
226
+ // SmartGrid Actions
227
+ getSmartGridLayout,
228
+ saveSmartGridLayout,
219
229
  // Custom Tables Actions
220
230
  getCustomTables,
221
231
  getCustomTableFields,
@@ -239,10 +249,12 @@ export const command = {
239
249
  getMedia,
240
250
  uploadMedia,
241
251
  getTaxTables,
242
- getBranding
252
+ getBranding,
253
+ // State Machine Queries
254
+ canTransition,
255
+ getAvailableTransitions,
256
+ applyTransition
243
257
  };
244
- export { EXTENSION_REFUND_REQUEST_ACTION } from "./actions/extension-refund/constants";
245
- export { installExtensionRefundListener } from "./actions/extension-refund/extension-refund-listener";
246
258
  // Export Common Types
247
259
  export * from "./CommonTypes";
248
260
  // Mock database override (standalone / extension dev)
@@ -259,6 +271,8 @@ export { commandFrameClient, CommandFrameClient } from "./client";
259
271
  export { topics } from "./pubsub/topics";
260
272
  // Export Hooks (extension iframe API for session-scoped event callbacks)
261
273
  export { hooks } from "./hooks";
274
+ // Export Interceptors (extension iframe API for gating host flows)
275
+ export { interceptors } from "./interceptors";
262
276
  // Export Pub/Sub Topics
263
277
  export { customersTopic } from "./pubsub/topics/customers";
264
278
  export { ordersTopic } from "./pubsub/topics/orders";
@@ -279,3 +293,5 @@ export { categoriesTopic } from "./pubsub/topics/categories";
279
293
  export { attributesTopic } from "./pubsub/topics/attributes";
280
294
  // Export Custom Tables Types
281
295
  export { AttributeType } from "./common-types/attribute-type";
296
+ // State Machine Fragments
297
+ export { preorderNoDepositFragment } from "./fragments";
@@ -0,0 +1,21 @@
1
+ import type { InterceptorFunction, InterceptorPoint, InterceptorRegisterOptions, InterceptorOverlayContext } from "./types";
2
+ /** Register a session-scoped interceptor for a named point. Callback is serialized to the host. */
3
+ declare function register(point: InterceptorPoint, callback: InterceptorFunction, options: InterceptorRegisterOptions): string;
4
+ declare function unregister(interceptorId: string): void;
5
+ /** Register a handler invoked when this iframe is opened as an overlay by the host. */
6
+ declare function onOverlay(handler: (ctx: InterceptorOverlayContext) => void): void;
7
+ /** Continue the gated flow, merging `data` into the flow payload. */
8
+ declare function resolve(data: Record<string, any>): Promise<void>;
9
+ /** Continue the gated flow with no data. */
10
+ declare function proceed(): Promise<void>;
11
+ /** Stop the gated flow. */
12
+ declare function cancel(): Promise<void>;
13
+ export declare const interceptors: {
14
+ register: typeof register;
15
+ unregister: typeof unregister;
16
+ onOverlay: typeof onOverlay;
17
+ resolve: typeof resolve;
18
+ proceed: typeof proceed;
19
+ cancel: typeof cancel;
20
+ };
21
+ export type { InterceptorFunction, InterceptorPoint, InterceptorRegisterOptions, InterceptorReturn, InterceptorOverlayContext, InterceptorHostCommands } from "./types";
@@ -0,0 +1,53 @@
1
+ import { commandFrameClient } from "../client";
2
+ const DEFAULT_ORIGIN = "*";
3
+ function getOrigin() {
4
+ return typeof window !== "undefined" ? window.__COMMAND_FRAME_ORIGIN__ ?? DEFAULT_ORIGIN : DEFAULT_ORIGIN;
5
+ }
6
+ let overlayId = null;
7
+ let overlayContext = null;
8
+ let overlayHandler = null;
9
+ if (typeof window !== "undefined") {
10
+ window.addEventListener("message", (event) => {
11
+ const data = event.data;
12
+ if (data && data.type === "interceptor-overlay-init" && typeof data.overlayId === "string") {
13
+ overlayId = data.overlayId;
14
+ overlayContext = { point: data.point, payload: data.payload };
15
+ if (overlayHandler)
16
+ overlayHandler(overlayContext);
17
+ }
18
+ });
19
+ }
20
+ /** Register a session-scoped interceptor for a named point. Callback is serialized to the host. */
21
+ function register(point, callback, options) {
22
+ const interceptorId = options.interceptorId;
23
+ const functionBody = callback.toString();
24
+ if (typeof window !== "undefined" && window.top && window.top !== window) {
25
+ window.top.postMessage({ type: "interceptor-register", point, functionBody, interceptorId, timeoutMs: options.timeoutMs }, getOrigin());
26
+ }
27
+ return interceptorId;
28
+ }
29
+ function unregister(interceptorId) {
30
+ if (typeof window !== "undefined" && window.top && window.top !== window) {
31
+ window.top.postMessage({ type: "interceptor-unregister", interceptorId }, getOrigin());
32
+ }
33
+ }
34
+ /** Register a handler invoked when this iframe is opened as an overlay by the host. */
35
+ function onOverlay(handler) {
36
+ overlayHandler = handler;
37
+ if (overlayContext)
38
+ handler(overlayContext);
39
+ }
40
+ async function report(result) {
41
+ if (!overlayId) {
42
+ console.warn("[interceptors] report called outside an overlay context — ignored");
43
+ return;
44
+ }
45
+ await commandFrameClient.call("resolveExtensionOverlay", { overlayId, result });
46
+ }
47
+ /** Continue the gated flow, merging `data` into the flow payload. */
48
+ function resolve(data) { return report(data); }
49
+ /** Continue the gated flow with no data. */
50
+ function proceed() { return report(true); }
51
+ /** Stop the gated flow. */
52
+ function cancel() { return report(false); }
53
+ export const interceptors = { register, unregister, onOverlay, resolve, proceed, cancel };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Interceptors let an installed extension gate a host flow at a named point.
3
+ * Registration mirrors hooks: the callback is serialized and reconstructed on the host,
4
+ * so it must be self-contained (use only its payload arg and the injected host commands).
5
+ */
6
+ export type InterceptorPoint = "refund_start";
7
+ /** false = stop the flow; true = continue, no data; object = continue and merge into the flow payload. */
8
+ export type InterceptorReturn<T extends Record<string, any> = Record<string, any>> = boolean | T;
9
+ export interface InterceptorHostCommands {
10
+ openExtensionOverlay: (params: {
11
+ point: InterceptorPoint;
12
+ payload?: any;
13
+ }) => Promise<InterceptorReturn>;
14
+ [command: string]: (params?: any) => Promise<any>;
15
+ }
16
+ export type InterceptorFunction = (payload: any, cmds: InterceptorHostCommands, callCommand: (action: string, params?: any) => Promise<any>) => InterceptorReturn | Promise<InterceptorReturn>;
17
+ export interface InterceptorRegisterOptions {
18
+ /** Stable id; re-registering with the same id replaces the previous one. */
19
+ interceptorId: string;
20
+ /** Per-interceptor timeout override (ms). */
21
+ timeoutMs?: number;
22
+ }
23
+ export interface InterceptorOverlayContext {
24
+ point: InterceptorPoint;
25
+ payload: any;
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -37,6 +37,8 @@ import { mockGetTaxTables } from "../../actions/get-tax-tables/mock";
37
37
  import { mockGetRemainingRefundableQuantities } from "../../actions/get-remaining-refundable-quantities/mock";
38
38
  import { mockGoToStationHome } from "../../actions/go-to-station-home/mock";
39
39
  import { mockInitiateRefund } from "../../actions/initiate-refund/mock";
40
+ import { mockOpenExtensionOverlay } from "../../actions/open-extension-overlay/mock";
41
+ import { mockResolveExtensionOverlay } from "../../actions/resolve-extension-overlay/mock";
40
42
  import { mockOpenCashDrawer } from "../../actions/open-cash-drawer/mock";
41
43
  import { mockParkOrder } from "../../actions/park-order/mock";
42
44
  import { mockPartialPayment } from "../../actions/partial-payment/mock";
@@ -86,6 +88,10 @@ import { mockSetActiveSession } from "../../actions/set-active-session/mock";
86
88
  import { mockGetActiveUser } from "../../actions/get-active-user/mock";
87
89
  import { mockSetActiveUser } from "../../actions/set-active-user/mock";
88
90
  import { mockSetActiveRefund } from "../../actions/set-active-refund/mock";
91
+ import { canTransitionMock } from "../../actions/can-transition/mock";
92
+ import { getAvailableTransitionsMock } from "../../actions/get-available-transitions/mock";
93
+ import { mockGetSmartGridLayout } from "../../actions/get-smart-grid-layout/mock";
94
+ import { mockSaveSmartGridLayout } from "../../actions/save-smart-grid-layout/mock";
89
95
  export const RENDER_MOCKS = {
90
96
  addCartDiscount: mockAddCartDiscount,
91
97
  addCartFee: mockAddCartFee,
@@ -124,6 +130,8 @@ export const RENDER_MOCKS = {
124
130
  getRemainingRefundableQuantities: mockGetRemainingRefundableQuantities,
125
131
  goToStationHome: mockGoToStationHome,
126
132
  initiateRefund: mockInitiateRefund,
133
+ openExtensionOverlay: mockOpenExtensionOverlay,
134
+ resolveExtensionOverlay: mockResolveExtensionOverlay,
127
135
  openCashDrawer: mockOpenCashDrawer,
128
136
  parkOrder: mockParkOrder,
129
137
  partialPayment: mockPartialPayment,
@@ -180,5 +188,9 @@ export const RENDER_MOCKS = {
180
188
  removeCartFee: mockRemoveCartFee,
181
189
  removeOrderNote: () => Promise.resolve({ success: true, timestamp: new Date().toISOString() }),
182
190
  removeCustomSale: params => Promise.resolve({ success: true, id: params.id, timestamp: new Date().toISOString() }),
183
- removeNonRevenueItem: params => Promise.resolve({ success: true, externalId: params.externalId, timestamp: new Date().toISOString() })
191
+ removeNonRevenueItem: params => Promise.resolve({ success: true, externalId: params.externalId, timestamp: new Date().toISOString() }),
192
+ canTransition: canTransitionMock,
193
+ getAvailableTransitions: getAvailableTransitionsMock,
194
+ getSmartGridLayout: mockGetSmartGridLayout,
195
+ saveSmartGridLayout: mockSaveSmartGridLayout
184
196
  };
@@ -1,4 +1,6 @@
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, IntegrationPayment } 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, CanTransition, GetAvailableTransitions, IntegrationPayment, GetSmartGridLayout, SaveSmartGridLayout } from "../../index";
2
+ import type { OpenExtensionOverlay } from "../../actions/open-extension-overlay/types";
3
+ import type { ResolveExtensionOverlay } from "../../actions/resolve-extension-overlay/types";
2
4
  export interface RenderProviderActions {
3
5
  exampleFunction: ExampleFunction;
4
6
  getProducts: GetProducts;
@@ -32,6 +34,8 @@ export interface RenderProviderActions {
32
34
  resumeParkedOrder: ResumeParkedOrder;
33
35
  deleteParkedOrder: DeleteParkedOrder;
34
36
  initiateRefund: InitiateRefund;
37
+ openExtensionOverlay: OpenExtensionOverlay;
38
+ resolveExtensionOverlay: ResolveExtensionOverlay;
35
39
  cashPayment: CashPayment;
36
40
  tapToPayPayment: TapToPayPayment;
37
41
  terminalPayment: TerminalPayment;
@@ -94,4 +98,8 @@ export interface RenderProviderActions {
94
98
  removeOrderNote: RemoveOrderNote;
95
99
  removeCustomSale: RemoveCustomSale;
96
100
  removeNonRevenueItem: RemoveNonRevenueItem;
101
+ canTransition: CanTransition;
102
+ getAvailableTransitions: GetAvailableTransitions;
103
+ getSmartGridLayout: GetSmartGridLayout;
104
+ saveSmartGridLayout: SaveSmartGridLayout;
97
105
  }
@@ -26,6 +26,16 @@ export const ordersTopic = {
26
26
  id: "get-active-order",
27
27
  name: "Get Active Order",
28
28
  description: "Published when the active order is retrieved for listeners"
29
+ },
30
+ {
31
+ id: "state-transition-completed",
32
+ name: "State Transition Completed",
33
+ description: "Published when an order state transition completes successfully"
34
+ },
35
+ {
36
+ id: "state-transition-blocked",
37
+ name: "State Transition Blocked",
38
+ description: "Published when an order state transition is blocked by the state machine"
29
39
  }
30
40
  ]
31
41
  };
@@ -0,0 +1,16 @@
1
+ import type { TopicEvent } from "../../../types";
2
+ import type { CFBlockedBy } from "../../../../common-types/order-state";
3
+ export interface OrderStateTransitionBlockedPayload {
4
+ orderId: string;
5
+ from: {
6
+ payment: string;
7
+ fulfillment: string;
8
+ };
9
+ to: {
10
+ payment: string;
11
+ fulfillment: string;
12
+ };
13
+ blockedBy: CFBlockedBy;
14
+ reason?: string;
15
+ }
16
+ export type OrderStateTransitionBlockedEvent = TopicEvent<OrderStateTransitionBlockedPayload>;
@@ -0,0 +1,15 @@
1
+ import type { TopicEvent } from "../../../types";
2
+ export interface OrderStateTransitionCompletedPayload {
3
+ orderId: string;
4
+ from: {
5
+ payment: string;
6
+ fulfillment: string;
7
+ };
8
+ to: {
9
+ payment: string;
10
+ fulfillment: string;
11
+ };
12
+ displayState: string;
13
+ forced?: boolean;
14
+ }
15
+ export type OrderStateTransitionCompletedEvent = TopicEvent<OrderStateTransitionCompletedPayload>;
@@ -6,9 +6,13 @@ export * from "./order-created/types";
6
6
  export * from "./order-updated/types";
7
7
  export * from "./set-active-order/types";
8
8
  export * from "./get-active-order/types";
9
+ export * from "./state-transition-completed/types";
10
+ export * from "./state-transition-blocked/types";
9
11
  import type { OrderCreatedPayload } from "./order-created/types";
10
12
  import type { OrderUpdatedPayload } from "./order-updated/types";
11
13
  import type { OrderActiveSetPayload } from "./set-active-order/types";
12
14
  import type { OrderActiveGetPayload } from "./get-active-order/types";
13
- export type OrdersEventPayload = OrderCreatedPayload | OrderUpdatedPayload | OrderActiveSetPayload | OrderActiveGetPayload;
14
- export type OrdersEventType = "order-created" | "order-updated" | "set-active-order" | "get-active-order";
15
+ import type { OrderStateTransitionCompletedPayload } from "./state-transition-completed/types";
16
+ import type { OrderStateTransitionBlockedPayload } from "./state-transition-blocked/types";
17
+ export type OrdersEventPayload = OrderCreatedPayload | OrderUpdatedPayload | OrderActiveSetPayload | OrderActiveGetPayload | OrderStateTransitionCompletedPayload | OrderStateTransitionBlockedPayload;
18
+ export type OrdersEventType = "order-created" | "order-updated" | "set-active-order" | "get-active-order" | "state-transition-completed" | "state-transition-blocked";
@@ -7,3 +7,5 @@ export * from "./order-created/types";
7
7
  export * from "./order-updated/types";
8
8
  export * from "./set-active-order/types";
9
9
  export * from "./get-active-order/types";
10
+ export * from "./state-transition-completed/types";
11
+ export * from "./state-transition-blocked/types";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@final-commerce/command-frame",
3
- "version": "0.1.72",
3
+ "version": "0.1.74",
4
4
  "description": "Commands Frame library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,2 +0,0 @@
1
- /** postMessage `action` for host → iframe extension refund requests. */
2
- export declare const EXTENSION_REFUND_REQUEST_ACTION = "extensionRefundRequest";
@@ -1,2 +0,0 @@
1
- /** postMessage `action` for host → iframe extension refund requests. */
2
- export const EXTENSION_REFUND_REQUEST_ACTION = "extensionRefundRequest";
@@ -1,11 +0,0 @@
1
- import type { ExtensionRefundParams, ExtensionRefundResponse } from "./types";
2
- /**
3
- * Install a message listener in the **extension iframe** so the host can request refunds.
4
- * Validates `event.source === window.top` before handling.
5
- *
6
- * Replies with {@link PostMessageResponse}, using `event.origin` as the target origin when posting back to the host.
7
- *
8
- * @param handler - Perform the extension-side refund (API call, etc.)
9
- * @returns Unsubscribe function
10
- */
11
- export declare function installExtensionRefundListener(handler: (params: ExtensionRefundParams) => Promise<ExtensionRefundResponse>): () => void;