brainerce 1.3.2 → 1.4.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.
@@ -675,6 +675,15 @@ if (result.verified) {
675
675
  // Resend verification code
676
676
  await client.resendVerificationEmail(token);
677
677
 
678
+ // Forgot password (on /forgot-password page)
679
+ await client.forgotPassword(email);
680
+ // Always succeeds (prevents email enumeration)
681
+
682
+ // Reset password (on /reset-password page — user arrives via email link)
683
+ const token = new URLSearchParams(window.location.search).get('token');
684
+ await client.resetPassword(token!, newPassword);
685
+ // On success: redirect to /login
686
+
678
687
  // Logout
679
688
  client.setCustomerToken(null);
680
689
  localStorage.removeItem('customerToken');
@@ -725,6 +734,8 @@ if (params.get('oauth_success') === 'true') {
725
734
  - [ ] **Login** (`/login`) - Email/password + social buttons, handle `requiresVerification`
726
735
  - [ ] **Register** (`/register`) - Registration form, handle `requiresVerification`
727
736
  - [ ] **Verify Email** (`/verify-email`) - 6-digit code input + resend button. **ALWAYS create this page** even if verification is currently disabled — the store owner can enable it at any time
737
+ - [ ] **Forgot Password** (`/forgot-password`) - Email input, shows success message
738
+ - [ ] **Reset Password** (`/reset-password`) - Token from URL + new password form
728
739
  - [ ] **OAuth Callback** (`/auth/callback`) - Handle OAuth redirect with token from URL params
729
740
  - [ ] **Account** (`/account`) - Profile + order history
730
741
  - [ ] **Header** - Logo, nav, cart icon with count, search
@@ -735,6 +746,7 @@ Some features may not be configured yet, but the store owner can enable them at
735
746
 
736
747
  - **Email Verification** → `/verify-email` page. `requiresVerification` is checked in login/register flows.
737
748
  - **OAuth Buttons** → Social login buttons on Login & Register + `/auth/callback` page. `getAvailableOAuthProviders()` returns `[]` when none configured — buttons just don't render.
749
+ - **Password Reset** → `/forgot-password` + `/reset-password` pages. `forgotPassword()` silently succeeds when no account exists.
738
750
  - **Discount Banners** → `getDiscountBanners()` returns `[]` when no rules — component renders nothing.
739
751
  - **Product Discount Badges** → `getProductDiscountBadge(id)` returns `null` — renders nothing.
740
752
  - **Cart Nudges** → `cart.nudges` is `[]` — renders nothing.
package/README.md CHANGED
@@ -2037,6 +2037,23 @@ window.location.href = returnUrl;
2037
2037
 
2038
2038
  > **Best Practice:** Before showing login page, save the current URL with `localStorage.setItem('returnUrl', window.location.pathname)`. After login, redirect back to that URL. This is how Amazon, Shopify, and most e-commerce sites work.
2039
2039
 
2040
+ #### Forgot Password
2041
+
2042
+ ```typescript
2043
+ await client.forgotPassword('customer@example.com');
2044
+ // Always returns success message (prevents email enumeration)
2045
+ // If account exists, sends email with reset link
2046
+ ```
2047
+
2048
+ #### Reset Password
2049
+
2050
+ ```typescript
2051
+ // On /reset-password page, extract token from URL
2052
+ const token = new URLSearchParams(window.location.search).get('token');
2053
+ const result = await client.resetPassword(token!, 'newSecurePassword123');
2054
+ // result.message = "Password has been reset successfully"
2055
+ ```
2056
+
2040
2057
  #### Logout Customer
2041
2058
 
2042
2059
  ```typescript
package/dist/index.d.mts CHANGED
@@ -176,12 +176,6 @@ interface Product {
176
176
  attributes?: string[];
177
177
  metafields?: ProductMetafield[];
178
178
  channels?: Record<string, Record<string, unknown>>;
179
- /** Shopify product ID (admin mode only) */
180
- shopifyProductId?: string | null;
181
- /** WooCommerce product ID (admin mode only) */
182
- woocommerceProductId?: string | null;
183
- /** Meta/Facebook Item Group ID (admin mode only) */
184
- metaItemGroupId?: string | null;
185
179
  /** Whether product needs sync to platforms. Always returned by backend. */
186
180
  needsSync: boolean;
187
181
  /** Last sync timestamp (admin mode only) */
@@ -761,6 +755,27 @@ interface Order {
761
755
  platform?: string;
762
756
  /** Whether this order contains downloadable products */
763
757
  hasDownloads?: boolean;
758
+ /** Subtotal before discounts/shipping/tax */
759
+ subtotal?: string | null;
760
+ /** Total discount amount */
761
+ discountAmount?: string | null;
762
+ /** Applied coupon code */
763
+ couponCode?: string | null;
764
+ /** Coupon discount amount */
765
+ couponDiscount?: string | null;
766
+ /** Total discount from rules */
767
+ ruleDiscountAmount?: string | null;
768
+ /** Per-rule discount snapshots */
769
+ appliedDiscounts?: Array<{
770
+ ruleId: string;
771
+ ruleName: string;
772
+ type: string;
773
+ discountAmount: string | null;
774
+ }> | null;
775
+ /** Shipping cost */
776
+ shippingAmount?: string | null;
777
+ /** Tax amount */
778
+ taxAmount?: string | null;
764
779
  createdAt: string;
765
780
  }
766
781
  /**
@@ -882,7 +897,7 @@ interface SyncJob {
882
897
  platform?: string;
883
898
  message?: string;
884
899
  }
885
- type ConnectorPlatform = 'SHOPIFY' | 'TIKTOK' | 'META' | 'WOOCOMMERCE' | 'CUSTOM';
900
+ type ConnectorPlatform = string;
886
901
  /**
887
902
  * Reference to an entity with ID and name.
888
903
  * Used for products, categories, and other related entities.
@@ -925,9 +940,6 @@ interface Coupon {
925
940
  lastSyncedAt?: string | null;
926
941
  /** Per-platform channel overrides */
927
942
  channels?: Record<string, Record<string, unknown>> | null;
928
- shopifyCouponId?: string | null;
929
- woocommerceCouponId?: string | null;
930
- tiktokCouponId?: string | null;
931
943
  createdAt: string;
932
944
  updatedAt: string;
933
945
  }
@@ -1839,8 +1851,8 @@ interface SelectPickupLocationDto {
1839
1851
  * 2. Select shipping method: `selectShippingMethod(id, rateId)`
1840
1852
  * 3. Pay with Stripe: `createPaymentIntent(id)` → `stripe.confirmPayment()` → Order created automatically!
1841
1853
  *
1842
- * **Note:** Order is created automatically via webhook when payment succeeds.
1843
- * No need to call `completeCheckout()` - it happens automatically.
1854
+ * **Note:** Always call `completeGuestCheckout()` on the success page.
1855
+ * It is idempotent if the payment webhook already created the order, it returns the existing order.
1844
1856
  *
1845
1857
  * **IMPORTANT: Order Summary Display**
1846
1858
  * Always use `checkout.lineItems` for displaying the Order Summary during checkout!
@@ -1906,6 +1918,8 @@ interface Checkout {
1906
1918
  subtotal: string;
1907
1919
  /** Discount amount as string - use parseFloat() */
1908
1920
  discountAmount: string;
1921
+ /** Discount amount from automatic rules as string - use parseFloat() */
1922
+ ruleDiscountAmount?: string;
1909
1923
  /** Shipping cost as string - use parseFloat() */
1910
1924
  shippingAmount: string;
1911
1925
  /** Tax amount as string - use parseFloat() */
@@ -4215,6 +4229,13 @@ declare class BrainerceClient {
4215
4229
  forgotPassword(email: string): Promise<{
4216
4230
  message: string;
4217
4231
  }>;
4232
+ /**
4233
+ * Reset customer password using a reset token received via email
4234
+ * Works in vibe-coded, storefront, and admin mode
4235
+ */
4236
+ resetPassword(token: string, newPassword: string): Promise<{
4237
+ message: string;
4238
+ }>;
4218
4239
  /**
4219
4240
  * Verify customer email with a verification code
4220
4241
  * Only available in vibe-coded mode
@@ -5164,16 +5185,22 @@ declare class BrainerceClient {
5164
5185
  */
5165
5186
  getPaymentStatus(checkoutId: string): Promise<PaymentStatus>;
5166
5187
  /**
5167
- * Confirm a Grow SDK payment from the frontend.
5168
- * Call this in the Grow SDK `onSuccess` callback to notify the backend
5169
- * that payment succeeded, triggering order creation.
5188
+ * Confirm a client-side SDK payment from the frontend.
5189
+ * Call this in the payment SDK's success callback (e.g., Grow onSuccess) to notify the
5190
+ * backend that payment succeeded, triggering order creation.
5170
5191
  *
5171
5192
  * **Vibe-coded mode only** - requires connectionId
5172
5193
  *
5173
5194
  * @param checkoutId - The checkout ID
5174
- * @param confirmationNumber - Optional confirmation number from Grow onSuccess
5195
+ * @param providerResponseData - Optional payment provider SDK callback data (transactionId, transactionToken, confirmation_number, etc.)
5196
+ */
5197
+ confirmSdkPayment(checkoutId: string, providerResponseData?: Record<string, unknown>): Promise<{
5198
+ confirmed: boolean;
5199
+ }>;
5200
+ /**
5201
+ * @deprecated Use `confirmSdkPayment` instead. This method will be removed in a future version.
5175
5202
  */
5176
- confirmGrowPayment(checkoutId: string, confirmationNumber?: string): Promise<{
5203
+ confirmGrowPayment(checkoutId: string, confirmationNumber?: string, growResponseData?: Record<string, unknown>): Promise<{
5177
5204
  confirmed: boolean;
5178
5205
  }>;
5179
5206
  /**
package/dist/index.d.ts CHANGED
@@ -176,12 +176,6 @@ interface Product {
176
176
  attributes?: string[];
177
177
  metafields?: ProductMetafield[];
178
178
  channels?: Record<string, Record<string, unknown>>;
179
- /** Shopify product ID (admin mode only) */
180
- shopifyProductId?: string | null;
181
- /** WooCommerce product ID (admin mode only) */
182
- woocommerceProductId?: string | null;
183
- /** Meta/Facebook Item Group ID (admin mode only) */
184
- metaItemGroupId?: string | null;
185
179
  /** Whether product needs sync to platforms. Always returned by backend. */
186
180
  needsSync: boolean;
187
181
  /** Last sync timestamp (admin mode only) */
@@ -761,6 +755,27 @@ interface Order {
761
755
  platform?: string;
762
756
  /** Whether this order contains downloadable products */
763
757
  hasDownloads?: boolean;
758
+ /** Subtotal before discounts/shipping/tax */
759
+ subtotal?: string | null;
760
+ /** Total discount amount */
761
+ discountAmount?: string | null;
762
+ /** Applied coupon code */
763
+ couponCode?: string | null;
764
+ /** Coupon discount amount */
765
+ couponDiscount?: string | null;
766
+ /** Total discount from rules */
767
+ ruleDiscountAmount?: string | null;
768
+ /** Per-rule discount snapshots */
769
+ appliedDiscounts?: Array<{
770
+ ruleId: string;
771
+ ruleName: string;
772
+ type: string;
773
+ discountAmount: string | null;
774
+ }> | null;
775
+ /** Shipping cost */
776
+ shippingAmount?: string | null;
777
+ /** Tax amount */
778
+ taxAmount?: string | null;
764
779
  createdAt: string;
765
780
  }
766
781
  /**
@@ -882,7 +897,7 @@ interface SyncJob {
882
897
  platform?: string;
883
898
  message?: string;
884
899
  }
885
- type ConnectorPlatform = 'SHOPIFY' | 'TIKTOK' | 'META' | 'WOOCOMMERCE' | 'CUSTOM';
900
+ type ConnectorPlatform = string;
886
901
  /**
887
902
  * Reference to an entity with ID and name.
888
903
  * Used for products, categories, and other related entities.
@@ -925,9 +940,6 @@ interface Coupon {
925
940
  lastSyncedAt?: string | null;
926
941
  /** Per-platform channel overrides */
927
942
  channels?: Record<string, Record<string, unknown>> | null;
928
- shopifyCouponId?: string | null;
929
- woocommerceCouponId?: string | null;
930
- tiktokCouponId?: string | null;
931
943
  createdAt: string;
932
944
  updatedAt: string;
933
945
  }
@@ -1839,8 +1851,8 @@ interface SelectPickupLocationDto {
1839
1851
  * 2. Select shipping method: `selectShippingMethod(id, rateId)`
1840
1852
  * 3. Pay with Stripe: `createPaymentIntent(id)` → `stripe.confirmPayment()` → Order created automatically!
1841
1853
  *
1842
- * **Note:** Order is created automatically via webhook when payment succeeds.
1843
- * No need to call `completeCheckout()` - it happens automatically.
1854
+ * **Note:** Always call `completeGuestCheckout()` on the success page.
1855
+ * It is idempotent if the payment webhook already created the order, it returns the existing order.
1844
1856
  *
1845
1857
  * **IMPORTANT: Order Summary Display**
1846
1858
  * Always use `checkout.lineItems` for displaying the Order Summary during checkout!
@@ -1906,6 +1918,8 @@ interface Checkout {
1906
1918
  subtotal: string;
1907
1919
  /** Discount amount as string - use parseFloat() */
1908
1920
  discountAmount: string;
1921
+ /** Discount amount from automatic rules as string - use parseFloat() */
1922
+ ruleDiscountAmount?: string;
1909
1923
  /** Shipping cost as string - use parseFloat() */
1910
1924
  shippingAmount: string;
1911
1925
  /** Tax amount as string - use parseFloat() */
@@ -4215,6 +4229,13 @@ declare class BrainerceClient {
4215
4229
  forgotPassword(email: string): Promise<{
4216
4230
  message: string;
4217
4231
  }>;
4232
+ /**
4233
+ * Reset customer password using a reset token received via email
4234
+ * Works in vibe-coded, storefront, and admin mode
4235
+ */
4236
+ resetPassword(token: string, newPassword: string): Promise<{
4237
+ message: string;
4238
+ }>;
4218
4239
  /**
4219
4240
  * Verify customer email with a verification code
4220
4241
  * Only available in vibe-coded mode
@@ -5164,16 +5185,22 @@ declare class BrainerceClient {
5164
5185
  */
5165
5186
  getPaymentStatus(checkoutId: string): Promise<PaymentStatus>;
5166
5187
  /**
5167
- * Confirm a Grow SDK payment from the frontend.
5168
- * Call this in the Grow SDK `onSuccess` callback to notify the backend
5169
- * that payment succeeded, triggering order creation.
5188
+ * Confirm a client-side SDK payment from the frontend.
5189
+ * Call this in the payment SDK's success callback (e.g., Grow onSuccess) to notify the
5190
+ * backend that payment succeeded, triggering order creation.
5170
5191
  *
5171
5192
  * **Vibe-coded mode only** - requires connectionId
5172
5193
  *
5173
5194
  * @param checkoutId - The checkout ID
5174
- * @param confirmationNumber - Optional confirmation number from Grow onSuccess
5195
+ * @param providerResponseData - Optional payment provider SDK callback data (transactionId, transactionToken, confirmation_number, etc.)
5196
+ */
5197
+ confirmSdkPayment(checkoutId: string, providerResponseData?: Record<string, unknown>): Promise<{
5198
+ confirmed: boolean;
5199
+ }>;
5200
+ /**
5201
+ * @deprecated Use `confirmSdkPayment` instead. This method will be removed in a future version.
5175
5202
  */
5176
- confirmGrowPayment(checkoutId: string, confirmationNumber?: string): Promise<{
5203
+ confirmGrowPayment(checkoutId: string, confirmationNumber?: string, growResponseData?: Record<string, unknown>): Promise<{
5177
5204
  confirmed: boolean;
5178
5205
  }>;
5179
5206
  /**
package/dist/index.js CHANGED
@@ -1501,6 +1501,20 @@ var BrainerceClient = class {
1501
1501
  email
1502
1502
  });
1503
1503
  }
1504
+ /**
1505
+ * Reset customer password using a reset token received via email
1506
+ * Works in vibe-coded, storefront, and admin mode
1507
+ */
1508
+ async resetPassword(token, newPassword) {
1509
+ const body = { token, newPassword };
1510
+ if (this.isVibeCodedMode()) {
1511
+ return this.vibeCodedRequest("POST", "/customers/reset-password", body);
1512
+ }
1513
+ if (this.storeId && !this.apiKey) {
1514
+ return this.storefrontRequest("POST", "/customers/reset-password", body);
1515
+ }
1516
+ return this.adminRequest("POST", "/api/v1/customers/reset-password", body);
1517
+ }
1504
1518
  /**
1505
1519
  * Verify customer email with a verification code
1506
1520
  * Only available in vibe-coded mode
@@ -3431,25 +3445,34 @@ var BrainerceClient = class {
3431
3445
  return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
3432
3446
  }
3433
3447
  /**
3434
- * Confirm a Grow SDK payment from the frontend.
3435
- * Call this in the Grow SDK `onSuccess` callback to notify the backend
3436
- * that payment succeeded, triggering order creation.
3448
+ * Confirm a client-side SDK payment from the frontend.
3449
+ * Call this in the payment SDK's success callback (e.g., Grow onSuccess) to notify the
3450
+ * backend that payment succeeded, triggering order creation.
3437
3451
  *
3438
3452
  * **Vibe-coded mode only** - requires connectionId
3439
3453
  *
3440
3454
  * @param checkoutId - The checkout ID
3441
- * @param confirmationNumber - Optional confirmation number from Grow onSuccess
3455
+ * @param providerResponseData - Optional payment provider SDK callback data (transactionId, transactionToken, confirmation_number, etc.)
3442
3456
  */
3443
- async confirmGrowPayment(checkoutId, confirmationNumber) {
3457
+ async confirmSdkPayment(checkoutId, providerResponseData) {
3444
3458
  if (!this.isVibeCodedMode()) {
3445
3459
  throw new BrainerceError(
3446
- "confirmGrowPayment is only available in vibe-coded mode (use connectionId)",
3460
+ "confirmSdkPayment is only available in vibe-coded mode (use connectionId)",
3447
3461
  400
3448
3462
  );
3449
3463
  }
3450
- return this.vibeCodedRequest("POST", "/payment/grow-confirm", {
3464
+ return this.vibeCodedRequest("POST", "/payment/sdk-confirm", {
3451
3465
  checkoutId,
3452
- confirmationNumber
3466
+ providerResponseData
3467
+ });
3468
+ }
3469
+ /**
3470
+ * @deprecated Use `confirmSdkPayment` instead. This method will be removed in a future version.
3471
+ */
3472
+ async confirmGrowPayment(checkoutId, confirmationNumber, growResponseData) {
3473
+ return this.confirmSdkPayment(checkoutId, {
3474
+ confirmation_number: confirmationNumber,
3475
+ ...growResponseData || {}
3453
3476
  });
3454
3477
  }
3455
3478
  /**
package/dist/index.mjs CHANGED
@@ -1443,6 +1443,20 @@ var BrainerceClient = class {
1443
1443
  email
1444
1444
  });
1445
1445
  }
1446
+ /**
1447
+ * Reset customer password using a reset token received via email
1448
+ * Works in vibe-coded, storefront, and admin mode
1449
+ */
1450
+ async resetPassword(token, newPassword) {
1451
+ const body = { token, newPassword };
1452
+ if (this.isVibeCodedMode()) {
1453
+ return this.vibeCodedRequest("POST", "/customers/reset-password", body);
1454
+ }
1455
+ if (this.storeId && !this.apiKey) {
1456
+ return this.storefrontRequest("POST", "/customers/reset-password", body);
1457
+ }
1458
+ return this.adminRequest("POST", "/api/v1/customers/reset-password", body);
1459
+ }
1446
1460
  /**
1447
1461
  * Verify customer email with a verification code
1448
1462
  * Only available in vibe-coded mode
@@ -3373,25 +3387,34 @@ var BrainerceClient = class {
3373
3387
  return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
3374
3388
  }
3375
3389
  /**
3376
- * Confirm a Grow SDK payment from the frontend.
3377
- * Call this in the Grow SDK `onSuccess` callback to notify the backend
3378
- * that payment succeeded, triggering order creation.
3390
+ * Confirm a client-side SDK payment from the frontend.
3391
+ * Call this in the payment SDK's success callback (e.g., Grow onSuccess) to notify the
3392
+ * backend that payment succeeded, triggering order creation.
3379
3393
  *
3380
3394
  * **Vibe-coded mode only** - requires connectionId
3381
3395
  *
3382
3396
  * @param checkoutId - The checkout ID
3383
- * @param confirmationNumber - Optional confirmation number from Grow onSuccess
3397
+ * @param providerResponseData - Optional payment provider SDK callback data (transactionId, transactionToken, confirmation_number, etc.)
3384
3398
  */
3385
- async confirmGrowPayment(checkoutId, confirmationNumber) {
3399
+ async confirmSdkPayment(checkoutId, providerResponseData) {
3386
3400
  if (!this.isVibeCodedMode()) {
3387
3401
  throw new BrainerceError(
3388
- "confirmGrowPayment is only available in vibe-coded mode (use connectionId)",
3402
+ "confirmSdkPayment is only available in vibe-coded mode (use connectionId)",
3389
3403
  400
3390
3404
  );
3391
3405
  }
3392
- return this.vibeCodedRequest("POST", "/payment/grow-confirm", {
3406
+ return this.vibeCodedRequest("POST", "/payment/sdk-confirm", {
3393
3407
  checkoutId,
3394
- confirmationNumber
3408
+ providerResponseData
3409
+ });
3410
+ }
3411
+ /**
3412
+ * @deprecated Use `confirmSdkPayment` instead. This method will be removed in a future version.
3413
+ */
3414
+ async confirmGrowPayment(checkoutId, confirmationNumber, growResponseData) {
3415
+ return this.confirmSdkPayment(checkoutId, {
3416
+ confirmation_number: confirmationNumber,
3417
+ ...growResponseData || {}
3395
3418
  });
3396
3419
  }
3397
3420
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainerce",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "description": "Official SDK for building e-commerce storefronts with Brainerce Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",