brainerce 1.16.0 → 1.18.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.mjs CHANGED
@@ -325,6 +325,9 @@ var BrainerceClient = class {
325
325
  if (this.origin) {
326
326
  headers["Origin"] = this.origin;
327
327
  }
328
+ if (this.locale) {
329
+ headers["Accept-Language"] = this.locale;
330
+ }
328
331
  const response = await fetch(url.toString(), {
329
332
  method,
330
333
  headers,
@@ -360,7 +363,7 @@ var BrainerceClient = class {
360
363
  /**
361
364
  * Make a request to the Vibe-Coded API (public, uses connectionId)
362
365
  */
363
- async vibeCodedRequest(method, path, body, queryParams) {
366
+ async vibeCodedRequest(method, path, body, queryParams, headerOverrides) {
364
367
  if (!this.connectionId) {
365
368
  throw new BrainerceError("connectionId is required for vibe-coded requests", 400);
366
369
  }
@@ -383,6 +386,12 @@ var BrainerceClient = class {
383
386
  if (this.origin) {
384
387
  headers["Origin"] = this.origin;
385
388
  }
389
+ if (this.locale) {
390
+ headers["Accept-Language"] = this.locale;
391
+ }
392
+ if (headerOverrides) {
393
+ Object.assign(headers, headerOverrides);
394
+ }
386
395
  if (this.proxyMode && method !== "GET") {
387
396
  headers["X-Requested-With"] = "brainerce";
388
397
  }
@@ -431,7 +440,7 @@ var BrainerceClient = class {
431
440
  /**
432
441
  * Make a request to the Storefront API (public, uses storeId)
433
442
  */
434
- async storefrontRequest(method, path, body, queryParams) {
443
+ async storefrontRequest(method, path, body, queryParams, headerOverrides) {
435
444
  if (!this.storeId) {
436
445
  throw new BrainerceError("storeId is required for storefront requests", 400);
437
446
  }
@@ -454,6 +463,12 @@ var BrainerceClient = class {
454
463
  if (this.origin) {
455
464
  headers["Origin"] = this.origin;
456
465
  }
466
+ if (this.locale) {
467
+ headers["Accept-Language"] = this.locale;
468
+ }
469
+ if (headerOverrides) {
470
+ Object.assign(headers, headerOverrides);
471
+ }
457
472
  if (this.customerToken) {
458
473
  headers["Authorization"] = `Bearer ${this.customerToken}`;
459
474
  }
@@ -555,7 +570,6 @@ var BrainerceClient = class {
555
570
  maxPrice: params?.maxPrice,
556
571
  sortBy: params?.sortBy,
557
572
  sortOrder: params?.sortOrder,
558
- locale: params?.locale || this.locale,
559
573
  // Admin-only params
560
574
  type: params?.type
561
575
  };
@@ -587,13 +601,14 @@ var BrainerceClient = class {
587
601
  * Works in vibe-coded, storefront (public), and admin mode
588
602
  */
589
603
  async getProduct(productId, options) {
590
- const localeParams = { locale: options?.locale || this.locale };
604
+ const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
591
605
  if (this.isVibeCodedMode()) {
592
606
  return this.vibeCodedRequest(
593
607
  "GET",
594
608
  `/products/${productId}`,
595
609
  void 0,
596
- localeParams
610
+ void 0,
611
+ headerOverrides
597
612
  );
598
613
  }
599
614
  if (this.storeId && !this.apiKey) {
@@ -601,7 +616,8 @@ var BrainerceClient = class {
601
616
  "GET",
602
617
  `/products/${productId}`,
603
618
  void 0,
604
- localeParams
619
+ void 0,
620
+ headerOverrides
605
621
  );
606
622
  }
607
623
  return this.adminRequest("GET", `/api/v1/products/${productId}`);
@@ -617,13 +633,14 @@ var BrainerceClient = class {
617
633
  * ```
618
634
  */
619
635
  async getProductBySlug(slug, options) {
620
- const localeParams = { locale: options?.locale || this.locale };
636
+ const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
621
637
  if (this.isVibeCodedMode()) {
622
638
  return this.vibeCodedRequest(
623
639
  "GET",
624
640
  `/products/slug/${slug}`,
625
641
  void 0,
626
- localeParams
642
+ void 0,
643
+ headerOverrides
627
644
  );
628
645
  }
629
646
  if (this.storeId && !this.apiKey) {
@@ -631,7 +648,8 @@ var BrainerceClient = class {
631
648
  "GET",
632
649
  `/products/slug/${slug}`,
633
650
  void 0,
634
- localeParams
651
+ void 0,
652
+ headerOverrides
635
653
  );
636
654
  }
637
655
  return this.adminRequest("GET", `/api/v1/products/by-slug/${slug}`);
@@ -647,9 +665,9 @@ var BrainerceClient = class {
647
665
  * ```
648
666
  */
649
667
  async getCategories(options) {
650
- const localeParams = { locale: options?.locale || this.locale };
668
+ const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
651
669
  if (this.isVibeCodedMode()) {
652
- return this.vibeCodedRequest("GET", "/categories", void 0, localeParams);
670
+ return this.vibeCodedRequest("GET", "/categories", void 0, void 0, headerOverrides);
653
671
  }
654
672
  throw new BrainerceError("getCategories is only available in vibe-coded mode", 400);
655
673
  }
@@ -664,9 +682,9 @@ var BrainerceClient = class {
664
682
  * ```
665
683
  */
666
684
  async getBrands(options) {
667
- const localeParams = { locale: options?.locale || this.locale };
685
+ const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
668
686
  if (this.isVibeCodedMode()) {
669
- return this.vibeCodedRequest("GET", "/brands", void 0, localeParams);
687
+ return this.vibeCodedRequest("GET", "/brands", void 0, void 0, headerOverrides);
670
688
  }
671
689
  throw new BrainerceError("getBrands is only available in vibe-coded mode", 400);
672
690
  }
@@ -680,11 +698,10 @@ var BrainerceClient = class {
680
698
  * // Use tag IDs in getProducts({ tags: ['tag_id'] })
681
699
  * ```
682
700
  */
683
- async getTags() {
701
+ async getTags(options) {
702
+ const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
684
703
  if (this.isVibeCodedMode()) {
685
- return this.vibeCodedRequest("GET", "/tags", void 0, {
686
- locale: this.locale
687
- });
704
+ return this.vibeCodedRequest("GET", "/tags", void 0, void 0, headerOverrides);
688
705
  }
689
706
  throw new BrainerceError("getTags is only available in vibe-coded mode", 400);
690
707
  }
@@ -728,7 +745,7 @@ var BrainerceClient = class {
728
745
  if (!query || query.trim().length === 0) {
729
746
  return { products: [], categories: [] };
730
747
  }
731
- const queryParams = { q: query, limit, locale: this.locale };
748
+ const queryParams = { q: query, limit };
732
749
  if (this.isVibeCodedMode()) {
733
750
  return this.vibeCodedRequest(
734
751
  "GET",
@@ -2034,30 +2051,82 @@ var BrainerceClient = class {
2034
2051
  }
2035
2052
  /**
2036
2053
  * Get a cart by ID
2054
+ *
2055
+ * @param cartId - The cart ID
2056
+ * @param options - Optional settings. Use `include` to fetch related data in a single request.
2057
+ *
2058
+ * @example
2059
+ * ```typescript
2060
+ * // Basic cart fetch
2061
+ * const cart = await client.getCart('cart_123');
2062
+ *
2063
+ * // Fetch cart with recommendations, upgrades, and bundles in one call
2064
+ * const enriched = await client.getCart('cart_123', {
2065
+ * include: ['recommendations', 'upgrades', 'bundles'],
2066
+ * });
2067
+ * console.log(enriched.recommendations); // { recommendations: [...] }
2068
+ * console.log(enriched.upgrades); // { upgrades: { ... } }
2069
+ * console.log(enriched.bundles); // { bundles: [...] }
2070
+ * ```
2037
2071
  */
2038
- async getCart(cartId) {
2072
+ async getCart(cartId, options) {
2039
2073
  if (cartId === this.VIRTUAL_LOCAL_CART_ID) {
2040
2074
  console.warn('getCart("__local__") is deprecated. Use smartGetCart() instead.');
2041
2075
  return this.withGuards(this.localCartToCart(this.getLocalCart()), "cart");
2042
2076
  }
2077
+ const queryParams = options?.include?.length ? { include: options.include.join(",") } : void 0;
2043
2078
  if (this.isVibeCodedMode()) {
2044
- return this.withGuards(this.vibeCodedRequest("GET", `/cart/${cartId}`), "cart");
2079
+ return this.withGuards(
2080
+ this.vibeCodedRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2081
+ "cart"
2082
+ );
2045
2083
  }
2046
2084
  if (this.storeId && !this.apiKey) {
2047
- return this.withGuards(this.storefrontRequest("GET", `/cart/${cartId}`), "cart");
2085
+ return this.withGuards(
2086
+ this.storefrontRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2087
+ "cart"
2088
+ );
2048
2089
  }
2049
- return this.withGuards(this.adminRequest("GET", `/api/v1/cart/${cartId}`), "cart");
2090
+ return this.withGuards(
2091
+ this.adminRequest("GET", `/api/v1/cart/${cartId}`, void 0, queryParams),
2092
+ "cart"
2093
+ );
2050
2094
  }
2051
2095
  /**
2052
- * Add an item to the cart
2096
+ * Add an item to the cart.
2097
+ *
2098
+ * If the product has `customizationFields` (merchant-defined buyer input
2099
+ * like engraving text, uploaded photos, select options), pass the buyer's
2100
+ * values in `metadata`. Keys must match each field's `key`. For `IMAGE` /
2101
+ * `GALLERY` types, upload the file first via `uploadCustomizationFile()`
2102
+ * and pass the returned URL. The server validates every value against its
2103
+ * `MetafieldDefinition` and rejects the request with HTTP 400 if anything
2104
+ * fails (type mismatch, required missing, not in `enumValues`, etc.).
2105
+ *
2106
+ * Values are snapshotted onto the order line at checkout — later edits to
2107
+ * the field definition do not retroactively change existing orders.
2053
2108
  *
2054
2109
  * @example
2055
2110
  * ```typescript
2111
+ * // Product with no customization fields
2056
2112
  * const cart = await client.addToCart('cart_123', {
2057
2113
  * productId: 'prod_abc',
2058
2114
  * quantity: 2,
2059
2115
  * notes: 'Gift wrap please',
2060
2116
  * });
2117
+ *
2118
+ * // Product WITH customization fields (engraving + photo + select + multi)
2119
+ * const { url: photoUrl } = await client.uploadCustomizationFile(file);
2120
+ * const cart = await client.addToCart('cart_123', {
2121
+ * productId: 'prod_mug',
2122
+ * quantity: 1,
2123
+ * metadata: {
2124
+ * engraving_text: 'Happy Birthday!', // TEXT
2125
+ * frame_color: 'Gold', // SELECT (must be in enumValues)
2126
+ * upload_photo: photoUrl, // IMAGE
2127
+ * addons: ['Gift wrap'], // MULTI_SELECT (always array)
2128
+ * },
2129
+ * });
2061
2130
  * ```
2062
2131
  */
2063
2132
  async addToCart(cartId, item) {
@@ -2390,17 +2459,21 @@ var BrainerceClient = class {
2390
2459
  * ```
2391
2460
  */
2392
2461
  async getProductRecommendations(productId, type) {
2393
- const params = type ? `?type=${type}` : "";
2462
+ const queryParams = type ? { type } : void 0;
2394
2463
  if (this.isVibeCodedMode()) {
2395
2464
  return this.vibeCodedRequest(
2396
2465
  "GET",
2397
- `/products/${productId}/recommendations${params}`
2466
+ `/products/${productId}/recommendations`,
2467
+ void 0,
2468
+ queryParams
2398
2469
  );
2399
2470
  }
2400
2471
  if (this.storeId && !this.apiKey) {
2401
2472
  return this.storefrontRequest(
2402
2473
  "GET",
2403
- `/products/${productId}/recommendations${params}`
2474
+ `/products/${productId}/recommendations`,
2475
+ void 0,
2476
+ queryParams
2404
2477
  );
2405
2478
  }
2406
2479
  throw new BrainerceError(
@@ -2424,17 +2497,21 @@ var BrainerceClient = class {
2424
2497
  * ```
2425
2498
  */
2426
2499
  async getCartRecommendations(cartId, limit) {
2427
- const params = limit ? `?limit=${limit}` : "";
2500
+ const queryParams = limit ? { limit } : void 0;
2428
2501
  if (this.isVibeCodedMode()) {
2429
2502
  return this.vibeCodedRequest(
2430
2503
  "GET",
2431
- `/cart/${cartId}/recommendations${params}`
2504
+ `/cart/${cartId}/recommendations`,
2505
+ void 0,
2506
+ queryParams
2432
2507
  );
2433
2508
  }
2434
2509
  if (this.storeId && !this.apiKey) {
2435
2510
  return this.storefrontRequest(
2436
2511
  "GET",
2437
- `/cart/${cartId}/recommendations${params}`
2512
+ `/cart/${cartId}/recommendations`,
2513
+ void 0,
2514
+ queryParams
2438
2515
  );
2439
2516
  }
2440
2517
  throw new BrainerceError(
@@ -2697,11 +2774,21 @@ var BrainerceClient = class {
2697
2774
  * Uses promise dedup lock to prevent race conditions on parallel calls.
2698
2775
  * @internal
2699
2776
  */
2700
- async getOrCreateSessionCart() {
2701
- if (this._sessionCartPromise) return this._sessionCartPromise;
2777
+ async getOrCreateSessionCart(options) {
2778
+ if (this._sessionCartPromise) {
2779
+ const base = await this._sessionCartPromise;
2780
+ if (options?.include?.length && base.id) {
2781
+ return this.getCart(base.id, options);
2782
+ }
2783
+ return base;
2784
+ }
2702
2785
  this._sessionCartPromise = this._getOrCreateSessionCartImpl();
2703
2786
  try {
2704
- return await this._sessionCartPromise;
2787
+ const base = await this._sessionCartPromise;
2788
+ if (options?.include?.length && base.id) {
2789
+ return this.getCart(base.id, options);
2790
+ }
2791
+ return base;
2705
2792
  } finally {
2706
2793
  this._sessionCartPromise = null;
2707
2794
  }
@@ -2834,10 +2921,10 @@ var BrainerceClient = class {
2834
2921
  * Caches the cart ID for subsequent calls
2835
2922
  * @internal
2836
2923
  */
2837
- async getOrCreateCustomerCart() {
2924
+ async getOrCreateCustomerCart(options) {
2838
2925
  if (this.customerCartId) {
2839
2926
  try {
2840
- const existingCart = await this.getCart(this.customerCartId);
2927
+ const existingCart = await this.getCart(this.customerCartId, options);
2841
2928
  if (existingCart.status === "ACTIVE") {
2842
2929
  return existingCart;
2843
2930
  }
@@ -2850,6 +2937,9 @@ var BrainerceClient = class {
2850
2937
  const cart2 = await this.fetchCustomerCart();
2851
2938
  if (cart2.status === "ACTIVE") {
2852
2939
  this.customerCartId = cart2.id;
2940
+ if (options?.include?.length) {
2941
+ return this.getCart(cart2.id, options);
2942
+ }
2853
2943
  return cart2;
2854
2944
  }
2855
2945
  } catch {
@@ -2901,7 +2991,8 @@ var BrainerceClient = class {
2901
2991
  const updated = await this.addToCart(cart.id, {
2902
2992
  productId: item.productId,
2903
2993
  variantId: item.variantId,
2904
- quantity: item.quantity
2994
+ quantity: item.quantity,
2995
+ metadata: item.metadata
2905
2996
  });
2906
2997
  return updated;
2907
2998
  } else {
@@ -2909,7 +3000,8 @@ var BrainerceClient = class {
2909
3000
  const updated = await this.addToCart(cart.id, {
2910
3001
  productId: item.productId,
2911
3002
  variantId: item.variantId,
2912
- quantity: item.quantity
3003
+ quantity: item.quantity,
3004
+ metadata: item.metadata
2913
3005
  });
2914
3006
  this.updateSessionCartItemCount(updated.items?.length ?? 0);
2915
3007
  return updated;
@@ -2922,20 +3014,28 @@ var BrainerceClient = class {
2922
3014
  * - **Guest with session**: Returns server-side session cart
2923
3015
  * - **Guest without session**: Returns empty cart (no server call, cart created lazily on add)
2924
3016
  *
3017
+ * @param options - Optional. Use `include` to fetch recommendations, upgrades, and bundles
3018
+ * in a single request instead of separate calls.
3019
+ *
2925
3020
  * @example
2926
3021
  * ```typescript
2927
3022
  * const cart = await client.smartGetCart();
2928
3023
  * console.log('Items:', cart.items.length);
3024
+ *
3025
+ * // With includes — single request for cart + extras
3026
+ * const enriched = await client.smartGetCart({
3027
+ * include: ['recommendations', 'upgrades', 'bundles'],
3028
+ * });
2929
3029
  * ```
2930
3030
  */
2931
- async smartGetCart() {
3031
+ async smartGetCart(options) {
2932
3032
  if (this.isCustomerLoggedIn()) {
2933
- return this.getOrCreateCustomerCart();
3033
+ return this.getOrCreateCustomerCart(options);
2934
3034
  } else {
2935
3035
  if (!this.sessionToken) {
2936
3036
  return this.emptyCart();
2937
3037
  }
2938
- return this.getOrCreateSessionCart();
3038
+ return this.getOrCreateSessionCart(options);
2939
3039
  }
2940
3040
  }
2941
3041
  /**
@@ -5612,9 +5712,35 @@ var BrainerceClient = class {
5612
5712
  );
5613
5713
  }
5614
5714
  /**
5615
- * Upload a file for product customization (e.g., customer logo for printing).
5616
- * Available in storefront and vibe-coded modes.
5617
- * Returns the uploaded file URL and key.
5715
+ * Upload a buyer-submitted file (engraving photo, custom image, etc.) for a
5716
+ * product customization field of type `IMAGE` or `GALLERY`. The returned `url`
5717
+ * is what you pass back in the add-to-cart `metadata` payload.
5718
+ *
5719
+ * Available in storefront and vibe-coded modes — no customer login required.
5720
+ *
5721
+ * Server rules:
5722
+ * - `image/*` MIME only. Other types → HTTP 400.
5723
+ * - Max 5 MB per file.
5724
+ * - Throttled to 10 uploads / minute per IP → HTTP 429.
5725
+ * - Retention: at least 7 days. If the cart never becomes an order, the file
5726
+ * is reclaimed automatically. Once the order exists, the file is kept for
5727
+ * order-history purposes.
5728
+ *
5729
+ * @example
5730
+ * ```ts
5731
+ * // On a product page with IMAGE/GALLERY customization fields:
5732
+ * const { url } = await client.uploadCustomizationFile(fileInput.files[0]);
5733
+ *
5734
+ * // Then include the URL in the add-to-cart metadata:
5735
+ * await client.addToCart(cart.id, {
5736
+ * productId: product.id,
5737
+ * quantity: 1,
5738
+ * metadata: {
5739
+ * engraving_text: 'Happy Birthday!',
5740
+ * upload_photo: url,
5741
+ * },
5742
+ * });
5743
+ * ```
5618
5744
  */
5619
5745
  async uploadCustomizationFile(file) {
5620
5746
  const formData = new FormData();
@@ -5829,7 +5955,9 @@ var BrainerceClient = class {
5829
5955
  return this.adminRequest("PUT", "/api/v1/email/settings", data);
5830
5956
  }
5831
5957
  /**
5832
- * Get all email templates for the store
5958
+ * Get all email templates for the store, grouped by (eventType, language).
5959
+ * Response includes the store's primary language and supported languages so
5960
+ * the caller can render a locale selector.
5833
5961
  * Requires Admin mode (apiKey)
5834
5962
  */
5835
5963
  async getEmailTemplates() {
@@ -6134,6 +6262,19 @@ function getProductPriceInfo(product) {
6134
6262
  if (!product) {
6135
6263
  return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
6136
6264
  }
6265
+ if (product.discount) {
6266
+ const ruleOriginal = parseFloat(product.discount.originalPrice) || 0;
6267
+ const ruleDiscounted = parseFloat(product.discount.discountedPrice) || 0;
6268
+ const ruleAmount = Math.max(0, ruleOriginal - ruleDiscounted);
6269
+ const rulePercent = ruleOriginal > 0 ? Math.round(ruleAmount / ruleOriginal * 100) : 0;
6270
+ return {
6271
+ price: ruleDiscounted,
6272
+ originalPrice: ruleOriginal,
6273
+ isOnSale: ruleDiscounted < ruleOriginal,
6274
+ discountAmount: ruleAmount,
6275
+ discountPercent: rulePercent
6276
+ };
6277
+ }
6137
6278
  const basePrice = parseFloat(product.basePrice) || 0;
6138
6279
  const salePrice = product.salePrice ? parseFloat(product.salePrice) : null;
6139
6280
  const isOnSale = salePrice !== null && salePrice < basePrice;
package/package.json CHANGED
@@ -1,76 +1,76 @@
1
- {
2
- "name": "brainerce",
3
- "version": "1.16.0",
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
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "require": "./dist/index.js",
12
- "import": "./dist/index.mjs"
13
- }
14
- },
15
- "files": [
16
- "dist",
17
- "README.md"
18
- ],
19
- "scripts": {
20
- "build": "tsup src/index.ts --format cjs,esm --dts",
21
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
- "lint": "eslint \"src/**/*.ts\"",
23
- "test": "vitest run",
24
- "test:watch": "vitest",
25
- "prepublishOnly": "pnpm build"
26
- },
27
- "keywords": [
28
- "brainerce",
29
- "e-commerce",
30
- "ecommerce",
31
- "sdk",
32
- "vibe-coding",
33
- "vibe-coded",
34
- "ai-commerce",
35
- "storefront",
36
- "headless-commerce",
37
- "multi-platform",
38
- "shopify",
39
- "tiktok",
40
- "cursor",
41
- "lovable",
42
- "v0",
43
- "cart",
44
- "checkout",
45
- "products",
46
- "sync"
47
- ],
48
- "author": "Brainerce",
49
- "license": "MIT",
50
- "repository": {
51
- "type": "git",
52
- "url": "https://github.com/brainerce/brainerce.git",
53
- "directory": "packages/sdk"
54
- },
55
- "homepage": "https://brainerce.com",
56
- "bugs": {
57
- "url": "https://github.com/brainerce/brainerce/issues"
58
- },
59
- "devDependencies": {
60
- "@types/node": "^25.0.3",
61
- "@typescript-eslint/eslint-plugin": "^8.50.1",
62
- "@typescript-eslint/parser": "^8.50.1",
63
- "eslint": "^9.39.2",
64
- "tsup": "^8.0.0",
65
- "typescript": "^5.3.0",
66
- "vitest": "^1.0.0"
67
- },
68
- "peerDependencies": {
69
- "typescript": ">=4.7.0"
70
- },
71
- "peerDependenciesMeta": {
72
- "typescript": {
73
- "optional": true
74
- }
75
- }
76
- }
1
+ {
2
+ "name": "brainerce",
3
+ "version": "1.18.0",
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
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "require": "./dist/index.js",
12
+ "import": "./dist/index.mjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts",
21
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
+ "lint": "eslint \"src/**/*.ts\"",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "prepublishOnly": "pnpm build"
26
+ },
27
+ "keywords": [
28
+ "brainerce",
29
+ "e-commerce",
30
+ "ecommerce",
31
+ "sdk",
32
+ "vibe-coding",
33
+ "vibe-coded",
34
+ "ai-commerce",
35
+ "storefront",
36
+ "headless-commerce",
37
+ "multi-platform",
38
+ "shopify",
39
+ "tiktok",
40
+ "cursor",
41
+ "lovable",
42
+ "v0",
43
+ "cart",
44
+ "checkout",
45
+ "products",
46
+ "sync"
47
+ ],
48
+ "author": "Brainerce",
49
+ "license": "MIT",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/brainerce/brainerce.git",
53
+ "directory": "packages/sdk"
54
+ },
55
+ "homepage": "https://brainerce.com",
56
+ "bugs": {
57
+ "url": "https://github.com/brainerce/brainerce/issues"
58
+ },
59
+ "devDependencies": {
60
+ "@types/node": "^25.0.3",
61
+ "@typescript-eslint/eslint-plugin": "^8.50.1",
62
+ "@typescript-eslint/parser": "^8.50.1",
63
+ "eslint": "^9.39.2",
64
+ "tsup": "^8.0.0",
65
+ "typescript": "^5.3.0",
66
+ "vitest": "^1.0.0"
67
+ },
68
+ "peerDependencies": {
69
+ "typescript": ">=4.7.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "typescript": {
73
+ "optional": true
74
+ }
75
+ }
76
+ }