create-brainerce-store 1.44.1 → 1.46.0
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/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "create-brainerce-store",
|
|
34
|
-
version: "1.
|
|
34
|
+
version: "1.46.0",
|
|
35
35
|
description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
|
|
36
36
|
bin: {
|
|
37
37
|
"create-brainerce-store": "dist/index.js"
|
|
@@ -178,7 +178,7 @@ var BRAINERCE_RUNTIME_DEPS = Object.freeze({
|
|
|
178
178
|
// (Product.displayPrice / displayCurrency / displaySalePrice attached
|
|
179
179
|
// additively when getProducts is called with a regionId). Scaffolded stores
|
|
180
180
|
// must pin >=1.30 to get the auto-region + tax-estimate methods.
|
|
181
|
-
brainerce: "^1.
|
|
181
|
+
brainerce: "^1.32.0",
|
|
182
182
|
"isomorphic-dompurify": "^3.8.0"
|
|
183
183
|
});
|
|
184
184
|
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"brainerce": "<%= brainerceVersion %>",
|
|
14
|
-
"next": "^15.
|
|
14
|
+
"next": "^15.3.4",
|
|
15
15
|
"react": "^19.0.0",
|
|
16
16
|
"react-dom": "^19.0.0",
|
|
17
17
|
"clsx": "^2.1.0",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"@types/react": "^19.0.0",
|
|
24
24
|
"@types/react-dom": "^19.0.0",
|
|
25
25
|
"autoprefixer": "^10.4.0",
|
|
26
|
-
"eslint": "^
|
|
27
|
-
"eslint-config-next": "^15.
|
|
28
|
-
"postcss": "^8.4.
|
|
26
|
+
"eslint": "^9.0.0",
|
|
27
|
+
"eslint-config-next": "^15.3.4",
|
|
28
|
+
"postcss": "^8.4.49",
|
|
29
29
|
"tailwindcss": "^3.4.0",
|
|
30
30
|
"typescript": "^5.4.0"
|
|
31
31
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useEffect } from 'react';
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useCart } from '@/providers/store-provider';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Mounts the Brainerce AI chat widget (the store's shopping assistant).
|
|
@@ -10,8 +12,16 @@ import { useEffect } from 'react';
|
|
|
10
12
|
* Brainerce dashboard (Customers → Storefront Bot). This component renders
|
|
11
13
|
* nothing until the bot is switched Live there, so it is always safe to keep
|
|
12
14
|
* mounted.
|
|
15
|
+
*
|
|
16
|
+
* The widget's product cards call `onAddToCart`, which goes through the same
|
|
17
|
+
* smartAddToCart + refreshCart path as the storefront's own product cards, so
|
|
18
|
+
* the header cart count stays in sync.
|
|
13
19
|
*/
|
|
14
20
|
export function BrainerceBotWidget() {
|
|
21
|
+
const { refreshCart } = useCart();
|
|
22
|
+
const refreshCartRef = useRef(refreshCart);
|
|
23
|
+
refreshCartRef.current = refreshCart;
|
|
24
|
+
|
|
15
25
|
useEffect(() => {
|
|
16
26
|
const connectionId =
|
|
17
27
|
process.env.NEXT_PUBLIC_BRAINERCE_SALES_CHANNEL_ID ||
|
|
@@ -24,6 +34,20 @@ export function BrainerceBotWidget() {
|
|
|
24
34
|
BrainerceBot.mount({
|
|
25
35
|
connectionId,
|
|
26
36
|
baseUrl: process.env.NEXT_PUBLIC_BRAINERCE_API_URL || undefined,
|
|
37
|
+
onAddToCart: async ({ productId, variantId, quantity }) => {
|
|
38
|
+
try {
|
|
39
|
+
const { getClient } = await import('@/lib/brainerce');
|
|
40
|
+
await getClient().smartAddToCart({
|
|
41
|
+
productId,
|
|
42
|
+
variantId: variantId ?? undefined,
|
|
43
|
+
quantity,
|
|
44
|
+
});
|
|
45
|
+
await refreshCartRef.current();
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
return false; // widget falls back to the product page
|
|
49
|
+
}
|
|
50
|
+
},
|
|
27
51
|
}).then((mounted) => {
|
|
28
52
|
if (cancelled) mounted?.destroy();
|
|
29
53
|
else bot = mounted;
|
|
@@ -19,6 +19,17 @@ function generateNonce(): string {
|
|
|
19
19
|
return btoa(binary);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// The Brainerce AI chat widget streams chat directly from the browser, so the
|
|
23
|
+
// API origin must be allowed in connect-src (derived from env so local/staging
|
|
24
|
+
// setups work without editing this file).
|
|
25
|
+
function brainerceApiOrigin(): string {
|
|
26
|
+
try {
|
|
27
|
+
return new URL(process.env.NEXT_PUBLIC_BRAINERCE_API_URL || 'https://api.brainerce.com').origin;
|
|
28
|
+
} catch {
|
|
29
|
+
return 'https://api.brainerce.com';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
function buildCsp(nonce: string): string {
|
|
23
34
|
const isDev = process.env.NODE_ENV === 'development';
|
|
24
35
|
// Next dev uses webpack's eval-source-map devtool, which requires 'unsafe-eval'
|
|
@@ -33,7 +44,7 @@ function buildCsp(nonce: string): string {
|
|
|
33
44
|
"img-src 'self' data: blob: https:",
|
|
34
45
|
"font-src 'self' data:",
|
|
35
46
|
"frame-src 'self' https://meshulam.co.il https://*.meshulam.co.il https://grow.link https://*.grow.link https://grow.security https://*.grow.security https://creditguard.co.il https://*.creditguard.co.il https://js.stripe.com https://hooks.stripe.com https://pay.google.com https://secure.cardcom.solutions https://checkout.stripe.com https://www.paypal.com https://www.sandbox.paypal.com https://*.brainerce.com",
|
|
36
|
-
|
|
47
|
+
`connect-src 'self' ${brainerceApiOrigin()} https://api.brainerce.com https://*.meshulam.co.il https://grow.link https://*.grow.link https://*.grow.security https://pay.google.com https://*.stripe.com https://*.creditguard.co.il`,
|
|
37
48
|
"worker-src 'self' blob:",
|
|
38
49
|
// 'self' (not 'none') so iframe-based payment providers (e.g. Cardcom)
|
|
39
50
|
// can redirect the iframe back to /payment-complete on the storefront
|
|
@@ -136,6 +147,17 @@ function generateNonce(): string {
|
|
|
136
147
|
return btoa(binary);
|
|
137
148
|
}
|
|
138
149
|
|
|
150
|
+
// The Brainerce AI chat widget streams chat directly from the browser, so the
|
|
151
|
+
// API origin must be allowed in connect-src (derived from env so local/staging
|
|
152
|
+
// setups work without editing this file).
|
|
153
|
+
function brainerceApiOrigin(): string {
|
|
154
|
+
try {
|
|
155
|
+
return new URL(process.env.NEXT_PUBLIC_BRAINERCE_API_URL || 'https://api.brainerce.com').origin;
|
|
156
|
+
} catch {
|
|
157
|
+
return 'https://api.brainerce.com';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
139
161
|
function buildCsp(nonce: string): string {
|
|
140
162
|
const isDev = process.env.NODE_ENV === 'development';
|
|
141
163
|
// Next dev uses webpack's eval-source-map devtool, which requires 'unsafe-eval'
|
|
@@ -150,7 +172,7 @@ function buildCsp(nonce: string): string {
|
|
|
150
172
|
"img-src 'self' data: blob: https:",
|
|
151
173
|
"font-src 'self' data:",
|
|
152
174
|
"frame-src 'self' https://meshulam.co.il https://*.meshulam.co.il https://grow.link https://*.grow.link https://grow.security https://*.grow.security https://creditguard.co.il https://*.creditguard.co.il https://js.stripe.com https://hooks.stripe.com https://pay.google.com https://secure.cardcom.solutions https://checkout.stripe.com https://www.paypal.com https://www.sandbox.paypal.com https://*.brainerce.com",
|
|
153
|
-
|
|
175
|
+
`connect-src 'self' ${brainerceApiOrigin()} https://api.brainerce.com https://*.meshulam.co.il https://grow.link https://*.grow.link https://*.grow.security https://pay.google.com https://*.stripe.com https://*.creditguard.co.il`,
|
|
154
176
|
"worker-src 'self' blob:",
|
|
155
177
|
// 'self' (not 'none') so iframe-based payment providers (e.g. Cardcom)
|
|
156
178
|
// can redirect the iframe back to /payment-complete on the storefront
|