brainerce 1.36.2 → 1.36.3

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.d.mts CHANGED
@@ -5287,6 +5287,13 @@ declare class BrainerceClient {
5287
5287
  private sessionToken;
5288
5288
  private _sessionCartPromise;
5289
5289
  private _migrationDone;
5290
+ /**
5291
+ * Cart id to adopt from an abandoned-checkout recovery redirect. brainerce's
5292
+ * recover endpoint 302s the shopper to `{storeDomain}/cart?brainerce_cart=<id>`;
5293
+ * we pick it up on construction and adopt it as the active cart on first access,
5294
+ * so the recovered cart shows up with zero per-store code.
5295
+ */
5296
+ private _pendingRecoverCartId;
5290
5297
  /** localStorage key for session cart reference (sessionToken + cartId) */
5291
5298
  private readonly SESSION_CART_KEY;
5292
5299
  /**
@@ -5582,8 +5589,12 @@ declare class BrainerceClient {
5582
5589
  */
5583
5590
  convertToVariable(productId: string): Promise<Product>;
5584
5591
  /**
5585
- * Convert a VARIABLE product to SIMPLE product
5586
- * Note: This will delete all variants
5592
+ * Convert a VARIABLE product back to SIMPLE.
5593
+ *
5594
+ * The product must have **at most one variant**. That variant's price and
5595
+ * inventory are merged back into the parent product, then the variant row is
5596
+ * deleted. Throws `400` if more than one variant exists — delete the extras
5597
+ * first. Throws `400` if the product is already SIMPLE.
5587
5598
  *
5588
5599
  * @example
5589
5600
  * ```typescript
@@ -5618,7 +5629,16 @@ declare class BrainerceClient {
5618
5629
  */
5619
5630
  createVariant(productId: string, data: CreateVariantDto): Promise<ProductVariant>;
5620
5631
  /**
5621
- * Bulk save variants (create, update, delete in one operation)
5632
+ * Bulk save variants (create, update, delete in one atomic operation).
5633
+ *
5634
+ * **Auto-conversion:** if the product is currently `SIMPLE` and the payload
5635
+ * includes new variants (entries without an `id`), the product is
5636
+ * automatically converted to `VARIABLE` before the variants are created.
5637
+ * You do **not** need to call `convertToVariable` first.
5638
+ *
5639
+ * To delete a variant include its `id` and set `isDeleted: true`.
5640
+ * To update an existing variant supply its `id` with changed fields.
5641
+ * Entries without an `id` (or with an `id` prefixed `new-`) are created.
5622
5642
  *
5623
5643
  * @example
5624
5644
  * ```typescript
@@ -7224,6 +7244,21 @@ declare class BrainerceClient {
7224
7244
  * @internal
7225
7245
  */
7226
7246
  private hydrateSessionCart;
7247
+ /**
7248
+ * Detect an abandoned-checkout recovery redirect. brainerce's recover endpoint
7249
+ * sends the shopper to `{storeDomain}/cart?brainerce_cart=<cartId>`; we stash
7250
+ * the id and adopt it (with its real session token) on the first cart access.
7251
+ * @internal
7252
+ */
7253
+ private detectRecoverCartFromUrl;
7254
+ /**
7255
+ * Adopt a recovery-redirect cart if one is pending. Runs as the first step of
7256
+ * session-cart resolution so the recovered cart wins over any stale local
7257
+ * session. Returns the adopted cart, or null to fall through to normal
7258
+ * resolution (no pending id, or the cart is no longer recoverable).
7259
+ * @internal
7260
+ */
7261
+ private adoptPendingRecoverCart;
7227
7262
  /**
7228
7263
  * Persist session cart reference to localStorage.
7229
7264
  * @internal
package/dist/index.d.ts CHANGED
@@ -5287,6 +5287,13 @@ declare class BrainerceClient {
5287
5287
  private sessionToken;
5288
5288
  private _sessionCartPromise;
5289
5289
  private _migrationDone;
5290
+ /**
5291
+ * Cart id to adopt from an abandoned-checkout recovery redirect. brainerce's
5292
+ * recover endpoint 302s the shopper to `{storeDomain}/cart?brainerce_cart=<id>`;
5293
+ * we pick it up on construction and adopt it as the active cart on first access,
5294
+ * so the recovered cart shows up with zero per-store code.
5295
+ */
5296
+ private _pendingRecoverCartId;
5290
5297
  /** localStorage key for session cart reference (sessionToken + cartId) */
5291
5298
  private readonly SESSION_CART_KEY;
5292
5299
  /**
@@ -5582,8 +5589,12 @@ declare class BrainerceClient {
5582
5589
  */
5583
5590
  convertToVariable(productId: string): Promise<Product>;
5584
5591
  /**
5585
- * Convert a VARIABLE product to SIMPLE product
5586
- * Note: This will delete all variants
5592
+ * Convert a VARIABLE product back to SIMPLE.
5593
+ *
5594
+ * The product must have **at most one variant**. That variant's price and
5595
+ * inventory are merged back into the parent product, then the variant row is
5596
+ * deleted. Throws `400` if more than one variant exists — delete the extras
5597
+ * first. Throws `400` if the product is already SIMPLE.
5587
5598
  *
5588
5599
  * @example
5589
5600
  * ```typescript
@@ -5618,7 +5629,16 @@ declare class BrainerceClient {
5618
5629
  */
5619
5630
  createVariant(productId: string, data: CreateVariantDto): Promise<ProductVariant>;
5620
5631
  /**
5621
- * Bulk save variants (create, update, delete in one operation)
5632
+ * Bulk save variants (create, update, delete in one atomic operation).
5633
+ *
5634
+ * **Auto-conversion:** if the product is currently `SIMPLE` and the payload
5635
+ * includes new variants (entries without an `id`), the product is
5636
+ * automatically converted to `VARIABLE` before the variants are created.
5637
+ * You do **not** need to call `convertToVariable` first.
5638
+ *
5639
+ * To delete a variant include its `id` and set `isDeleted: true`.
5640
+ * To update an existing variant supply its `id` with changed fields.
5641
+ * Entries without an `id` (or with an `id` prefixed `new-`) are created.
5622
5642
  *
5623
5643
  * @example
5624
5644
  * ```typescript
@@ -7224,6 +7244,21 @@ declare class BrainerceClient {
7224
7244
  * @internal
7225
7245
  */
7226
7246
  private hydrateSessionCart;
7247
+ /**
7248
+ * Detect an abandoned-checkout recovery redirect. brainerce's recover endpoint
7249
+ * sends the shopper to `{storeDomain}/cart?brainerce_cart=<cartId>`; we stash
7250
+ * the id and adopt it (with its real session token) on the first cart access.
7251
+ * @internal
7252
+ */
7253
+ private detectRecoverCartFromUrl;
7254
+ /**
7255
+ * Adopt a recovery-redirect cart if one is pending. Runs as the first step of
7256
+ * session-cart resolution so the recovered cart wins over any stale local
7257
+ * session. Returns the adopted cart, or null to fall through to normal
7258
+ * resolution (no pending id, or the cart is no longer recoverable).
7259
+ * @internal
7260
+ */
7261
+ private adoptPendingRecoverCart;
7227
7262
  /**
7228
7263
  * Persist session cart reference to localStorage.
7229
7264
  * @internal
package/dist/index.js CHANGED
@@ -234,6 +234,13 @@ var BrainerceClient = class {
234
234
  this.sessionToken = null;
235
235
  this._sessionCartPromise = null;
236
236
  this._migrationDone = false;
237
+ /**
238
+ * Cart id to adopt from an abandoned-checkout recovery redirect. brainerce's
239
+ * recover endpoint 302s the shopper to `{storeDomain}/cart?brainerce_cart=<id>`;
240
+ * we pick it up on construction and adopt it as the active cart on first access,
241
+ * so the recovered cart shows up with zero per-store code.
242
+ */
243
+ this._pendingRecoverCartId = null;
237
244
  /** localStorage key for session cart reference (sessionToken + cartId) */
238
245
  this.SESSION_CART_KEY = "brainerce_session";
239
246
  /**
@@ -648,6 +655,7 @@ var BrainerceClient = class {
648
655
  this.proxyMode = options.proxyMode || false;
649
656
  this.onAuthError = options.onAuthError;
650
657
  this.hydrateSessionCart();
658
+ this.detectRecoverCartFromUrl();
651
659
  }
652
660
  // -------------------- Locale --------------------
653
661
  /**
@@ -1379,8 +1387,12 @@ var BrainerceClient = class {
1379
1387
  );
1380
1388
  }
1381
1389
  /**
1382
- * Convert a VARIABLE product to SIMPLE product
1383
- * Note: This will delete all variants
1390
+ * Convert a VARIABLE product back to SIMPLE.
1391
+ *
1392
+ * The product must have **at most one variant**. That variant's price and
1393
+ * inventory are merged back into the parent product, then the variant row is
1394
+ * deleted. Throws `400` if more than one variant exists — delete the extras
1395
+ * first. Throws `400` if the product is already SIMPLE.
1384
1396
  *
1385
1397
  * @example
1386
1398
  * ```typescript
@@ -1435,7 +1447,16 @@ var BrainerceClient = class {
1435
1447
  );
1436
1448
  }
1437
1449
  /**
1438
- * Bulk save variants (create, update, delete in one operation)
1450
+ * Bulk save variants (create, update, delete in one atomic operation).
1451
+ *
1452
+ * **Auto-conversion:** if the product is currently `SIMPLE` and the payload
1453
+ * includes new variants (entries without an `id`), the product is
1454
+ * automatically converted to `VARIABLE` before the variants are created.
1455
+ * You do **not** need to call `convertToVariable` first.
1456
+ *
1457
+ * To delete a variant include its `id` and set `isDeleted: true`.
1458
+ * To update an existing variant supply its `id` with changed fields.
1459
+ * Entries without an `id` (or with an `id` prefixed `new-`) are created.
1439
1460
  *
1440
1461
  * @example
1441
1462
  * ```typescript
@@ -3953,6 +3974,48 @@ var BrainerceClient = class {
3953
3974
  } catch {
3954
3975
  }
3955
3976
  }
3977
+ /**
3978
+ * Detect an abandoned-checkout recovery redirect. brainerce's recover endpoint
3979
+ * sends the shopper to `{storeDomain}/cart?brainerce_cart=<cartId>`; we stash
3980
+ * the id and adopt it (with its real session token) on the first cart access.
3981
+ * @internal
3982
+ */
3983
+ detectRecoverCartFromUrl() {
3984
+ if (typeof window === "undefined" || !window.location?.search) return;
3985
+ try {
3986
+ const recoverId = new URLSearchParams(window.location.search).get("brainerce_cart");
3987
+ if (recoverId) this._pendingRecoverCartId = recoverId;
3988
+ } catch {
3989
+ }
3990
+ }
3991
+ /**
3992
+ * Adopt a recovery-redirect cart if one is pending. Runs as the first step of
3993
+ * session-cart resolution so the recovered cart wins over any stale local
3994
+ * session. Returns the adopted cart, or null to fall through to normal
3995
+ * resolution (no pending id, or the cart is no longer recoverable).
3996
+ * @internal
3997
+ */
3998
+ async adoptPendingRecoverCart() {
3999
+ const recoverId = this._pendingRecoverCartId;
4000
+ if (!recoverId) return null;
4001
+ this._pendingRecoverCartId = null;
4002
+ try {
4003
+ const cart = await this.getCart(recoverId);
4004
+ if (cart.status !== "ACTIVE") return null;
4005
+ if (cart.sessionToken) {
4006
+ this.saveSessionCart({
4007
+ sessionToken: cart.sessionToken,
4008
+ cartId: cart.id,
4009
+ itemCount: cart.itemCount
4010
+ });
4011
+ } else {
4012
+ this.sessionCartId = cart.id;
4013
+ }
4014
+ return cart;
4015
+ } catch {
4016
+ return null;
4017
+ }
4018
+ }
3956
4019
  /**
3957
4020
  * Persist session cart reference to localStorage.
3958
4021
  * @internal
@@ -4052,6 +4115,8 @@ var BrainerceClient = class {
4052
4115
  }
4053
4116
  /** @internal */
4054
4117
  async _getOrCreateSessionCartImpl() {
4118
+ const recovered = await this.adoptPendingRecoverCart();
4119
+ if (recovered) return recovered;
4055
4120
  const migrated = await this.migrateLocalCartToSession();
4056
4121
  if (migrated) return migrated;
4057
4122
  if (this.sessionCartId && this.sessionToken) {
@@ -4285,9 +4350,13 @@ var BrainerceClient = class {
4285
4350
  */
4286
4351
  async smartGetCart(options) {
4287
4352
  if (this.isCustomerLoggedIn()) {
4353
+ if (this._pendingRecoverCartId) {
4354
+ const recovered = await this.adoptPendingRecoverCart();
4355
+ if (recovered) return recovered;
4356
+ }
4288
4357
  return this.getOrCreateCustomerCart(options);
4289
4358
  } else {
4290
- if (!this.sessionToken) {
4359
+ if (!this.sessionToken && !this._pendingRecoverCartId) {
4291
4360
  return this.emptyCart();
4292
4361
  }
4293
4362
  return this.getOrCreateSessionCart(options);
package/dist/index.mjs CHANGED
@@ -164,6 +164,13 @@ var BrainerceClient = class {
164
164
  this.sessionToken = null;
165
165
  this._sessionCartPromise = null;
166
166
  this._migrationDone = false;
167
+ /**
168
+ * Cart id to adopt from an abandoned-checkout recovery redirect. brainerce's
169
+ * recover endpoint 302s the shopper to `{storeDomain}/cart?brainerce_cart=<id>`;
170
+ * we pick it up on construction and adopt it as the active cart on first access,
171
+ * so the recovered cart shows up with zero per-store code.
172
+ */
173
+ this._pendingRecoverCartId = null;
167
174
  /** localStorage key for session cart reference (sessionToken + cartId) */
168
175
  this.SESSION_CART_KEY = "brainerce_session";
169
176
  /**
@@ -578,6 +585,7 @@ var BrainerceClient = class {
578
585
  this.proxyMode = options.proxyMode || false;
579
586
  this.onAuthError = options.onAuthError;
580
587
  this.hydrateSessionCart();
588
+ this.detectRecoverCartFromUrl();
581
589
  }
582
590
  // -------------------- Locale --------------------
583
591
  /**
@@ -1309,8 +1317,12 @@ var BrainerceClient = class {
1309
1317
  );
1310
1318
  }
1311
1319
  /**
1312
- * Convert a VARIABLE product to SIMPLE product
1313
- * Note: This will delete all variants
1320
+ * Convert a VARIABLE product back to SIMPLE.
1321
+ *
1322
+ * The product must have **at most one variant**. That variant's price and
1323
+ * inventory are merged back into the parent product, then the variant row is
1324
+ * deleted. Throws `400` if more than one variant exists — delete the extras
1325
+ * first. Throws `400` if the product is already SIMPLE.
1314
1326
  *
1315
1327
  * @example
1316
1328
  * ```typescript
@@ -1365,7 +1377,16 @@ var BrainerceClient = class {
1365
1377
  );
1366
1378
  }
1367
1379
  /**
1368
- * Bulk save variants (create, update, delete in one operation)
1380
+ * Bulk save variants (create, update, delete in one atomic operation).
1381
+ *
1382
+ * **Auto-conversion:** if the product is currently `SIMPLE` and the payload
1383
+ * includes new variants (entries without an `id`), the product is
1384
+ * automatically converted to `VARIABLE` before the variants are created.
1385
+ * You do **not** need to call `convertToVariable` first.
1386
+ *
1387
+ * To delete a variant include its `id` and set `isDeleted: true`.
1388
+ * To update an existing variant supply its `id` with changed fields.
1389
+ * Entries without an `id` (or with an `id` prefixed `new-`) are created.
1369
1390
  *
1370
1391
  * @example
1371
1392
  * ```typescript
@@ -3883,6 +3904,48 @@ var BrainerceClient = class {
3883
3904
  } catch {
3884
3905
  }
3885
3906
  }
3907
+ /**
3908
+ * Detect an abandoned-checkout recovery redirect. brainerce's recover endpoint
3909
+ * sends the shopper to `{storeDomain}/cart?brainerce_cart=<cartId>`; we stash
3910
+ * the id and adopt it (with its real session token) on the first cart access.
3911
+ * @internal
3912
+ */
3913
+ detectRecoverCartFromUrl() {
3914
+ if (typeof window === "undefined" || !window.location?.search) return;
3915
+ try {
3916
+ const recoverId = new URLSearchParams(window.location.search).get("brainerce_cart");
3917
+ if (recoverId) this._pendingRecoverCartId = recoverId;
3918
+ } catch {
3919
+ }
3920
+ }
3921
+ /**
3922
+ * Adopt a recovery-redirect cart if one is pending. Runs as the first step of
3923
+ * session-cart resolution so the recovered cart wins over any stale local
3924
+ * session. Returns the adopted cart, or null to fall through to normal
3925
+ * resolution (no pending id, or the cart is no longer recoverable).
3926
+ * @internal
3927
+ */
3928
+ async adoptPendingRecoverCart() {
3929
+ const recoverId = this._pendingRecoverCartId;
3930
+ if (!recoverId) return null;
3931
+ this._pendingRecoverCartId = null;
3932
+ try {
3933
+ const cart = await this.getCart(recoverId);
3934
+ if (cart.status !== "ACTIVE") return null;
3935
+ if (cart.sessionToken) {
3936
+ this.saveSessionCart({
3937
+ sessionToken: cart.sessionToken,
3938
+ cartId: cart.id,
3939
+ itemCount: cart.itemCount
3940
+ });
3941
+ } else {
3942
+ this.sessionCartId = cart.id;
3943
+ }
3944
+ return cart;
3945
+ } catch {
3946
+ return null;
3947
+ }
3948
+ }
3886
3949
  /**
3887
3950
  * Persist session cart reference to localStorage.
3888
3951
  * @internal
@@ -3982,6 +4045,8 @@ var BrainerceClient = class {
3982
4045
  }
3983
4046
  /** @internal */
3984
4047
  async _getOrCreateSessionCartImpl() {
4048
+ const recovered = await this.adoptPendingRecoverCart();
4049
+ if (recovered) return recovered;
3985
4050
  const migrated = await this.migrateLocalCartToSession();
3986
4051
  if (migrated) return migrated;
3987
4052
  if (this.sessionCartId && this.sessionToken) {
@@ -4215,9 +4280,13 @@ var BrainerceClient = class {
4215
4280
  */
4216
4281
  async smartGetCart(options) {
4217
4282
  if (this.isCustomerLoggedIn()) {
4283
+ if (this._pendingRecoverCartId) {
4284
+ const recovered = await this.adoptPendingRecoverCart();
4285
+ if (recovered) return recovered;
4286
+ }
4218
4287
  return this.getOrCreateCustomerCart(options);
4219
4288
  } else {
4220
- if (!this.sessionToken) {
4289
+ if (!this.sessionToken && !this._pendingRecoverCartId) {
4221
4290
  return this.emptyCart();
4222
4291
  }
4223
4292
  return this.getOrCreateSessionCart(options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainerce",
3
- "version": "1.36.2",
3
+ "version": "1.36.3",
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",