create-brainerce-store 1.44.1 → 1.45.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.44.1",
34
+ version: "1.45.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.30.0",
181
+ brainerce: "^1.32.0",
182
182
  "isomorphic-dompurify": "^3.8.0"
183
183
  });
184
184
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-brainerce-store",
3
- "version": "1.44.1",
3
+ "version": "1.45.0",
4
4
  "description": "Scaffold a production-ready e-commerce storefront connected to Brainerce",
5
5
  "bin": {
6
6
  "create-brainerce-store": "dist/index.js"
@@ -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
- "connect-src 'self' https://*.meshulam.co.il https://grow.link https://*.grow.link https://*.grow.security https://pay.google.com https://*.stripe.com https://*.creditguard.co.il",
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
- "connect-src 'self' https://*.meshulam.co.il https://grow.link https://*.grow.link https://*.grow.security https://pay.google.com https://*.stripe.com https://*.creditguard.co.il",
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