@jay-framework/wix-cart 0.18.4 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -0
- package/dist/contracts/cart-page.jay-contract +1 -0
- package/dist/{index.client-DWB0MOQ0.d.ts → index.client-C7UwcsSn.d.ts} +13 -1
- package/dist/index.client.d.ts +2 -1
- package/dist/index.client.js +685 -4
- package/dist/index.d.ts +9 -3
- package/dist/index.js +52 -5
- package/package.json +14 -13
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# @jay-framework/wix-cart
|
|
2
|
+
|
|
3
|
+
Shared cart and checkout package for Jay Framework Wix integrations. Provides headless cart components with server-side rendering and client-side interactivity, plus checkout redirect to Wix's hosted checkout.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Cart page** — Full cart with line items, quantity controls, coupon codes, and estimated totals
|
|
8
|
+
- **Cart indicator** — Reactive badge showing item count (updates automatically on add/remove)
|
|
9
|
+
- **Mini cart** — Compact cart drawer/modal
|
|
10
|
+
- **Checkout redirect** — Creates a checkout from the current cart and redirects to Wix's hosted checkout page
|
|
11
|
+
- **Three-phase rendering** — Slow (build), Fast (request/SSR), Interactive (client)
|
|
12
|
+
- **Shared across stores packages** — Used by both `@jay-framework/wix-stores` and `@jay-framework/wix-stores-v1`
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
### `config/.wix-cart.yaml`
|
|
17
|
+
|
|
18
|
+
Optional configuration file. Created automatically by `jay-stack-cli setup` if missing.
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
# Checkout callback URLs
|
|
22
|
+
urls:
|
|
23
|
+
thankYou: '/thank-you' # Where Wix redirects after successful checkout (default: /thank-you)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Headless Components
|
|
27
|
+
|
|
28
|
+
### Cart Page (`cart-page`)
|
|
29
|
+
|
|
30
|
+
Full shopping cart with line item management and checkout.
|
|
31
|
+
|
|
32
|
+
- **Slow phase**: Cart ID, empty cart message
|
|
33
|
+
- **Fast phase**: Loading state
|
|
34
|
+
- **Interactive**: Line items (quantity, remove), coupon input, checkout button
|
|
35
|
+
|
|
36
|
+
Key interactions:
|
|
37
|
+
|
|
38
|
+
- `checkoutButton` — Creates a Wix checkout and redirects to hosted checkout
|
|
39
|
+
- `continueShoppingLink` — Link back to products
|
|
40
|
+
- `clearCartButton` — Remove all items
|
|
41
|
+
- Quantity increment/decrement per line item
|
|
42
|
+
- Coupon apply/remove
|
|
43
|
+
|
|
44
|
+
### Cart Indicator (`cart-indicator`)
|
|
45
|
+
|
|
46
|
+
Header badge showing cart item count.
|
|
47
|
+
|
|
48
|
+
- **Fast+Interactive**: `itemCount`, `hasItems`, `isLoading`, `justAdded`
|
|
49
|
+
- Reactive — updates automatically when items are added/removed from any page
|
|
50
|
+
|
|
51
|
+
### Mini Cart (`mini-cart`)
|
|
52
|
+
|
|
53
|
+
Compact cart for drawer/modal display. Same data as cart-page in a condensed format.
|
|
54
|
+
|
|
55
|
+
## Checkout Flow
|
|
56
|
+
|
|
57
|
+
The checkout button triggers a redirect to Wix's hosted checkout:
|
|
58
|
+
|
|
59
|
+
1. `createCheckoutFromCurrentCart()` — creates a Wix checkout from the current cart
|
|
60
|
+
2. `createRedirectSession({ ecomCheckout: { checkoutId } })` — gets a redirect URL
|
|
61
|
+
3. Browser navigates to Wix checkout — payment, shipping, order review
|
|
62
|
+
4. After completion, Wix redirects to the configured `thankYou` URL
|
|
63
|
+
|
|
64
|
+
No PCI compliance or payment integration needed — Wix handles everything.
|
|
65
|
+
|
|
66
|
+
## Services & Contexts
|
|
67
|
+
|
|
68
|
+
### `WIX_CART_SERVICE` (server)
|
|
69
|
+
|
|
70
|
+
Server-side cart operations using API key authentication.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { WIX_CART_SERVICE } from '@jay-framework/wix-cart';
|
|
74
|
+
|
|
75
|
+
// Available in .withServices(WIX_CART_SERVICE)
|
|
76
|
+
interface WixCartService {
|
|
77
|
+
cart: CurrentCartClient; // @wix/ecom currentCart
|
|
78
|
+
redirects: RedirectsClient; // @wix/redirects
|
|
79
|
+
urls: { thankYou: string }; // Configured URLs
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `WIX_CART_CONTEXT` (client)
|
|
84
|
+
|
|
85
|
+
Client-side cart operations using OAuth authentication.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { WIX_CART_CONTEXT } from '@jay-framework/wix-cart';
|
|
89
|
+
|
|
90
|
+
// Available in useContext(WIX_CART_CONTEXT)
|
|
91
|
+
interface WixCartContext {
|
|
92
|
+
cartIndicator: { itemCount: Getter<number>; hasItems: Getter<boolean> };
|
|
93
|
+
refreshCartIndicator(): Promise<void>;
|
|
94
|
+
getEstimatedCart(): Promise<CartState>;
|
|
95
|
+
addToCart(
|
|
96
|
+
productId: string,
|
|
97
|
+
quantity?: number,
|
|
98
|
+
options?: AddToCartOptions,
|
|
99
|
+
): Promise<CartOperationResult>;
|
|
100
|
+
removeLineItems(lineItemIds: string[]): Promise<CartOperationResult>;
|
|
101
|
+
updateLineItemQuantity(lineItemId: string, quantity: number): Promise<CartOperationResult>;
|
|
102
|
+
clearCart(): Promise<void>;
|
|
103
|
+
applyCoupon(couponCode: string): Promise<CartOperationResult>;
|
|
104
|
+
removeCoupon(): Promise<CartOperationResult>;
|
|
105
|
+
checkout(): Promise<string>; // Returns Wix checkout redirect URL
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Dependencies
|
|
110
|
+
|
|
111
|
+
- `@wix/ecom` — Cart operations (currentCart)
|
|
112
|
+
- `@wix/redirects` — Checkout redirect sessions
|
|
113
|
+
- `@jay-framework/wix-server-client` — Wix SDK client and authentication
|
|
@@ -7,6 +7,7 @@ import { BuildDescriptors } from '@wix/sdk-types';
|
|
|
7
7
|
import * as _jay_framework_fullstack_component from '@jay-framework/fullstack-component';
|
|
8
8
|
import { Signals, PageProps } from '@jay-framework/fullstack-component';
|
|
9
9
|
import * as _jay_framework_component from '@jay-framework/component';
|
|
10
|
+
import { redirects } from '@wix/redirects';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Cart Helper Types and Functions
|
|
@@ -138,6 +139,8 @@ declare function mapEstimateTotalsToState(estimate: EstimateTotalsResult | null)
|
|
|
138
139
|
interface WixCartInitData {
|
|
139
140
|
/** Enable client-side cart operations */
|
|
140
141
|
enableClientCart: boolean;
|
|
142
|
+
/** URL path for post-checkout redirect (default: /thank-you) */
|
|
143
|
+
thankYouUrl: string;
|
|
141
144
|
}
|
|
142
145
|
/**
|
|
143
146
|
* Reactive cart indicator state.
|
|
@@ -239,6 +242,11 @@ interface WixCartContext {
|
|
|
239
242
|
* @returns Updated cart state
|
|
240
243
|
*/
|
|
241
244
|
removeCoupon(): Promise<CartOperationResult>;
|
|
245
|
+
/**
|
|
246
|
+
* Create a Wix checkout redirect session and return the URL.
|
|
247
|
+
* Redirects the user to Wix's hosted checkout page.
|
|
248
|
+
*/
|
|
249
|
+
checkout(): Promise<string>;
|
|
242
250
|
onItemAddedToCart: EventEmitter<void, any>;
|
|
243
251
|
}
|
|
244
252
|
/**
|
|
@@ -253,7 +261,7 @@ declare const WIX_CART_CONTEXT: _jay_framework_runtime.ContextMarker<WixCartCont
|
|
|
253
261
|
*
|
|
254
262
|
* @returns The created context for immediate use (e.g., to call refreshCartIndicator)
|
|
255
263
|
*/
|
|
256
|
-
declare function provideWixCartContext(): WixCartContext;
|
|
264
|
+
declare function provideWixCartContext(thankYouUrl?: string): WixCartContext;
|
|
257
265
|
|
|
258
266
|
interface CartIndicatorViewState {
|
|
259
267
|
itemCount: number,
|
|
@@ -276,6 +284,10 @@ interface CartIndicatorRefs {
|
|
|
276
284
|
|
|
277
285
|
interface WixCartService {
|
|
278
286
|
cart: BuildDescriptors<typeof currentCart, {}>;
|
|
287
|
+
redirects: BuildDescriptors<typeof redirects, {}>;
|
|
288
|
+
urls: {
|
|
289
|
+
thankYou: string;
|
|
290
|
+
};
|
|
279
291
|
}
|
|
280
292
|
/**
|
|
281
293
|
* Server service marker for Wix Cart.
|
package/dist/index.client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AddToCartOptions, q as CartIndicatorState, n as CartLineItem, C as CartOperationResult, l as CartState, o as CartSummary, R as ReactiveCartIndicator, b as WIX_CART_CONTEXT, c as WixCartContext, r as cartIndicator, s as cartPage, u as init, t as miniCart } from './index.client-
|
|
1
|
+
export { A as AddToCartOptions, q as CartIndicatorState, n as CartLineItem, C as CartOperationResult, l as CartState, o as CartSummary, R as ReactiveCartIndicator, b as WIX_CART_CONTEXT, c as WixCartContext, r as cartIndicator, s as cartPage, u as init, t as miniCart } from './index.client-C7UwcsSn.js';
|
|
2
2
|
import '@jay-framework/runtime';
|
|
3
3
|
import '@jay-framework/reactive';
|
|
4
4
|
import '@wix/ecom';
|
|
@@ -6,3 +6,4 @@ import '@wix/auto_sdk_ecom_current-cart';
|
|
|
6
6
|
import '@wix/sdk-types';
|
|
7
7
|
import '@jay-framework/fullstack-component';
|
|
8
8
|
import '@jay-framework/component';
|
|
9
|
+
import '@wix/redirects';
|
package/dist/index.client.js
CHANGED
|
@@ -11,6 +11,666 @@ function getCurrentCartClient(wixClient) {
|
|
|
11
11
|
}
|
|
12
12
|
return currentCartInstance;
|
|
13
13
|
}
|
|
14
|
+
const SDKRequestToRESTRequestRenameMap = {
|
|
15
|
+
_id: "id",
|
|
16
|
+
_createdDate: "createdDate",
|
|
17
|
+
_updatedDate: "updatedDate"
|
|
18
|
+
};
|
|
19
|
+
const RESTResponseToSDKResponseRenameMap = {
|
|
20
|
+
id: "_id",
|
|
21
|
+
createdDate: "_createdDate",
|
|
22
|
+
updatedDate: "_updatedDate"
|
|
23
|
+
};
|
|
24
|
+
function renameAllNestedKeys(payload, renameMap, ignorePaths) {
|
|
25
|
+
const isIgnored = (path) => ignorePaths.includes(path);
|
|
26
|
+
const traverse = (obj, path) => {
|
|
27
|
+
if (Array.isArray(obj)) {
|
|
28
|
+
obj.forEach((item) => {
|
|
29
|
+
traverse(item, path);
|
|
30
|
+
});
|
|
31
|
+
} else if (typeof obj === "object" && obj !== null) {
|
|
32
|
+
const objAsRecord = obj;
|
|
33
|
+
Object.keys(objAsRecord).forEach((key) => {
|
|
34
|
+
const newPath = path === "" ? key : `${path}.${key}`;
|
|
35
|
+
if (isIgnored(newPath)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const transformedKey = renameKey(key, renameMap);
|
|
39
|
+
if (transformedKey !== key && !(transformedKey in objAsRecord)) {
|
|
40
|
+
objAsRecord[transformedKey] = objAsRecord[key];
|
|
41
|
+
delete objAsRecord[key];
|
|
42
|
+
}
|
|
43
|
+
traverse(objAsRecord[transformedKey], newPath);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
traverse(payload, "");
|
|
48
|
+
return payload;
|
|
49
|
+
}
|
|
50
|
+
function renameKey(key, renameMap) {
|
|
51
|
+
let transformedKey;
|
|
52
|
+
if (key.includes(".")) {
|
|
53
|
+
const parts = key.split(".");
|
|
54
|
+
const transformedParts = parts.map((part) => renameMap[part] ?? part);
|
|
55
|
+
transformedKey = transformedParts.join(".");
|
|
56
|
+
} else {
|
|
57
|
+
transformedKey = renameMap[key] ?? key;
|
|
58
|
+
}
|
|
59
|
+
return transformedKey;
|
|
60
|
+
}
|
|
61
|
+
function renameKeysFromSDKRequestToRESTRequest(payload, ignorePaths = []) {
|
|
62
|
+
return renameAllNestedKeys(payload, SDKRequestToRESTRequestRenameMap, ignorePaths);
|
|
63
|
+
}
|
|
64
|
+
function renameKeysFromRESTResponseToSDKResponse(payload, ignorePaths = []) {
|
|
65
|
+
return renameAllNestedKeys(payload, RESTResponseToSDKResponseRenameMap, ignorePaths);
|
|
66
|
+
}
|
|
67
|
+
function transformRESTTimestampToSDKTimestamp(val) {
|
|
68
|
+
return val ? new Date(val) : void 0;
|
|
69
|
+
}
|
|
70
|
+
function transformPath(obj, { path, isRepeated, isMap }, transformFn) {
|
|
71
|
+
const pathParts = path.split(".");
|
|
72
|
+
if (pathParts.length === 1 && path in obj) {
|
|
73
|
+
obj[path] = isRepeated ? obj[path].map(transformFn) : isMap ? Object.fromEntries(Object.entries(obj[path]).map(([key, value]) => [key, transformFn(value)])) : transformFn(obj[path]);
|
|
74
|
+
return obj;
|
|
75
|
+
}
|
|
76
|
+
const [first, ...rest] = pathParts;
|
|
77
|
+
if (first.endsWith("{}")) {
|
|
78
|
+
const cleanPath = first.slice(0, -2);
|
|
79
|
+
obj[cleanPath] = Object.fromEntries(Object.entries(obj[cleanPath]).map(([key, value]) => [
|
|
80
|
+
key,
|
|
81
|
+
transformPath(value, { path: rest.join("."), isRepeated, isMap }, transformFn)
|
|
82
|
+
]));
|
|
83
|
+
} else if (Array.isArray(obj[first])) {
|
|
84
|
+
obj[first] = obj[first].map((item) => transformPath(item, { path: rest.join("."), isRepeated, isMap }, transformFn));
|
|
85
|
+
} else if (first in obj && typeof obj[first] === "object" && obj[first] !== null) {
|
|
86
|
+
obj[first] = transformPath(obj[first], { path: rest.join("."), isRepeated, isMap }, transformFn);
|
|
87
|
+
} else if (first === "*") {
|
|
88
|
+
Object.keys(obj).reduce((acc, curr) => {
|
|
89
|
+
acc[curr] = transformPath(obj[curr], { path: rest.join("."), isRepeated, isMap }, transformFn);
|
|
90
|
+
return acc;
|
|
91
|
+
}, obj);
|
|
92
|
+
}
|
|
93
|
+
return obj;
|
|
94
|
+
}
|
|
95
|
+
function transformPaths(obj, transformations) {
|
|
96
|
+
return transformations.reduce((acc, { paths, transformFn }) => paths.reduce((transformerAcc, path) => transformPath(transformerAcc, path, transformFn), acc), obj);
|
|
97
|
+
}
|
|
98
|
+
function EventDefinition(type, isDomainEvent = false, transformations = (x) => x) {
|
|
99
|
+
return () => ({
|
|
100
|
+
__type: "event-definition",
|
|
101
|
+
type,
|
|
102
|
+
isDomainEvent,
|
|
103
|
+
transformations
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function constantCase(input) {
|
|
107
|
+
return split(input).map((part) => part.toLocaleUpperCase()).join("_");
|
|
108
|
+
}
|
|
109
|
+
const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
|
|
110
|
+
const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
|
|
111
|
+
const SPLIT_REPLACE_VALUE = "$1\0$2";
|
|
112
|
+
const DEFAULT_STRIP_REGEXP = /[^\p{L}\d]+/giu;
|
|
113
|
+
function split(value) {
|
|
114
|
+
let result = value.trim();
|
|
115
|
+
result = result.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE).replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);
|
|
116
|
+
result = result.replace(DEFAULT_STRIP_REGEXP, "\0");
|
|
117
|
+
let start = 0;
|
|
118
|
+
let end = result.length;
|
|
119
|
+
while (result.charAt(start) === "\0") {
|
|
120
|
+
start++;
|
|
121
|
+
}
|
|
122
|
+
if (start === end) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
while (result.charAt(end - 1) === "\0") {
|
|
126
|
+
end--;
|
|
127
|
+
}
|
|
128
|
+
return result.slice(start, end).split(/\0/g);
|
|
129
|
+
}
|
|
130
|
+
const isValidationError = (httpClientError) => "validationError" in (httpClientError.response?.data?.details ?? {});
|
|
131
|
+
const isApplicationError = (httpClientError) => "applicationError" in (httpClientError.response?.data?.details ?? {});
|
|
132
|
+
const isClientError = (httpClientError) => (httpClientError.response?.status ?? -1) >= 400 && (httpClientError.response?.status ?? -1) < 500;
|
|
133
|
+
function transformError(httpClientError, pathsToArguments = {
|
|
134
|
+
explicitPathsToArguments: {},
|
|
135
|
+
spreadPathsToArguments: {},
|
|
136
|
+
singleArgumentUnchanged: false
|
|
137
|
+
}, argumentNames = []) {
|
|
138
|
+
if (typeof httpClientError !== "object" || httpClientError === null) {
|
|
139
|
+
throw httpClientError;
|
|
140
|
+
}
|
|
141
|
+
if (isValidationError(httpClientError)) {
|
|
142
|
+
return buildValidationError(httpClientError, pathsToArguments, argumentNames);
|
|
143
|
+
}
|
|
144
|
+
if (isApplicationError(httpClientError)) {
|
|
145
|
+
return buildApplicationError(httpClientError);
|
|
146
|
+
}
|
|
147
|
+
if (isClientError(httpClientError)) {
|
|
148
|
+
const status = httpClientError.response?.status;
|
|
149
|
+
const statusText = httpClientError.response?.statusText ?? "UNKNOWN";
|
|
150
|
+
const message = httpClientError.response?.data?.message ?? statusText;
|
|
151
|
+
const details = {
|
|
152
|
+
applicationError: {
|
|
153
|
+
description: statusText,
|
|
154
|
+
code: constantCase(statusText),
|
|
155
|
+
data: {}
|
|
156
|
+
},
|
|
157
|
+
requestId: httpClientError.requestId
|
|
158
|
+
};
|
|
159
|
+
return wrapError(httpClientError, {
|
|
160
|
+
message: JSON.stringify({
|
|
161
|
+
message,
|
|
162
|
+
details
|
|
163
|
+
}, null, 2),
|
|
164
|
+
extraProperties: {
|
|
165
|
+
details,
|
|
166
|
+
status
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return buildSystemError(httpClientError);
|
|
171
|
+
}
|
|
172
|
+
const buildValidationError = (httpClientError, pathsToArguments, argumentNames) => {
|
|
173
|
+
const validationErrorResponse = httpClientError.response?.data;
|
|
174
|
+
const requestId = httpClientError.requestId;
|
|
175
|
+
const { fieldViolations } = validationErrorResponse.details.validationError;
|
|
176
|
+
const transformedFieldViolations = violationsWithRenamedFields(pathsToArguments, fieldViolations, argumentNames)?.sort((a, b) => a.field < b.field ? -1 : 1);
|
|
177
|
+
const message = `INVALID_ARGUMENT: ${transformedFieldViolations?.map(({ field, description }) => `"${field}" ${description}`)?.join(", ")}`;
|
|
178
|
+
const details = {
|
|
179
|
+
validationError: { fieldViolations: transformedFieldViolations },
|
|
180
|
+
requestId
|
|
181
|
+
};
|
|
182
|
+
return wrapError(httpClientError, {
|
|
183
|
+
message: JSON.stringify({ message, details }, null, 2),
|
|
184
|
+
extraProperties: {
|
|
185
|
+
details,
|
|
186
|
+
status: httpClientError.response?.status,
|
|
187
|
+
requestId
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
const wrapError = (baseError, { message, extraProperties }) => {
|
|
192
|
+
return Object.assign(baseError, {
|
|
193
|
+
...extraProperties,
|
|
194
|
+
message
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
const buildApplicationError = (httpClientError) => {
|
|
198
|
+
const status = httpClientError.response?.status;
|
|
199
|
+
const statusText = httpClientError.response?.statusText ?? "UNKNOWN";
|
|
200
|
+
const message = httpClientError.response?.data?.message ?? statusText;
|
|
201
|
+
const description = httpClientError.response?.data?.details?.applicationError?.description ?? statusText;
|
|
202
|
+
const code = httpClientError.response?.data?.details?.applicationError?.code ?? constantCase(statusText);
|
|
203
|
+
const data = httpClientError.response?.data?.details?.applicationError?.data ?? {};
|
|
204
|
+
const combinedMessage = message === description ? message : `${message}: ${description}`;
|
|
205
|
+
const details = {
|
|
206
|
+
applicationError: {
|
|
207
|
+
description,
|
|
208
|
+
code,
|
|
209
|
+
data
|
|
210
|
+
},
|
|
211
|
+
requestId: httpClientError.requestId
|
|
212
|
+
};
|
|
213
|
+
return wrapError(httpClientError, {
|
|
214
|
+
message: JSON.stringify({ message: combinedMessage, details }, null, 2),
|
|
215
|
+
extraProperties: {
|
|
216
|
+
details,
|
|
217
|
+
status,
|
|
218
|
+
requestId: httpClientError.requestId
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
const buildSystemError = (httpClientError) => {
|
|
223
|
+
const message = httpClientError.requestId ? `System error occurred, request-id: ${httpClientError.requestId}` : `System error occurred: ${JSON.stringify(httpClientError)}`;
|
|
224
|
+
return wrapError(httpClientError, {
|
|
225
|
+
message,
|
|
226
|
+
extraProperties: {
|
|
227
|
+
requestId: httpClientError.requestId,
|
|
228
|
+
status: httpClientError.response?.status,
|
|
229
|
+
code: constantCase(httpClientError.response?.statusText ?? "UNKNOWN"),
|
|
230
|
+
...!httpClientError.response && {
|
|
231
|
+
runtimeError: httpClientError
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
};
|
|
236
|
+
const violationsWithRenamedFields = ({ spreadPathsToArguments, explicitPathsToArguments, singleArgumentUnchanged }, fieldViolations, argumentNames) => {
|
|
237
|
+
const allPathsToArguments = {
|
|
238
|
+
...spreadPathsToArguments,
|
|
239
|
+
...explicitPathsToArguments
|
|
240
|
+
};
|
|
241
|
+
const allPathsToArgumentsKeys = Object.keys(allPathsToArguments);
|
|
242
|
+
return fieldViolations?.filter((fieldViolation) => {
|
|
243
|
+
const containedInAMoreSpecificViolationField = fieldViolations.some((anotherViolation) => anotherViolation.field.length > fieldViolation.field.length && anotherViolation.field.startsWith(fieldViolation.field) && allPathsToArgumentsKeys.includes(anotherViolation.field));
|
|
244
|
+
return !containedInAMoreSpecificViolationField;
|
|
245
|
+
}).map((fieldViolation) => {
|
|
246
|
+
const exactMatchArgumentExpression = explicitPathsToArguments[fieldViolation.field];
|
|
247
|
+
if (exactMatchArgumentExpression) {
|
|
248
|
+
return {
|
|
249
|
+
...fieldViolation,
|
|
250
|
+
field: withRenamedArgument(exactMatchArgumentExpression, argumentNames)
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const longestPartialPathMatch = allPathsToArgumentsKeys?.sort((a, b) => b.length - a.length)?.find((path) => fieldViolation.field.startsWith(path));
|
|
254
|
+
if (longestPartialPathMatch) {
|
|
255
|
+
const partialMatchArgumentExpression = allPathsToArguments[longestPartialPathMatch];
|
|
256
|
+
if (partialMatchArgumentExpression) {
|
|
257
|
+
return {
|
|
258
|
+
...fieldViolation,
|
|
259
|
+
field: fieldViolation.field.replace(longestPartialPathMatch, withRenamedArgument(partialMatchArgumentExpression, argumentNames))
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (singleArgumentUnchanged) {
|
|
264
|
+
return {
|
|
265
|
+
...fieldViolation,
|
|
266
|
+
field: `${argumentNames[0]}.${fieldViolation.field}`
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return fieldViolation;
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
const withRenamedArgument = (fieldValue, argumentNames) => {
|
|
273
|
+
const argIndex = getArgumentIndex(fieldValue);
|
|
274
|
+
if (argIndex !== null && typeof argIndex !== "undefined") {
|
|
275
|
+
return fieldValue.replace(`$[${argIndex}]`, argumentNames[argIndex]);
|
|
276
|
+
}
|
|
277
|
+
return fieldValue;
|
|
278
|
+
};
|
|
279
|
+
const getArgumentIndex = (s) => {
|
|
280
|
+
const match = s.match(/\$\[(?<argIndex>\d+)\]/);
|
|
281
|
+
return match && match.groups && Number(match.groups.argIndex);
|
|
282
|
+
};
|
|
283
|
+
var wixContext = {};
|
|
284
|
+
function resolveContext() {
|
|
285
|
+
const oldContext = typeof $wixContext !== "undefined" && $wixContext.initWixModules ? $wixContext.initWixModules : typeof globalThis.__wix_context__ !== "undefined" && globalThis.__wix_context__.initWixModules ? globalThis.__wix_context__.initWixModules : void 0;
|
|
286
|
+
if (oldContext) {
|
|
287
|
+
return {
|
|
288
|
+
// @ts-expect-error
|
|
289
|
+
initWixModules(modules, elevated) {
|
|
290
|
+
return runWithoutContext(() => oldContext(modules, elevated));
|
|
291
|
+
},
|
|
292
|
+
fetchWithAuth() {
|
|
293
|
+
throw new Error("fetchWithAuth is not available in this context");
|
|
294
|
+
},
|
|
295
|
+
graphql() {
|
|
296
|
+
throw new Error("graphql is not available in this context");
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
const contextualClient = typeof $wixContext !== "undefined" ? $wixContext.client : typeof wixContext.client !== "undefined" ? wixContext.client : typeof globalThis.__wix_context__ !== "undefined" ? globalThis.__wix_context__.client : void 0;
|
|
301
|
+
const elevatedClient = typeof $wixContext !== "undefined" ? $wixContext.elevatedClient : typeof wixContext.elevatedClient !== "undefined" ? wixContext.elevatedClient : typeof globalThis.__wix_context__ !== "undefined" ? globalThis.__wix_context__.elevatedClient : void 0;
|
|
302
|
+
if (!contextualClient && !elevatedClient) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
initWixModules(wixModules, elevated) {
|
|
307
|
+
if (elevated) {
|
|
308
|
+
if (!elevatedClient) {
|
|
309
|
+
throw new Error("An elevated client is required to use elevated modules. Make sure to initialize the Wix context with an elevated client before using elevated SDK modules");
|
|
310
|
+
}
|
|
311
|
+
return runWithoutContext(() => elevatedClient.use(wixModules));
|
|
312
|
+
}
|
|
313
|
+
if (!contextualClient) {
|
|
314
|
+
throw new Error("Wix context is not available. Make sure to initialize the Wix context before using SDK modules");
|
|
315
|
+
}
|
|
316
|
+
return runWithoutContext(() => contextualClient.use(wixModules));
|
|
317
|
+
},
|
|
318
|
+
fetchWithAuth: (urlOrRequest, requestInit) => {
|
|
319
|
+
if (!contextualClient) {
|
|
320
|
+
throw new Error("Wix context is not available. Make sure to initialize the Wix context before using SDK modules");
|
|
321
|
+
}
|
|
322
|
+
return contextualClient.fetchWithAuth(urlOrRequest, requestInit);
|
|
323
|
+
},
|
|
324
|
+
getAuth() {
|
|
325
|
+
if (!contextualClient) {
|
|
326
|
+
throw new Error("Wix context is not available. Make sure to initialize the Wix context before using SDK modules");
|
|
327
|
+
}
|
|
328
|
+
return contextualClient.auth;
|
|
329
|
+
},
|
|
330
|
+
async graphql(query, variables, opts) {
|
|
331
|
+
if (!contextualClient) {
|
|
332
|
+
throw new Error("Wix context is not available. Make sure to initialize the Wix context before using SDK modules");
|
|
333
|
+
}
|
|
334
|
+
return contextualClient.graphql(query, variables, opts);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function runWithoutContext(fn) {
|
|
339
|
+
const globalContext = globalThis.__wix_context__;
|
|
340
|
+
const moduleContext = {
|
|
341
|
+
client: wixContext.client,
|
|
342
|
+
elevatedClient: wixContext.elevatedClient
|
|
343
|
+
};
|
|
344
|
+
let closureContext;
|
|
345
|
+
globalThis.__wix_context__ = void 0;
|
|
346
|
+
wixContext.client = void 0;
|
|
347
|
+
wixContext.elevatedClient = void 0;
|
|
348
|
+
if (typeof $wixContext !== "undefined") {
|
|
349
|
+
closureContext = {
|
|
350
|
+
client: $wixContext?.client,
|
|
351
|
+
elevatedClient: $wixContext?.elevatedClient
|
|
352
|
+
};
|
|
353
|
+
delete $wixContext.client;
|
|
354
|
+
delete $wixContext.elevatedClient;
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
return fn();
|
|
358
|
+
} finally {
|
|
359
|
+
globalThis.__wix_context__ = globalContext;
|
|
360
|
+
wixContext.client = moduleContext.client;
|
|
361
|
+
wixContext.elevatedClient = moduleContext.elevatedClient;
|
|
362
|
+
if (typeof $wixContext !== "undefined") {
|
|
363
|
+
$wixContext.client = closureContext.client;
|
|
364
|
+
$wixContext.elevatedClient = closureContext.elevatedClient;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function contextualizeRESTModuleV2(restModule, elevated) {
|
|
369
|
+
return (...args) => {
|
|
370
|
+
const context = resolveContext();
|
|
371
|
+
if (!context) {
|
|
372
|
+
return restModule.apply(void 0, args);
|
|
373
|
+
}
|
|
374
|
+
return context.initWixModules(restModule, elevated).apply(void 0, args);
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function contextualizeEventDefinitionModuleV2(eventDefinition) {
|
|
378
|
+
const contextualMethod = (...args) => {
|
|
379
|
+
const context = resolveContext();
|
|
380
|
+
if (!context) {
|
|
381
|
+
return () => {
|
|
382
|
+
return {
|
|
383
|
+
slug: eventDefinition.type
|
|
384
|
+
};
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return context.initWixModules(eventDefinition).apply(void 0, args);
|
|
388
|
+
};
|
|
389
|
+
contextualMethod.__type = eventDefinition.__type;
|
|
390
|
+
contextualMethod.type = eventDefinition.type;
|
|
391
|
+
contextualMethod.isDomainEvent = eventDefinition.isDomainEvent;
|
|
392
|
+
contextualMethod.transformations = eventDefinition.transformations;
|
|
393
|
+
return contextualMethod;
|
|
394
|
+
}
|
|
395
|
+
function createRESTModule(descriptor, elevated = false) {
|
|
396
|
+
return contextualizeRESTModuleV2(descriptor, elevated);
|
|
397
|
+
}
|
|
398
|
+
function resolveUrl(opts) {
|
|
399
|
+
const domain = resolveDomain(opts.host);
|
|
400
|
+
const mappings = resolveMappingsByDomain(domain, opts.domainToMappings);
|
|
401
|
+
const path = injectDataIntoProtoPath(opts.protoPath, opts.data || {});
|
|
402
|
+
return resolvePathFromMappings(path, mappings);
|
|
403
|
+
}
|
|
404
|
+
const DOMAINS = ["wix.com", "editorx.com"];
|
|
405
|
+
const USER_DOMAIN = "_";
|
|
406
|
+
const REGEX_CAPTURE_DOMAINS = new RegExp(`\\.(${DOMAINS.join("|")})$`);
|
|
407
|
+
const WIX_API_DOMAINS = ["42.wixprod.net", "uw2-edt-1.wixprod.net"];
|
|
408
|
+
const DEV_WIX_CODE_DOMAIN = "dev.wix-code.com";
|
|
409
|
+
const REGEX_CAPTURE_PROTO_FIELD = /{(.*)}/;
|
|
410
|
+
const REGEX_CAPTURE_API_DOMAINS = new RegExp(`\\.(${WIX_API_DOMAINS.join("|")})$`);
|
|
411
|
+
const REGEX_CAPTURE_DEV_WIX_CODE_DOMAIN = new RegExp(`.*\\.${DEV_WIX_CODE_DOMAIN}$`);
|
|
412
|
+
function resolveDomain(host) {
|
|
413
|
+
const resolvedHost = fixHostExceptions(host);
|
|
414
|
+
return resolvedHost.replace(REGEX_CAPTURE_DOMAINS, "._base_domain_").replace(REGEX_CAPTURE_API_DOMAINS, "._api_base_domain_").replace(REGEX_CAPTURE_DEV_WIX_CODE_DOMAIN, "*.dev.wix-code.com");
|
|
415
|
+
}
|
|
416
|
+
function fixHostExceptions(host) {
|
|
417
|
+
return host.replace("create.editorx.com", "editor.editorx.com");
|
|
418
|
+
}
|
|
419
|
+
function resolveMappingsByDomain(domain, domainToMappings) {
|
|
420
|
+
const mappings = domainToMappings[domain] || domainToMappings[USER_DOMAIN];
|
|
421
|
+
if (mappings) {
|
|
422
|
+
return mappings;
|
|
423
|
+
}
|
|
424
|
+
const rootDomainMappings = resolveRootDomain(domain, domainToMappings);
|
|
425
|
+
if (!rootDomainMappings) {
|
|
426
|
+
if (isBaseDomain(domain)) {
|
|
427
|
+
return domainToMappings[wwwBaseDomain];
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return rootDomainMappings ?? [];
|
|
431
|
+
}
|
|
432
|
+
function resolveRootDomain(domain, domainToMappings) {
|
|
433
|
+
return Object.entries(domainToMappings).find(([entryDomain]) => {
|
|
434
|
+
const [, ...rooDomainSegments] = domain.split(".");
|
|
435
|
+
return rooDomainSegments.join(".") === entryDomain;
|
|
436
|
+
})?.[1];
|
|
437
|
+
}
|
|
438
|
+
function isBaseDomain(domain) {
|
|
439
|
+
return !!domain.match(/\._base_domain_$/);
|
|
440
|
+
}
|
|
441
|
+
const wwwBaseDomain = "www._base_domain_";
|
|
442
|
+
function injectDataIntoProtoPath(protoPath, data) {
|
|
443
|
+
return protoPath.split("/").map((path) => maybeProtoPathToData(path, data)).join("/");
|
|
444
|
+
}
|
|
445
|
+
function maybeProtoPathToData(protoPath, data) {
|
|
446
|
+
const protoRegExpMatch = protoPath.match(REGEX_CAPTURE_PROTO_FIELD) || [];
|
|
447
|
+
const field = protoRegExpMatch[1];
|
|
448
|
+
if (field) {
|
|
449
|
+
const suffix = protoPath.replace(protoRegExpMatch[0], "");
|
|
450
|
+
return findByPath(data, field, protoPath, suffix);
|
|
451
|
+
}
|
|
452
|
+
return protoPath;
|
|
453
|
+
}
|
|
454
|
+
function findByPath(obj, path, defaultValue, suffix) {
|
|
455
|
+
let result = obj;
|
|
456
|
+
for (const field of path.split(".")) {
|
|
457
|
+
if (!result) {
|
|
458
|
+
return defaultValue;
|
|
459
|
+
}
|
|
460
|
+
result = result[field];
|
|
461
|
+
}
|
|
462
|
+
return `${result}${suffix}`;
|
|
463
|
+
}
|
|
464
|
+
function resolvePathFromMappings(protoPath, mappings) {
|
|
465
|
+
const mapping = mappings?.find((m) => protoPath.startsWith(m.destPath));
|
|
466
|
+
if (!mapping) {
|
|
467
|
+
return protoPath;
|
|
468
|
+
}
|
|
469
|
+
return mapping.srcPath + protoPath.slice(mapping.destPath.length);
|
|
470
|
+
}
|
|
471
|
+
function createEventModule(eventDefinition) {
|
|
472
|
+
return contextualizeEventDefinitionModuleV2(eventDefinition);
|
|
473
|
+
}
|
|
474
|
+
function resolveWixHeadlessV1RedirectSessionServiceUrl(opts) {
|
|
475
|
+
const domainToMappings = {
|
|
476
|
+
"www._base_domain_": [
|
|
477
|
+
{
|
|
478
|
+
srcPath: "/_api/redirects-api",
|
|
479
|
+
destPath: ""
|
|
480
|
+
}
|
|
481
|
+
],
|
|
482
|
+
"www.wixapis.com": [
|
|
483
|
+
{
|
|
484
|
+
srcPath: "/_api/redirects-api",
|
|
485
|
+
destPath: ""
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
srcPath: "/redirect-session",
|
|
489
|
+
destPath: ""
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
srcPath: "/headless/v1/redirect-session",
|
|
493
|
+
destPath: "/v1/redirect-session"
|
|
494
|
+
}
|
|
495
|
+
],
|
|
496
|
+
"*.dev.wix-code.com": [
|
|
497
|
+
{
|
|
498
|
+
srcPath: "/headless/v1/redirect-session",
|
|
499
|
+
destPath: "/v1/redirect-session"
|
|
500
|
+
}
|
|
501
|
+
],
|
|
502
|
+
_: [
|
|
503
|
+
{
|
|
504
|
+
srcPath: "/headless/v1/redirect-session",
|
|
505
|
+
destPath: "/v1/redirect-session"
|
|
506
|
+
}
|
|
507
|
+
]
|
|
508
|
+
};
|
|
509
|
+
return resolveUrl(Object.assign(opts, { domainToMappings }));
|
|
510
|
+
}
|
|
511
|
+
var PACKAGE_NAME = "@wix/auto_sdk_redirects_redirects";
|
|
512
|
+
function createRedirectSession(payload) {
|
|
513
|
+
function __createRedirectSession({ host }) {
|
|
514
|
+
const metadata = {
|
|
515
|
+
entityFqdn: "wix.headless.v1.redirect_session",
|
|
516
|
+
method: "POST",
|
|
517
|
+
methodFqn: "wix.headless.v1.RedirectSessionService.CreateRedirectSession",
|
|
518
|
+
packageName: PACKAGE_NAME,
|
|
519
|
+
migrationOptions: {
|
|
520
|
+
optInTransformResponse: true
|
|
521
|
+
},
|
|
522
|
+
url: resolveWixHeadlessV1RedirectSessionServiceUrl({
|
|
523
|
+
protoPath: "/v1/redirect-session",
|
|
524
|
+
data: payload,
|
|
525
|
+
host
|
|
526
|
+
}),
|
|
527
|
+
data: payload
|
|
528
|
+
};
|
|
529
|
+
return metadata;
|
|
530
|
+
}
|
|
531
|
+
return __createRedirectSession;
|
|
532
|
+
}
|
|
533
|
+
var LocationType = /* @__PURE__ */ ((LocationType2) => {
|
|
534
|
+
LocationType2["UNDEFINED"] = "UNDEFINED";
|
|
535
|
+
LocationType2["OWNER_BUSINESS"] = "OWNER_BUSINESS";
|
|
536
|
+
LocationType2["OWNER_CUSTOM"] = "OWNER_CUSTOM";
|
|
537
|
+
LocationType2["CUSTOM"] = "CUSTOM";
|
|
538
|
+
return LocationType2;
|
|
539
|
+
})(LocationType || {});
|
|
540
|
+
var Prompt = /* @__PURE__ */ ((Prompt2) => {
|
|
541
|
+
Prompt2["login"] = "login";
|
|
542
|
+
Prompt2["none"] = "none";
|
|
543
|
+
Prompt2["consent"] = "consent";
|
|
544
|
+
Prompt2["select_account"] = "select_account";
|
|
545
|
+
return Prompt2;
|
|
546
|
+
})(Prompt || {});
|
|
547
|
+
var MembersAccountSection = /* @__PURE__ */ ((MembersAccountSection2) => {
|
|
548
|
+
MembersAccountSection2["ACCOUNT_INFO"] = "ACCOUNT_INFO";
|
|
549
|
+
MembersAccountSection2["BOOKINGS"] = "BOOKINGS";
|
|
550
|
+
MembersAccountSection2["ORDERS"] = "ORDERS";
|
|
551
|
+
MembersAccountSection2["SUBSCRIPTIONS"] = "SUBSCRIPTIONS";
|
|
552
|
+
MembersAccountSection2["EVENTS"] = "EVENTS";
|
|
553
|
+
return MembersAccountSection2;
|
|
554
|
+
})(MembersAccountSection || {});
|
|
555
|
+
var AttachPagesResponseStatus = /* @__PURE__ */ ((AttachPagesResponseStatus2) => {
|
|
556
|
+
AttachPagesResponseStatus2["UNKNOWN"] = "UNKNOWN";
|
|
557
|
+
AttachPagesResponseStatus2["SUCCESS"] = "SUCCESS";
|
|
558
|
+
AttachPagesResponseStatus2["NO_ACTION"] = "NO_ACTION";
|
|
559
|
+
AttachPagesResponseStatus2["ERROR"] = "ERROR";
|
|
560
|
+
return AttachPagesResponseStatus2;
|
|
561
|
+
})(AttachPagesResponseStatus || {});
|
|
562
|
+
var CallbackType = /* @__PURE__ */ ((CallbackType2) => {
|
|
563
|
+
CallbackType2["UNKNOWN"] = "UNKNOWN";
|
|
564
|
+
CallbackType2["LOGOUT"] = "LOGOUT";
|
|
565
|
+
CallbackType2["CHECKOUT"] = "CHECKOUT";
|
|
566
|
+
CallbackType2["AUTHORIZE"] = "AUTHORIZE";
|
|
567
|
+
return CallbackType2;
|
|
568
|
+
})(CallbackType || {});
|
|
569
|
+
var Status = /* @__PURE__ */ ((Status2) => {
|
|
570
|
+
Status2["UNKNOWN"] = "UNKNOWN";
|
|
571
|
+
Status2["SUCCESS"] = "SUCCESS";
|
|
572
|
+
Status2["ERROR"] = "ERROR";
|
|
573
|
+
return Status2;
|
|
574
|
+
})(Status || {});
|
|
575
|
+
var WebhookIdentityType = /* @__PURE__ */ ((WebhookIdentityType2) => {
|
|
576
|
+
WebhookIdentityType2["UNKNOWN"] = "UNKNOWN";
|
|
577
|
+
WebhookIdentityType2["ANONYMOUS_VISITOR"] = "ANONYMOUS_VISITOR";
|
|
578
|
+
WebhookIdentityType2["MEMBER"] = "MEMBER";
|
|
579
|
+
WebhookIdentityType2["WIX_USER"] = "WIX_USER";
|
|
580
|
+
WebhookIdentityType2["APP"] = "APP";
|
|
581
|
+
return WebhookIdentityType2;
|
|
582
|
+
})(WebhookIdentityType || {});
|
|
583
|
+
async function createRedirectSession2(options) {
|
|
584
|
+
const { httpClient, sideEffects } = arguments[1];
|
|
585
|
+
const payload = renameKeysFromSDKRequestToRESTRequest({
|
|
586
|
+
bookingsCheckout: options?.bookingsCheckout,
|
|
587
|
+
ecomCheckout: options?.ecomCheckout,
|
|
588
|
+
eventsCheckout: options?.eventsCheckout,
|
|
589
|
+
paidPlansCheckout: options?.paidPlansCheckout,
|
|
590
|
+
login: options?.login,
|
|
591
|
+
logout: options?.logout,
|
|
592
|
+
auth: options?.auth,
|
|
593
|
+
storesProduct: options?.storesProduct,
|
|
594
|
+
bookingsBook: options?.bookingsBook,
|
|
595
|
+
callbacks: options?.callbacks,
|
|
596
|
+
preferences: options?.preferences,
|
|
597
|
+
origin: options?.origin
|
|
598
|
+
});
|
|
599
|
+
const reqOpts = createRedirectSession(payload);
|
|
600
|
+
sideEffects?.onSiteCall?.();
|
|
601
|
+
try {
|
|
602
|
+
const result = await httpClient.request(reqOpts);
|
|
603
|
+
sideEffects?.onSuccess?.(result);
|
|
604
|
+
return renameKeysFromRESTResponseToSDKResponse(result.data);
|
|
605
|
+
} catch (err) {
|
|
606
|
+
const transformedError = transformError(
|
|
607
|
+
err,
|
|
608
|
+
{
|
|
609
|
+
spreadPathsToArguments: {},
|
|
610
|
+
explicitPathsToArguments: {
|
|
611
|
+
bookingsCheckout: "$[0].bookingsCheckout",
|
|
612
|
+
ecomCheckout: "$[0].ecomCheckout",
|
|
613
|
+
eventsCheckout: "$[0].eventsCheckout",
|
|
614
|
+
paidPlansCheckout: "$[0].paidPlansCheckout",
|
|
615
|
+
login: "$[0].login",
|
|
616
|
+
logout: "$[0].logout",
|
|
617
|
+
auth: "$[0].auth",
|
|
618
|
+
storesProduct: "$[0].storesProduct",
|
|
619
|
+
bookingsBook: "$[0].bookingsBook",
|
|
620
|
+
callbacks: "$[0].callbacks",
|
|
621
|
+
preferences: "$[0].preferences",
|
|
622
|
+
origin: "$[0].origin"
|
|
623
|
+
},
|
|
624
|
+
singleArgumentUnchanged: false
|
|
625
|
+
},
|
|
626
|
+
["options"]
|
|
627
|
+
);
|
|
628
|
+
sideEffects?.onError?.(err);
|
|
629
|
+
throw transformedError;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
function createRedirectSession3(httpClient) {
|
|
633
|
+
return (options) => createRedirectSession2(
|
|
634
|
+
options,
|
|
635
|
+
// @ts-ignore
|
|
636
|
+
{ httpClient }
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
var onRedirectSessionCreated = EventDefinition(
|
|
640
|
+
"wix.headless.v1.redirect_session_created",
|
|
641
|
+
true,
|
|
642
|
+
(event) => renameKeysFromRESTResponseToSDKResponse(
|
|
643
|
+
transformPaths(event, [
|
|
644
|
+
{
|
|
645
|
+
transformFn: transformRESTTimestampToSDKTimestamp,
|
|
646
|
+
paths: [{ path: "metadata.eventTime" }]
|
|
647
|
+
}
|
|
648
|
+
])
|
|
649
|
+
)
|
|
650
|
+
)();
|
|
651
|
+
var createRedirectSession4 = /* @__PURE__ */ createRESTModule(createRedirectSession3);
|
|
652
|
+
var onRedirectSessionCreated2 = createEventModule(
|
|
653
|
+
onRedirectSessionCreated
|
|
654
|
+
);
|
|
655
|
+
const redirects = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
656
|
+
__proto__: null,
|
|
657
|
+
AttachPagesResponseStatus,
|
|
658
|
+
CallbackType,
|
|
659
|
+
LocationType,
|
|
660
|
+
MembersAccountSection,
|
|
661
|
+
Prompt,
|
|
662
|
+
Status,
|
|
663
|
+
WebhookIdentityType,
|
|
664
|
+
createRedirectSession: createRedirectSession4,
|
|
665
|
+
onRedirectSessionCreated: onRedirectSessionCreated2
|
|
666
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
667
|
+
let redirectsInstance;
|
|
668
|
+
function getRedirectsClient(wixClient) {
|
|
669
|
+
if (!redirectsInstance) {
|
|
670
|
+
redirectsInstance = wixClient.use(redirects);
|
|
671
|
+
}
|
|
672
|
+
return redirectsInstance;
|
|
673
|
+
}
|
|
14
674
|
function parseWixMediaUrl(url) {
|
|
15
675
|
if (!url) return null;
|
|
16
676
|
const match = url.match(
|
|
@@ -252,10 +912,11 @@ function mapEstimateTotalsToState(estimate) {
|
|
|
252
912
|
}
|
|
253
913
|
const WIX_STORES_APP_ID = "215238eb-22a5-4c36-9e7b-e7c08025e04e";
|
|
254
914
|
const WIX_CART_CONTEXT = createJayContext("wix:cart");
|
|
255
|
-
function provideWixCartContext() {
|
|
915
|
+
function provideWixCartContext(thankYouUrl = "/thank-you") {
|
|
256
916
|
const wixClientContext = useGlobalContext(WIX_CLIENT_CONTEXT);
|
|
257
917
|
const wixClient = wixClientContext.client;
|
|
258
918
|
const cartClient = getCurrentCartClient(wixClient);
|
|
919
|
+
const redirectsClient = getRedirectsClient(wixClient);
|
|
259
920
|
const cartContext = registerReactiveGlobalContext(WIX_CART_CONTEXT, () => {
|
|
260
921
|
const [itemCount, setItemCount] = createSignal(0);
|
|
261
922
|
const [hasItems, setHasItems] = createSignal(false);
|
|
@@ -335,6 +996,19 @@ function provideWixCartContext() {
|
|
|
335
996
|
updateIndicatorFromCart(result.cart ?? null);
|
|
336
997
|
return { cartState: mapCartToState(result.cart ?? null) };
|
|
337
998
|
}
|
|
999
|
+
async function checkout() {
|
|
1000
|
+
const { checkoutId } = await cartClient.createCheckoutFromCurrentCart({});
|
|
1001
|
+
if (!checkoutId) throw new Error("Failed to create checkout from cart");
|
|
1002
|
+
const postFlowUrl = window.location.origin + thankYouUrl;
|
|
1003
|
+
const { redirectSession } = await redirectsClient.createRedirectSession({
|
|
1004
|
+
ecomCheckout: { checkoutId },
|
|
1005
|
+
callbacks: { postFlowUrl }
|
|
1006
|
+
});
|
|
1007
|
+
if (!redirectSession?.fullUrl) {
|
|
1008
|
+
throw new Error("Failed to create checkout redirect session");
|
|
1009
|
+
}
|
|
1010
|
+
return redirectSession.fullUrl;
|
|
1011
|
+
}
|
|
338
1012
|
return {
|
|
339
1013
|
cartIndicator: {
|
|
340
1014
|
itemCount,
|
|
@@ -348,6 +1022,7 @@ function provideWixCartContext() {
|
|
|
348
1022
|
clearCart,
|
|
349
1023
|
applyCoupon,
|
|
350
1024
|
removeCoupon,
|
|
1025
|
+
checkout,
|
|
351
1026
|
onItemAddedToCart
|
|
352
1027
|
};
|
|
353
1028
|
});
|
|
@@ -507,7 +1182,13 @@ function CartPageInteractive(_props, refs, viewStateSignals, _carryForward, cart
|
|
|
507
1182
|
}
|
|
508
1183
|
async function handleCheckout() {
|
|
509
1184
|
setIsCheckingOut(true);
|
|
510
|
-
|
|
1185
|
+
try {
|
|
1186
|
+
const checkoutUrl = await cartContext.checkout();
|
|
1187
|
+
window.location.href = checkoutUrl;
|
|
1188
|
+
} catch (e) {
|
|
1189
|
+
console.error("[wix-cart] Checkout redirect failed:", e);
|
|
1190
|
+
setIsCheckingOut(false);
|
|
1191
|
+
}
|
|
511
1192
|
}
|
|
512
1193
|
refs.clearCartButton?.onclick(handleClearCart);
|
|
513
1194
|
refs.checkoutButton?.onclick(handleCheckout);
|
|
@@ -567,8 +1248,8 @@ function MiniCartInteractive(_props, refs, viewStateSignals, _carryForward, cart
|
|
|
567
1248
|
const miniCart = makeJayStackComponent().withProps().withContexts(WIX_CART_CONTEXT).withInteractive(MiniCartInteractive);
|
|
568
1249
|
const init = makeJayInit().withClient(async (data) => {
|
|
569
1250
|
console.log("[wix-cart] Initializing client-side cart context...");
|
|
570
|
-
const { enableClientCart } = data;
|
|
571
|
-
const cartContext = provideWixCartContext();
|
|
1251
|
+
const { enableClientCart, thankYouUrl } = data;
|
|
1252
|
+
const cartContext = provideWixCartContext(thankYouUrl);
|
|
572
1253
|
if (enableClientCart) {
|
|
573
1254
|
cartContext.refreshCartIndicator();
|
|
574
1255
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WixClient } from '@wix/sdk';
|
|
2
|
-
import { W as WixCartService } from './index.client-
|
|
3
|
-
export { A as AddToCartOptions, q as CartIndicatorState, n as CartLineItem, C as CartOperationResult, l as CartState, o as CartSummary, R as ReactiveCartIndicator, b as WIX_CART_CONTEXT, a as WIX_CART_SERVICE, c as WixCartContext, d as WixCartInitData, r as cartIndicator, s as cartPage, j as estimateCurrentCartTotalsOrNull, i as getCurrentCartOrNull, h as getEmptyCartState, u as init, e as mapCartSummary, g as mapCartToIndicator, f as mapCartToState, k as mapEstimateTotalsToState, m as mapLineItem, t as miniCart, p as provideWixCartContext } from './index.client-
|
|
2
|
+
import { W as WixCartService } from './index.client-C7UwcsSn.js';
|
|
3
|
+
export { A as AddToCartOptions, q as CartIndicatorState, n as CartLineItem, C as CartOperationResult, l as CartState, o as CartSummary, R as ReactiveCartIndicator, b as WIX_CART_CONTEXT, a as WIX_CART_SERVICE, c as WixCartContext, d as WixCartInitData, r as cartIndicator, s as cartPage, j as estimateCurrentCartTotalsOrNull, i as getCurrentCartOrNull, h as getEmptyCartState, u as init, e as mapCartSummary, g as mapCartToIndicator, f as mapCartToState, k as mapEstimateTotalsToState, m as mapLineItem, t as miniCart, p as provideWixCartContext } from './index.client-C7UwcsSn.js';
|
|
4
4
|
import { currentCart } from '@wix/ecom';
|
|
5
5
|
import { BuildDescriptors } from '@wix/sdk-types';
|
|
6
6
|
import '@jay-framework/runtime';
|
|
@@ -8,6 +8,7 @@ import '@jay-framework/reactive';
|
|
|
8
8
|
import '@wix/auto_sdk_ecom_current-cart';
|
|
9
9
|
import '@jay-framework/fullstack-component';
|
|
10
10
|
import '@jay-framework/component';
|
|
11
|
+
import '@wix/redirects';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Wix Cart Client Factory
|
|
@@ -33,10 +34,15 @@ declare function getCurrentCartClient(wixClient: WixClient): BuildDescriptors<ty
|
|
|
33
34
|
* This file contains server-only code (registerService).
|
|
34
35
|
*/
|
|
35
36
|
|
|
37
|
+
interface WixCartServiceOptions {
|
|
38
|
+
urls?: {
|
|
39
|
+
thankYou?: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
36
42
|
/**
|
|
37
43
|
* Creates, registers, and returns a Wix Cart service instance.
|
|
38
44
|
* Called during server initialization.
|
|
39
45
|
*/
|
|
40
|
-
declare function provideWixCartService(wixClient: WixClient): WixCartService;
|
|
46
|
+
declare function provideWixCartService(wixClient: WixClient, options?: WixCartServiceOptions): WixCartService;
|
|
41
47
|
|
|
42
48
|
export { WixCartService, getCurrentCartClient, provideWixCartService };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { registerService, getService } from "@jay-framework/stack-server-runtime";
|
|
2
2
|
import { currentCart } from "@wix/ecom";
|
|
3
|
+
import { redirects } from "@wix/redirects";
|
|
3
4
|
import { createJayService, makeJayStackComponent, RenderPipeline, makeJayInit } from "@jay-framework/fullstack-component";
|
|
4
5
|
import { createJayContext, useGlobalContext } from "@jay-framework/runtime";
|
|
5
6
|
import { registerReactiveGlobalContext, createSignal, useReactive, createEvent } from "@jay-framework/component";
|
|
6
7
|
import { WIX_CLIENT_CONTEXT, WIX_CLIENT_SERVICE } from "@jay-framework/wix-server-client";
|
|
8
|
+
import * as fs from "fs";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
import * as yaml from "js-yaml";
|
|
7
11
|
let currentCartInstance;
|
|
8
12
|
function getCurrentCartClient(wixClient) {
|
|
9
13
|
if (!currentCartInstance) {
|
|
@@ -11,10 +15,19 @@ function getCurrentCartClient(wixClient) {
|
|
|
11
15
|
}
|
|
12
16
|
return currentCartInstance;
|
|
13
17
|
}
|
|
18
|
+
let redirectsInstance;
|
|
19
|
+
function getRedirectsClient(wixClient) {
|
|
20
|
+
if (!redirectsInstance) {
|
|
21
|
+
redirectsInstance = wixClient.use(redirects);
|
|
22
|
+
}
|
|
23
|
+
return redirectsInstance;
|
|
24
|
+
}
|
|
14
25
|
const WIX_CART_SERVICE = createJayService("Wix Cart Service");
|
|
15
|
-
function provideWixCartService(wixClient) {
|
|
26
|
+
function provideWixCartService(wixClient, options) {
|
|
16
27
|
const service = {
|
|
17
|
-
cart: getCurrentCartClient(wixClient)
|
|
28
|
+
cart: getCurrentCartClient(wixClient),
|
|
29
|
+
redirects: getRedirectsClient(wixClient),
|
|
30
|
+
urls: { thankYou: options?.urls?.thankYou || "/thank-you" }
|
|
18
31
|
};
|
|
19
32
|
registerService(WIX_CART_SERVICE, service);
|
|
20
33
|
return service;
|
|
@@ -260,10 +273,11 @@ function mapEstimateTotalsToState(estimate) {
|
|
|
260
273
|
}
|
|
261
274
|
const WIX_STORES_APP_ID = "215238eb-22a5-4c36-9e7b-e7c08025e04e";
|
|
262
275
|
const WIX_CART_CONTEXT = createJayContext("wix:cart");
|
|
263
|
-
function provideWixCartContext() {
|
|
276
|
+
function provideWixCartContext(thankYouUrl = "/thank-you") {
|
|
264
277
|
const wixClientContext = useGlobalContext(WIX_CLIENT_CONTEXT);
|
|
265
278
|
const wixClient = wixClientContext.client;
|
|
266
279
|
const cartClient = getCurrentCartClient(wixClient);
|
|
280
|
+
const redirectsClient = getRedirectsClient(wixClient);
|
|
267
281
|
const cartContext = registerReactiveGlobalContext(WIX_CART_CONTEXT, () => {
|
|
268
282
|
const [itemCount, setItemCount] = createSignal(0);
|
|
269
283
|
const [hasItems, setHasItems] = createSignal(false);
|
|
@@ -343,6 +357,19 @@ function provideWixCartContext() {
|
|
|
343
357
|
updateIndicatorFromCart(result.cart ?? null);
|
|
344
358
|
return { cartState: mapCartToState(result.cart ?? null) };
|
|
345
359
|
}
|
|
360
|
+
async function checkout() {
|
|
361
|
+
const { checkoutId } = await cartClient.createCheckoutFromCurrentCart({});
|
|
362
|
+
if (!checkoutId) throw new Error("Failed to create checkout from cart");
|
|
363
|
+
const postFlowUrl = window.location.origin + thankYouUrl;
|
|
364
|
+
const { redirectSession } = await redirectsClient.createRedirectSession({
|
|
365
|
+
ecomCheckout: { checkoutId },
|
|
366
|
+
callbacks: { postFlowUrl }
|
|
367
|
+
});
|
|
368
|
+
if (!redirectSession?.fullUrl) {
|
|
369
|
+
throw new Error("Failed to create checkout redirect session");
|
|
370
|
+
}
|
|
371
|
+
return redirectSession.fullUrl;
|
|
372
|
+
}
|
|
346
373
|
return {
|
|
347
374
|
cartIndicator: {
|
|
348
375
|
itemCount,
|
|
@@ -356,6 +383,7 @@ function provideWixCartContext() {
|
|
|
356
383
|
clearCart,
|
|
357
384
|
applyCoupon,
|
|
358
385
|
removeCoupon,
|
|
386
|
+
checkout,
|
|
359
387
|
onItemAddedToCart
|
|
360
388
|
};
|
|
361
389
|
});
|
|
@@ -429,13 +457,32 @@ async function renderFastChanging(_props, _wixCart) {
|
|
|
429
457
|
}));
|
|
430
458
|
}
|
|
431
459
|
const miniCart = makeJayStackComponent().withProps().withServices(WIX_CART_SERVICE).withFastRender(renderFastChanging);
|
|
460
|
+
function loadWixCartConfig() {
|
|
461
|
+
const configPath = path.join(process.cwd(), "config", ".wix-cart.yaml");
|
|
462
|
+
const defaults = {
|
|
463
|
+
urls: { thankYou: "/thank-you" }
|
|
464
|
+
};
|
|
465
|
+
if (!fs.existsSync(configPath)) return defaults;
|
|
466
|
+
try {
|
|
467
|
+
const raw = yaml.load(fs.readFileSync(configPath, "utf-8"));
|
|
468
|
+
return {
|
|
469
|
+
urls: {
|
|
470
|
+
thankYou: raw?.urls?.thankYou || defaults.urls.thankYou
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
} catch {
|
|
474
|
+
return defaults;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
432
477
|
const init = makeJayInit().withServer(async () => {
|
|
433
478
|
console.log("[wix-cart] Initializing Wix Cart service...");
|
|
434
479
|
const wixClient = getService(WIX_CLIENT_SERVICE);
|
|
435
|
-
|
|
480
|
+
const config = loadWixCartConfig();
|
|
481
|
+
provideWixCartService(wixClient, { urls: config.urls });
|
|
436
482
|
console.log("[wix-cart] Server initialization complete");
|
|
437
483
|
return {
|
|
438
|
-
enableClientCart: true
|
|
484
|
+
enableClientCart: true,
|
|
485
|
+
thankYouUrl: config.urls.thankYou
|
|
439
486
|
};
|
|
440
487
|
});
|
|
441
488
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/wix-cart",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Wix Cart/Ecom shared package for Jay Framework",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -37,16 +37,17 @@
|
|
|
37
37
|
"test": ":"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@jay-framework/component": "^0.
|
|
41
|
-
"@jay-framework/fullstack-component": "^0.
|
|
42
|
-
"@jay-framework/reactive": "^0.
|
|
43
|
-
"@jay-framework/runtime": "^0.
|
|
44
|
-
"@jay-framework/secure": "^0.
|
|
45
|
-
"@jay-framework/stack-client-runtime": "^0.
|
|
46
|
-
"@jay-framework/stack-server-runtime": "^0.
|
|
47
|
-
"@jay-framework/wix-server-client": "^0.
|
|
48
|
-
"@jay-framework/wix-utils": "^0.
|
|
40
|
+
"@jay-framework/component": "^0.19.1",
|
|
41
|
+
"@jay-framework/fullstack-component": "^0.19.1",
|
|
42
|
+
"@jay-framework/reactive": "^0.19.1",
|
|
43
|
+
"@jay-framework/runtime": "^0.19.1",
|
|
44
|
+
"@jay-framework/secure": "^0.19.1",
|
|
45
|
+
"@jay-framework/stack-client-runtime": "^0.19.1",
|
|
46
|
+
"@jay-framework/stack-server-runtime": "^0.19.1",
|
|
47
|
+
"@jay-framework/wix-server-client": "^0.19.1",
|
|
48
|
+
"@jay-framework/wix-utils": "^0.19.1",
|
|
49
49
|
"@wix/ecom": "^1.0.1996",
|
|
50
|
+
"@wix/redirects": "^1.0.77",
|
|
50
51
|
"@wix/sdk": "^1.21.5",
|
|
51
52
|
"@wix/sdk-runtime": "^1.0.11"
|
|
52
53
|
},
|
|
@@ -54,9 +55,9 @@
|
|
|
54
55
|
"@babel/core": "^7.23.7",
|
|
55
56
|
"@babel/preset-env": "^7.23.8",
|
|
56
57
|
"@babel/preset-typescript": "^7.23.3",
|
|
57
|
-
"@jay-framework/compiler-jay-stack": "^0.
|
|
58
|
-
"@jay-framework/jay-cli": "^0.
|
|
59
|
-
"@jay-framework/vite-plugin": "^0.
|
|
58
|
+
"@jay-framework/compiler-jay-stack": "^0.19.1",
|
|
59
|
+
"@jay-framework/jay-cli": "^0.19.1",
|
|
60
|
+
"@jay-framework/vite-plugin": "^0.19.1",
|
|
60
61
|
"@jay-framework/wix-dev-environment": "^0.6.12",
|
|
61
62
|
"nodemon": "^3.0.3",
|
|
62
63
|
"rimraf": "^5.0.5",
|