@final-commerce/command-frame 0.1.73 → 0.1.75
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 +50 -28
- package/dist/CommonTypes.d.ts +124 -7
- package/dist/CommonTypes.js +112 -0
- package/dist/actions/add-cart-discount/mock.js +6 -3
- package/dist/actions/add-cart-fee/mock.js +6 -6
- package/dist/actions/add-custom-sale/mock.js +7 -2
- package/dist/actions/add-order-note/mock.js +3 -1
- package/dist/actions/add-product-discount/mock.js +10 -3
- package/dist/actions/add-product-fee/mock.js +10 -1
- package/dist/actions/apply-transition/action.d.ts +2 -0
- package/dist/actions/apply-transition/action.js +4 -0
- package/dist/actions/apply-transition/mock.d.ts +6 -0
- package/dist/actions/apply-transition/mock.js +33 -0
- package/dist/actions/apply-transition/types.d.ts +17 -0
- package/dist/actions/apply-transition/types.js +1 -0
- package/dist/actions/can-transition/action.d.ts +2 -0
- package/dist/actions/can-transition/action.js +4 -0
- package/dist/actions/can-transition/mock.d.ts +6 -0
- package/dist/actions/can-transition/mock.js +28 -0
- package/dist/actions/can-transition/types.d.ts +11 -0
- package/dist/actions/can-transition/types.js +1 -0
- package/dist/actions/cash-payment/mock.js +12 -18
- package/dist/actions/cash-payment/types.d.ts +5 -0
- package/dist/actions/delete-parked-order/mock.js +3 -1
- package/dist/actions/delete-parked-order/types.d.ts +3 -0
- package/dist/actions/extension-payment/types.d.ts +5 -0
- package/dist/actions/get-available-transitions/action.d.ts +2 -0
- package/dist/actions/get-available-transitions/action.js +4 -0
- package/dist/actions/get-available-transitions/mock.d.ts +6 -0
- package/dist/actions/get-available-transitions/mock.js +26 -0
- package/dist/actions/get-available-transitions/types.d.ts +9 -0
- package/dist/actions/get-available-transitions/types.js +1 -0
- package/dist/actions/get-context/mock.js +1 -1
- package/dist/actions/get-orders/mock.js +3 -3
- package/dist/actions/initiate-refund/types.d.ts +3 -0
- package/dist/actions/open-extension-overlay/mock.d.ts +2 -0
- package/dist/actions/open-extension-overlay/mock.js +1 -0
- package/dist/actions/open-extension-overlay/types.d.ts +9 -0
- package/dist/actions/open-extension-overlay/types.js +1 -0
- package/dist/actions/park-order/mock.js +4 -1
- package/dist/actions/park-order/types.d.ts +3 -0
- package/dist/actions/partial-payment/mock.js +21 -3
- package/dist/actions/partial-payment/types.d.ts +5 -0
- package/dist/actions/process-partial-refund/types.d.ts +3 -0
- package/dist/actions/remove-custom-sale/mock.d.ts +2 -0
- package/dist/actions/remove-custom-sale/mock.js +29 -0
- package/dist/actions/remove-customer-from-cart/mock.js +3 -1
- package/dist/actions/remove-order-note/mock.d.ts +2 -0
- package/dist/actions/remove-order-note/mock.js +12 -0
- package/dist/actions/remove-product-discount/mock.d.ts +2 -0
- package/dist/actions/remove-product-discount/mock.js +17 -0
- package/dist/actions/remove-product-fee/mock.d.ts +2 -0
- package/dist/actions/remove-product-fee/mock.js +17 -0
- package/dist/actions/remove-product-from-cart/mock.js +5 -5
- package/dist/actions/resolve-extension-overlay/mock.d.ts +2 -0
- package/dist/actions/resolve-extension-overlay/mock.js +1 -0
- package/dist/actions/resolve-extension-overlay/types.d.ts +9 -0
- package/dist/actions/resolve-extension-overlay/types.js +1 -0
- package/dist/actions/resume-parked-order/mock.js +4 -1
- package/dist/actions/resume-parked-order/types.d.ts +3 -0
- package/dist/actions/tap-to-pay-payment/mock.js +5 -3
- package/dist/actions/tap-to-pay-payment/types.d.ts +5 -0
- package/dist/actions/terminal-payment/mock.js +4 -5
- package/dist/actions/terminal-payment/types.d.ts +5 -0
- package/dist/actions/update-cart-item-quantity/mock.js +9 -9
- package/dist/actions/vendara-payment/types.d.ts +5 -0
- package/dist/common-types/index.d.ts +1 -0
- package/dist/common-types/index.js +1 -0
- package/dist/common-types/order-state.d.ts +32 -0
- package/dist/common-types/order-state.js +6 -0
- package/dist/common-types/state-fragment.d.ts +77 -0
- package/dist/common-types/state-fragment.js +10 -0
- package/dist/demo/database.d.ts +10 -0
- package/dist/demo/database.js +169 -3
- package/dist/fragments/index.d.ts +1 -0
- package/dist/fragments/index.js +1 -0
- package/dist/fragments/preorder-no-deposit.d.ts +26 -0
- package/dist/fragments/preorder-no-deposit.js +166 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.js +13 -3
- package/dist/interceptors/index.d.ts +21 -0
- package/dist/interceptors/index.js +53 -0
- package/dist/interceptors/types.d.ts +26 -0
- package/dist/interceptors/types.js +1 -0
- package/dist/projects/render/mocks.js +16 -4
- package/dist/projects/render/types.d.ts +7 -1
- package/dist/pubsub/topics/orders/index.js +10 -0
- package/dist/pubsub/topics/orders/state-transition-blocked/types.d.ts +16 -0
- package/dist/pubsub/topics/orders/state-transition-blocked/types.js +1 -0
- package/dist/pubsub/topics/orders/state-transition-completed/types.d.ts +15 -0
- package/dist/pubsub/topics/orders/state-transition-completed/types.js +1 -0
- package/dist/pubsub/topics/orders/types.d.ts +6 -2
- package/dist/pubsub/topics/orders/types.js +2 -0
- package/package.json +1 -1
- package/dist/actions/extension-refund/constants.d.ts +0 -2
- package/dist/actions/extension-refund/constants.js +0 -2
- package/dist/actions/extension-refund/extension-refund-listener.d.ts +0 -11
- package/dist/actions/extension-refund/extension-refund-listener.js +0 -60
- package/dist/actions/extension-refund/types.d.ts +0 -32
- 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
|
@@ -107,6 +107,9 @@ export declare const command: {
|
|
|
107
107
|
readonly uploadMedia: import("./actions/upload-media/types").UploadMedia;
|
|
108
108
|
readonly getTaxTables: import("./actions/get-tax-tables/types").GetTaxTables;
|
|
109
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;
|
|
110
113
|
};
|
|
111
114
|
export type { ExampleFunction, ExampleFunctionParams, ExampleFunctionResponse } from "./actions/example-function/types";
|
|
112
115
|
export type { GenerateAPIKey, GenerateAPIKeyParams, GenerateAPIKeyResponse } from "./actions/generate-api-key/types";
|
|
@@ -135,6 +138,8 @@ export type { CalculateRefundTotal, CalculateRefundTotalParams, CalculateRefundT
|
|
|
135
138
|
export type { GetRemainingRefundableQuantities, GetRemainingRefundableQuantitiesParams, GetRemainingRefundableQuantitiesResponse } from "./actions/get-remaining-refundable-quantities/types";
|
|
136
139
|
export type { ProcessPartialRefund, ProcessPartialRefundParams, ProcessPartialRefundResponse } from "./actions/process-partial-refund/types";
|
|
137
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";
|
|
138
143
|
export type { GetCurrentCart, GetCurrentCartResponse } from "./actions/get-current-cart/types";
|
|
139
144
|
export type { AddProductDiscount, AddProductDiscountParams, AddProductDiscountResponse } from "./actions/add-product-discount/types";
|
|
140
145
|
export type { AddProductToCart, AddProductToCartParams, AddProductToCartResponse } from "./actions/add-product-to-cart/types";
|
|
@@ -163,9 +168,6 @@ export type { VendaraPayment, VendaraPaymentParams, VendaraPaymentResponse } fro
|
|
|
163
168
|
export type { ExtensionPayment, ExtensionPaymentParams, ExtensionPaymentResponse } from "./actions/extension-payment/types";
|
|
164
169
|
export type { RedeemPayment, RedeemPaymentParams, RedeemPaymentResponse } from "./actions/redeem-payment/types";
|
|
165
170
|
export type { IntegrationPayment, IntegrationPaymentParams, IntegrationPaymentResponse, IntegrationEmvData } from "./actions/integration-payment/types";
|
|
166
|
-
export { EXTENSION_REFUND_REQUEST_ACTION } from "./actions/extension-refund/constants";
|
|
167
|
-
export { installExtensionRefundListener } from "./actions/extension-refund/extension-refund-listener";
|
|
168
|
-
export type { ExtensionRefundParams, ExtensionRefundResponse } from "./actions/extension-refund/types";
|
|
169
171
|
export type { AddCustomerNote, AddCustomerNoteParams, AddCustomerNoteResponse } from "./actions/add-customer-note/types";
|
|
170
172
|
export type { RemoveCustomerNote, RemoveCustomerNoteParams, RemoveCustomerNoteResponse } from "./actions/remove-customer-note/types";
|
|
171
173
|
export type { RemoveCustomerFromCart, RemoveCustomerFromCartResponse } from "./actions/remove-customer-from-cart/types";
|
|
@@ -220,6 +222,8 @@ export type { TopicDefinition, TopicEvent, TopicEventType, TopicSubscriptionCall
|
|
|
220
222
|
export type { TopicEventPayloadMap } from "./pubsub/topics/types";
|
|
221
223
|
export { hooks } from "./hooks";
|
|
222
224
|
export type { HookFunction, HookRegisterOptions } from "./hooks";
|
|
225
|
+
export { interceptors } from "./interceptors";
|
|
226
|
+
export type { InterceptorFunction, InterceptorPoint, InterceptorRegisterOptions, InterceptorReturn, InterceptorOverlayContext, InterceptorHostCommands } from "./interceptors";
|
|
223
227
|
export { customersTopic } from "./pubsub/topics/customers";
|
|
224
228
|
export { ordersTopic } from "./pubsub/topics/orders";
|
|
225
229
|
export { refundsTopic } from "./pubsub/topics/refunds";
|
|
@@ -238,7 +242,7 @@ export { transactionsTopic } from "./pubsub/topics/transactions";
|
|
|
238
242
|
export { categoriesTopic } from "./pubsub/topics/categories";
|
|
239
243
|
export { attributesTopic } from "./pubsub/topics/attributes";
|
|
240
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";
|
|
241
|
-
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";
|
|
242
246
|
export type { RefundCreatedPayload, RefundUpdatedPayload, RefundActiveSetPayload, RefundActiveGetPayload, RefundCreatedEvent, RefundUpdatedEvent, RefundActiveSetEvent, RefundActiveGetEvent, RefundsEventType, RefundsEventPayload } from "./pubsub/topics/refunds/types";
|
|
243
247
|
export type { ProductCreatedPayload, ProductUpdatedPayload, ProductSetActivePayload, ProductGetActivePayload, ProductCreatedEvent, ProductUpdatedEvent, ProductSetActiveEvent, ProductGetActiveEvent, ProductsEventType, ProductsEventPayload } from "./pubsub/topics/products/types";
|
|
244
248
|
export type { OutletActiveSetPayload, OutletActiveGetPayload, OutletActiveSetEvent, OutletActiveGetEvent, OutletEventType, OutletEventPayload } from "./pubsub/topics/outlet/types";
|
|
@@ -269,3 +273,9 @@ export type { GetSecretVal, GetSecretValParams, GetSecretValResponse } from "./a
|
|
|
269
273
|
export type { SetSecretVal, SetSecretValParams, SetSecretValResponse } from "./actions/set-secret-val/types";
|
|
270
274
|
export type { GetUsers, GetUsersParams, GetUsersResponse } from "./actions/get-users/types";
|
|
271
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";
|
|
@@ -245,10 +249,12 @@ export const command = {
|
|
|
245
249
|
getMedia,
|
|
246
250
|
uploadMedia,
|
|
247
251
|
getTaxTables,
|
|
248
|
-
getBranding
|
|
252
|
+
getBranding,
|
|
253
|
+
// State Machine Queries
|
|
254
|
+
canTransition,
|
|
255
|
+
getAvailableTransitions,
|
|
256
|
+
applyTransition
|
|
249
257
|
};
|
|
250
|
-
export { EXTENSION_REFUND_REQUEST_ACTION } from "./actions/extension-refund/constants";
|
|
251
|
-
export { installExtensionRefundListener } from "./actions/extension-refund/extension-refund-listener";
|
|
252
258
|
// Export Common Types
|
|
253
259
|
export * from "./CommonTypes";
|
|
254
260
|
// Mock database override (standalone / extension dev)
|
|
@@ -265,6 +271,8 @@ export { commandFrameClient, CommandFrameClient } from "./client";
|
|
|
265
271
|
export { topics } from "./pubsub/topics";
|
|
266
272
|
// Export Hooks (extension iframe API for session-scoped event callbacks)
|
|
267
273
|
export { hooks } from "./hooks";
|
|
274
|
+
// Export Interceptors (extension iframe API for gating host flows)
|
|
275
|
+
export { interceptors } from "./interceptors";
|
|
268
276
|
// Export Pub/Sub Topics
|
|
269
277
|
export { customersTopic } from "./pubsub/topics/customers";
|
|
270
278
|
export { ordersTopic } from "./pubsub/topics/orders";
|
|
@@ -285,3 +293,5 @@ export { categoriesTopic } from "./pubsub/topics/categories";
|
|
|
285
293
|
export { attributesTopic } from "./pubsub/topics/attributes";
|
|
286
294
|
// Export Custom Tables Types
|
|
287
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 {};
|
|
@@ -2,13 +2,17 @@ import { mockAddCartDiscount } from "../../actions/add-cart-discount/mock";
|
|
|
2
2
|
import { mockAddCartFee } from "../../actions/add-cart-fee/mock";
|
|
3
3
|
import { mockRemoveCartFee } from "../../actions/remove-cart-fee/mock";
|
|
4
4
|
import { mockAddCustomSale } from "../../actions/add-custom-sale/mock";
|
|
5
|
+
import { mockRemoveCustomSale } from "../../actions/remove-custom-sale/mock";
|
|
5
6
|
import { mockAddCustomer } from "../../actions/add-customer/mock";
|
|
6
7
|
import { mockAddCustomerNote } from "../../actions/add-customer-note/mock";
|
|
7
8
|
import { mockRemoveCustomerNote } from "../../actions/remove-customer-note/mock";
|
|
8
9
|
import { mockEditCustomer } from "../../actions/edit-customer/mock";
|
|
9
10
|
import { mockAddOrderNote } from "../../actions/add-order-note/mock";
|
|
11
|
+
import { mockRemoveOrderNote } from "../../actions/remove-order-note/mock";
|
|
10
12
|
import { mockAddProductDiscount } from "../../actions/add-product-discount/mock";
|
|
11
13
|
import { mockAddProductFee } from "../../actions/add-product-fee/mock";
|
|
14
|
+
import { mockRemoveProductDiscount } from "../../actions/remove-product-discount/mock";
|
|
15
|
+
import { mockRemoveProductFee } from "../../actions/remove-product-fee/mock";
|
|
12
16
|
import { mockSetActiveProductFee } from "../../actions/set-active-product-fee/mock";
|
|
13
17
|
import { mockSetActiveProductDiscount } from "../../actions/set-active-product-discount/mock";
|
|
14
18
|
import { mockGetActiveProduct } from "../../actions/get-active-product/mock";
|
|
@@ -37,6 +41,8 @@ import { mockGetTaxTables } from "../../actions/get-tax-tables/mock";
|
|
|
37
41
|
import { mockGetRemainingRefundableQuantities } from "../../actions/get-remaining-refundable-quantities/mock";
|
|
38
42
|
import { mockGoToStationHome } from "../../actions/go-to-station-home/mock";
|
|
39
43
|
import { mockInitiateRefund } from "../../actions/initiate-refund/mock";
|
|
44
|
+
import { mockOpenExtensionOverlay } from "../../actions/open-extension-overlay/mock";
|
|
45
|
+
import { mockResolveExtensionOverlay } from "../../actions/resolve-extension-overlay/mock";
|
|
40
46
|
import { mockOpenCashDrawer } from "../../actions/open-cash-drawer/mock";
|
|
41
47
|
import { mockParkOrder } from "../../actions/park-order/mock";
|
|
42
48
|
import { mockPartialPayment } from "../../actions/partial-payment/mock";
|
|
@@ -86,6 +92,8 @@ import { mockSetActiveSession } from "../../actions/set-active-session/mock";
|
|
|
86
92
|
import { mockGetActiveUser } from "../../actions/get-active-user/mock";
|
|
87
93
|
import { mockSetActiveUser } from "../../actions/set-active-user/mock";
|
|
88
94
|
import { mockSetActiveRefund } from "../../actions/set-active-refund/mock";
|
|
95
|
+
import { canTransitionMock } from "../../actions/can-transition/mock";
|
|
96
|
+
import { getAvailableTransitionsMock } from "../../actions/get-available-transitions/mock";
|
|
89
97
|
import { mockGetSmartGridLayout } from "../../actions/get-smart-grid-layout/mock";
|
|
90
98
|
import { mockSaveSmartGridLayout } from "../../actions/save-smart-grid-layout/mock";
|
|
91
99
|
export const RENDER_MOCKS = {
|
|
@@ -126,6 +134,8 @@ export const RENDER_MOCKS = {
|
|
|
126
134
|
getRemainingRefundableQuantities: mockGetRemainingRefundableQuantities,
|
|
127
135
|
goToStationHome: mockGoToStationHome,
|
|
128
136
|
initiateRefund: mockInitiateRefund,
|
|
137
|
+
openExtensionOverlay: mockOpenExtensionOverlay,
|
|
138
|
+
resolveExtensionOverlay: mockResolveExtensionOverlay,
|
|
129
139
|
openCashDrawer: mockOpenCashDrawer,
|
|
130
140
|
parkOrder: mockParkOrder,
|
|
131
141
|
partialPayment: mockPartialPayment,
|
|
@@ -176,13 +186,15 @@ export const RENDER_MOCKS = {
|
|
|
176
186
|
getActiveUser: mockGetActiveUser,
|
|
177
187
|
setActiveUser: mockSetActiveUser,
|
|
178
188
|
setActiveRefund: mockSetActiveRefund,
|
|
179
|
-
removeProductDiscount:
|
|
180
|
-
removeProductFee:
|
|
189
|
+
removeProductDiscount: mockRemoveProductDiscount,
|
|
190
|
+
removeProductFee: mockRemoveProductFee,
|
|
181
191
|
removeProductNote: () => Promise.resolve({ success: true, timestamp: new Date().toISOString() }),
|
|
182
192
|
removeCartFee: mockRemoveCartFee,
|
|
183
|
-
removeOrderNote:
|
|
184
|
-
removeCustomSale:
|
|
193
|
+
removeOrderNote: mockRemoveOrderNote,
|
|
194
|
+
removeCustomSale: mockRemoveCustomSale,
|
|
185
195
|
removeNonRevenueItem: params => Promise.resolve({ success: true, externalId: params.externalId, timestamp: new Date().toISOString() }),
|
|
196
|
+
canTransition: canTransitionMock,
|
|
197
|
+
getAvailableTransitions: getAvailableTransitionsMock,
|
|
186
198
|
getSmartGridLayout: mockGetSmartGridLayout,
|
|
187
199
|
saveSmartGridLayout: mockSaveSmartGridLayout
|
|
188
200
|
};
|
|
@@ -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, GetSmartGridLayout, SaveSmartGridLayout } 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,6 +98,8 @@ export interface RenderProviderActions {
|
|
|
94
98
|
removeOrderNote: RemoveOrderNote;
|
|
95
99
|
removeCustomSale: RemoveCustomSale;
|
|
96
100
|
removeNonRevenueItem: RemoveNonRevenueItem;
|
|
101
|
+
canTransition: CanTransition;
|
|
102
|
+
getAvailableTransitions: GetAvailableTransitions;
|
|
97
103
|
getSmartGridLayout: GetSmartGridLayout;
|
|
98
104
|
saveSmartGridLayout: SaveSmartGridLayout;
|
|
99
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
-
|
|
14
|
-
|
|
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,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;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { EXTENSION_REFUND_REQUEST_ACTION } from "./constants";
|
|
2
|
-
function isRecord(value) {
|
|
3
|
-
return typeof value === "object" && value !== null;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Install a message listener in the **extension iframe** so the host can request refunds.
|
|
7
|
-
* Validates `event.source === window.top` before handling.
|
|
8
|
-
*
|
|
9
|
-
* Replies with {@link PostMessageResponse}, using `event.origin` as the target origin when posting back to the host.
|
|
10
|
-
*
|
|
11
|
-
* @param handler - Perform the extension-side refund (API call, etc.)
|
|
12
|
-
* @returns Unsubscribe function
|
|
13
|
-
*/
|
|
14
|
-
export function installExtensionRefundListener(handler) {
|
|
15
|
-
const onMessage = async (event) => {
|
|
16
|
-
const raw = event.data;
|
|
17
|
-
if (!isRecord(raw) || raw.action !== EXTENSION_REFUND_REQUEST_ACTION) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
const requestId = raw.requestId;
|
|
21
|
-
if (typeof requestId !== "string") {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
if (event.source !== window.top || !event.source) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
const source = event.source;
|
|
28
|
-
const replyOrigin = typeof event.origin === "string" ? event.origin : "*";
|
|
29
|
-
const params = raw.params;
|
|
30
|
-
try {
|
|
31
|
-
if (!params || typeof params.paymentType !== "string" || typeof params.amount !== "number" || typeof params.saleId !== "string") {
|
|
32
|
-
const errPayload = {
|
|
33
|
-
requestId,
|
|
34
|
-
success: false,
|
|
35
|
-
error: "Invalid extension refund params"
|
|
36
|
-
};
|
|
37
|
-
source.postMessage(errPayload, replyOrigin);
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const result = await handler(params);
|
|
41
|
-
const payload = {
|
|
42
|
-
requestId,
|
|
43
|
-
success: true,
|
|
44
|
-
data: result
|
|
45
|
-
};
|
|
46
|
-
source.postMessage(payload, replyOrigin);
|
|
47
|
-
}
|
|
48
|
-
catch (e) {
|
|
49
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
50
|
-
const errPayload = {
|
|
51
|
-
requestId,
|
|
52
|
-
success: false,
|
|
53
|
-
error: message
|
|
54
|
-
};
|
|
55
|
-
source.postMessage(errPayload, replyOrigin);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
window.addEventListener("message", onMessage);
|
|
59
|
-
return () => window.removeEventListener("message", onMessage);
|
|
60
|
-
}
|