brainerce 1.27.1 → 1.28.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
@@ -135,6 +135,26 @@ function encodePathSegment(value) {
135
135
  }
136
136
  return encodeURIComponent(normalized);
137
137
  }
138
+ var MAX_RETRY_AFTER_MS = 6e4;
139
+ function parseRetryAfterMs(response) {
140
+ const header = response.headers.get("retry-after");
141
+ if (!header) return null;
142
+ const trimmed = header.trim();
143
+ if (!trimmed) return null;
144
+ if (/^\d+$/.test(trimmed)) {
145
+ const seconds = parseInt(trimmed, 10);
146
+ if (!Number.isFinite(seconds) || seconds < 0) return null;
147
+ return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
148
+ }
149
+ const target = Date.parse(trimmed);
150
+ if (Number.isNaN(target)) return null;
151
+ const deltaMs = target - Date.now();
152
+ if (deltaMs <= 0) return 0;
153
+ return Math.min(deltaMs, MAX_RETRY_AFTER_MS);
154
+ }
155
+ function sleep(ms) {
156
+ return new Promise((resolve) => setTimeout(resolve, ms));
157
+ }
138
158
  var BrainerceClient = class {
139
159
  constructor(options) {
140
160
  this.customerToken = null;
@@ -568,7 +588,7 @@ var BrainerceClient = class {
568
588
  /**
569
589
  * Make a request to the Admin API (requires apiKey)
570
590
  */
571
- async adminRequest(method, path, body, queryParams) {
591
+ async adminRequest(method, path, body, queryParams, responseType = "json") {
572
592
  if (!this.apiKey) {
573
593
  throw new BrainerceError(
574
594
  "This operation requires an API key. Initialize with apiKey instead of storeId.",
@@ -583,52 +603,64 @@ var BrainerceClient = class {
583
603
  }
584
604
  });
585
605
  }
586
- const controller = new AbortController();
587
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
588
- try {
589
- const headers = {
590
- Authorization: `Bearer ${this.apiKey}`,
591
- "Content-Type": "application/json",
592
- "X-SDK-Version": SDK_VERSION,
593
- "ngrok-skip-browser-warning": "true"
594
- };
595
- if (this.origin) {
596
- headers["Origin"] = this.origin;
597
- }
598
- if (this.locale) {
599
- headers["Accept-Language"] = this.locale;
600
- }
601
- const response = await fetch(url.toString(), {
602
- method,
603
- headers,
604
- body: body ? JSON.stringify(body) : void 0,
605
- signal: controller.signal
606
- });
607
- clearTimeout(timeoutId);
608
- if (!response.ok) {
609
- const errorData = await response.json().catch(() => ({}));
610
- throw new BrainerceError(
611
- errorData.message || `Request failed with status ${response.status}`,
612
- response.status,
613
- errorData
614
- );
615
- }
616
- const text = await response.text();
617
- if (!text) return {};
618
- return JSON.parse(text);
619
- } catch (error) {
620
- clearTimeout(timeoutId);
621
- if (error instanceof BrainerceError) {
622
- throw error;
623
- }
624
- if (error instanceof Error) {
625
- if (error.name === "AbortError") {
626
- throw new BrainerceError("Request timeout", 408);
606
+ const headers = {
607
+ Authorization: `Bearer ${this.apiKey}`,
608
+ "Content-Type": "application/json",
609
+ "X-SDK-Version": SDK_VERSION,
610
+ "ngrok-skip-browser-warning": "true"
611
+ };
612
+ if (this.origin) {
613
+ headers["Origin"] = this.origin;
614
+ }
615
+ if (this.locale) {
616
+ headers["Accept-Language"] = this.locale;
617
+ }
618
+ for (let attempt = 0; attempt < 2; attempt++) {
619
+ const controller = new AbortController();
620
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
621
+ try {
622
+ const response = await fetch(url.toString(), {
623
+ method,
624
+ headers,
625
+ body: body ? JSON.stringify(body) : void 0,
626
+ signal: controller.signal
627
+ });
628
+ clearTimeout(timeoutId);
629
+ if (response.status === 429 && attempt === 0) {
630
+ const retryAfterMs = parseRetryAfterMs(response);
631
+ if (retryAfterMs !== null) {
632
+ await response.text().catch(() => void 0);
633
+ await sleep(retryAfterMs);
634
+ continue;
635
+ }
627
636
  }
628
- throw new BrainerceError(error.message, 0);
637
+ if (!response.ok) {
638
+ const errorData = await response.json().catch(() => ({}));
639
+ throw new BrainerceError(
640
+ errorData.message || `Request failed with status ${response.status}`,
641
+ response.status,
642
+ errorData
643
+ );
644
+ }
645
+ const text = await response.text();
646
+ if (responseType === "text") return text;
647
+ if (!text) return {};
648
+ return JSON.parse(text);
649
+ } catch (error) {
650
+ clearTimeout(timeoutId);
651
+ if (error instanceof BrainerceError) {
652
+ throw error;
653
+ }
654
+ if (error instanceof Error) {
655
+ if (error.name === "AbortError") {
656
+ throw new BrainerceError("Request timeout", 408);
657
+ }
658
+ throw new BrainerceError(error.message, 0);
659
+ }
660
+ throw new BrainerceError("Unknown error occurred", 0);
629
661
  }
630
- throw new BrainerceError("Unknown error occurred", 0);
631
662
  }
663
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
632
664
  }
633
665
  /**
634
666
  * Make a request to the Vibe-Coded API (public, uses connectionId)
@@ -637,7 +669,7 @@ var BrainerceClient = class {
637
669
  if (!this.connectionId) {
638
670
  throw new BrainerceError("connectionId is required for vibe-coded requests", 400);
639
671
  }
640
- const url = new URL(`${this.baseUrl}/api/vc/${this.connectionId}${path}`);
672
+ const url = new URL(`${this.baseUrl}/api/vc/${encodePathSegment(this.connectionId)}${path}`);
641
673
  if (queryParams) {
642
674
  Object.entries(queryParams).forEach(([key, value]) => {
643
675
  if (value !== void 0) {
@@ -645,70 +677,81 @@ var BrainerceClient = class {
645
677
  }
646
678
  });
647
679
  }
648
- const controller = new AbortController();
649
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
650
- try {
651
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
652
- const headers = {
653
- "X-SDK-Version": SDK_VERSION,
654
- "ngrok-skip-browser-warning": "true"
655
- };
656
- if (!isFormData) {
657
- headers["Content-Type"] = "application/json";
658
- }
659
- if (this.origin) {
660
- headers["Origin"] = this.origin;
661
- }
662
- if (this.locale) {
663
- headers["Accept-Language"] = this.locale;
664
- }
665
- if (headerOverrides) {
666
- Object.assign(headers, headerOverrides);
667
- }
668
- if (this.proxyMode && method !== "GET") {
669
- headers["X-Requested-With"] = "brainerce";
670
- }
671
- if (this.customerToken) {
672
- headers["Authorization"] = `Bearer ${this.customerToken}`;
673
- }
674
- const response = await fetch(url.toString(), {
675
- method,
676
- headers,
677
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
678
- signal: controller.signal
679
- });
680
- clearTimeout(timeoutId);
681
- if (!response.ok) {
682
- const errorData = await response.json().catch(() => ({}));
683
- if (response.status === 401 && this.onAuthError) {
684
- this.onAuthError({
685
- message: errorData.message || "Unauthorized",
686
- statusCode: 401,
687
- path
688
- });
680
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
681
+ const headers = {
682
+ "X-SDK-Version": SDK_VERSION,
683
+ "ngrok-skip-browser-warning": "true"
684
+ };
685
+ if (!isFormData) {
686
+ headers["Content-Type"] = "application/json";
687
+ }
688
+ if (this.origin) {
689
+ headers["Origin"] = this.origin;
690
+ }
691
+ if (this.locale) {
692
+ headers["Accept-Language"] = this.locale;
693
+ }
694
+ if (headerOverrides) {
695
+ Object.assign(headers, headerOverrides);
696
+ }
697
+ if (this.proxyMode && method !== "GET") {
698
+ headers["X-Requested-With"] = "brainerce";
699
+ }
700
+ if (this.customerToken) {
701
+ headers["Authorization"] = `Bearer ${this.customerToken}`;
702
+ }
703
+ for (let attempt = 0; attempt < 2; attempt++) {
704
+ const controller = new AbortController();
705
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
706
+ try {
707
+ const response = await fetch(url.toString(), {
708
+ method,
709
+ headers,
710
+ body: body ? isFormData ? body : JSON.stringify(body) : void 0,
711
+ signal: controller.signal
712
+ });
713
+ clearTimeout(timeoutId);
714
+ if (response.status === 429 && attempt === 0) {
715
+ const retryAfterMs = parseRetryAfterMs(response);
716
+ if (retryAfterMs !== null) {
717
+ await response.text().catch(() => void 0);
718
+ await sleep(retryAfterMs);
719
+ continue;
720
+ }
689
721
  }
690
- throw new BrainerceError(
691
- errorData.message || `Request failed with status ${response.status}`,
692
- response.status,
693
- errorData
694
- );
695
- }
696
- const text = await response.text();
697
- if (!text) return {};
698
- return JSON.parse(text);
699
- } catch (error) {
700
- clearTimeout(timeoutId);
701
- if (error instanceof BrainerceError) {
702
- throw error;
703
- }
704
- if (error instanceof Error) {
705
- if (error.name === "AbortError") {
706
- throw new BrainerceError("Request timeout", 408);
722
+ if (!response.ok) {
723
+ const errorData = await response.json().catch(() => ({}));
724
+ if (response.status === 401 && this.onAuthError) {
725
+ this.onAuthError({
726
+ message: errorData.message || "Unauthorized",
727
+ statusCode: 401,
728
+ path
729
+ });
730
+ }
731
+ throw new BrainerceError(
732
+ errorData.message || `Request failed with status ${response.status}`,
733
+ response.status,
734
+ errorData
735
+ );
707
736
  }
708
- throw new BrainerceError(error.message, 0);
737
+ const text = await response.text();
738
+ if (!text) return {};
739
+ return JSON.parse(text);
740
+ } catch (error) {
741
+ clearTimeout(timeoutId);
742
+ if (error instanceof BrainerceError) {
743
+ throw error;
744
+ }
745
+ if (error instanceof Error) {
746
+ if (error.name === "AbortError") {
747
+ throw new BrainerceError("Request timeout", 408);
748
+ }
749
+ throw new BrainerceError(error.message, 0);
750
+ }
751
+ throw new BrainerceError("Unknown error occurred", 0);
709
752
  }
710
- throw new BrainerceError("Unknown error occurred", 0);
711
753
  }
754
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
712
755
  }
713
756
  /**
714
757
  * Make a request to the Storefront API (public, uses storeId)
@@ -717,7 +760,7 @@ var BrainerceClient = class {
717
760
  if (!this.storeId) {
718
761
  throw new BrainerceError("storeId is required for storefront requests", 400);
719
762
  }
720
- const url = new URL(`${this.baseUrl}/stores/${this.storeId}${path}`);
763
+ const url = new URL(`${this.baseUrl}/stores/${encodePathSegment(this.storeId)}${path}`);
721
764
  if (queryParams) {
722
765
  Object.entries(queryParams).forEach(([key, value]) => {
723
766
  if (value !== void 0) {
@@ -725,67 +768,78 @@ var BrainerceClient = class {
725
768
  }
726
769
  });
727
770
  }
728
- const controller = new AbortController();
729
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
730
- try {
731
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
732
- const headers = {
733
- "X-SDK-Version": SDK_VERSION,
734
- "ngrok-skip-browser-warning": "true"
735
- };
736
- if (!isFormData) {
737
- headers["Content-Type"] = "application/json";
738
- }
739
- if (this.origin) {
740
- headers["Origin"] = this.origin;
741
- }
742
- if (this.locale) {
743
- headers["Accept-Language"] = this.locale;
744
- }
745
- if (headerOverrides) {
746
- Object.assign(headers, headerOverrides);
747
- }
748
- if (this.customerToken) {
749
- headers["Authorization"] = `Bearer ${this.customerToken}`;
750
- }
751
- const response = await fetch(url.toString(), {
752
- method,
753
- headers,
754
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
755
- signal: controller.signal
756
- });
757
- clearTimeout(timeoutId);
758
- if (!response.ok) {
759
- const errorData = await response.json().catch(() => ({}));
760
- if (response.status === 401 && this.onAuthError) {
761
- this.onAuthError({
762
- message: errorData.message || "Unauthorized",
763
- statusCode: 401,
764
- path
765
- });
771
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
772
+ const headers = {
773
+ "X-SDK-Version": SDK_VERSION,
774
+ "ngrok-skip-browser-warning": "true"
775
+ };
776
+ if (!isFormData) {
777
+ headers["Content-Type"] = "application/json";
778
+ }
779
+ if (this.origin) {
780
+ headers["Origin"] = this.origin;
781
+ }
782
+ if (this.locale) {
783
+ headers["Accept-Language"] = this.locale;
784
+ }
785
+ if (headerOverrides) {
786
+ Object.assign(headers, headerOverrides);
787
+ }
788
+ if (this.customerToken) {
789
+ headers["Authorization"] = `Bearer ${this.customerToken}`;
790
+ }
791
+ for (let attempt = 0; attempt < 2; attempt++) {
792
+ const controller = new AbortController();
793
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
794
+ try {
795
+ const response = await fetch(url.toString(), {
796
+ method,
797
+ headers,
798
+ body: body ? isFormData ? body : JSON.stringify(body) : void 0,
799
+ signal: controller.signal
800
+ });
801
+ clearTimeout(timeoutId);
802
+ if (response.status === 429 && attempt === 0) {
803
+ const retryAfterMs = parseRetryAfterMs(response);
804
+ if (retryAfterMs !== null) {
805
+ await response.text().catch(() => void 0);
806
+ await sleep(retryAfterMs);
807
+ continue;
808
+ }
766
809
  }
767
- throw new BrainerceError(
768
- errorData.message || `Request failed with status ${response.status}`,
769
- response.status,
770
- errorData
771
- );
772
- }
773
- const text = await response.text();
774
- if (!text) return {};
775
- return JSON.parse(text);
776
- } catch (error) {
777
- clearTimeout(timeoutId);
778
- if (error instanceof BrainerceError) {
779
- throw error;
780
- }
781
- if (error instanceof Error) {
782
- if (error.name === "AbortError") {
783
- throw new BrainerceError("Request timeout", 408);
810
+ if (!response.ok) {
811
+ const errorData = await response.json().catch(() => ({}));
812
+ if (response.status === 401 && this.onAuthError) {
813
+ this.onAuthError({
814
+ message: errorData.message || "Unauthorized",
815
+ statusCode: 401,
816
+ path
817
+ });
818
+ }
819
+ throw new BrainerceError(
820
+ errorData.message || `Request failed with status ${response.status}`,
821
+ response.status,
822
+ errorData
823
+ );
784
824
  }
785
- throw new BrainerceError(error.message, 0);
825
+ const text = await response.text();
826
+ if (!text) return {};
827
+ return JSON.parse(text);
828
+ } catch (error) {
829
+ clearTimeout(timeoutId);
830
+ if (error instanceof BrainerceError) {
831
+ throw error;
832
+ }
833
+ if (error instanceof Error) {
834
+ if (error.name === "AbortError") {
835
+ throw new BrainerceError("Request timeout", 408);
836
+ }
837
+ throw new BrainerceError(error.message, 0);
838
+ }
839
+ throw new BrainerceError("Unknown error occurred", 0);
786
840
  }
787
- throw new BrainerceError("Unknown error occurred", 0);
788
841
  }
842
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
789
843
  }
790
844
  /**
791
845
  * Smart request - uses storefront or admin API based on client mode
@@ -875,6 +929,7 @@ var BrainerceClient = class {
875
929
  // Admin-only params
876
930
  type: params?.type
877
931
  };
932
+ const queryParamsWithRegion = params?.regionId ? { ...queryParams, regionId: params.regionId } : queryParams;
878
933
  if (this.isVibeCodedMode()) {
879
934
  return this.vibeCodedRequest(
880
935
  "GET",
@@ -888,14 +943,14 @@ var BrainerceClient = class {
888
943
  "GET",
889
944
  "/products",
890
945
  void 0,
891
- queryParams
946
+ queryParamsWithRegion
892
947
  );
893
948
  }
894
949
  return this.adminRequest(
895
950
  "GET",
896
951
  "/api/v1/products",
897
952
  void 0,
898
- queryParams
953
+ queryParamsWithRegion
899
954
  );
900
955
  }
901
956
  /**
@@ -904,10 +959,11 @@ var BrainerceClient = class {
904
959
  */
905
960
  async getProduct(productId, options) {
906
961
  const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
962
+ const queryParams = options?.regionId ? { regionId: options.regionId } : void 0;
907
963
  if (this.isVibeCodedMode()) {
908
964
  return this.vibeCodedRequest(
909
965
  "GET",
910
- `/products/${productId}`,
966
+ `/products/${encodePathSegment(productId)}`,
911
967
  void 0,
912
968
  void 0,
913
969
  headerOverrides
@@ -916,13 +972,18 @@ var BrainerceClient = class {
916
972
  if (this.storeId && !this.apiKey) {
917
973
  return this.storefrontRequest(
918
974
  "GET",
919
- `/products/${productId}`,
920
- void 0,
975
+ `/products/${encodePathSegment(productId)}`,
921
976
  void 0,
977
+ queryParams,
922
978
  headerOverrides
923
979
  );
924
980
  }
925
- return this.adminRequest("GET", `/api/v1/products/${productId}`);
981
+ return this.adminRequest(
982
+ "GET",
983
+ `/api/v1/products/${encodePathSegment(productId)}`,
984
+ void 0,
985
+ queryParams
986
+ );
926
987
  }
927
988
  /**
928
989
  * Get a single product by slug
@@ -1040,7 +1101,7 @@ var BrainerceClient = class {
1040
1101
  */
1041
1102
  async getProductAlternates(productId) {
1042
1103
  if (this.storeId && !this.apiKey) {
1043
- return this.storefrontRequest("GET", `/products/${productId}/alternates`);
1104
+ return this.storefrontRequest("GET", `/products/${encodePathSegment(productId)}/alternates`);
1044
1105
  }
1045
1106
  throw new BrainerceError("getProductAlternates is only available in storefront mode", 400);
1046
1107
  }
@@ -1082,7 +1143,7 @@ var BrainerceClient = class {
1082
1143
  * Update an existing product
1083
1144
  */
1084
1145
  async updateProduct(productId, data) {
1085
- return this.request("PATCH", `/api/v1/products/${productId}`, data);
1146
+ return this.request("PATCH", `/api/v1/products/${encodePathSegment(productId)}`, data);
1086
1147
  }
1087
1148
  /**
1088
1149
  * Delete a product
@@ -1110,7 +1171,7 @@ var BrainerceClient = class {
1110
1171
  const queryParams = options?.platforms?.length ? { platforms: options.platforms.join(",") } : void 0;
1111
1172
  return this.request(
1112
1173
  "DELETE",
1113
- `/api/v1/products/${productId}`,
1174
+ `/api/v1/products/${encodePathSegment(productId)}`,
1114
1175
  void 0,
1115
1176
  queryParams
1116
1177
  );
@@ -1125,7 +1186,10 @@ var BrainerceClient = class {
1125
1186
  * ```
1126
1187
  */
1127
1188
  async convertToVariable(productId) {
1128
- return this.request("PATCH", `/api/v1/products/${productId}/convert-to-variable`);
1189
+ return this.request(
1190
+ "PATCH",
1191
+ `/api/v1/products/${encodePathSegment(productId)}/convert-to-variable`
1192
+ );
1129
1193
  }
1130
1194
  /**
1131
1195
  * Convert a VARIABLE product to SIMPLE product
@@ -1138,7 +1202,10 @@ var BrainerceClient = class {
1138
1202
  * ```
1139
1203
  */
1140
1204
  async convertToSimple(productId) {
1141
- return this.request("PATCH", `/api/v1/products/${productId}/convert-to-simple`);
1205
+ return this.request(
1206
+ "PATCH",
1207
+ `/api/v1/products/${encodePathSegment(productId)}/convert-to-simple`
1208
+ );
1142
1209
  }
1143
1210
  /**
1144
1211
  * Publish a product to specific platforms
@@ -1150,9 +1217,13 @@ var BrainerceClient = class {
1150
1217
  * ```
1151
1218
  */
1152
1219
  async publishProduct(productId, platforms) {
1153
- return this.request("POST", `/api/v1/products/${productId}/publish`, {
1154
- platforms
1155
- });
1220
+ return this.request(
1221
+ "POST",
1222
+ `/api/v1/products/${encodePathSegment(productId)}/publish`,
1223
+ {
1224
+ platforms
1225
+ }
1226
+ );
1156
1227
  }
1157
1228
  // -------------------- Variants --------------------
1158
1229
  /**
@@ -1170,7 +1241,11 @@ var BrainerceClient = class {
1170
1241
  * ```
1171
1242
  */
1172
1243
  async createVariant(productId, data) {
1173
- return this.request("POST", `/api/v1/products/${productId}/variants`, data);
1244
+ return this.request(
1245
+ "POST",
1246
+ `/api/v1/products/${encodePathSegment(productId)}/variants`,
1247
+ data
1248
+ );
1174
1249
  }
1175
1250
  /**
1176
1251
  * Bulk save variants (create, update, delete in one operation)
@@ -1190,7 +1265,7 @@ var BrainerceClient = class {
1190
1265
  async bulkSaveVariants(productId, data) {
1191
1266
  return this.request(
1192
1267
  "POST",
1193
- `/api/v1/products/${productId}/variants/bulk`,
1268
+ `/api/v1/products/${encodePathSegment(productId)}/variants/bulk`,
1194
1269
  data
1195
1270
  );
1196
1271
  }
@@ -1208,7 +1283,7 @@ var BrainerceClient = class {
1208
1283
  async updateVariant(productId, variantId, data) {
1209
1284
  return this.request(
1210
1285
  "PATCH",
1211
- `/api/v1/products/${productId}/variants/${variantId}`,
1286
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`,
1212
1287
  data
1213
1288
  );
1214
1289
  }
@@ -1221,7 +1296,10 @@ var BrainerceClient = class {
1221
1296
  * ```
1222
1297
  */
1223
1298
  async deleteVariant(productId, variantId) {
1224
- await this.request("DELETE", `/api/v1/products/${productId}/variants/${variantId}`);
1299
+ await this.request(
1300
+ "DELETE",
1301
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`
1302
+ );
1225
1303
  }
1226
1304
  /**
1227
1305
  * Get inventory for a specific variant
@@ -1235,7 +1313,7 @@ var BrainerceClient = class {
1235
1313
  async getVariantInventory(productId, variantId) {
1236
1314
  return this.request(
1237
1315
  "GET",
1238
- `/api/v1/products/${productId}/variants/${variantId}/inventory`
1316
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`
1239
1317
  );
1240
1318
  }
1241
1319
  /**
@@ -1252,7 +1330,7 @@ var BrainerceClient = class {
1252
1330
  async updateVariantInventory(productId, variantId, data) {
1253
1331
  return this.request(
1254
1332
  "PATCH",
1255
- `/api/v1/products/${productId}/variants/${variantId}/inventory`,
1333
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`,
1256
1334
  data
1257
1335
  );
1258
1336
  }
@@ -1276,7 +1354,10 @@ var BrainerceClient = class {
1276
1354
  * Get a single order by ID
1277
1355
  */
1278
1356
  async getOrder(orderId) {
1279
- return this.withGuards(this.request("GET", `/api/v1/orders/${orderId}`), "order");
1357
+ return this.withGuards(
1358
+ this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}`),
1359
+ "order"
1360
+ );
1280
1361
  }
1281
1362
  /**
1282
1363
  * Create a new order
@@ -1289,7 +1370,7 @@ var BrainerceClient = class {
1289
1370
  * Update an order (e.g., change status)
1290
1371
  */
1291
1372
  async updateOrder(orderId, data) {
1292
- return this.request("PATCH", `/api/v1/orders/${orderId}`, data);
1373
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}`, data);
1293
1374
  }
1294
1375
  /**
1295
1376
  * Update order status
@@ -1300,7 +1381,9 @@ var BrainerceClient = class {
1300
1381
  * ```
1301
1382
  */
1302
1383
  async updateOrderStatus(orderId, status) {
1303
- return this.request("PATCH", `/api/v1/orders/${orderId}/status`, { status });
1384
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/status`, {
1385
+ status
1386
+ });
1304
1387
  }
1305
1388
  /**
1306
1389
  * Update order payment method
@@ -1312,9 +1395,13 @@ var BrainerceClient = class {
1312
1395
  * ```
1313
1396
  */
1314
1397
  async updatePaymentMethod(orderId, paymentMethod) {
1315
- return this.request("PATCH", `/api/v1/orders/${orderId}/payment-method`, {
1316
- paymentMethod
1317
- });
1398
+ return this.request(
1399
+ "PATCH",
1400
+ `/api/v1/orders/${encodePathSegment(orderId)}/payment-method`,
1401
+ {
1402
+ paymentMethod
1403
+ }
1404
+ );
1318
1405
  }
1319
1406
  /**
1320
1407
  * Update order notes
@@ -1325,7 +1412,9 @@ var BrainerceClient = class {
1325
1412
  * ```
1326
1413
  */
1327
1414
  async updateOrderNotes(orderId, notes) {
1328
- return this.request("PATCH", `/api/v1/orders/${orderId}/notes`, { notes });
1415
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/notes`, {
1416
+ notes
1417
+ });
1329
1418
  }
1330
1419
  /**
1331
1420
  * Get refunds for an order
@@ -1338,7 +1427,7 @@ var BrainerceClient = class {
1338
1427
  * ```
1339
1428
  */
1340
1429
  async getOrderRefunds(orderId) {
1341
- return this.request("GET", `/api/v1/orders/${orderId}/refunds`);
1430
+ return this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}/refunds`);
1342
1431
  }
1343
1432
  /**
1344
1433
  * Create a refund for an order
@@ -1365,7 +1454,11 @@ var BrainerceClient = class {
1365
1454
  * ```
1366
1455
  */
1367
1456
  async createRefund(orderId, data) {
1368
- return this.request("POST", `/api/v1/orders/${orderId}/refunds`, data);
1457
+ return this.request(
1458
+ "POST",
1459
+ `/api/v1/orders/${encodePathSegment(orderId)}/refunds`,
1460
+ data
1461
+ );
1369
1462
  }
1370
1463
  /**
1371
1464
  * Update order shipping address
@@ -1385,7 +1478,11 @@ var BrainerceClient = class {
1385
1478
  * ```
1386
1479
  */
1387
1480
  async updateOrderShipping(orderId, data) {
1388
- return this.request("PATCH", `/api/v1/orders/${orderId}/shipping`, data);
1481
+ return this.request(
1482
+ "PATCH",
1483
+ `/api/v1/orders/${encodePathSegment(orderId)}/shipping`,
1484
+ data
1485
+ );
1389
1486
  }
1390
1487
  /**
1391
1488
  * Cancel an order
@@ -1398,7 +1495,7 @@ var BrainerceClient = class {
1398
1495
  * ```
1399
1496
  */
1400
1497
  async cancelOrder(orderId) {
1401
- return this.request("POST", `/api/v1/orders/${orderId}/cancel`);
1498
+ return this.request("POST", `/api/v1/orders/${encodePathSegment(orderId)}/cancel`);
1402
1499
  }
1403
1500
  /**
1404
1501
  * Fulfill an order (mark as shipped)
@@ -1414,7 +1511,11 @@ var BrainerceClient = class {
1414
1511
  * ```
1415
1512
  */
1416
1513
  async fulfillOrder(orderId, data) {
1417
- return this.request("POST", `/api/v1/orders/${orderId}/fulfill`, data || {});
1514
+ return this.request(
1515
+ "POST",
1516
+ `/api/v1/orders/${encodePathSegment(orderId)}/fulfill`,
1517
+ data || {}
1518
+ );
1418
1519
  }
1419
1520
  /**
1420
1521
  * Sync draft orders from connected platforms
@@ -1439,7 +1540,11 @@ var BrainerceClient = class {
1439
1540
  * ```
1440
1541
  */
1441
1542
  async completeDraftOrder(orderId, data) {
1442
- return this.request("POST", `/api/v1/orders/${orderId}/complete-draft`, data || {});
1543
+ return this.request(
1544
+ "POST",
1545
+ `/api/v1/orders/${encodePathSegment(orderId)}/complete-draft`,
1546
+ data || {}
1547
+ );
1443
1548
  }
1444
1549
  /**
1445
1550
  * Send invoice for a draft order
@@ -1456,7 +1561,7 @@ var BrainerceClient = class {
1456
1561
  async sendDraftInvoice(orderId, data) {
1457
1562
  return this.request(
1458
1563
  "POST",
1459
- `/api/v1/orders/${orderId}/send-invoice`,
1564
+ `/api/v1/orders/${encodePathSegment(orderId)}/send-invoice`,
1460
1565
  data || {}
1461
1566
  );
1462
1567
  }
@@ -1469,7 +1574,7 @@ var BrainerceClient = class {
1469
1574
  * ```
1470
1575
  */
1471
1576
  async deleteDraftOrder(orderId) {
1472
- await this.request("DELETE", `/api/v1/orders/${orderId}/draft`);
1577
+ await this.request("DELETE", `/api/v1/orders/${encodePathSegment(orderId)}/draft`);
1473
1578
  }
1474
1579
  /**
1475
1580
  * Update a draft order
@@ -1492,7 +1597,7 @@ var BrainerceClient = class {
1492
1597
  * ```
1493
1598
  */
1494
1599
  async updateDraftOrder(orderId, data) {
1495
- return this.request("PATCH", `/api/v1/orders/${orderId}/draft`, data);
1600
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/draft`, data);
1496
1601
  }
1497
1602
  // -------------------- Inventory --------------------
1498
1603
  /**
@@ -1500,13 +1605,17 @@ var BrainerceClient = class {
1500
1605
  * This will sync inventory to all connected platforms
1501
1606
  */
1502
1607
  async updateInventory(productId, data) {
1503
- await this.request("PUT", `/api/v1/products/${productId}/inventory`, data);
1608
+ await this.request(
1609
+ "PUT",
1610
+ `/api/v1/products/${encodePathSegment(productId)}/inventory`,
1611
+ data
1612
+ );
1504
1613
  }
1505
1614
  /**
1506
1615
  * Get current inventory for a product
1507
1616
  */
1508
1617
  async getInventory(productId) {
1509
- return this.request("GET", `/api/v1/inventory/${productId}`);
1618
+ return this.request("GET", `/api/v1/inventory/${encodePathSegment(productId)}`);
1510
1619
  }
1511
1620
  /**
1512
1621
  * Edit inventory manually with reason for audit trail
@@ -1667,7 +1776,7 @@ var BrainerceClient = class {
1667
1776
  * Get the status of a sync job
1668
1777
  */
1669
1778
  async getSyncStatus(jobId) {
1670
- return this.request("GET", `/api/v1/sync/${jobId}`);
1779
+ return this.request("GET", `/api/v1/sync/${encodePathSegment(jobId)}`);
1671
1780
  }
1672
1781
  // -------------------- Coupons --------------------
1673
1782
  /**
@@ -1689,7 +1798,7 @@ var BrainerceClient = class {
1689
1798
  * Get a single coupon by ID
1690
1799
  */
1691
1800
  async getCoupon(couponId) {
1692
- return this.request("GET", `/api/v1/coupons/${couponId}`);
1801
+ return this.request("GET", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1693
1802
  }
1694
1803
  /**
1695
1804
  * Create a new coupon.
@@ -1719,20 +1828,20 @@ var BrainerceClient = class {
1719
1828
  * Update an existing coupon
1720
1829
  */
1721
1830
  async updateCoupon(couponId, data) {
1722
- return this.request("PATCH", `/api/v1/coupons/${couponId}`, data);
1831
+ return this.request("PATCH", `/api/v1/coupons/${encodePathSegment(couponId)}`, data);
1723
1832
  }
1724
1833
  /**
1725
1834
  * Delete a coupon
1726
1835
  */
1727
1836
  async deleteCoupon(couponId) {
1728
- await this.request("DELETE", `/api/v1/coupons/${couponId}`);
1837
+ await this.request("DELETE", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1729
1838
  }
1730
1839
  /**
1731
1840
  * Sync a coupon to all connected platforms.
1732
1841
  * Returns a sync job that can be tracked with getSyncStatus().
1733
1842
  */
1734
1843
  async syncCoupon(couponId) {
1735
- return this.request("POST", `/api/v1/coupons/${couponId}/sync`);
1844
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/sync`);
1736
1845
  }
1737
1846
  /**
1738
1847
  * Publish a coupon to specific platforms.
@@ -1745,7 +1854,9 @@ var BrainerceClient = class {
1745
1854
  * ```
1746
1855
  */
1747
1856
  async publishCoupon(couponId, platforms) {
1748
- return this.request("POST", `/api/v1/coupons/${couponId}/publish`, { platforms });
1857
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/publish`, {
1858
+ platforms
1859
+ });
1749
1860
  }
1750
1861
  /**
1751
1862
  * Get platform capabilities for coupon features.
@@ -1786,13 +1897,17 @@ var BrainerceClient = class {
1786
1897
  * Get a customer by ID
1787
1898
  */
1788
1899
  async getCustomer(customerId) {
1789
- return this.request("GET", `/api/v1/customers/${customerId}`);
1900
+ return this.request("GET", `/api/v1/customers/${encodePathSegment(customerId)}`);
1790
1901
  }
1791
1902
  /**
1792
1903
  * Update a customer
1793
1904
  */
1794
1905
  async updateCustomer(customerId, data) {
1795
- return this.request("PATCH", `/api/v1/customers/${customerId}`, data);
1906
+ return this.request(
1907
+ "PATCH",
1908
+ `/api/v1/customers/${encodePathSegment(customerId)}`,
1909
+ data
1910
+ );
1796
1911
  }
1797
1912
  /**
1798
1913
  * Get a customer by email
@@ -1800,56 +1915,84 @@ var BrainerceClient = class {
1800
1915
  async getCustomerByEmail(email) {
1801
1916
  return this.request("GET", "/api/v1/customers/by-email", void 0, { email });
1802
1917
  }
1803
- /**
1804
- * List a customer's saved payment methods (vaulted cards).
1805
- *
1806
- * Returns display-only metadata — last4, brand, expiry, default flag,
1807
- * status. The underlying provider token is encrypted at rest and
1808
- * NEVER returned through this API.
1809
- *
1810
- * Apps mode requires `customers:read` and `payments:read` scopes.
1811
- *
1812
- * @param storeId - The store this customer belongs to
1813
- * @param customerId - The customer's ID
1814
- * @returns Array of saved payment methods
1815
- *
1816
- * @example
1817
- * ```typescript
1818
- * const methods = await client.listSavedPaymentMethods(storeId, customerId);
1819
- * methods.forEach((m) => {
1820
- * console.log(`${m.brand} ending in ${m.last4} (expires ${m.expMonth}/${m.expYear})`);
1821
- * });
1822
- * ```
1823
- */
1824
- async listSavedPaymentMethods(storeId, customerId) {
1918
+ async listSavedPaymentMethods(customerIdOrStoreId, maybeCustomerId) {
1919
+ const customerId = this.resolveSavedPaymentMethodsArgs(
1920
+ "listSavedPaymentMethods",
1921
+ customerIdOrStoreId,
1922
+ maybeCustomerId
1923
+ );
1825
1924
  return this.request(
1826
1925
  "GET",
1827
- `/api/stores/${storeId}/customers/${customerId}/payment-methods`
1926
+ `/api/stores/${this.storeId}/customers/${encodePathSegment(customerId)}/payment-methods`
1927
+ );
1928
+ }
1929
+ async removeSavedPaymentMethod(customerIdOrStoreId, paymentMethodIdOrCustomerId, maybePaymentMethodId) {
1930
+ const { customerId, paymentMethodId } = this.resolveRemovePaymentMethodArgs(
1931
+ customerIdOrStoreId,
1932
+ paymentMethodIdOrCustomerId,
1933
+ maybePaymentMethodId
1934
+ );
1935
+ return this.request(
1936
+ "DELETE",
1937
+ `/api/stores/${this.storeId}/customers/${encodePathSegment(customerId)}/payment-methods/${encodePathSegment(paymentMethodId)}`
1828
1938
  );
1829
1939
  }
1830
1940
  /**
1831
- * Remove a customer's saved payment method.
1941
+ * Internal helper: normalize legacy `(storeId, customerId)` callers to the
1942
+ * new `(customerId)` signature for `listSavedPaymentMethods`.
1832
1943
  *
1833
- * Hard-deletes the row. The provider may still hold the underlying
1834
- * token internally we don't issue a delete-at-provider call because
1835
- * not every provider supports it. From the platform's perspective the
1836
- * token is gone; subsequent charges will fail.
1837
- *
1838
- * Apps mode requires `customers:write` scope.
1839
- *
1840
- * @param storeId - The store this customer belongs to
1841
- * @param customerId - The customer's ID
1842
- * @param paymentMethodId - The saved payment method ID to remove
1843
- *
1844
- * @example
1845
- * ```typescript
1846
- * await client.removeSavedPaymentMethod(storeId, customerId, methodId);
1847
- * ```
1944
+ * Throws if the SDK instance has no `storeId` (these endpoints are
1945
+ * storefront-scoped) and warns when the deprecated overload is detected.
1848
1946
  */
1849
- async removeSavedPaymentMethod(storeId, customerId, paymentMethodId) {
1850
- return this.request(
1851
- "DELETE",
1852
- `/api/stores/${storeId}/customers/${customerId}/payment-methods/${paymentMethodId}`
1947
+ resolveSavedPaymentMethodsArgs(methodName, customerIdOrStoreId, maybeCustomerId) {
1948
+ if (!this.storeId) {
1949
+ throw new BrainerceError(
1950
+ `${methodName}: this method requires a storeId on the SDK instance. Pass \`storeId\` when constructing \`new BrainerceClient({ storeId })\`.`,
1951
+ 400
1952
+ );
1953
+ }
1954
+ if (maybeCustomerId !== void 0) {
1955
+ this.warnDeprecatedStoreIdArg(methodName, customerIdOrStoreId);
1956
+ return maybeCustomerId;
1957
+ }
1958
+ return customerIdOrStoreId;
1959
+ }
1960
+ /**
1961
+ * Internal helper: normalize legacy `(storeId, customerId, paymentMethodId)`
1962
+ * callers to the new `(customerId, paymentMethodId)` signature.
1963
+ */
1964
+ resolveRemovePaymentMethodArgs(customerIdOrStoreId, paymentMethodIdOrCustomerId, maybePaymentMethodId) {
1965
+ if (!this.storeId) {
1966
+ throw new BrainerceError(
1967
+ "removeSavedPaymentMethod: this method requires a storeId on the SDK instance. Pass `storeId` when constructing `new BrainerceClient({ storeId })`.",
1968
+ 400
1969
+ );
1970
+ }
1971
+ if (maybePaymentMethodId !== void 0) {
1972
+ this.warnDeprecatedStoreIdArg("removeSavedPaymentMethod", customerIdOrStoreId);
1973
+ return {
1974
+ customerId: paymentMethodIdOrCustomerId,
1975
+ paymentMethodId: maybePaymentMethodId
1976
+ };
1977
+ }
1978
+ return {
1979
+ customerId: customerIdOrStoreId,
1980
+ paymentMethodId: paymentMethodIdOrCustomerId
1981
+ };
1982
+ }
1983
+ /**
1984
+ * One-shot deprecation warning per (method, mismatch?) — verifies the
1985
+ * caller-supplied storeId matches the SDK config and warns regardless.
1986
+ */
1987
+ warnDeprecatedStoreIdArg(methodName, suppliedStoreId) {
1988
+ if (suppliedStoreId !== this.storeId) {
1989
+ throw new BrainerceError(
1990
+ `${methodName}: supplied storeId "${suppliedStoreId}" does not match the SDK instance storeId "${this.storeId}". Construct a new client per store.`,
1991
+ 400
1992
+ );
1993
+ }
1994
+ console.warn(
1995
+ `BrainerceClient.${methodName}: passing \`storeId\` is deprecated \u2014 it is now derived from the SDK config. Remove the leading argument; this overload will be removed in SDK 2.0.`
1853
1996
  );
1854
1997
  }
1855
1998
  /**
@@ -1908,12 +2051,33 @@ var BrainerceClient = class {
1908
2051
  * Request a password reset email for a customer
1909
2052
  * Works in vibe-coded, storefront, and admin mode
1910
2053
  *
2054
+ * The `resetUrl` MUST be supplied explicitly in non-browser (SSR / Node)
2055
+ * contexts — auto-deriving it from `window.location.origin` is impossible
2056
+ * there and historically resulted in `undefined` being sent to the backend,
2057
+ * which then bounced the email to a broken link. In browser contexts the
2058
+ * origin is still used as a fallback but the SDK logs a one-time warning
2059
+ * recommending an explicit value so server-rendered + proxied dashboards
2060
+ * don't silently rely on the wrong host.
2061
+ *
1911
2062
  * @param email - Customer email address
1912
2063
  * @param options - Optional settings
1913
- * @param options.resetUrl - Override the auto-detected reset URL (e.g. for BFF proxy callback)
2064
+ * @param options.resetUrl - Reset URL the email links should point to.
2065
+ * Required outside the browser; recommended inside it.
1914
2066
  */
1915
2067
  async forgotPassword(email, options) {
1916
- const resetUrl = options?.resetUrl ?? (typeof window !== "undefined" ? `${window.location.origin}/reset-password` : void 0);
2068
+ let resetUrl = options?.resetUrl;
2069
+ if (!resetUrl) {
2070
+ if (typeof window === "undefined") {
2071
+ throw new BrainerceError(
2072
+ 'forgotPassword: `resetUrl` is required outside the browser. Pass `{ resetUrl: "https://your-site.example/reset-password" }` so the email links to the right host.',
2073
+ 400
2074
+ );
2075
+ }
2076
+ console.warn(
2077
+ "BrainerceClient.forgotPassword: deriving `resetUrl` from `window.location.origin` \u2014 pass `{ resetUrl }` explicitly to avoid wrong-host links behind proxies or in SSR."
2078
+ );
2079
+ resetUrl = `${window.location.origin}/reset-password`;
2080
+ }
1917
2081
  if (this.isVibeCodedMode()) {
1918
2082
  return this.vibeCodedRequest("POST", "/customers/forgot-password", {
1919
2083
  email,
@@ -2096,12 +2260,14 @@ var BrainerceClient = class {
2096
2260
  * // Redirect user to Google
2097
2261
  * window.location.href = authorizationUrl;
2098
2262
  *
2099
- * // On /auth/callback page — the backend handles code exchange and redirects with params:
2263
+ * // On /auth/callback page — exchange the one-time auth_code for the JWT.
2264
+ * // (The backend used to put the JWT directly in the redirect URL; that path
2265
+ * // is deprecated because URL params leak into browser history and logs.)
2100
2266
  * const params = new URLSearchParams(window.location.search);
2101
- * if (params.get('oauth_success') === 'true') {
2102
- * const token = params.get('token');
2103
- * client.setCustomerToken(token);
2104
- * // Also available: customer_id, customer_email, is_new
2267
+ * if (params.get('oauth_success') === 'true' && params.get('auth_code')) {
2268
+ * const result = await client.exchangeOAuthCode(params.get('auth_code')!);
2269
+ * client.setCustomerToken(result.token);
2270
+ * // result.customer, result.isNewCustomer, result.redirectUrl, ...
2105
2271
  * } else if (params.get('oauth_error')) {
2106
2272
  * // Show error
2107
2273
  * }
@@ -2119,7 +2285,7 @@ var BrainerceClient = class {
2119
2285
  params.set("redirectUrl", options.redirectUrl);
2120
2286
  }
2121
2287
  const queryString = params.toString();
2122
- const endpoint = `/oauth/${provider}/authorize${queryString ? `?${queryString}` : ""}`;
2288
+ const endpoint = `/oauth/${encodePathSegment(provider)}/authorize${queryString ? `?${queryString}` : ""}`;
2123
2289
  if (this.isVibeCodedMode()) {
2124
2290
  return this.vibeCodedRequest("GET", endpoint);
2125
2291
  }
@@ -2128,6 +2294,83 @@ var BrainerceClient = class {
2128
2294
  }
2129
2295
  throw new BrainerceError("getOAuthAuthorizeUrl requires vibe-coded or storefront mode", 400);
2130
2296
  }
2297
+ /**
2298
+ * Exchange a one-time `auth_code` (returned in the post-OAuth redirect URL)
2299
+ * for the customer JWT. Use this on the `/auth/callback` storefront page
2300
+ * after reading `auth_code` from `window.location.search`.
2301
+ *
2302
+ * The code is single-use and expires 2 minutes after the OAuth callback
2303
+ * issued it. A second call with the same code returns 400.
2304
+ *
2305
+ * This replaces the legacy flow where the JWT was placed directly in the
2306
+ * redirect URL (`?token=...`). The legacy URL params still ship behind a
2307
+ * server feature flag during the migration window, but they will be
2308
+ * removed in the next major release — migrate now.
2309
+ *
2310
+ * @param authCode - The single-use code from the `?auth_code=` URL param.
2311
+ *
2312
+ * @example
2313
+ * ```typescript
2314
+ * const params = new URLSearchParams(window.location.search);
2315
+ * const code = params.get('auth_code');
2316
+ * if (code) {
2317
+ * const { token, customer, isNewCustomer, redirectUrl } =
2318
+ * await client.exchangeOAuthCode(code);
2319
+ * client.setCustomerToken(token);
2320
+ * }
2321
+ * ```
2322
+ */
2323
+ async exchangeOAuthCode(authCode) {
2324
+ if (!authCode) {
2325
+ throw new BrainerceError("authCode is required", 400);
2326
+ }
2327
+ const url = `${this.baseUrl}/api/oauth/customer/exchange`;
2328
+ const controller = new AbortController();
2329
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2330
+ try {
2331
+ const headers = {
2332
+ "Content-Type": "application/json",
2333
+ "X-SDK-Version": SDK_VERSION,
2334
+ "ngrok-skip-browser-warning": "true"
2335
+ };
2336
+ if (this.origin) {
2337
+ headers["Origin"] = this.origin;
2338
+ }
2339
+ if (this.locale) {
2340
+ headers["Accept-Language"] = this.locale;
2341
+ }
2342
+ const response = await fetch(url, {
2343
+ method: "POST",
2344
+ headers,
2345
+ body: JSON.stringify({ code: authCode }),
2346
+ signal: controller.signal
2347
+ });
2348
+ clearTimeout(timeoutId);
2349
+ if (!response.ok) {
2350
+ const errorData = await response.json().catch(() => ({}));
2351
+ throw new BrainerceError(
2352
+ errorData.message || `Request failed with status ${response.status}`,
2353
+ response.status,
2354
+ errorData
2355
+ );
2356
+ }
2357
+ const text = await response.text();
2358
+ if (!text) return {};
2359
+ return JSON.parse(text);
2360
+ } catch (error) {
2361
+ clearTimeout(timeoutId);
2362
+ if (error instanceof BrainerceError) {
2363
+ throw error;
2364
+ }
2365
+ if (error instanceof Error) {
2366
+ if (error.name === "AbortError") {
2367
+ throw new BrainerceError("Request timeout", 408);
2368
+ }
2369
+ throw new BrainerceError(error.message, 0);
2370
+ }
2371
+ throw new BrainerceError("Unknown error occurred", 0);
2372
+ }
2373
+ }
2131
2374
  /**
2132
2375
  * Handle OAuth callback - exchange code for customer token (server-to-server)
2133
2376
  *
@@ -2148,7 +2391,7 @@ var BrainerceClient = class {
2148
2391
  throw new BrainerceError("provider is required (e.g., 'GOOGLE', 'FACEBOOK', 'GITHUB')", 400);
2149
2392
  }
2150
2393
  const params = new URLSearchParams({ code, state });
2151
- const endpoint = `/oauth/${provider}/callback?${params.toString()}`;
2394
+ const endpoint = `/oauth/${encodePathSegment(provider)}/callback?${params.toString()}`;
2152
2395
  if (this.isVibeCodedMode()) {
2153
2396
  return this.vibeCodedRequest("GET", endpoint);
2154
2397
  }
@@ -2192,7 +2435,7 @@ var BrainerceClient = class {
2192
2435
  params.set("redirectUrl", options.redirectUrl);
2193
2436
  }
2194
2437
  const queryString = params.toString();
2195
- const endpoint = `/oauth/${provider}/link${queryString ? `?${queryString}` : ""}`;
2438
+ const endpoint = `/oauth/${encodePathSegment(provider)}/link${queryString ? `?${queryString}` : ""}`;
2196
2439
  if (this.isVibeCodedMode()) {
2197
2440
  return this.vibeCodedRequest("POST", endpoint);
2198
2441
  }
@@ -2221,10 +2464,16 @@ var BrainerceClient = class {
2221
2464
  throw new BrainerceError("Customer token is required. Call setCustomerToken() first.", 401);
2222
2465
  }
2223
2466
  if (this.isVibeCodedMode()) {
2224
- return this.vibeCodedRequest("DELETE", `/oauth/${provider}/link`);
2467
+ return this.vibeCodedRequest(
2468
+ "DELETE",
2469
+ `/oauth/${encodePathSegment(provider)}/link`
2470
+ );
2225
2471
  }
2226
2472
  if (this.isStorefrontMode()) {
2227
- return this.storefrontRequest("DELETE", `/oauth/${provider}/link`);
2473
+ return this.storefrontRequest(
2474
+ "DELETE",
2475
+ `/oauth/${encodePathSegment(provider)}/link`
2476
+ );
2228
2477
  }
2229
2478
  throw new BrainerceError("unlinkOAuthProvider requires vibe-coded or storefront mode", 400);
2230
2479
  }
@@ -2291,7 +2540,10 @@ var BrainerceClient = class {
2291
2540
  * Get all addresses for a customer
2292
2541
  */
2293
2542
  async getCustomerAddresses(customerId) {
2294
- return this.request("GET", `/api/v1/customers/${customerId}/addresses`);
2543
+ return this.request(
2544
+ "GET",
2545
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`
2546
+ );
2295
2547
  }
2296
2548
  /**
2297
2549
  * Add an address to a customer
@@ -2313,7 +2565,7 @@ var BrainerceClient = class {
2313
2565
  async addCustomerAddress(customerId, address) {
2314
2566
  return this.request(
2315
2567
  "POST",
2316
- `/api/v1/customers/${customerId}/addresses`,
2568
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`,
2317
2569
  address
2318
2570
  );
2319
2571
  }
@@ -2323,7 +2575,7 @@ var BrainerceClient = class {
2323
2575
  async updateCustomerAddress(customerId, addressId, address) {
2324
2576
  return this.request(
2325
2577
  "PATCH",
2326
- `/api/v1/customers/${customerId}/addresses/${addressId}`,
2578
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`,
2327
2579
  address
2328
2580
  );
2329
2581
  }
@@ -2331,7 +2583,10 @@ var BrainerceClient = class {
2331
2583
  * Delete a customer address
2332
2584
  */
2333
2585
  async deleteCustomerAddress(customerId, addressId) {
2334
- await this.request("DELETE", `/api/v1/customers/${customerId}/addresses/${addressId}`);
2586
+ await this.request(
2587
+ "DELETE",
2588
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`
2589
+ );
2335
2590
  }
2336
2591
  /**
2337
2592
  * Get orders for a customer
@@ -2345,7 +2600,7 @@ var BrainerceClient = class {
2345
2600
  async getCustomerOrders(customerId, params) {
2346
2601
  return this.request(
2347
2602
  "GET",
2348
- `/api/v1/customers/${customerId}/orders`,
2603
+ `/api/v1/customers/${encodePathSegment(customerId)}/orders`,
2349
2604
  void 0,
2350
2605
  { page: params?.page, limit: params?.limit }
2351
2606
  );
@@ -2417,12 +2672,18 @@ var BrainerceClient = class {
2417
2672
  */
2418
2673
  async getCartBySession(sessionToken) {
2419
2674
  if (this.isVibeCodedMode()) {
2420
- return this.vibeCodedRequest("GET", `/cart/session/${sessionToken}`);
2675
+ return this.vibeCodedRequest("GET", `/cart/session/${encodePathSegment(sessionToken)}`);
2421
2676
  }
2422
2677
  if (this.storeId && !this.apiKey) {
2423
- return this.storefrontRequest("GET", `/cart/session/${sessionToken}`);
2678
+ return this.storefrontRequest(
2679
+ "GET",
2680
+ `/cart/session/${encodePathSegment(sessionToken)}`
2681
+ );
2424
2682
  }
2425
- return this.adminRequest("GET", `/api/v1/cart/session/${sessionToken}`);
2683
+ return this.adminRequest(
2684
+ "GET",
2685
+ `/api/v1/cart/session/${encodePathSegment(sessionToken)}`
2686
+ );
2426
2687
  }
2427
2688
  /**
2428
2689
  * Get a cart by customer ID (for authenticated users)
@@ -2435,9 +2696,9 @@ var BrainerceClient = class {
2435
2696
  */
2436
2697
  async getCartByCustomer(customerId) {
2437
2698
  if (this.storeId && !this.apiKey) {
2438
- return this.storefrontRequest("GET", `/cart/customer/${customerId}`);
2699
+ return this.storefrontRequest("GET", `/cart/customer/${encodePathSegment(customerId)}`);
2439
2700
  }
2440
- return this.adminRequest("GET", `/api/v1/cart/customer/${customerId}`);
2701
+ return this.adminRequest("GET", `/api/v1/cart/customer/${encodePathSegment(customerId)}`);
2441
2702
  }
2442
2703
  /**
2443
2704
  * Get a cart by ID
@@ -2467,18 +2728,33 @@ var BrainerceClient = class {
2467
2728
  const queryParams = options?.include?.length ? { include: options.include.join(",") } : void 0;
2468
2729
  if (this.isVibeCodedMode()) {
2469
2730
  return this.withGuards(
2470
- this.vibeCodedRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2731
+ this.vibeCodedRequest(
2732
+ "GET",
2733
+ `/cart/${encodePathSegment(cartId)}`,
2734
+ void 0,
2735
+ queryParams
2736
+ ),
2471
2737
  "cart"
2472
2738
  );
2473
2739
  }
2474
2740
  if (this.storeId && !this.apiKey) {
2475
2741
  return this.withGuards(
2476
- this.storefrontRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2742
+ this.storefrontRequest(
2743
+ "GET",
2744
+ `/cart/${encodePathSegment(cartId)}`,
2745
+ void 0,
2746
+ queryParams
2747
+ ),
2477
2748
  "cart"
2478
2749
  );
2479
2750
  }
2480
2751
  return this.withGuards(
2481
- this.adminRequest("GET", `/api/v1/cart/${cartId}`, void 0, queryParams),
2752
+ this.adminRequest(
2753
+ "GET",
2754
+ `/api/v1/cart/${encodePathSegment(cartId)}`,
2755
+ void 0,
2756
+ queryParams
2757
+ ),
2482
2758
  "cart"
2483
2759
  );
2484
2760
  }
@@ -2534,18 +2810,18 @@ var BrainerceClient = class {
2534
2810
  }
2535
2811
  if (this.isVibeCodedMode()) {
2536
2812
  return this.withGuards(
2537
- this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item),
2813
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2538
2814
  "cart"
2539
2815
  );
2540
2816
  }
2541
2817
  if (this.storeId && !this.apiKey) {
2542
2818
  return this.withGuards(
2543
- this.storefrontRequest("POST", `/cart/${cartId}/items`, item),
2819
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2544
2820
  "cart"
2545
2821
  );
2546
2822
  }
2547
2823
  return this.withGuards(
2548
- this.adminRequest("POST", `/api/v1/cart/${cartId}/items`, item),
2824
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/items`, item),
2549
2825
  "cart"
2550
2826
  );
2551
2827
  }
@@ -2572,18 +2848,30 @@ var BrainerceClient = class {
2572
2848
  }
2573
2849
  if (this.isVibeCodedMode()) {
2574
2850
  return this.withGuards(
2575
- this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2851
+ this.vibeCodedRequest(
2852
+ "PATCH",
2853
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2854
+ data
2855
+ ),
2576
2856
  "cart"
2577
2857
  );
2578
2858
  }
2579
2859
  if (this.storeId && !this.apiKey) {
2580
2860
  return this.withGuards(
2581
- this.storefrontRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2861
+ this.storefrontRequest(
2862
+ "PATCH",
2863
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2864
+ data
2865
+ ),
2582
2866
  "cart"
2583
2867
  );
2584
2868
  }
2585
2869
  return this.withGuards(
2586
- this.adminRequest("PATCH", `/api/v1/cart/${cartId}/items/${itemId}`, data),
2870
+ this.adminRequest(
2871
+ "PATCH",
2872
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2873
+ data
2874
+ ),
2587
2875
  "cart"
2588
2876
  );
2589
2877
  }
@@ -2610,18 +2898,27 @@ var BrainerceClient = class {
2610
2898
  }
2611
2899
  if (this.isVibeCodedMode()) {
2612
2900
  return this.withGuards(
2613
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2901
+ this.vibeCodedRequest(
2902
+ "DELETE",
2903
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2904
+ ),
2614
2905
  "cart"
2615
2906
  );
2616
2907
  }
2617
2908
  if (this.storeId && !this.apiKey) {
2618
2909
  return this.withGuards(
2619
- this.storefrontRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2910
+ this.storefrontRequest(
2911
+ "DELETE",
2912
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2913
+ ),
2620
2914
  "cart"
2621
2915
  );
2622
2916
  }
2623
2917
  return this.withGuards(
2624
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items/${itemId}`),
2918
+ this.adminRequest(
2919
+ "DELETE",
2920
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2921
+ ),
2625
2922
  "cart"
2626
2923
  );
2627
2924
  }
@@ -2642,13 +2939,16 @@ var BrainerceClient = class {
2642
2939
  return this.withGuards(this.localCartToCart(this.getLocalCart()), "cart");
2643
2940
  }
2644
2941
  if (this.isVibeCodedMode()) {
2645
- return this.withGuards(this.vibeCodedRequest("DELETE", `/cart/${cartId}`), "cart");
2942
+ return this.withGuards(
2943
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}`),
2944
+ "cart"
2945
+ );
2646
2946
  }
2647
2947
  if (this.storeId && !this.apiKey) {
2648
- await this.storefrontRequest("DELETE", `/cart/${cartId}/items`);
2948
+ await this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/items`);
2649
2949
  return this.withGuards({}, "cart");
2650
2950
  }
2651
- await this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items`);
2951
+ await this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/items`);
2652
2952
  return this.withGuards({}, "cart");
2653
2953
  }
2654
2954
  /**
@@ -2663,18 +2963,18 @@ var BrainerceClient = class {
2663
2963
  async applyCoupon(cartId, code) {
2664
2964
  if (this.isVibeCodedMode()) {
2665
2965
  return this.withGuards(
2666
- this.vibeCodedRequest("POST", `/cart/${cartId}/coupon`, { code }),
2966
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2667
2967
  "cart"
2668
2968
  );
2669
2969
  }
2670
2970
  if (this.storeId && !this.apiKey) {
2671
2971
  return this.withGuards(
2672
- this.storefrontRequest("POST", `/cart/${cartId}/coupon`, { code }),
2972
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2673
2973
  "cart"
2674
2974
  );
2675
2975
  }
2676
2976
  return this.withGuards(
2677
- this.adminRequest("POST", `/api/v1/cart/${cartId}/coupon`, { code }),
2977
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2678
2978
  "cart"
2679
2979
  );
2680
2980
  }
@@ -2689,18 +2989,18 @@ var BrainerceClient = class {
2689
2989
  async removeCoupon(cartId) {
2690
2990
  if (this.isVibeCodedMode()) {
2691
2991
  return this.withGuards(
2692
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/coupon`),
2992
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2693
2993
  "cart"
2694
2994
  );
2695
2995
  }
2696
2996
  if (this.storeId && !this.apiKey) {
2697
2997
  return this.withGuards(
2698
- this.storefrontRequest("DELETE", `/cart/${cartId}/coupon`),
2998
+ this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2699
2999
  "cart"
2700
3000
  );
2701
3001
  }
2702
3002
  return this.withGuards(
2703
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/coupon`),
3003
+ this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`),
2704
3004
  "cart"
2705
3005
  );
2706
3006
  }
@@ -2725,18 +3025,18 @@ var BrainerceClient = class {
2725
3025
  }
2726
3026
  if (this.isVibeCodedMode()) {
2727
3027
  return this.withGuards(
2728
- this.vibeCodedRequest("POST", `/cart/${cartId}/recalculate`),
3028
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2729
3029
  "cart"
2730
3030
  );
2731
3031
  }
2732
3032
  if (this.storeId && !this.apiKey) {
2733
3033
  return this.withGuards(
2734
- this.storefrontRequest("POST", `/cart/${cartId}/recalculate`),
3034
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2735
3035
  "cart"
2736
3036
  );
2737
3037
  }
2738
3038
  return this.withGuards(
2739
- this.adminRequest("POST", `/api/v1/cart/${cartId}/recalculate`),
3039
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/recalculate`),
2740
3040
  "cart"
2741
3041
  );
2742
3042
  }
@@ -2765,18 +3065,24 @@ var BrainerceClient = class {
2765
3065
  }
2766
3066
  if (this.isVibeCodedMode()) {
2767
3067
  return this.withGuards(
2768
- this.vibeCodedRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3068
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/refresh-snapshots`),
2769
3069
  "cart"
2770
3070
  );
2771
3071
  }
2772
3072
  if (this.storeId && !this.apiKey) {
2773
3073
  return this.withGuards(
2774
- this.storefrontRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3074
+ this.storefrontRequest(
3075
+ "POST",
3076
+ `/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3077
+ ),
2775
3078
  "cart"
2776
3079
  );
2777
3080
  }
2778
3081
  return this.withGuards(
2779
- this.adminRequest("POST", `/api/v1/cart/${cartId}/refresh-snapshots`),
3082
+ this.adminRequest(
3083
+ "POST",
3084
+ `/api/v1/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3085
+ ),
2780
3086
  "cart"
2781
3087
  );
2782
3088
  }
@@ -2805,10 +3111,10 @@ var BrainerceClient = class {
2805
3111
  );
2806
3112
  }
2807
3113
  if (this.isVibeCodedMode()) {
2808
- return this.vibeCodedRequest("POST", `/cart/${cartId}/link`);
3114
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2809
3115
  }
2810
3116
  if (this.storeId && !this.apiKey) {
2811
- return this.storefrontRequest("POST", `/cart/${cartId}/link`);
3117
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2812
3118
  }
2813
3119
  throw new BrainerceError("linkCart is only available in vibe-coded or storefront mode", 400);
2814
3120
  }
@@ -2871,13 +3177,13 @@ var BrainerceClient = class {
2871
3177
  if (this.isVibeCodedMode()) {
2872
3178
  return this.vibeCodedRequest(
2873
3179
  "GET",
2874
- `/products/${productId}/discount-badge`
3180
+ `/products/${encodePathSegment(productId)}/discount-badge`
2875
3181
  );
2876
3182
  }
2877
3183
  if (this.storeId && !this.apiKey) {
2878
3184
  return this.storefrontRequest(
2879
3185
  "GET",
2880
- `/products/${productId}/discount-badge`
3186
+ `/products/${encodePathSegment(productId)}/discount-badge`
2881
3187
  );
2882
3188
  }
2883
3189
  throw new BrainerceError(
@@ -2901,10 +3207,13 @@ var BrainerceClient = class {
2901
3207
  */
2902
3208
  async getCartNudges(cartId) {
2903
3209
  if (this.isVibeCodedMode()) {
2904
- return this.vibeCodedRequest("GET", `/cart/${cartId}/nudges`);
3210
+ return this.vibeCodedRequest("GET", `/cart/${encodePathSegment(cartId)}/nudges`);
2905
3211
  }
2906
3212
  if (this.storeId && !this.apiKey) {
2907
- return this.storefrontRequest("GET", `/cart/${cartId}/nudges`);
3213
+ return this.storefrontRequest(
3214
+ "GET",
3215
+ `/cart/${encodePathSegment(cartId)}/nudges`
3216
+ );
2908
3217
  }
2909
3218
  throw new BrainerceError("getCartNudges() requires vibe-coded or storefront mode", 400);
2910
3219
  }
@@ -2929,7 +3238,7 @@ var BrainerceClient = class {
2929
3238
  if (this.isVibeCodedMode()) {
2930
3239
  return this.vibeCodedRequest(
2931
3240
  "GET",
2932
- `/products/${productId}/recommendations`,
3241
+ `/products/${encodePathSegment(productId)}/recommendations`,
2933
3242
  void 0,
2934
3243
  queryParams
2935
3244
  );
@@ -2937,7 +3246,7 @@ var BrainerceClient = class {
2937
3246
  if (this.storeId && !this.apiKey) {
2938
3247
  return this.storefrontRequest(
2939
3248
  "GET",
2940
- `/products/${productId}/recommendations`,
3249
+ `/products/${encodePathSegment(productId)}/recommendations`,
2941
3250
  void 0,
2942
3251
  queryParams
2943
3252
  );
@@ -2967,7 +3276,7 @@ var BrainerceClient = class {
2967
3276
  if (this.isVibeCodedMode()) {
2968
3277
  return this.vibeCodedRequest(
2969
3278
  "GET",
2970
- `/products/${productId}/reviews`,
3279
+ `/products/${encodePathSegment(productId)}/reviews`,
2971
3280
  void 0,
2972
3281
  queryParams
2973
3282
  );
@@ -2975,7 +3284,7 @@ var BrainerceClient = class {
2975
3284
  if (this.storeId && !this.apiKey) {
2976
3285
  return this.storefrontRequest(
2977
3286
  "GET",
2978
- `/products/${productId}/reviews`,
3287
+ `/products/${encodePathSegment(productId)}/reviews`,
2979
3288
  void 0,
2980
3289
  queryParams
2981
3290
  );
@@ -2999,10 +3308,16 @@ var BrainerceClient = class {
2999
3308
  */
3000
3309
  async getMyProductReview(productId) {
3001
3310
  if (this.isVibeCodedMode()) {
3002
- return this.vibeCodedRequest("GET", `/products/${productId}/reviews/me`);
3311
+ return this.vibeCodedRequest(
3312
+ "GET",
3313
+ `/products/${encodePathSegment(productId)}/reviews/me`
3314
+ );
3003
3315
  }
3004
3316
  if (this.storeId && !this.apiKey) {
3005
- return this.storefrontRequest("GET", `/products/${productId}/reviews/me`);
3317
+ return this.storefrontRequest(
3318
+ "GET",
3319
+ `/products/${encodePathSegment(productId)}/reviews/me`
3320
+ );
3006
3321
  }
3007
3322
  throw new BrainerceError("getMyProductReview() requires vibe-coded or storefront mode", 400);
3008
3323
  }
@@ -3026,10 +3341,18 @@ var BrainerceClient = class {
3026
3341
  */
3027
3342
  async submitProductReview(productId, input) {
3028
3343
  if (this.isVibeCodedMode()) {
3029
- return this.vibeCodedRequest("POST", `/products/${productId}/reviews`, input);
3344
+ return this.vibeCodedRequest(
3345
+ "POST",
3346
+ `/products/${encodePathSegment(productId)}/reviews`,
3347
+ input
3348
+ );
3030
3349
  }
3031
3350
  if (this.storeId && !this.apiKey) {
3032
- return this.storefrontRequest("POST", `/products/${productId}/reviews`, input);
3351
+ return this.storefrontRequest(
3352
+ "POST",
3353
+ `/products/${encodePathSegment(productId)}/reviews`,
3354
+ input
3355
+ );
3033
3356
  }
3034
3357
  throw new BrainerceError("submitProductReview() requires vibe-coded or storefront mode", 400);
3035
3358
  }
@@ -3042,14 +3365,14 @@ var BrainerceClient = class {
3042
3365
  if (this.isVibeCodedMode()) {
3043
3366
  return this.vibeCodedRequest(
3044
3367
  "PATCH",
3045
- `/products/${productId}/reviews/me`,
3368
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3046
3369
  input
3047
3370
  );
3048
3371
  }
3049
3372
  if (this.storeId && !this.apiKey) {
3050
3373
  return this.storefrontRequest(
3051
3374
  "PATCH",
3052
- `/products/${productId}/reviews/me`,
3375
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3053
3376
  input
3054
3377
  );
3055
3378
  }
@@ -3061,11 +3384,17 @@ var BrainerceClient = class {
3061
3384
  */
3062
3385
  async deleteMyProductReview(productId) {
3063
3386
  if (this.isVibeCodedMode()) {
3064
- await this.vibeCodedRequest("DELETE", `/products/${productId}/reviews/me`);
3387
+ await this.vibeCodedRequest(
3388
+ "DELETE",
3389
+ `/products/${encodePathSegment(productId)}/reviews/me`
3390
+ );
3065
3391
  return;
3066
3392
  }
3067
3393
  if (this.storeId && !this.apiKey) {
3068
- await this.storefrontRequest("DELETE", `/products/${productId}/reviews/me`);
3394
+ await this.storefrontRequest(
3395
+ "DELETE",
3396
+ `/products/${encodePathSegment(productId)}/reviews/me`
3397
+ );
3069
3398
  return;
3070
3399
  }
3071
3400
  throw new BrainerceError("deleteMyProductReview() requires vibe-coded or storefront mode", 400);
@@ -3084,7 +3413,7 @@ var BrainerceClient = class {
3084
3413
  if (params?.visibility) queryParams.visibility = params.visibility;
3085
3414
  return this.adminRequest(
3086
3415
  "GET",
3087
- `/api/v1/products/${productId}/reviews`,
3416
+ `/api/v1/products/${encodePathSegment(productId)}/reviews`,
3088
3417
  void 0,
3089
3418
  queryParams
3090
3419
  );
@@ -3096,7 +3425,7 @@ var BrainerceClient = class {
3096
3425
  }
3097
3426
  return this.adminRequest(
3098
3427
  "PATCH",
3099
- `/api/v1/reviews/${reviewId}/hide`,
3428
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/hide`,
3100
3429
  void 0,
3101
3430
  storeId ? { storeId } : void 0
3102
3431
  );
@@ -3108,7 +3437,7 @@ var BrainerceClient = class {
3108
3437
  }
3109
3438
  return this.adminRequest(
3110
3439
  "PATCH",
3111
- `/api/v1/reviews/${reviewId}/show`,
3440
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/show`,
3112
3441
  void 0,
3113
3442
  storeId ? { storeId } : void 0
3114
3443
  );
@@ -3133,7 +3462,7 @@ var BrainerceClient = class {
3133
3462
  if (this.isVibeCodedMode()) {
3134
3463
  return this.vibeCodedRequest(
3135
3464
  "GET",
3136
- `/cart/${cartId}/recommendations`,
3465
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3137
3466
  void 0,
3138
3467
  queryParams
3139
3468
  );
@@ -3141,7 +3470,7 @@ var BrainerceClient = class {
3141
3470
  if (this.storeId && !this.apiKey) {
3142
3471
  return this.storefrontRequest(
3143
3472
  "GET",
3144
- `/cart/${cartId}/recommendations`,
3473
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3145
3474
  void 0,
3146
3475
  queryParams
3147
3476
  );
@@ -3168,10 +3497,16 @@ var BrainerceClient = class {
3168
3497
  */
3169
3498
  async getCartUpgrades(cartId) {
3170
3499
  if (this.isVibeCodedMode()) {
3171
- return this.vibeCodedRequest("GET", `/cart/${cartId}/upgrades`);
3500
+ return this.vibeCodedRequest(
3501
+ "GET",
3502
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3503
+ );
3172
3504
  }
3173
3505
  if (this.storeId && !this.apiKey) {
3174
- return this.storefrontRequest("GET", `/cart/${cartId}/upgrades`);
3506
+ return this.storefrontRequest(
3507
+ "GET",
3508
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3509
+ );
3175
3510
  }
3176
3511
  throw new BrainerceError("getCartUpgrades() requires vibe-coded or storefront mode", 400);
3177
3512
  }
@@ -3193,10 +3528,16 @@ var BrainerceClient = class {
3193
3528
  */
3194
3529
  async getCartBundles(cartId) {
3195
3530
  if (this.isVibeCodedMode()) {
3196
- return this.vibeCodedRequest("GET", `/cart/${cartId}/bundles`);
3531
+ return this.vibeCodedRequest(
3532
+ "GET",
3533
+ `/cart/${encodePathSegment(cartId)}/bundles`
3534
+ );
3197
3535
  }
3198
3536
  if (this.storeId && !this.apiKey) {
3199
- return this.storefrontRequest("GET", `/cart/${cartId}/bundles`);
3537
+ return this.storefrontRequest(
3538
+ "GET",
3539
+ `/cart/${encodePathSegment(cartId)}/bundles`
3540
+ );
3200
3541
  }
3201
3542
  throw new BrainerceError("getCartBundles() requires vibe-coded or storefront mode", 400);
3202
3543
  }
@@ -3208,10 +3549,16 @@ var BrainerceClient = class {
3208
3549
  */
3209
3550
  async getCheckoutBumps(checkoutId) {
3210
3551
  if (this.isVibeCodedMode()) {
3211
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/bumps`);
3552
+ return this.vibeCodedRequest(
3553
+ "GET",
3554
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3555
+ );
3212
3556
  }
3213
3557
  if (this.storeId && !this.apiKey) {
3214
- return this.storefrontRequest("GET", `/checkout/${checkoutId}/bumps`);
3558
+ return this.storefrontRequest(
3559
+ "GET",
3560
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3561
+ );
3215
3562
  }
3216
3563
  throw new BrainerceError("getCheckoutBumps() requires vibe-coded or storefront mode", 400);
3217
3564
  }
@@ -3226,10 +3573,10 @@ var BrainerceClient = class {
3226
3573
  async addOrderBump(cartId, bumpConfigId, variantId) {
3227
3574
  const body = { bumpConfigId, ...variantId && { variantId } };
3228
3575
  if (this.isVibeCodedMode()) {
3229
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bump`, body);
3576
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3230
3577
  }
3231
3578
  if (this.storeId && !this.apiKey) {
3232
- return this.storefrontRequest("POST", `/cart/${cartId}/bump`, body);
3579
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3233
3580
  }
3234
3581
  throw new BrainerceError("addOrderBump() requires vibe-coded or storefront mode", 400);
3235
3582
  }
@@ -3242,10 +3589,16 @@ var BrainerceClient = class {
3242
3589
  */
3243
3590
  async removeOrderBump(cartId, bumpConfigId) {
3244
3591
  if (this.isVibeCodedMode()) {
3245
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3592
+ return this.vibeCodedRequest(
3593
+ "DELETE",
3594
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3595
+ );
3246
3596
  }
3247
3597
  if (this.storeId && !this.apiKey) {
3248
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3598
+ return this.storefrontRequest(
3599
+ "DELETE",
3600
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3601
+ );
3249
3602
  }
3250
3603
  throw new BrainerceError("removeOrderBump() requires vibe-coded or storefront mode", 400);
3251
3604
  }
@@ -3276,10 +3629,14 @@ var BrainerceClient = class {
3276
3629
  ...variantSelections && Object.keys(variantSelections).length > 0 ? { variantSelections } : {}
3277
3630
  };
3278
3631
  if (this.isVibeCodedMode()) {
3279
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bundle`, body);
3632
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bundle`, body);
3280
3633
  }
3281
3634
  if (this.storeId && !this.apiKey) {
3282
- return this.storefrontRequest("POST", `/cart/${cartId}/bundle`, body);
3635
+ return this.storefrontRequest(
3636
+ "POST",
3637
+ `/cart/${encodePathSegment(cartId)}/bundle`,
3638
+ body
3639
+ );
3283
3640
  }
3284
3641
  throw new BrainerceError("addBundleToCart() requires vibe-coded or storefront mode", 400);
3285
3642
  }
@@ -3292,10 +3649,16 @@ var BrainerceClient = class {
3292
3649
  */
3293
3650
  async removeBundleFromCart(cartId, bundleOfferId) {
3294
3651
  if (this.isVibeCodedMode()) {
3295
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3652
+ return this.vibeCodedRequest(
3653
+ "DELETE",
3654
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3655
+ );
3296
3656
  }
3297
3657
  if (this.storeId && !this.apiKey) {
3298
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3658
+ return this.storefrontRequest(
3659
+ "DELETE",
3660
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3661
+ );
3299
3662
  }
3300
3663
  throw new BrainerceError("removeBundleFromCart() requires vibe-coded or storefront mode", 400);
3301
3664
  }
@@ -3881,18 +4244,18 @@ var BrainerceClient = class {
3881
4244
  async getCheckout(checkoutId) {
3882
4245
  if (this.isVibeCodedMode()) {
3883
4246
  return this.withGuards(
3884
- this.vibeCodedRequest("GET", `/checkout/${checkoutId}`),
4247
+ this.vibeCodedRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3885
4248
  "checkout"
3886
4249
  );
3887
4250
  }
3888
4251
  if (this.storeId && !this.apiKey) {
3889
4252
  return this.withGuards(
3890
- this.storefrontRequest("GET", `/checkout/${checkoutId}`),
4253
+ this.storefrontRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3891
4254
  "checkout"
3892
4255
  );
3893
4256
  }
3894
4257
  return this.withGuards(
3895
- this.adminRequest("GET", `/api/v1/checkout/${checkoutId}`),
4258
+ this.adminRequest("GET", `/api/v1/checkout/${encodePathSegment(checkoutId)}`),
3896
4259
  "checkout"
3897
4260
  );
3898
4261
  }
@@ -3915,18 +4278,30 @@ var BrainerceClient = class {
3915
4278
  async applyCheckoutCoupon(checkoutId, code) {
3916
4279
  if (this.isVibeCodedMode()) {
3917
4280
  return this.withGuards(
3918
- this.vibeCodedRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4281
+ this.vibeCodedRequest(
4282
+ "POST",
4283
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4284
+ { code }
4285
+ ),
3919
4286
  "checkout"
3920
4287
  );
3921
4288
  }
3922
4289
  if (this.storeId && !this.apiKey) {
3923
4290
  return this.withGuards(
3924
- this.storefrontRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4291
+ this.storefrontRequest(
4292
+ "POST",
4293
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4294
+ { code }
4295
+ ),
3925
4296
  "checkout"
3926
4297
  );
3927
4298
  }
3928
4299
  return this.withGuards(
3929
- this.adminRequest("POST", `/api/v1/checkout/${checkoutId}/coupon`, { code }),
4300
+ this.adminRequest(
4301
+ "POST",
4302
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`,
4303
+ { code }
4304
+ ),
3930
4305
  "checkout"
3931
4306
  );
3932
4307
  }
@@ -3944,18 +4319,27 @@ var BrainerceClient = class {
3944
4319
  async removeCheckoutCoupon(checkoutId) {
3945
4320
  if (this.isVibeCodedMode()) {
3946
4321
  return this.withGuards(
3947
- this.vibeCodedRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4322
+ this.vibeCodedRequest(
4323
+ "DELETE",
4324
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4325
+ ),
3948
4326
  "checkout"
3949
4327
  );
3950
4328
  }
3951
4329
  if (this.storeId && !this.apiKey) {
3952
4330
  return this.withGuards(
3953
- this.storefrontRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4331
+ this.storefrontRequest(
4332
+ "DELETE",
4333
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4334
+ ),
3954
4335
  "checkout"
3955
4336
  );
3956
4337
  }
3957
4338
  return this.withGuards(
3958
- this.adminRequest("DELETE", `/api/v1/checkout/${checkoutId}/coupon`),
4339
+ this.adminRequest(
4340
+ "DELETE",
4341
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`
4342
+ ),
3959
4343
  "checkout"
3960
4344
  );
3961
4345
  }
@@ -3973,12 +4357,24 @@ var BrainerceClient = class {
3973
4357
  */
3974
4358
  async setCheckoutCustomer(checkoutId, data) {
3975
4359
  if (this.isVibeCodedMode()) {
3976
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4360
+ return this.vibeCodedRequest(
4361
+ "PATCH",
4362
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4363
+ data
4364
+ );
3977
4365
  }
3978
4366
  if (this.storeId && !this.apiKey) {
3979
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4367
+ return this.storefrontRequest(
4368
+ "PATCH",
4369
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4370
+ data
4371
+ );
3980
4372
  }
3981
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/customer`, data);
4373
+ return this.adminRequest(
4374
+ "PATCH",
4375
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/customer`,
4376
+ data
4377
+ );
3982
4378
  }
3983
4379
  /**
3984
4380
  * Get available shipping destinations for this store.
@@ -4046,20 +4442,20 @@ var BrainerceClient = class {
4046
4442
  if (this.isVibeCodedMode()) {
4047
4443
  return this.vibeCodedRequest(
4048
4444
  "PATCH",
4049
- `/checkout/${checkoutId}/shipping-address`,
4445
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4050
4446
  address
4051
4447
  );
4052
4448
  }
4053
4449
  if (this.storeId && !this.apiKey) {
4054
4450
  return this.storefrontRequest(
4055
4451
  "PATCH",
4056
- `/checkout/${checkoutId}/shipping-address`,
4452
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4057
4453
  address
4058
4454
  );
4059
4455
  }
4060
4456
  return this.adminRequest(
4061
4457
  "PATCH",
4062
- `/api/v1/checkout/${checkoutId}/shipping-address`,
4458
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4063
4459
  address
4064
4460
  );
4065
4461
  }
@@ -4077,19 +4473,19 @@ var BrainerceClient = class {
4077
4473
  if (this.isVibeCodedMode()) {
4078
4474
  const result = await this.vibeCodedRequest(
4079
4475
  "GET",
4080
- `/checkout/${checkoutId}/shipping-rates`
4476
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4081
4477
  );
4082
4478
  return result.rates;
4083
4479
  }
4084
4480
  if (this.storeId && !this.apiKey) {
4085
4481
  return this.storefrontRequest(
4086
4482
  "GET",
4087
- `/checkout/${checkoutId}/shipping-rates`
4483
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4088
4484
  );
4089
4485
  }
4090
4486
  return this.adminRequest(
4091
4487
  "GET",
4092
- `/api/v1/checkout/${checkoutId}/shipping-rates`
4488
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4093
4489
  );
4094
4490
  }
4095
4491
  /**
@@ -4104,24 +4500,36 @@ var BrainerceClient = class {
4104
4500
  async selectShippingMethod(checkoutId, shippingRateId) {
4105
4501
  if (this.isVibeCodedMode()) {
4106
4502
  return this.withGuards(
4107
- this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4108
- shippingMethodId: shippingRateId
4109
- }),
4503
+ this.vibeCodedRequest(
4504
+ "PATCH",
4505
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4506
+ {
4507
+ shippingRateId
4508
+ }
4509
+ ),
4110
4510
  "checkout"
4111
4511
  );
4112
4512
  }
4113
4513
  if (this.storeId && !this.apiKey) {
4114
4514
  return this.withGuards(
4115
- this.storefrontRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4116
- shippingRateId
4117
- }),
4515
+ this.storefrontRequest(
4516
+ "PATCH",
4517
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4518
+ {
4519
+ shippingRateId
4520
+ }
4521
+ ),
4118
4522
  "checkout"
4119
4523
  );
4120
4524
  }
4121
4525
  return this.withGuards(
4122
- this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/shipping-method`, {
4123
- shippingRateId
4124
- }),
4526
+ this.adminRequest(
4527
+ "PATCH",
4528
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4529
+ {
4530
+ shippingRateId
4531
+ }
4532
+ ),
4125
4533
  "checkout"
4126
4534
  );
4127
4535
  }
@@ -4160,18 +4568,30 @@ var BrainerceClient = class {
4160
4568
  */
4161
4569
  async setDeliveryType(checkoutId, deliveryType) {
4162
4570
  if (this.isVibeCodedMode()) {
4163
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4164
- deliveryType
4165
- });
4571
+ return this.vibeCodedRequest(
4572
+ "PATCH",
4573
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4574
+ {
4575
+ deliveryType
4576
+ }
4577
+ );
4166
4578
  }
4167
4579
  if (this.storeId && !this.apiKey) {
4168
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4169
- deliveryType
4170
- });
4580
+ return this.storefrontRequest(
4581
+ "PATCH",
4582
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4583
+ {
4584
+ deliveryType
4585
+ }
4586
+ );
4171
4587
  }
4172
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/delivery-type`, {
4173
- deliveryType
4174
- });
4588
+ return this.adminRequest(
4589
+ "PATCH",
4590
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4591
+ {
4592
+ deliveryType
4593
+ }
4594
+ );
4175
4595
  }
4176
4596
  /**
4177
4597
  * Select a pickup location for checkout.
@@ -4193,20 +4613,20 @@ var BrainerceClient = class {
4193
4613
  if (this.isVibeCodedMode()) {
4194
4614
  return this.vibeCodedRequest(
4195
4615
  "PATCH",
4196
- `/checkout/${checkoutId}/pickup-location`,
4616
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4197
4617
  data
4198
4618
  );
4199
4619
  }
4200
4620
  if (this.storeId && !this.apiKey) {
4201
4621
  return this.storefrontRequest(
4202
4622
  "PATCH",
4203
- `/checkout/${checkoutId}/pickup-location`,
4623
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4204
4624
  data
4205
4625
  );
4206
4626
  }
4207
4627
  return this.adminRequest(
4208
4628
  "PATCH",
4209
- `/api/v1/checkout/${checkoutId}/pickup-location`,
4629
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4210
4630
  data
4211
4631
  );
4212
4632
  }
@@ -4238,20 +4658,20 @@ var BrainerceClient = class {
4238
4658
  if (this.isVibeCodedMode()) {
4239
4659
  return this.vibeCodedRequest(
4240
4660
  "PATCH",
4241
- `/checkout/${checkoutId}/billing-address`,
4661
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4242
4662
  address
4243
4663
  );
4244
4664
  }
4245
4665
  if (this.storeId && !this.apiKey) {
4246
4666
  return this.storefrontRequest(
4247
4667
  "PATCH",
4248
- `/checkout/${checkoutId}/billing-address`,
4668
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4249
4669
  address
4250
4670
  );
4251
4671
  }
4252
4672
  return this.adminRequest(
4253
4673
  "PATCH",
4254
- `/api/v1/checkout/${checkoutId}/billing-address`,
4674
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4255
4675
  address
4256
4676
  );
4257
4677
  }
@@ -4270,17 +4690,17 @@ var BrainerceClient = class {
4270
4690
  if (this.isVibeCodedMode()) {
4271
4691
  result = await this.vibeCodedRequest(
4272
4692
  "POST",
4273
- `/checkout/${checkoutId}/complete`
4693
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4274
4694
  );
4275
4695
  } else if (this.storeId && !this.apiKey) {
4276
4696
  result = await this.storefrontRequest(
4277
4697
  "POST",
4278
- `/checkout/${checkoutId}/complete`
4698
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4279
4699
  );
4280
4700
  } else {
4281
4701
  result = await this.adminRequest(
4282
4702
  "POST",
4283
- `/api/v1/checkout/${checkoutId}/complete`
4703
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/complete`
4284
4704
  );
4285
4705
  }
4286
4706
  this.customerCartId = null;
@@ -4298,18 +4718,18 @@ var BrainerceClient = class {
4298
4718
  if (this.isVibeCodedMode()) {
4299
4719
  return this.vibeCodedRequest(
4300
4720
  "GET",
4301
- `/checkout/${checkoutId}/custom-fields`
4721
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4302
4722
  );
4303
4723
  }
4304
4724
  if (this.storeId && !this.apiKey) {
4305
4725
  return this.storefrontRequest(
4306
4726
  "GET",
4307
- `/checkout/${checkoutId}/custom-fields`
4727
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4308
4728
  );
4309
4729
  }
4310
4730
  return this.adminRequest(
4311
4731
  "GET",
4312
- `/api/v1/checkouts/${checkoutId}/custom-fields`
4732
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`
4313
4733
  );
4314
4734
  }
4315
4735
  /**
@@ -4332,20 +4752,20 @@ var BrainerceClient = class {
4332
4752
  if (this.isVibeCodedMode()) {
4333
4753
  return this.vibeCodedRequest(
4334
4754
  "PATCH",
4335
- `/checkout/${checkoutId}/custom-fields`,
4755
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4336
4756
  data
4337
4757
  );
4338
4758
  }
4339
4759
  if (this.storeId && !this.apiKey) {
4340
4760
  return this.storefrontRequest(
4341
4761
  "PATCH",
4342
- `/checkout/${checkoutId}/custom-fields`,
4762
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4343
4763
  data
4344
4764
  );
4345
4765
  }
4346
4766
  return this.adminRequest(
4347
4767
  "PATCH",
4348
- `/api/v1/checkouts/${checkoutId}/custom-fields`,
4768
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`,
4349
4769
  data
4350
4770
  );
4351
4771
  }
@@ -4360,17 +4780,17 @@ var BrainerceClient = class {
4360
4780
  if (this.isVibeCodedMode()) {
4361
4781
  result = await this.vibeCodedRequest(
4362
4782
  "DELETE",
4363
- `/checkout/${checkoutId}`
4783
+ `/checkout/${encodePathSegment(checkoutId)}`
4364
4784
  );
4365
4785
  } else if (this.storeId && !this.apiKey) {
4366
4786
  result = await this.storefrontRequest(
4367
4787
  "DELETE",
4368
- `/checkout/${checkoutId}`
4788
+ `/checkout/${encodePathSegment(checkoutId)}`
4369
4789
  );
4370
4790
  } else {
4371
4791
  result = await this.adminRequest(
4372
4792
  "DELETE",
4373
- `/api/v1/checkout/${checkoutId}`
4793
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}`
4374
4794
  );
4375
4795
  }
4376
4796
  this.clearActiveCheckoutStorage();
@@ -4538,7 +4958,10 @@ var BrainerceClient = class {
4538
4958
  400
4539
4959
  );
4540
4960
  }
4541
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
4961
+ return this.vibeCodedRequest(
4962
+ "GET",
4963
+ `/checkout/${encodePathSegment(checkoutId)}/payment-status`
4964
+ );
4542
4965
  }
4543
4966
  /**
4544
4967
  * Confirm a client-side SDK payment from the frontend.
@@ -4637,7 +5060,7 @@ var BrainerceClient = class {
4637
5060
  const startTime = Date.now();
4638
5061
  let attempts = 0;
4639
5062
  let currentDelay = initialDelayMs;
4640
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5063
+ const sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4641
5064
  while (Date.now() - startTime < maxWaitMs) {
4642
5065
  attempts++;
4643
5066
  const status = await this.getPaymentStatus(checkoutId);
@@ -4662,7 +5085,7 @@ var BrainerceClient = class {
4662
5085
  const remainingTime = maxWaitMs - (Date.now() - startTime);
4663
5086
  const sleepTime = Math.min(currentDelay, remainingTime, 8e3);
4664
5087
  if (sleepTime > 0) {
4665
- await sleep(sleepTime);
5088
+ await sleep2(sleepTime);
4666
5089
  currentDelay = Math.min(currentDelay * 2, 8e3);
4667
5090
  }
4668
5091
  }
@@ -5177,7 +5600,7 @@ var BrainerceClient = class {
5177
5600
  if (data.shippingAddress) {
5178
5601
  const result = await this.vibeCodedRequest(
5179
5602
  "PATCH",
5180
- `/checkout/${checkoutId}/shipping-address`,
5603
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
5181
5604
  data.shippingAddress
5182
5605
  );
5183
5606
  checkout = result.checkout;
@@ -5185,7 +5608,7 @@ var BrainerceClient = class {
5185
5608
  if (data.billingAddress) {
5186
5609
  checkout = await this.vibeCodedRequest(
5187
5610
  "PATCH",
5188
- `/checkout/${checkoutId}/billing-address`,
5611
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
5189
5612
  data.billingAddress
5190
5613
  );
5191
5614
  }
@@ -5219,7 +5642,7 @@ var BrainerceClient = class {
5219
5642
  async completeGuestCheckout(checkoutId, options) {
5220
5643
  const result = await this.vibeCodedRequest(
5221
5644
  "POST",
5222
- `/checkout/${checkoutId}/complete`,
5645
+ `/checkout/${encodePathSegment(checkoutId)}/complete`,
5223
5646
  {}
5224
5647
  );
5225
5648
  if (options?.clearCartOnSuccess !== false) {
@@ -5527,13 +5950,13 @@ var BrainerceClient = class {
5527
5950
  if (this.isVibeCodedMode()) {
5528
5951
  return this.vibeCodedRequest(
5529
5952
  "GET",
5530
- `/customers/me/orders/${orderId}/downloads${qs}`
5953
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5531
5954
  );
5532
5955
  }
5533
5956
  if (this.storeId && !this.apiKey) {
5534
5957
  return this.storefrontRequest(
5535
5958
  "GET",
5536
- `/customers/me/orders/${orderId}/downloads${qs}`
5959
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5537
5960
  );
5538
5961
  }
5539
5962
  throw new BrainerceError(
@@ -5626,14 +6049,14 @@ var BrainerceClient = class {
5626
6049
  if (this.isVibeCodedMode()) {
5627
6050
  return this.vibeCodedRequest(
5628
6051
  "PATCH",
5629
- `/customers/me/addresses/${addressId}`,
6052
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5630
6053
  data
5631
6054
  );
5632
6055
  }
5633
6056
  if (this.storeId && !this.apiKey) {
5634
6057
  return this.storefrontRequest(
5635
6058
  "PATCH",
5636
- `/customers/me/addresses/${addressId}`,
6059
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5637
6060
  data
5638
6061
  );
5639
6062
  }
@@ -5654,11 +6077,17 @@ var BrainerceClient = class {
5654
6077
  );
5655
6078
  }
5656
6079
  if (this.isVibeCodedMode()) {
5657
- await this.vibeCodedRequest("DELETE", `/customers/me/addresses/${addressId}`);
6080
+ await this.vibeCodedRequest(
6081
+ "DELETE",
6082
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6083
+ );
5658
6084
  return;
5659
6085
  }
5660
6086
  if (this.storeId && !this.apiKey) {
5661
- await this.storefrontRequest("DELETE", `/customers/me/addresses/${addressId}`);
6087
+ await this.storefrontRequest(
6088
+ "DELETE",
6089
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6090
+ );
5662
6091
  return;
5663
6092
  }
5664
6093
  throw new BrainerceError(
@@ -5711,7 +6140,10 @@ var BrainerceClient = class {
5711
6140
  * ```
5712
6141
  */
5713
6142
  async getCustomApiIntegration(integrationId) {
5714
- return this.adminRequest("GET", `/api/v1/custom-api/${integrationId}`);
6143
+ return this.adminRequest(
6144
+ "GET",
6145
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6146
+ );
5715
6147
  }
5716
6148
  /**
5717
6149
  * Create a new Custom API integration
@@ -5754,7 +6186,7 @@ var BrainerceClient = class {
5754
6186
  async updateCustomApiIntegration(integrationId, data) {
5755
6187
  return this.adminRequest(
5756
6188
  "PATCH",
5757
- `/api/v1/custom-api/${integrationId}`,
6189
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`,
5758
6190
  data
5759
6191
  );
5760
6192
  }
@@ -5768,7 +6200,10 @@ var BrainerceClient = class {
5768
6200
  * ```
5769
6201
  */
5770
6202
  async deleteCustomApiIntegration(integrationId) {
5771
- await this.adminRequest("DELETE", `/api/v1/custom-api/${integrationId}`);
6203
+ await this.adminRequest(
6204
+ "DELETE",
6205
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6206
+ );
5772
6207
  }
5773
6208
  /**
5774
6209
  * Test connection to a Custom API
@@ -5787,7 +6222,7 @@ var BrainerceClient = class {
5787
6222
  async testCustomApiConnection(integrationId) {
5788
6223
  return this.adminRequest(
5789
6224
  "POST",
5790
- `/api/v1/custom-api/${integrationId}/test`
6225
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}/test`
5791
6226
  );
5792
6227
  }
5793
6228
  // -------------------- Inventory Reservations --------------------
@@ -5908,7 +6343,10 @@ var BrainerceClient = class {
5908
6343
  * Requires Admin mode (apiKey)
5909
6344
  */
5910
6345
  async getCategory(categoryId) {
5911
- return this.adminRequest("GET", `/api/v1/categories/${categoryId}`);
6346
+ return this.adminRequest(
6347
+ "GET",
6348
+ `/api/v1/categories/${encodePathSegment(categoryId)}`
6349
+ );
5912
6350
  }
5913
6351
  /**
5914
6352
  * Create a new category
@@ -5931,14 +6369,18 @@ var BrainerceClient = class {
5931
6369
  * Requires Admin mode (apiKey)
5932
6370
  */
5933
6371
  async updateCategory(categoryId, data) {
5934
- return this.adminRequest("PATCH", `/api/v1/categories/${categoryId}`, data);
6372
+ return this.adminRequest(
6373
+ "PATCH",
6374
+ `/api/v1/categories/${encodePathSegment(categoryId)}`,
6375
+ data
6376
+ );
5935
6377
  }
5936
6378
  /**
5937
6379
  * Delete a category
5938
6380
  * Requires Admin mode (apiKey)
5939
6381
  */
5940
6382
  async deleteCategory(categoryId) {
5941
- await this.adminRequest("DELETE", `/api/v1/categories/${categoryId}`);
6383
+ await this.adminRequest("DELETE", `/api/v1/categories/${encodePathSegment(categoryId)}`);
5942
6384
  }
5943
6385
  // -------------------- Taxonomy: Brands (Admin) --------------------
5944
6386
  // These methods require Admin mode (apiKey)
@@ -5954,7 +6396,7 @@ var BrainerceClient = class {
5954
6396
  * Requires Admin mode (apiKey)
5955
6397
  */
5956
6398
  async getBrand(brandId) {
5957
- return this.adminRequest("GET", `/api/v1/brands/${brandId}`);
6399
+ return this.adminRequest("GET", `/api/v1/brands/${encodePathSegment(brandId)}`);
5958
6400
  }
5959
6401
  /**
5960
6402
  * Create a new brand
@@ -5977,14 +6419,14 @@ var BrainerceClient = class {
5977
6419
  * Requires Admin mode (apiKey)
5978
6420
  */
5979
6421
  async updateBrand(brandId, data) {
5980
- return this.adminRequest("PATCH", `/api/v1/brands/${brandId}`, data);
6422
+ return this.adminRequest("PATCH", `/api/v1/brands/${encodePathSegment(brandId)}`, data);
5981
6423
  }
5982
6424
  /**
5983
6425
  * Delete a brand
5984
6426
  * Requires Admin mode (apiKey)
5985
6427
  */
5986
6428
  async deleteBrand(brandId) {
5987
- await this.adminRequest("DELETE", `/api/v1/brands/${brandId}`);
6429
+ await this.adminRequest("DELETE", `/api/v1/brands/${encodePathSegment(brandId)}`);
5988
6430
  }
5989
6431
  // -------------------- Taxonomy: Tags (Admin) --------------------
5990
6432
  // These methods require Admin mode (apiKey)
@@ -6000,7 +6442,7 @@ var BrainerceClient = class {
6000
6442
  * Requires Admin mode (apiKey)
6001
6443
  */
6002
6444
  async getTag(tagId) {
6003
- return this.adminRequest("GET", `/api/v1/tags/${tagId}`);
6445
+ return this.adminRequest("GET", `/api/v1/tags/${encodePathSegment(tagId)}`);
6004
6446
  }
6005
6447
  /**
6006
6448
  * Create a new tag
@@ -6022,14 +6464,14 @@ var BrainerceClient = class {
6022
6464
  * Requires Admin mode (apiKey)
6023
6465
  */
6024
6466
  async updateTag(tagId, data) {
6025
- return this.adminRequest("PATCH", `/api/v1/tags/${tagId}`, data);
6467
+ return this.adminRequest("PATCH", `/api/v1/tags/${encodePathSegment(tagId)}`, data);
6026
6468
  }
6027
6469
  /**
6028
6470
  * Delete a tag
6029
6471
  * Requires Admin mode (apiKey)
6030
6472
  */
6031
6473
  async deleteTag(tagId) {
6032
- await this.adminRequest("DELETE", `/api/v1/tags/${tagId}`);
6474
+ await this.adminRequest("DELETE", `/api/v1/tags/${encodePathSegment(tagId)}`);
6033
6475
  }
6034
6476
  // -------------------- Taxonomy: Attributes (Admin) --------------------
6035
6477
  // These methods require Admin mode (apiKey)
@@ -6050,7 +6492,10 @@ var BrainerceClient = class {
6050
6492
  * Requires Admin mode (apiKey)
6051
6493
  */
6052
6494
  async getAttribute(attributeId) {
6053
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}`);
6495
+ return this.adminRequest(
6496
+ "GET",
6497
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`
6498
+ );
6054
6499
  }
6055
6500
  /**
6056
6501
  * Create a new attribute
@@ -6073,21 +6518,28 @@ var BrainerceClient = class {
6073
6518
  * Requires Admin mode (apiKey)
6074
6519
  */
6075
6520
  async updateAttribute(attributeId, data) {
6076
- return this.adminRequest("PATCH", `/api/v1/attributes/${attributeId}`, data);
6521
+ return this.adminRequest(
6522
+ "PATCH",
6523
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`,
6524
+ data
6525
+ );
6077
6526
  }
6078
6527
  /**
6079
6528
  * Delete an attribute
6080
6529
  * Requires Admin mode (apiKey)
6081
6530
  */
6082
6531
  async deleteAttribute(attributeId) {
6083
- await this.adminRequest("DELETE", `/api/v1/attributes/${attributeId}`);
6532
+ await this.adminRequest("DELETE", `/api/v1/attributes/${encodePathSegment(attributeId)}`);
6084
6533
  }
6085
6534
  /**
6086
6535
  * Get all options for an attribute
6087
6536
  * Requires Admin mode (apiKey)
6088
6537
  */
6089
6538
  async getAttributeOptions(attributeId) {
6090
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}/options`);
6539
+ return this.adminRequest(
6540
+ "GET",
6541
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`
6542
+ );
6091
6543
  }
6092
6544
  /**
6093
6545
  * Create a new option for an attribute
@@ -6105,7 +6557,7 @@ var BrainerceClient = class {
6105
6557
  async createAttributeOption(attributeId, data) {
6106
6558
  return this.adminRequest(
6107
6559
  "POST",
6108
- `/api/v1/attributes/${attributeId}/options`,
6560
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`,
6109
6561
  data
6110
6562
  );
6111
6563
  }
@@ -6116,7 +6568,7 @@ var BrainerceClient = class {
6116
6568
  async updateAttributeOption(attributeId, optionId, data) {
6117
6569
  return this.adminRequest(
6118
6570
  "PATCH",
6119
- `/api/v1/attributes/${attributeId}/options/${optionId}`,
6571
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`,
6120
6572
  data
6121
6573
  );
6122
6574
  }
@@ -6127,7 +6579,7 @@ var BrainerceClient = class {
6127
6579
  async deleteAttributeOption(attributeId, optionId) {
6128
6580
  await this.adminRequest(
6129
6581
  "DELETE",
6130
- `/api/v1/attributes/${attributeId}/options/${optionId}`
6582
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`
6131
6583
  );
6132
6584
  }
6133
6585
  // -------------------- Modifier Groups (Admin) --------------------
@@ -6156,7 +6608,7 @@ var BrainerceClient = class {
6156
6608
  async listModifierGroups(storeId, params) {
6157
6609
  return this.adminRequest(
6158
6610
  "GET",
6159
- `/api/stores/${storeId}/modifier-groups`,
6611
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6160
6612
  void 0,
6161
6613
  params
6162
6614
  );
@@ -6171,7 +6623,7 @@ var BrainerceClient = class {
6171
6623
  async getModifierGroup(storeId, groupId) {
6172
6624
  return this.adminRequest(
6173
6625
  "GET",
6174
- `/api/stores/${storeId}/modifier-groups/${groupId}`
6626
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6175
6627
  );
6176
6628
  }
6177
6629
  /**
@@ -6193,7 +6645,11 @@ var BrainerceClient = class {
6193
6645
  * ```
6194
6646
  */
6195
6647
  async createModifierGroup(storeId, data) {
6196
- return this.adminRequest("POST", `/api/stores/${storeId}/modifier-groups`, data);
6648
+ return this.adminRequest(
6649
+ "POST",
6650
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6651
+ data
6652
+ );
6197
6653
  }
6198
6654
  /**
6199
6655
  * Update a modifier group's metadata or selection rules. Pass `status: 'archived'`
@@ -6203,7 +6659,7 @@ var BrainerceClient = class {
6203
6659
  async updateModifierGroup(storeId, groupId, data) {
6204
6660
  return this.adminRequest(
6205
6661
  "PATCH",
6206
- `/api/stores/${storeId}/modifier-groups/${groupId}`,
6662
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`,
6207
6663
  data
6208
6664
  );
6209
6665
  }
@@ -6214,7 +6670,10 @@ var BrainerceClient = class {
6214
6670
  * Requires Admin mode (apiKey).
6215
6671
  */
6216
6672
  async deleteModifierGroup(storeId, groupId) {
6217
- await this.adminRequest("DELETE", `/api/stores/${storeId}/modifier-groups/${groupId}`);
6673
+ await this.adminRequest(
6674
+ "DELETE",
6675
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6676
+ );
6218
6677
  }
6219
6678
  /**
6220
6679
  * Create a modifier inside a group (e.g., "Olives" inside the "Toppings" group).
@@ -6238,7 +6697,7 @@ var BrainerceClient = class {
6238
6697
  async createModifier(storeId, groupId, data) {
6239
6698
  return this.adminRequest(
6240
6699
  "POST",
6241
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers`,
6700
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers`,
6242
6701
  data
6243
6702
  );
6244
6703
  }
@@ -6249,7 +6708,7 @@ var BrainerceClient = class {
6249
6708
  async updateModifier(storeId, groupId, modifierId, data) {
6250
6709
  return this.adminRequest(
6251
6710
  "PATCH",
6252
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`,
6711
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`,
6253
6712
  data
6254
6713
  );
6255
6714
  }
@@ -6261,7 +6720,7 @@ var BrainerceClient = class {
6261
6720
  async deleteModifier(storeId, groupId, modifierId) {
6262
6721
  await this.adminRequest(
6263
6722
  "DELETE",
6264
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`
6723
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`
6265
6724
  );
6266
6725
  }
6267
6726
  /**
@@ -6280,7 +6739,7 @@ var BrainerceClient = class {
6280
6739
  async toggleModifierAvailability(storeId, groupId, modifierId, available) {
6281
6740
  return this.adminRequest(
6282
6741
  "POST",
6283
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}/availability-toggle`,
6742
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}/availability-toggle`,
6284
6743
  { available }
6285
6744
  );
6286
6745
  }
@@ -6301,7 +6760,7 @@ var BrainerceClient = class {
6301
6760
  async attachModifierGroup(storeId, productId, data) {
6302
6761
  return this.adminRequest(
6303
6762
  "POST",
6304
- `/api/stores/${storeId}/products/${productId}/modifier-groups`,
6763
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups`,
6305
6764
  data
6306
6765
  );
6307
6766
  }
@@ -6314,7 +6773,7 @@ var BrainerceClient = class {
6314
6773
  async updateAttachment(storeId, productId, attachmentId, data) {
6315
6774
  return this.adminRequest(
6316
6775
  "PATCH",
6317
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`,
6776
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`,
6318
6777
  data
6319
6778
  );
6320
6779
  }
@@ -6325,7 +6784,7 @@ var BrainerceClient = class {
6325
6784
  async detachModifierGroup(storeId, productId, attachmentId) {
6326
6785
  await this.adminRequest(
6327
6786
  "DELETE",
6328
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`
6787
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`
6329
6788
  );
6330
6789
  }
6331
6790
  // -------------------- Shipping: Zones and Rates (Admin) --------------------
@@ -6347,7 +6806,10 @@ var BrainerceClient = class {
6347
6806
  * Requires Admin mode (apiKey)
6348
6807
  */
6349
6808
  async getShippingZone(zoneId) {
6350
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}`);
6809
+ return this.adminRequest(
6810
+ "GET",
6811
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`
6812
+ );
6351
6813
  }
6352
6814
  /**
6353
6815
  * Create a new shipping zone
@@ -6370,21 +6832,28 @@ var BrainerceClient = class {
6370
6832
  * Requires Admin mode (apiKey)
6371
6833
  */
6372
6834
  async updateShippingZone(zoneId, data) {
6373
- return this.adminRequest("PATCH", `/api/v1/shipping/zones/${zoneId}`, data);
6835
+ return this.adminRequest(
6836
+ "PATCH",
6837
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`,
6838
+ data
6839
+ );
6374
6840
  }
6375
6841
  /**
6376
6842
  * Delete a shipping zone
6377
6843
  * Requires Admin mode (apiKey)
6378
6844
  */
6379
6845
  async deleteShippingZone(zoneId) {
6380
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}`);
6846
+ await this.adminRequest("DELETE", `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`);
6381
6847
  }
6382
6848
  /**
6383
6849
  * Get all shipping rates for a zone
6384
6850
  * Requires Admin mode (apiKey)
6385
6851
  */
6386
6852
  async getZoneShippingRates(zoneId) {
6387
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}/rates`);
6853
+ return this.adminRequest(
6854
+ "GET",
6855
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`
6856
+ );
6388
6857
  }
6389
6858
  /**
6390
6859
  * Create a new shipping rate for a zone
@@ -6404,7 +6873,7 @@ var BrainerceClient = class {
6404
6873
  async createZoneShippingRate(zoneId, data) {
6405
6874
  return this.adminRequest(
6406
6875
  "POST",
6407
- `/api/v1/shipping/zones/${zoneId}/rates`,
6876
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`,
6408
6877
  data
6409
6878
  );
6410
6879
  }
@@ -6415,7 +6884,7 @@ var BrainerceClient = class {
6415
6884
  async updateZoneShippingRate(zoneId, rateId, data) {
6416
6885
  return this.adminRequest(
6417
6886
  "PATCH",
6418
- `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`,
6887
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`,
6419
6888
  data
6420
6889
  );
6421
6890
  }
@@ -6424,7 +6893,149 @@ var BrainerceClient = class {
6424
6893
  * Requires Admin mode (apiKey)
6425
6894
  */
6426
6895
  async deleteZoneShippingRate(zoneId, rateId) {
6427
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`);
6896
+ await this.adminRequest(
6897
+ "DELETE",
6898
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`
6899
+ );
6900
+ }
6901
+ // -------------------- Regions (Admin mode, apiKey) --------------------
6902
+ // Multi-region commerce. storeId is derived from the api_key — do not pass it.
6903
+ // Requires the `regions:read` / `regions:write` scopes on the key.
6904
+ /** List the store's regions (paginated). */
6905
+ async getRegions() {
6906
+ return this.adminRequest("GET", "/api/v1/regions");
6907
+ }
6908
+ async getRegion(regionId) {
6909
+ return this.adminRequest("GET", `/api/v1/regions/${encodePathSegment(regionId)}`);
6910
+ }
6911
+ async createRegion(data) {
6912
+ return this.adminRequest("POST", "/api/v1/regions", data);
6913
+ }
6914
+ async updateRegion(regionId, data) {
6915
+ return this.adminRequest(
6916
+ "PATCH",
6917
+ `/api/v1/regions/${encodePathSegment(regionId)}`,
6918
+ data
6919
+ );
6920
+ }
6921
+ async deleteRegion(regionId) {
6922
+ await this.adminRequest("DELETE", `/api/v1/regions/${encodePathSegment(regionId)}`);
6923
+ }
6924
+ async setDefaultRegion(regionId) {
6925
+ return this.adminRequest(
6926
+ "PATCH",
6927
+ `/api/v1/regions/${encodePathSegment(regionId)}/set-default`
6928
+ );
6929
+ }
6930
+ /** Replace the region's enabled payment providers (AppInstallation IDs). */
6931
+ async updateRegionPaymentProviders(regionId, providerIds) {
6932
+ return this.adminRequest(
6933
+ "PUT",
6934
+ `/api/v1/regions/${encodePathSegment(regionId)}/payment-providers`,
6935
+ { providerIds }
6936
+ );
6937
+ }
6938
+ async addRegionCountries(regionId, countries) {
6939
+ return this.adminRequest(
6940
+ "POST",
6941
+ `/api/v1/regions/${encodePathSegment(regionId)}/countries`,
6942
+ { countries }
6943
+ );
6944
+ }
6945
+ async removeRegionCountry(regionId, countryCode) {
6946
+ return this.adminRequest(
6947
+ "DELETE",
6948
+ `/api/v1/regions/${encodePathSegment(regionId)}/countries/${encodePathSegment(countryCode)}`
6949
+ );
6950
+ }
6951
+ /** Installed payment providers compatible with this region's countries. */
6952
+ async getRegionCompatibleProviders(regionId) {
6953
+ return this.adminRequest(
6954
+ "GET",
6955
+ `/api/v1/regions/${encodePathSegment(regionId)}/compatible-providers`
6956
+ );
6957
+ }
6958
+ // -------------------- Regions (Storefront mode, public — no apiKey) --------------------
6959
+ // storeId-based, no auth. Call these from a storefront to detect the buyer's
6960
+ // region (story S1), then pair with detectRegion(). Admin/api-key callers use
6961
+ // getRegions()/getRegion() instead.
6962
+ /**
6963
+ * List the store's ACTIVE regions (public, no apiKey). Requires storeId mode.
6964
+ * Returns only storefront-safe fields (no internal flags). Default region first.
6965
+ */
6966
+ async getStoreRegions() {
6967
+ return this.storefrontRequest("GET", "/regions");
6968
+ }
6969
+ /**
6970
+ * Get one active public region plus its enabled payment providers (public).
6971
+ * Requires storeId mode. Throws 404 if the region is inactive or not found.
6972
+ */
6973
+ async getStoreRegion(regionId) {
6974
+ return this.storefrontRequest(
6975
+ "GET",
6976
+ `/regions/${encodePathSegment(regionId)}`
6977
+ );
6978
+ }
6979
+ /**
6980
+ * Client-side region detection — no network call. Returns the region whose
6981
+ * `countries` includes `country`, else the default region, else null.
6982
+ */
6983
+ detectRegion(country, regions) {
6984
+ const code = country.toUpperCase();
6985
+ return regions.find((r) => r.countries.includes(code)) ?? regions.find((r) => r.isDefault) ?? null;
6986
+ }
6987
+ // -------------------- Tax Classes (Storefront mode, public — no apiKey) --------------------
6988
+ /**
6989
+ * List the store's tax classes (public, no apiKey — storeId mode). Storefront-
6990
+ * safe fields only (id/name/slug/description/isDefault) for transparency UIs
6991
+ * such as a "9% VAT" badge. Admin/api-key callers use getTaxClasses().
6992
+ */
6993
+ async getStoreTaxClasses() {
6994
+ return this.storefrontRequest("GET", "/tax-classes");
6995
+ }
6996
+ // -------------------- Tax Classes (Admin mode, apiKey) --------------------
6997
+ // Requires the `tax-classes:read` / `tax-classes:write` scopes on the key.
6998
+ /** List the store's tax classes. */
6999
+ async getTaxClasses() {
7000
+ return this.adminRequest("GET", "/api/v1/tax-classes");
7001
+ }
7002
+ /** Get a tax class with its dependent counts (products/variants/categories/rates). */
7003
+ async getTaxClass(id) {
7004
+ return this.adminRequest("GET", `/api/v1/tax-classes/${encodePathSegment(id)}`);
7005
+ }
7006
+ async createTaxClass(data) {
7007
+ return this.adminRequest("POST", "/api/v1/tax-classes", data);
7008
+ }
7009
+ async updateTaxClass(id, data) {
7010
+ return this.adminRequest(
7011
+ "PATCH",
7012
+ `/api/v1/tax-classes/${encodePathSegment(id)}`,
7013
+ data
7014
+ );
7015
+ }
7016
+ async deleteTaxClass(id) {
7017
+ await this.adminRequest("DELETE", `/api/v1/tax-classes/${encodePathSegment(id)}`);
7018
+ }
7019
+ async setDefaultTaxClass(id) {
7020
+ return this.adminRequest(
7021
+ "PATCH",
7022
+ `/api/v1/tax-classes/${encodePathSegment(id)}/set-default`
7023
+ );
7024
+ }
7025
+ /** Bulk-assign this tax class to products / variants / categories. */
7026
+ async assignTaxClass(id, data) {
7027
+ return this.adminRequest(
7028
+ "POST",
7029
+ `/api/v1/tax-classes/${encodePathSegment(id)}/assign`,
7030
+ data
7031
+ );
7032
+ }
7033
+ /** Merge this tax class into another, moving all FKs, then delete it. */
7034
+ async mergeTaxClasses(id, targetId) {
7035
+ await this.adminRequest(
7036
+ "POST",
7037
+ `/api/v1/tax-classes/${encodePathSegment(id)}/merge-into/${encodePathSegment(targetId)}`
7038
+ );
6428
7039
  }
6429
7040
  // -------------------- Tax: Rates --------------------
6430
7041
  // These methods require Admin mode (apiKey)
@@ -6440,7 +7051,7 @@ var BrainerceClient = class {
6440
7051
  * Requires Admin mode (apiKey)
6441
7052
  */
6442
7053
  async getTaxRate(rateId) {
6443
- return this.adminRequest("GET", `/api/v1/tax/rates/${rateId}`);
7054
+ return this.adminRequest("GET", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6444
7055
  }
6445
7056
  /**
6446
7057
  * Create a new tax rate
@@ -6465,14 +7076,18 @@ var BrainerceClient = class {
6465
7076
  * Requires Admin mode (apiKey)
6466
7077
  */
6467
7078
  async updateTaxRate(rateId, data) {
6468
- return this.adminRequest("PATCH", `/api/v1/tax/rates/${rateId}`, data);
7079
+ return this.adminRequest(
7080
+ "PATCH",
7081
+ `/api/v1/tax/rates/${encodePathSegment(rateId)}`,
7082
+ data
7083
+ );
6469
7084
  }
6470
7085
  /**
6471
7086
  * Delete a tax rate
6472
7087
  * Requires Admin mode (apiKey)
6473
7088
  */
6474
7089
  async deleteTaxRate(rateId) {
6475
- await this.adminRequest("DELETE", `/api/v1/tax/rates/${rateId}`);
7090
+ await this.adminRequest("DELETE", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6476
7091
  }
6477
7092
  // -------------------- Metafields: Definitions --------------------
6478
7093
  // These methods require Admin mode (apiKey)
@@ -6528,7 +7143,7 @@ var BrainerceClient = class {
6528
7143
  async getMetafieldDefinition(definitionId) {
6529
7144
  return this.adminRequest(
6530
7145
  "GET",
6531
- `/api/v1/metafield-definitions/${definitionId}`
7146
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
6532
7147
  );
6533
7148
  }
6534
7149
  /**
@@ -6555,7 +7170,7 @@ var BrainerceClient = class {
6555
7170
  async updateMetafieldDefinition(definitionId, data) {
6556
7171
  return this.adminRequest(
6557
7172
  "PATCH",
6558
- `/api/v1/metafield-definitions/${definitionId}`,
7173
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`,
6559
7174
  data
6560
7175
  );
6561
7176
  }
@@ -6564,7 +7179,10 @@ var BrainerceClient = class {
6564
7179
  * Requires Admin mode (apiKey)
6565
7180
  */
6566
7181
  async deleteMetafieldDefinition(definitionId) {
6567
- await this.adminRequest("DELETE", `/api/v1/metafield-definitions/${definitionId}`);
7182
+ await this.adminRequest(
7183
+ "DELETE",
7184
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
7185
+ );
6568
7186
  }
6569
7187
  /**
6570
7188
  * Replace the platform publishing configuration on a metafield definition.
@@ -6588,7 +7206,7 @@ var BrainerceClient = class {
6588
7206
  async setMetafieldPlatforms(definitionId, data) {
6589
7207
  return this.adminRequest(
6590
7208
  "PUT",
6591
- `/api/v1/metafield-definitions/${definitionId}/platforms`,
7209
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/platforms`,
6592
7210
  data
6593
7211
  );
6594
7212
  }
@@ -6607,7 +7225,7 @@ var BrainerceClient = class {
6607
7225
  async publishMetafieldDefinitionToVibeCodedSite(definitionId, vibeCodedConnectionId) {
6608
7226
  return this.adminRequest(
6609
7227
  "POST",
6610
- `/api/v1/metafield-definitions/${definitionId}/publish-vibe-coded`,
7228
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/publish-vibe-coded`,
6611
7229
  { vibeCodedConnectionId }
6612
7230
  );
6613
7231
  }
@@ -6615,7 +7233,7 @@ var BrainerceClient = class {
6615
7233
  async unpublishMetafieldDefinitionFromVibeCodedSite(definitionId, vibeCodedConnectionId) {
6616
7234
  return this.adminRequest(
6617
7235
  "POST",
6618
- `/api/v1/metafield-definitions/${definitionId}/unpublish-vibe-coded`,
7236
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/unpublish-vibe-coded`,
6619
7237
  { vibeCodedConnectionId }
6620
7238
  );
6621
7239
  }
@@ -6623,7 +7241,7 @@ var BrainerceClient = class {
6623
7241
  async publishCategoryToVibeCodedSite(categoryId, vibeCodedConnectionId) {
6624
7242
  return this.adminRequest(
6625
7243
  "POST",
6626
- `/api/v1/categories/${categoryId}/publish-vibe-coded`,
7244
+ `/api/v1/categories/${encodePathSegment(categoryId)}/publish-vibe-coded`,
6627
7245
  { vibeCodedConnectionId }
6628
7246
  );
6629
7247
  }
@@ -6631,7 +7249,7 @@ var BrainerceClient = class {
6631
7249
  async unpublishCategoryFromVibeCodedSite(categoryId, vibeCodedConnectionId) {
6632
7250
  return this.adminRequest(
6633
7251
  "POST",
6634
- `/api/v1/categories/${categoryId}/unpublish-vibe-coded`,
7252
+ `/api/v1/categories/${encodePathSegment(categoryId)}/unpublish-vibe-coded`,
6635
7253
  { vibeCodedConnectionId }
6636
7254
  );
6637
7255
  }
@@ -6639,7 +7257,7 @@ var BrainerceClient = class {
6639
7257
  async publishTagToVibeCodedSite(tagId, vibeCodedConnectionId) {
6640
7258
  return this.adminRequest(
6641
7259
  "POST",
6642
- `/api/v1/tags/${tagId}/publish-vibe-coded`,
7260
+ `/api/v1/tags/${encodePathSegment(tagId)}/publish-vibe-coded`,
6643
7261
  { vibeCodedConnectionId }
6644
7262
  );
6645
7263
  }
@@ -6647,7 +7265,7 @@ var BrainerceClient = class {
6647
7265
  async unpublishTagFromVibeCodedSite(tagId, vibeCodedConnectionId) {
6648
7266
  return this.adminRequest(
6649
7267
  "POST",
6650
- `/api/v1/tags/${tagId}/unpublish-vibe-coded`,
7268
+ `/api/v1/tags/${encodePathSegment(tagId)}/unpublish-vibe-coded`,
6651
7269
  { vibeCodedConnectionId }
6652
7270
  );
6653
7271
  }
@@ -6655,7 +7273,7 @@ var BrainerceClient = class {
6655
7273
  async publishBrandToVibeCodedSite(brandId, vibeCodedConnectionId) {
6656
7274
  return this.adminRequest(
6657
7275
  "POST",
6658
- `/api/v1/brands/${brandId}/publish-vibe-coded`,
7276
+ `/api/v1/brands/${encodePathSegment(brandId)}/publish-vibe-coded`,
6659
7277
  { vibeCodedConnectionId }
6660
7278
  );
6661
7279
  }
@@ -6663,7 +7281,7 @@ var BrainerceClient = class {
6663
7281
  async unpublishBrandFromVibeCodedSite(brandId, vibeCodedConnectionId) {
6664
7282
  return this.adminRequest(
6665
7283
  "POST",
6666
- `/api/v1/brands/${brandId}/unpublish-vibe-coded`,
7284
+ `/api/v1/brands/${encodePathSegment(brandId)}/unpublish-vibe-coded`,
6667
7285
  { vibeCodedConnectionId }
6668
7286
  );
6669
7287
  }
@@ -6689,7 +7307,7 @@ var BrainerceClient = class {
6689
7307
  async setDefinitionProducts(definitionId, data) {
6690
7308
  return this.adminRequest(
6691
7309
  "PATCH",
6692
- `/api/v1/metafield-definitions/${definitionId}/products`,
7310
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/products`,
6693
7311
  data
6694
7312
  );
6695
7313
  }
@@ -6702,7 +7320,7 @@ var BrainerceClient = class {
6702
7320
  async getProductMetafields(productId) {
6703
7321
  return this.adminRequest(
6704
7322
  "GET",
6705
- `/api/v1/products/${productId}/metafields`
7323
+ `/api/v1/products/${encodePathSegment(productId)}/metafields`
6706
7324
  );
6707
7325
  }
6708
7326
  /**
@@ -6719,7 +7337,7 @@ var BrainerceClient = class {
6719
7337
  async setProductMetafield(productId, definitionId, data) {
6720
7338
  return this.adminRequest(
6721
7339
  "PUT",
6722
- `/api/v1/products/${productId}/metafields/${definitionId}`,
7340
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`,
6723
7341
  data
6724
7342
  );
6725
7343
  }
@@ -6730,7 +7348,7 @@ var BrainerceClient = class {
6730
7348
  async deleteProductMetafield(productId, definitionId) {
6731
7349
  await this.adminRequest(
6732
7350
  "DELETE",
6733
- `/api/v1/products/${productId}/metafields/${definitionId}`
7351
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`
6734
7352
  );
6735
7353
  }
6736
7354
  // -------------------- Product Customization Fields (Admin) --------------------
@@ -6741,7 +7359,7 @@ var BrainerceClient = class {
6741
7359
  async getProductCustomizationFields(productId) {
6742
7360
  return this.adminRequest(
6743
7361
  "GET",
6744
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`
7362
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`
6745
7363
  );
6746
7364
  }
6747
7365
  /**
@@ -6752,7 +7370,7 @@ var BrainerceClient = class {
6752
7370
  async setProductCustomizationFields(productId, definitionIds) {
6753
7371
  return this.adminRequest(
6754
7372
  "PATCH",
6755
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`,
7373
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`,
6756
7374
  { definitionIds }
6757
7375
  );
6758
7376
  }
@@ -6832,26 +7450,33 @@ var BrainerceClient = class {
6832
7450
  async resendTeamInvitation(invitationId) {
6833
7451
  return this.adminRequest(
6834
7452
  "POST",
6835
- `/api/v1/team/invitations/${invitationId}/resend`
7453
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}/resend`
6836
7454
  );
6837
7455
  }
6838
7456
  /**
6839
7457
  * @deprecated Use `revokeStoreInvitation(storeId, invitationId)` instead.
6840
7458
  */
6841
7459
  async revokeTeamInvitation(invitationId) {
6842
- await this.adminRequest("DELETE", `/api/v1/team/invitations/${invitationId}`);
7460
+ await this.adminRequest(
7461
+ "DELETE",
7462
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}`
7463
+ );
6843
7464
  }
6844
7465
  /**
6845
7466
  * @deprecated Use `updateStoreMember(storeId, memberId, data)` instead.
6846
7467
  */
6847
7468
  async updateTeamMemberRole(memberId, data) {
6848
- return this.adminRequest("PATCH", `/api/v1/team/members/${memberId}/role`, data);
7469
+ return this.adminRequest(
7470
+ "PATCH",
7471
+ `/api/v1/team/members/${encodePathSegment(memberId)}/role`,
7472
+ data
7473
+ );
6849
7474
  }
6850
7475
  /**
6851
7476
  * @deprecated Use `removeStoreMember(storeId, memberId)` instead.
6852
7477
  */
6853
7478
  async removeTeamMember(memberId) {
6854
- await this.adminRequest("DELETE", `/api/v1/team/members/${memberId}`);
7479
+ await this.adminRequest("DELETE", `/api/v1/team/members/${encodePathSegment(memberId)}`);
6855
7480
  }
6856
7481
  // -------------------- Store Team Management (Admin) --------------------
6857
7482
  // Store-level team management. Each store has its own team with roles and permissions.
@@ -6865,7 +7490,10 @@ var BrainerceClient = class {
6865
7490
  * ```
6866
7491
  */
6867
7492
  async getStoreTeam(storeId) {
6868
- return this.adminRequest("GET", `/api/v1/stores/${storeId}/team`);
7493
+ return this.adminRequest(
7494
+ "GET",
7495
+ `/api/v1/stores/${encodePathSegment(storeId)}/team`
7496
+ );
6869
7497
  }
6870
7498
  /**
6871
7499
  * Invite a new member to a store
@@ -6876,13 +7504,16 @@ var BrainerceClient = class {
6876
7504
  * const invitation = await client.inviteStoreMember('store_id', {
6877
7505
  * email: 'newmember@example.com',
6878
7506
  * role: 'MANAGER', // 'MANAGER' | 'STAFF' | 'VIEWER'
7507
+ * // Optional: restrict to specific vibe-coded channels (connectionId, vc_*).
7508
+ * // Omit or pass [] for unrestricted access to all channels.
7509
+ * salesChannelIds: ['vc_abc123', 'vc_def456'],
6879
7510
  * });
6880
7511
  * ```
6881
7512
  */
6882
7513
  async inviteStoreMember(storeId, data) {
6883
7514
  return this.adminRequest(
6884
7515
  "POST",
6885
- `/api/v1/stores/${storeId}/team/invite`,
7516
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invite`,
6886
7517
  data
6887
7518
  );
6888
7519
  }
@@ -6904,7 +7535,33 @@ var BrainerceClient = class {
6904
7535
  async updateStoreMember(storeId, memberId, data) {
6905
7536
  return this.adminRequest(
6906
7537
  "PATCH",
6907
- `/api/v1/stores/${storeId}/team/${memberId}`,
7538
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`,
7539
+ data
7540
+ );
7541
+ }
7542
+ /**
7543
+ * Replace the set of vibe-coded sales channels a store member is restricted to.
7544
+ * Channels are identified by their public `connectionId` (`vc_*` format). Pass
7545
+ * an empty array to clear all restrictions (member becomes unrestricted).
7546
+ * Requires Admin mode (apiKey) and MANAGE_TEAM permission
7547
+ *
7548
+ * @example
7549
+ * ```typescript
7550
+ * // Restrict to two vibe-coded channels
7551
+ * await client.updateStoreMemberSalesChannels('store_id', 'member_id', {
7552
+ * salesChannelIds: ['vc_abc123', 'vc_def456'],
7553
+ * });
7554
+ *
7555
+ * // Clear all restrictions (unrestricted access)
7556
+ * await client.updateStoreMemberSalesChannels('store_id', 'member_id', {
7557
+ * salesChannelIds: [],
7558
+ * });
7559
+ * ```
7560
+ */
7561
+ async updateStoreMemberSalesChannels(storeId, memberId, data) {
7562
+ return this.adminRequest(
7563
+ "PATCH",
7564
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}/sales-channels`,
6908
7565
  data
6909
7566
  );
6910
7567
  }
@@ -6913,7 +7570,10 @@ var BrainerceClient = class {
6913
7570
  * Requires Admin mode (apiKey) and MANAGE_TEAM permission
6914
7571
  */
6915
7572
  async removeStoreMember(storeId, memberId) {
6916
- await this.adminRequest("DELETE", `/api/v1/stores/${storeId}/team/${memberId}`);
7573
+ await this.adminRequest(
7574
+ "DELETE",
7575
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`
7576
+ );
6917
7577
  }
6918
7578
  /**
6919
7579
  * Resend a store invitation email
@@ -6922,7 +7582,7 @@ var BrainerceClient = class {
6922
7582
  async resendStoreInvitation(storeId, invitationId) {
6923
7583
  return this.adminRequest(
6924
7584
  "POST",
6925
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}/resend`
7585
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}/resend`
6926
7586
  );
6927
7587
  }
6928
7588
  /**
@@ -6932,7 +7592,7 @@ var BrainerceClient = class {
6932
7592
  async revokeStoreInvitation(storeId, invitationId) {
6933
7593
  await this.adminRequest(
6934
7594
  "DELETE",
6935
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}`
7595
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}`
6936
7596
  );
6937
7597
  }
6938
7598
  /**
@@ -6940,14 +7600,20 @@ var BrainerceClient = class {
6940
7600
  * Used on the invitation acceptance page
6941
7601
  */
6942
7602
  async getStoreInvitationByToken(token) {
6943
- return this.request("GET", `/api/v1/store-invitations/${token}`);
7603
+ return this.request(
7604
+ "GET",
7605
+ `/api/v1/store-invitations/${encodePathSegment(token)}`
7606
+ );
6944
7607
  }
6945
7608
  /**
6946
7609
  * Accept a store invitation
6947
7610
  * Requires Admin mode (apiKey)
6948
7611
  */
6949
7612
  async acceptStoreInvitation(token) {
6950
- await this.adminRequest("POST", `/api/v1/store-invitations/${token}/accept`);
7613
+ await this.adminRequest(
7614
+ "POST",
7615
+ `/api/v1/store-invitations/${encodePathSegment(token)}/accept`
7616
+ );
6951
7617
  }
6952
7618
  /**
6953
7619
  * Get all stores accessible to the current user (owned + member of)
@@ -6980,7 +7646,7 @@ var BrainerceClient = class {
6980
7646
  async getMyStorePermissions(storeId) {
6981
7647
  return this.adminRequest(
6982
7648
  "GET",
6983
- `/api/v1/me/stores/${storeId}/permissions`
7649
+ `/api/v1/me/stores/${encodePathSegment(storeId)}/permissions`
6984
7650
  );
6985
7651
  }
6986
7652
  // -------------------- Email Settings & Templates (Admin) --------------------
@@ -7013,7 +7679,10 @@ var BrainerceClient = class {
7013
7679
  * Requires Admin mode (apiKey)
7014
7680
  */
7015
7681
  async getEmailTemplate(templateId) {
7016
- return this.adminRequest("GET", `/api/v1/email/templates/${templateId}`);
7682
+ return this.adminRequest(
7683
+ "GET",
7684
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7685
+ );
7017
7686
  }
7018
7687
  /**
7019
7688
  * Create a new email template
@@ -7037,14 +7706,21 @@ var BrainerceClient = class {
7037
7706
  * Requires Admin mode (apiKey)
7038
7707
  */
7039
7708
  async updateEmailTemplate(templateId, data) {
7040
- return this.adminRequest("PUT", `/api/v1/email/templates/${templateId}`, data);
7709
+ return this.adminRequest(
7710
+ "PUT",
7711
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`,
7712
+ data
7713
+ );
7041
7714
  }
7042
7715
  /**
7043
7716
  * Delete an email template
7044
7717
  * Requires Admin mode (apiKey)
7045
7718
  */
7046
7719
  async deleteEmailTemplate(templateId) {
7047
- await this.adminRequest("DELETE", `/api/v1/email/templates/${templateId}`);
7720
+ await this.adminRequest(
7721
+ "DELETE",
7722
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7723
+ );
7048
7724
  }
7049
7725
  /**
7050
7726
  * Preview an email template with sample data
@@ -7053,7 +7729,7 @@ var BrainerceClient = class {
7053
7729
  async previewEmailTemplate(templateId, data) {
7054
7730
  return this.adminRequest(
7055
7731
  "POST",
7056
- `/api/v1/email/templates/${templateId}/preview`,
7732
+ `/api/v1/email/templates/${encodePathSegment(templateId)}/preview`,
7057
7733
  data || {}
7058
7734
  );
7059
7735
  }
@@ -7074,9 +7750,13 @@ var BrainerceClient = class {
7074
7750
  * @param resolution - 'MERGE' to link to existing product, 'CREATE_NEW' to create new product
7075
7751
  */
7076
7752
  async resolveSyncConflict(conflictId, resolution) {
7077
- return this.adminRequest("POST", `/api/v1/sync-conflicts/${conflictId}/resolve`, {
7078
- resolution
7079
- });
7753
+ return this.adminRequest(
7754
+ "POST",
7755
+ `/api/v1/sync-conflicts/${encodePathSegment(conflictId)}/resolve`,
7756
+ {
7757
+ resolution
7758
+ }
7759
+ );
7080
7760
  }
7081
7761
  // -------------------- Metafield Conflicts (Admin) --------------------
7082
7762
  // These methods require Admin mode (apiKey)
@@ -7097,7 +7777,7 @@ var BrainerceClient = class {
7097
7777
  async resolveMetafieldConflict(conflictId, data) {
7098
7778
  return this.adminRequest(
7099
7779
  "POST",
7100
- `/api/v1/metafield-conflicts/${conflictId}/resolve`,
7780
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/resolve`,
7101
7781
  data
7102
7782
  );
7103
7783
  }
@@ -7108,7 +7788,7 @@ var BrainerceClient = class {
7108
7788
  async ignoreMetafieldConflict(conflictId) {
7109
7789
  return this.adminRequest(
7110
7790
  "POST",
7111
- `/api/v1/metafield-conflicts/${conflictId}/ignore`
7791
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/ignore`
7112
7792
  );
7113
7793
  }
7114
7794
  // -------------------- OAuth Provider Configuration (Admin) --------------------
@@ -7125,7 +7805,10 @@ var BrainerceClient = class {
7125
7805
  * Requires Admin mode (apiKey)
7126
7806
  */
7127
7807
  async getOAuthProvider(provider) {
7128
- return this.adminRequest("GET", `/api/v1/oauth-providers/${provider}`);
7808
+ return this.adminRequest(
7809
+ "GET",
7810
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7811
+ );
7129
7812
  }
7130
7813
  /**
7131
7814
  * Configure an OAuth provider for customer login
@@ -7151,7 +7834,7 @@ var BrainerceClient = class {
7151
7834
  async updateOAuthProvider(provider, data) {
7152
7835
  return this.adminRequest(
7153
7836
  "PATCH",
7154
- `/api/v1/oauth-providers/${provider}`,
7837
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`,
7155
7838
  data
7156
7839
  );
7157
7840
  }
@@ -7160,7 +7843,10 @@ var BrainerceClient = class {
7160
7843
  * Requires Admin mode (apiKey)
7161
7844
  */
7162
7845
  async deleteOAuthProvider(provider) {
7163
- await this.adminRequest("DELETE", `/api/v1/oauth-providers/${provider}`);
7846
+ await this.adminRequest(
7847
+ "DELETE",
7848
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7849
+ );
7164
7850
  }
7165
7851
  };
7166
7852
  var BrainerceError = class extends Error {
@@ -7257,7 +7943,7 @@ var ALLOWED_PAYMENT_HOSTS = [
7257
7943
  // Brainerce-hosted payment embeds (backend payment-embed proxy at
7258
7944
  // `/api/payment/embed/...` that fronts provider apps' embed shells —
7259
7945
  // e.g. cardcom-payments OpenFields wrapper). The match also covers
7260
- // subdomains like `api.brainerce.com`, `staging.brainerce.com`.
7946
+ // every brainerce.com subdomain (api., docs., …).
7261
7947
  "brainerce.com"
7262
7948
  ];
7263
7949
  function isAllowedPaymentUrl(url, options) {
@@ -7376,7 +8062,9 @@ function getProductPriceInfo(product) {
7376
8062
  if (!product) {
7377
8063
  return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
7378
8064
  }
7379
- const resolvedBasePrice = parseFloat(product.basePrice) === 0 && product.priceMin ? product.priceMin : product.basePrice;
8065
+ const parsedBase = parseFloat(product.basePrice);
8066
+ const baseIsUsable = typeof product.basePrice === "string" && product.basePrice.length > 0 && !isNaN(parsedBase) && parsedBase > 0;
8067
+ const resolvedBasePrice = !baseIsUsable && product.priceMin ? product.priceMin : product.basePrice;
7380
8068
  if (product.discount) {
7381
8069
  const ruleOriginal = parseFloat(product.discount.originalPrice) || 0;
7382
8070
  const ruleDiscounted = parseFloat(product.discount.discountedPrice) || 0;