brainerce 1.27.0 → 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.js CHANGED
@@ -193,6 +193,35 @@ function getDirectionForLocale(locale) {
193
193
  const primary = locale.split("-")[0].toLowerCase();
194
194
  return RTL_LOCALES.has(primary) ? "rtl" : "ltr";
195
195
  }
196
+ function encodePathSegment(value) {
197
+ let normalized = value;
198
+ try {
199
+ normalized = decodeURIComponent(value);
200
+ } catch {
201
+ normalized = value;
202
+ }
203
+ return encodeURIComponent(normalized);
204
+ }
205
+ var MAX_RETRY_AFTER_MS = 6e4;
206
+ function parseRetryAfterMs(response) {
207
+ const header = response.headers.get("retry-after");
208
+ if (!header) return null;
209
+ const trimmed = header.trim();
210
+ if (!trimmed) return null;
211
+ if (/^\d+$/.test(trimmed)) {
212
+ const seconds = parseInt(trimmed, 10);
213
+ if (!Number.isFinite(seconds) || seconds < 0) return null;
214
+ return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
215
+ }
216
+ const target = Date.parse(trimmed);
217
+ if (Number.isNaN(target)) return null;
218
+ const deltaMs = target - Date.now();
219
+ if (deltaMs <= 0) return 0;
220
+ return Math.min(deltaMs, MAX_RETRY_AFTER_MS);
221
+ }
222
+ function sleep(ms) {
223
+ return new Promise((resolve) => setTimeout(resolve, ms));
224
+ }
196
225
  var BrainerceClient = class {
197
226
  constructor(options) {
198
227
  this.customerToken = null;
@@ -408,7 +437,7 @@ var BrainerceClient = class {
408
437
  */
409
438
  getBySlug: async (slug, locale) => {
410
439
  const query = locale ? { locale } : void 0;
411
- const path = `/content/pages/by-slug/${encodeURIComponent(slug)}`;
440
+ const path = `/content/pages/by-slug/${encodePathSegment(slug)}`;
412
441
  const onNotFound = (err) => {
413
442
  if (err instanceof BrainerceError && err.statusCode === 404) return null;
414
443
  throw err;
@@ -626,7 +655,7 @@ var BrainerceClient = class {
626
655
  /**
627
656
  * Make a request to the Admin API (requires apiKey)
628
657
  */
629
- async adminRequest(method, path, body, queryParams) {
658
+ async adminRequest(method, path, body, queryParams, responseType = "json") {
630
659
  if (!this.apiKey) {
631
660
  throw new BrainerceError(
632
661
  "This operation requires an API key. Initialize with apiKey instead of storeId.",
@@ -641,52 +670,64 @@ var BrainerceClient = class {
641
670
  }
642
671
  });
643
672
  }
644
- const controller = new AbortController();
645
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
646
- try {
647
- const headers = {
648
- Authorization: `Bearer ${this.apiKey}`,
649
- "Content-Type": "application/json",
650
- "X-SDK-Version": SDK_VERSION,
651
- "ngrok-skip-browser-warning": "true"
652
- };
653
- if (this.origin) {
654
- headers["Origin"] = this.origin;
655
- }
656
- if (this.locale) {
657
- headers["Accept-Language"] = this.locale;
658
- }
659
- const response = await fetch(url.toString(), {
660
- method,
661
- headers,
662
- body: body ? JSON.stringify(body) : void 0,
663
- signal: controller.signal
664
- });
665
- clearTimeout(timeoutId);
666
- if (!response.ok) {
667
- const errorData = await response.json().catch(() => ({}));
668
- throw new BrainerceError(
669
- errorData.message || `Request failed with status ${response.status}`,
670
- response.status,
671
- errorData
672
- );
673
- }
674
- const text = await response.text();
675
- if (!text) return {};
676
- return JSON.parse(text);
677
- } catch (error) {
678
- clearTimeout(timeoutId);
679
- if (error instanceof BrainerceError) {
680
- throw error;
681
- }
682
- if (error instanceof Error) {
683
- if (error.name === "AbortError") {
684
- throw new BrainerceError("Request timeout", 408);
673
+ const headers = {
674
+ Authorization: `Bearer ${this.apiKey}`,
675
+ "Content-Type": "application/json",
676
+ "X-SDK-Version": SDK_VERSION,
677
+ "ngrok-skip-browser-warning": "true"
678
+ };
679
+ if (this.origin) {
680
+ headers["Origin"] = this.origin;
681
+ }
682
+ if (this.locale) {
683
+ headers["Accept-Language"] = this.locale;
684
+ }
685
+ for (let attempt = 0; attempt < 2; attempt++) {
686
+ const controller = new AbortController();
687
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
688
+ try {
689
+ const response = await fetch(url.toString(), {
690
+ method,
691
+ headers,
692
+ body: body ? JSON.stringify(body) : void 0,
693
+ signal: controller.signal
694
+ });
695
+ clearTimeout(timeoutId);
696
+ if (response.status === 429 && attempt === 0) {
697
+ const retryAfterMs = parseRetryAfterMs(response);
698
+ if (retryAfterMs !== null) {
699
+ await response.text().catch(() => void 0);
700
+ await sleep(retryAfterMs);
701
+ continue;
702
+ }
685
703
  }
686
- throw new BrainerceError(error.message, 0);
704
+ if (!response.ok) {
705
+ const errorData = await response.json().catch(() => ({}));
706
+ throw new BrainerceError(
707
+ errorData.message || `Request failed with status ${response.status}`,
708
+ response.status,
709
+ errorData
710
+ );
711
+ }
712
+ const text = await response.text();
713
+ if (responseType === "text") return text;
714
+ if (!text) return {};
715
+ return JSON.parse(text);
716
+ } catch (error) {
717
+ clearTimeout(timeoutId);
718
+ if (error instanceof BrainerceError) {
719
+ throw error;
720
+ }
721
+ if (error instanceof Error) {
722
+ if (error.name === "AbortError") {
723
+ throw new BrainerceError("Request timeout", 408);
724
+ }
725
+ throw new BrainerceError(error.message, 0);
726
+ }
727
+ throw new BrainerceError("Unknown error occurred", 0);
687
728
  }
688
- throw new BrainerceError("Unknown error occurred", 0);
689
729
  }
730
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
690
731
  }
691
732
  /**
692
733
  * Make a request to the Vibe-Coded API (public, uses connectionId)
@@ -695,7 +736,7 @@ var BrainerceClient = class {
695
736
  if (!this.connectionId) {
696
737
  throw new BrainerceError("connectionId is required for vibe-coded requests", 400);
697
738
  }
698
- const url = new URL(`${this.baseUrl}/api/vc/${this.connectionId}${path}`);
739
+ const url = new URL(`${this.baseUrl}/api/vc/${encodePathSegment(this.connectionId)}${path}`);
699
740
  if (queryParams) {
700
741
  Object.entries(queryParams).forEach(([key, value]) => {
701
742
  if (value !== void 0) {
@@ -703,70 +744,81 @@ var BrainerceClient = class {
703
744
  }
704
745
  });
705
746
  }
706
- const controller = new AbortController();
707
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
708
- try {
709
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
710
- const headers = {
711
- "X-SDK-Version": SDK_VERSION,
712
- "ngrok-skip-browser-warning": "true"
713
- };
714
- if (!isFormData) {
715
- headers["Content-Type"] = "application/json";
716
- }
717
- if (this.origin) {
718
- headers["Origin"] = this.origin;
719
- }
720
- if (this.locale) {
721
- headers["Accept-Language"] = this.locale;
722
- }
723
- if (headerOverrides) {
724
- Object.assign(headers, headerOverrides);
725
- }
726
- if (this.proxyMode && method !== "GET") {
727
- headers["X-Requested-With"] = "brainerce";
728
- }
729
- if (this.customerToken) {
730
- headers["Authorization"] = `Bearer ${this.customerToken}`;
731
- }
732
- const response = await fetch(url.toString(), {
733
- method,
734
- headers,
735
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
736
- signal: controller.signal
737
- });
738
- clearTimeout(timeoutId);
739
- if (!response.ok) {
740
- const errorData = await response.json().catch(() => ({}));
741
- if (response.status === 401 && this.onAuthError) {
742
- this.onAuthError({
743
- message: errorData.message || "Unauthorized",
744
- statusCode: 401,
745
- path
746
- });
747
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
748
+ const headers = {
749
+ "X-SDK-Version": SDK_VERSION,
750
+ "ngrok-skip-browser-warning": "true"
751
+ };
752
+ if (!isFormData) {
753
+ headers["Content-Type"] = "application/json";
754
+ }
755
+ if (this.origin) {
756
+ headers["Origin"] = this.origin;
757
+ }
758
+ if (this.locale) {
759
+ headers["Accept-Language"] = this.locale;
760
+ }
761
+ if (headerOverrides) {
762
+ Object.assign(headers, headerOverrides);
763
+ }
764
+ if (this.proxyMode && method !== "GET") {
765
+ headers["X-Requested-With"] = "brainerce";
766
+ }
767
+ if (this.customerToken) {
768
+ headers["Authorization"] = `Bearer ${this.customerToken}`;
769
+ }
770
+ for (let attempt = 0; attempt < 2; attempt++) {
771
+ const controller = new AbortController();
772
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
773
+ try {
774
+ const response = await fetch(url.toString(), {
775
+ method,
776
+ headers,
777
+ body: body ? isFormData ? body : JSON.stringify(body) : void 0,
778
+ signal: controller.signal
779
+ });
780
+ clearTimeout(timeoutId);
781
+ if (response.status === 429 && attempt === 0) {
782
+ const retryAfterMs = parseRetryAfterMs(response);
783
+ if (retryAfterMs !== null) {
784
+ await response.text().catch(() => void 0);
785
+ await sleep(retryAfterMs);
786
+ continue;
787
+ }
747
788
  }
748
- throw new BrainerceError(
749
- errorData.message || `Request failed with status ${response.status}`,
750
- response.status,
751
- errorData
752
- );
753
- }
754
- const text = await response.text();
755
- if (!text) return {};
756
- return JSON.parse(text);
757
- } catch (error) {
758
- clearTimeout(timeoutId);
759
- if (error instanceof BrainerceError) {
760
- throw error;
761
- }
762
- if (error instanceof Error) {
763
- if (error.name === "AbortError") {
764
- throw new BrainerceError("Request timeout", 408);
789
+ if (!response.ok) {
790
+ const errorData = await response.json().catch(() => ({}));
791
+ if (response.status === 401 && this.onAuthError) {
792
+ this.onAuthError({
793
+ message: errorData.message || "Unauthorized",
794
+ statusCode: 401,
795
+ path
796
+ });
797
+ }
798
+ throw new BrainerceError(
799
+ errorData.message || `Request failed with status ${response.status}`,
800
+ response.status,
801
+ errorData
802
+ );
765
803
  }
766
- throw new BrainerceError(error.message, 0);
804
+ const text = await response.text();
805
+ if (!text) return {};
806
+ return JSON.parse(text);
807
+ } catch (error) {
808
+ clearTimeout(timeoutId);
809
+ if (error instanceof BrainerceError) {
810
+ throw error;
811
+ }
812
+ if (error instanceof Error) {
813
+ if (error.name === "AbortError") {
814
+ throw new BrainerceError("Request timeout", 408);
815
+ }
816
+ throw new BrainerceError(error.message, 0);
817
+ }
818
+ throw new BrainerceError("Unknown error occurred", 0);
767
819
  }
768
- throw new BrainerceError("Unknown error occurred", 0);
769
820
  }
821
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
770
822
  }
771
823
  /**
772
824
  * Make a request to the Storefront API (public, uses storeId)
@@ -775,7 +827,7 @@ var BrainerceClient = class {
775
827
  if (!this.storeId) {
776
828
  throw new BrainerceError("storeId is required for storefront requests", 400);
777
829
  }
778
- const url = new URL(`${this.baseUrl}/stores/${this.storeId}${path}`);
830
+ const url = new URL(`${this.baseUrl}/stores/${encodePathSegment(this.storeId)}${path}`);
779
831
  if (queryParams) {
780
832
  Object.entries(queryParams).forEach(([key, value]) => {
781
833
  if (value !== void 0) {
@@ -783,67 +835,78 @@ var BrainerceClient = class {
783
835
  }
784
836
  });
785
837
  }
786
- const controller = new AbortController();
787
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
788
- try {
789
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
790
- const headers = {
791
- "X-SDK-Version": SDK_VERSION,
792
- "ngrok-skip-browser-warning": "true"
793
- };
794
- if (!isFormData) {
795
- headers["Content-Type"] = "application/json";
796
- }
797
- if (this.origin) {
798
- headers["Origin"] = this.origin;
799
- }
800
- if (this.locale) {
801
- headers["Accept-Language"] = this.locale;
802
- }
803
- if (headerOverrides) {
804
- Object.assign(headers, headerOverrides);
805
- }
806
- if (this.customerToken) {
807
- headers["Authorization"] = `Bearer ${this.customerToken}`;
808
- }
809
- const response = await fetch(url.toString(), {
810
- method,
811
- headers,
812
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
813
- signal: controller.signal
814
- });
815
- clearTimeout(timeoutId);
816
- if (!response.ok) {
817
- const errorData = await response.json().catch(() => ({}));
818
- if (response.status === 401 && this.onAuthError) {
819
- this.onAuthError({
820
- message: errorData.message || "Unauthorized",
821
- statusCode: 401,
822
- path
823
- });
838
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
839
+ const headers = {
840
+ "X-SDK-Version": SDK_VERSION,
841
+ "ngrok-skip-browser-warning": "true"
842
+ };
843
+ if (!isFormData) {
844
+ headers["Content-Type"] = "application/json";
845
+ }
846
+ if (this.origin) {
847
+ headers["Origin"] = this.origin;
848
+ }
849
+ if (this.locale) {
850
+ headers["Accept-Language"] = this.locale;
851
+ }
852
+ if (headerOverrides) {
853
+ Object.assign(headers, headerOverrides);
854
+ }
855
+ if (this.customerToken) {
856
+ headers["Authorization"] = `Bearer ${this.customerToken}`;
857
+ }
858
+ for (let attempt = 0; attempt < 2; attempt++) {
859
+ const controller = new AbortController();
860
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
861
+ try {
862
+ const response = await fetch(url.toString(), {
863
+ method,
864
+ headers,
865
+ body: body ? isFormData ? body : JSON.stringify(body) : void 0,
866
+ signal: controller.signal
867
+ });
868
+ clearTimeout(timeoutId);
869
+ if (response.status === 429 && attempt === 0) {
870
+ const retryAfterMs = parseRetryAfterMs(response);
871
+ if (retryAfterMs !== null) {
872
+ await response.text().catch(() => void 0);
873
+ await sleep(retryAfterMs);
874
+ continue;
875
+ }
824
876
  }
825
- throw new BrainerceError(
826
- errorData.message || `Request failed with status ${response.status}`,
827
- response.status,
828
- errorData
829
- );
830
- }
831
- const text = await response.text();
832
- if (!text) return {};
833
- return JSON.parse(text);
834
- } catch (error) {
835
- clearTimeout(timeoutId);
836
- if (error instanceof BrainerceError) {
837
- throw error;
838
- }
839
- if (error instanceof Error) {
840
- if (error.name === "AbortError") {
841
- throw new BrainerceError("Request timeout", 408);
877
+ if (!response.ok) {
878
+ const errorData = await response.json().catch(() => ({}));
879
+ if (response.status === 401 && this.onAuthError) {
880
+ this.onAuthError({
881
+ message: errorData.message || "Unauthorized",
882
+ statusCode: 401,
883
+ path
884
+ });
885
+ }
886
+ throw new BrainerceError(
887
+ errorData.message || `Request failed with status ${response.status}`,
888
+ response.status,
889
+ errorData
890
+ );
842
891
  }
843
- throw new BrainerceError(error.message, 0);
892
+ const text = await response.text();
893
+ if (!text) return {};
894
+ return JSON.parse(text);
895
+ } catch (error) {
896
+ clearTimeout(timeoutId);
897
+ if (error instanceof BrainerceError) {
898
+ throw error;
899
+ }
900
+ if (error instanceof Error) {
901
+ if (error.name === "AbortError") {
902
+ throw new BrainerceError("Request timeout", 408);
903
+ }
904
+ throw new BrainerceError(error.message, 0);
905
+ }
906
+ throw new BrainerceError("Unknown error occurred", 0);
844
907
  }
845
- throw new BrainerceError("Unknown error occurred", 0);
846
908
  }
909
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
847
910
  }
848
911
  /**
849
912
  * Smart request - uses storefront or admin API based on client mode
@@ -933,6 +996,7 @@ var BrainerceClient = class {
933
996
  // Admin-only params
934
997
  type: params?.type
935
998
  };
999
+ const queryParamsWithRegion = params?.regionId ? { ...queryParams, regionId: params.regionId } : queryParams;
936
1000
  if (this.isVibeCodedMode()) {
937
1001
  return this.vibeCodedRequest(
938
1002
  "GET",
@@ -946,14 +1010,14 @@ var BrainerceClient = class {
946
1010
  "GET",
947
1011
  "/products",
948
1012
  void 0,
949
- queryParams
1013
+ queryParamsWithRegion
950
1014
  );
951
1015
  }
952
1016
  return this.adminRequest(
953
1017
  "GET",
954
1018
  "/api/v1/products",
955
1019
  void 0,
956
- queryParams
1020
+ queryParamsWithRegion
957
1021
  );
958
1022
  }
959
1023
  /**
@@ -962,10 +1026,11 @@ var BrainerceClient = class {
962
1026
  */
963
1027
  async getProduct(productId, options) {
964
1028
  const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
1029
+ const queryParams = options?.regionId ? { regionId: options.regionId } : void 0;
965
1030
  if (this.isVibeCodedMode()) {
966
1031
  return this.vibeCodedRequest(
967
1032
  "GET",
968
- `/products/${productId}`,
1033
+ `/products/${encodePathSegment(productId)}`,
969
1034
  void 0,
970
1035
  void 0,
971
1036
  headerOverrides
@@ -974,13 +1039,18 @@ var BrainerceClient = class {
974
1039
  if (this.storeId && !this.apiKey) {
975
1040
  return this.storefrontRequest(
976
1041
  "GET",
977
- `/products/${productId}`,
978
- void 0,
1042
+ `/products/${encodePathSegment(productId)}`,
979
1043
  void 0,
1044
+ queryParams,
980
1045
  headerOverrides
981
1046
  );
982
1047
  }
983
- return this.adminRequest("GET", `/api/v1/products/${productId}`);
1048
+ return this.adminRequest(
1049
+ "GET",
1050
+ `/api/v1/products/${encodePathSegment(productId)}`,
1051
+ void 0,
1052
+ queryParams
1053
+ );
984
1054
  }
985
1055
  /**
986
1056
  * Get a single product by slug
@@ -994,7 +1064,7 @@ var BrainerceClient = class {
994
1064
  */
995
1065
  async getProductBySlug(slug, options) {
996
1066
  const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
997
- const encodedSlug = encodeURIComponent(slug);
1067
+ const encodedSlug = encodePathSegment(slug);
998
1068
  if (this.isVibeCodedMode()) {
999
1069
  return this.vibeCodedRequest(
1000
1070
  "GET",
@@ -1098,7 +1168,7 @@ var BrainerceClient = class {
1098
1168
  */
1099
1169
  async getProductAlternates(productId) {
1100
1170
  if (this.storeId && !this.apiKey) {
1101
- return this.storefrontRequest("GET", `/products/${productId}/alternates`);
1171
+ return this.storefrontRequest("GET", `/products/${encodePathSegment(productId)}/alternates`);
1102
1172
  }
1103
1173
  throw new BrainerceError("getProductAlternates is only available in storefront mode", 400);
1104
1174
  }
@@ -1140,7 +1210,7 @@ var BrainerceClient = class {
1140
1210
  * Update an existing product
1141
1211
  */
1142
1212
  async updateProduct(productId, data) {
1143
- return this.request("PATCH", `/api/v1/products/${productId}`, data);
1213
+ return this.request("PATCH", `/api/v1/products/${encodePathSegment(productId)}`, data);
1144
1214
  }
1145
1215
  /**
1146
1216
  * Delete a product
@@ -1168,7 +1238,7 @@ var BrainerceClient = class {
1168
1238
  const queryParams = options?.platforms?.length ? { platforms: options.platforms.join(",") } : void 0;
1169
1239
  return this.request(
1170
1240
  "DELETE",
1171
- `/api/v1/products/${productId}`,
1241
+ `/api/v1/products/${encodePathSegment(productId)}`,
1172
1242
  void 0,
1173
1243
  queryParams
1174
1244
  );
@@ -1183,7 +1253,10 @@ var BrainerceClient = class {
1183
1253
  * ```
1184
1254
  */
1185
1255
  async convertToVariable(productId) {
1186
- return this.request("PATCH", `/api/v1/products/${productId}/convert-to-variable`);
1256
+ return this.request(
1257
+ "PATCH",
1258
+ `/api/v1/products/${encodePathSegment(productId)}/convert-to-variable`
1259
+ );
1187
1260
  }
1188
1261
  /**
1189
1262
  * Convert a VARIABLE product to SIMPLE product
@@ -1196,7 +1269,10 @@ var BrainerceClient = class {
1196
1269
  * ```
1197
1270
  */
1198
1271
  async convertToSimple(productId) {
1199
- return this.request("PATCH", `/api/v1/products/${productId}/convert-to-simple`);
1272
+ return this.request(
1273
+ "PATCH",
1274
+ `/api/v1/products/${encodePathSegment(productId)}/convert-to-simple`
1275
+ );
1200
1276
  }
1201
1277
  /**
1202
1278
  * Publish a product to specific platforms
@@ -1208,9 +1284,13 @@ var BrainerceClient = class {
1208
1284
  * ```
1209
1285
  */
1210
1286
  async publishProduct(productId, platforms) {
1211
- return this.request("POST", `/api/v1/products/${productId}/publish`, {
1212
- platforms
1213
- });
1287
+ return this.request(
1288
+ "POST",
1289
+ `/api/v1/products/${encodePathSegment(productId)}/publish`,
1290
+ {
1291
+ platforms
1292
+ }
1293
+ );
1214
1294
  }
1215
1295
  // -------------------- Variants --------------------
1216
1296
  /**
@@ -1228,7 +1308,11 @@ var BrainerceClient = class {
1228
1308
  * ```
1229
1309
  */
1230
1310
  async createVariant(productId, data) {
1231
- return this.request("POST", `/api/v1/products/${productId}/variants`, data);
1311
+ return this.request(
1312
+ "POST",
1313
+ `/api/v1/products/${encodePathSegment(productId)}/variants`,
1314
+ data
1315
+ );
1232
1316
  }
1233
1317
  /**
1234
1318
  * Bulk save variants (create, update, delete in one operation)
@@ -1248,7 +1332,7 @@ var BrainerceClient = class {
1248
1332
  async bulkSaveVariants(productId, data) {
1249
1333
  return this.request(
1250
1334
  "POST",
1251
- `/api/v1/products/${productId}/variants/bulk`,
1335
+ `/api/v1/products/${encodePathSegment(productId)}/variants/bulk`,
1252
1336
  data
1253
1337
  );
1254
1338
  }
@@ -1266,7 +1350,7 @@ var BrainerceClient = class {
1266
1350
  async updateVariant(productId, variantId, data) {
1267
1351
  return this.request(
1268
1352
  "PATCH",
1269
- `/api/v1/products/${productId}/variants/${variantId}`,
1353
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`,
1270
1354
  data
1271
1355
  );
1272
1356
  }
@@ -1279,7 +1363,10 @@ var BrainerceClient = class {
1279
1363
  * ```
1280
1364
  */
1281
1365
  async deleteVariant(productId, variantId) {
1282
- await this.request("DELETE", `/api/v1/products/${productId}/variants/${variantId}`);
1366
+ await this.request(
1367
+ "DELETE",
1368
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`
1369
+ );
1283
1370
  }
1284
1371
  /**
1285
1372
  * Get inventory for a specific variant
@@ -1293,7 +1380,7 @@ var BrainerceClient = class {
1293
1380
  async getVariantInventory(productId, variantId) {
1294
1381
  return this.request(
1295
1382
  "GET",
1296
- `/api/v1/products/${productId}/variants/${variantId}/inventory`
1383
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`
1297
1384
  );
1298
1385
  }
1299
1386
  /**
@@ -1310,7 +1397,7 @@ var BrainerceClient = class {
1310
1397
  async updateVariantInventory(productId, variantId, data) {
1311
1398
  return this.request(
1312
1399
  "PATCH",
1313
- `/api/v1/products/${productId}/variants/${variantId}/inventory`,
1400
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`,
1314
1401
  data
1315
1402
  );
1316
1403
  }
@@ -1334,7 +1421,10 @@ var BrainerceClient = class {
1334
1421
  * Get a single order by ID
1335
1422
  */
1336
1423
  async getOrder(orderId) {
1337
- return this.withGuards(this.request("GET", `/api/v1/orders/${orderId}`), "order");
1424
+ return this.withGuards(
1425
+ this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}`),
1426
+ "order"
1427
+ );
1338
1428
  }
1339
1429
  /**
1340
1430
  * Create a new order
@@ -1347,7 +1437,7 @@ var BrainerceClient = class {
1347
1437
  * Update an order (e.g., change status)
1348
1438
  */
1349
1439
  async updateOrder(orderId, data) {
1350
- return this.request("PATCH", `/api/v1/orders/${orderId}`, data);
1440
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}`, data);
1351
1441
  }
1352
1442
  /**
1353
1443
  * Update order status
@@ -1358,7 +1448,9 @@ var BrainerceClient = class {
1358
1448
  * ```
1359
1449
  */
1360
1450
  async updateOrderStatus(orderId, status) {
1361
- return this.request("PATCH", `/api/v1/orders/${orderId}/status`, { status });
1451
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/status`, {
1452
+ status
1453
+ });
1362
1454
  }
1363
1455
  /**
1364
1456
  * Update order payment method
@@ -1370,9 +1462,13 @@ var BrainerceClient = class {
1370
1462
  * ```
1371
1463
  */
1372
1464
  async updatePaymentMethod(orderId, paymentMethod) {
1373
- return this.request("PATCH", `/api/v1/orders/${orderId}/payment-method`, {
1374
- paymentMethod
1375
- });
1465
+ return this.request(
1466
+ "PATCH",
1467
+ `/api/v1/orders/${encodePathSegment(orderId)}/payment-method`,
1468
+ {
1469
+ paymentMethod
1470
+ }
1471
+ );
1376
1472
  }
1377
1473
  /**
1378
1474
  * Update order notes
@@ -1383,7 +1479,9 @@ var BrainerceClient = class {
1383
1479
  * ```
1384
1480
  */
1385
1481
  async updateOrderNotes(orderId, notes) {
1386
- return this.request("PATCH", `/api/v1/orders/${orderId}/notes`, { notes });
1482
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/notes`, {
1483
+ notes
1484
+ });
1387
1485
  }
1388
1486
  /**
1389
1487
  * Get refunds for an order
@@ -1396,7 +1494,7 @@ var BrainerceClient = class {
1396
1494
  * ```
1397
1495
  */
1398
1496
  async getOrderRefunds(orderId) {
1399
- return this.request("GET", `/api/v1/orders/${orderId}/refunds`);
1497
+ return this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}/refunds`);
1400
1498
  }
1401
1499
  /**
1402
1500
  * Create a refund for an order
@@ -1423,7 +1521,11 @@ var BrainerceClient = class {
1423
1521
  * ```
1424
1522
  */
1425
1523
  async createRefund(orderId, data) {
1426
- return this.request("POST", `/api/v1/orders/${orderId}/refunds`, data);
1524
+ return this.request(
1525
+ "POST",
1526
+ `/api/v1/orders/${encodePathSegment(orderId)}/refunds`,
1527
+ data
1528
+ );
1427
1529
  }
1428
1530
  /**
1429
1531
  * Update order shipping address
@@ -1443,7 +1545,11 @@ var BrainerceClient = class {
1443
1545
  * ```
1444
1546
  */
1445
1547
  async updateOrderShipping(orderId, data) {
1446
- return this.request("PATCH", `/api/v1/orders/${orderId}/shipping`, data);
1548
+ return this.request(
1549
+ "PATCH",
1550
+ `/api/v1/orders/${encodePathSegment(orderId)}/shipping`,
1551
+ data
1552
+ );
1447
1553
  }
1448
1554
  /**
1449
1555
  * Cancel an order
@@ -1456,7 +1562,7 @@ var BrainerceClient = class {
1456
1562
  * ```
1457
1563
  */
1458
1564
  async cancelOrder(orderId) {
1459
- return this.request("POST", `/api/v1/orders/${orderId}/cancel`);
1565
+ return this.request("POST", `/api/v1/orders/${encodePathSegment(orderId)}/cancel`);
1460
1566
  }
1461
1567
  /**
1462
1568
  * Fulfill an order (mark as shipped)
@@ -1472,7 +1578,11 @@ var BrainerceClient = class {
1472
1578
  * ```
1473
1579
  */
1474
1580
  async fulfillOrder(orderId, data) {
1475
- return this.request("POST", `/api/v1/orders/${orderId}/fulfill`, data || {});
1581
+ return this.request(
1582
+ "POST",
1583
+ `/api/v1/orders/${encodePathSegment(orderId)}/fulfill`,
1584
+ data || {}
1585
+ );
1476
1586
  }
1477
1587
  /**
1478
1588
  * Sync draft orders from connected platforms
@@ -1497,7 +1607,11 @@ var BrainerceClient = class {
1497
1607
  * ```
1498
1608
  */
1499
1609
  async completeDraftOrder(orderId, data) {
1500
- return this.request("POST", `/api/v1/orders/${orderId}/complete-draft`, data || {});
1610
+ return this.request(
1611
+ "POST",
1612
+ `/api/v1/orders/${encodePathSegment(orderId)}/complete-draft`,
1613
+ data || {}
1614
+ );
1501
1615
  }
1502
1616
  /**
1503
1617
  * Send invoice for a draft order
@@ -1514,7 +1628,7 @@ var BrainerceClient = class {
1514
1628
  async sendDraftInvoice(orderId, data) {
1515
1629
  return this.request(
1516
1630
  "POST",
1517
- `/api/v1/orders/${orderId}/send-invoice`,
1631
+ `/api/v1/orders/${encodePathSegment(orderId)}/send-invoice`,
1518
1632
  data || {}
1519
1633
  );
1520
1634
  }
@@ -1527,7 +1641,7 @@ var BrainerceClient = class {
1527
1641
  * ```
1528
1642
  */
1529
1643
  async deleteDraftOrder(orderId) {
1530
- await this.request("DELETE", `/api/v1/orders/${orderId}/draft`);
1644
+ await this.request("DELETE", `/api/v1/orders/${encodePathSegment(orderId)}/draft`);
1531
1645
  }
1532
1646
  /**
1533
1647
  * Update a draft order
@@ -1550,7 +1664,7 @@ var BrainerceClient = class {
1550
1664
  * ```
1551
1665
  */
1552
1666
  async updateDraftOrder(orderId, data) {
1553
- return this.request("PATCH", `/api/v1/orders/${orderId}/draft`, data);
1667
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/draft`, data);
1554
1668
  }
1555
1669
  // -------------------- Inventory --------------------
1556
1670
  /**
@@ -1558,13 +1672,17 @@ var BrainerceClient = class {
1558
1672
  * This will sync inventory to all connected platforms
1559
1673
  */
1560
1674
  async updateInventory(productId, data) {
1561
- await this.request("PUT", `/api/v1/products/${productId}/inventory`, data);
1675
+ await this.request(
1676
+ "PUT",
1677
+ `/api/v1/products/${encodePathSegment(productId)}/inventory`,
1678
+ data
1679
+ );
1562
1680
  }
1563
1681
  /**
1564
1682
  * Get current inventory for a product
1565
1683
  */
1566
1684
  async getInventory(productId) {
1567
- return this.request("GET", `/api/v1/inventory/${productId}`);
1685
+ return this.request("GET", `/api/v1/inventory/${encodePathSegment(productId)}`);
1568
1686
  }
1569
1687
  /**
1570
1688
  * Edit inventory manually with reason for audit trail
@@ -1725,7 +1843,7 @@ var BrainerceClient = class {
1725
1843
  * Get the status of a sync job
1726
1844
  */
1727
1845
  async getSyncStatus(jobId) {
1728
- return this.request("GET", `/api/v1/sync/${jobId}`);
1846
+ return this.request("GET", `/api/v1/sync/${encodePathSegment(jobId)}`);
1729
1847
  }
1730
1848
  // -------------------- Coupons --------------------
1731
1849
  /**
@@ -1747,7 +1865,7 @@ var BrainerceClient = class {
1747
1865
  * Get a single coupon by ID
1748
1866
  */
1749
1867
  async getCoupon(couponId) {
1750
- return this.request("GET", `/api/v1/coupons/${couponId}`);
1868
+ return this.request("GET", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1751
1869
  }
1752
1870
  /**
1753
1871
  * Create a new coupon.
@@ -1777,20 +1895,20 @@ var BrainerceClient = class {
1777
1895
  * Update an existing coupon
1778
1896
  */
1779
1897
  async updateCoupon(couponId, data) {
1780
- return this.request("PATCH", `/api/v1/coupons/${couponId}`, data);
1898
+ return this.request("PATCH", `/api/v1/coupons/${encodePathSegment(couponId)}`, data);
1781
1899
  }
1782
1900
  /**
1783
1901
  * Delete a coupon
1784
1902
  */
1785
1903
  async deleteCoupon(couponId) {
1786
- await this.request("DELETE", `/api/v1/coupons/${couponId}`);
1904
+ await this.request("DELETE", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1787
1905
  }
1788
1906
  /**
1789
1907
  * Sync a coupon to all connected platforms.
1790
1908
  * Returns a sync job that can be tracked with getSyncStatus().
1791
1909
  */
1792
1910
  async syncCoupon(couponId) {
1793
- return this.request("POST", `/api/v1/coupons/${couponId}/sync`);
1911
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/sync`);
1794
1912
  }
1795
1913
  /**
1796
1914
  * Publish a coupon to specific platforms.
@@ -1803,7 +1921,9 @@ var BrainerceClient = class {
1803
1921
  * ```
1804
1922
  */
1805
1923
  async publishCoupon(couponId, platforms) {
1806
- return this.request("POST", `/api/v1/coupons/${couponId}/publish`, { platforms });
1924
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/publish`, {
1925
+ platforms
1926
+ });
1807
1927
  }
1808
1928
  /**
1809
1929
  * Get platform capabilities for coupon features.
@@ -1844,13 +1964,17 @@ var BrainerceClient = class {
1844
1964
  * Get a customer by ID
1845
1965
  */
1846
1966
  async getCustomer(customerId) {
1847
- return this.request("GET", `/api/v1/customers/${customerId}`);
1967
+ return this.request("GET", `/api/v1/customers/${encodePathSegment(customerId)}`);
1848
1968
  }
1849
1969
  /**
1850
1970
  * Update a customer
1851
1971
  */
1852
1972
  async updateCustomer(customerId, data) {
1853
- return this.request("PATCH", `/api/v1/customers/${customerId}`, data);
1973
+ return this.request(
1974
+ "PATCH",
1975
+ `/api/v1/customers/${encodePathSegment(customerId)}`,
1976
+ data
1977
+ );
1854
1978
  }
1855
1979
  /**
1856
1980
  * Get a customer by email
@@ -1858,56 +1982,84 @@ var BrainerceClient = class {
1858
1982
  async getCustomerByEmail(email) {
1859
1983
  return this.request("GET", "/api/v1/customers/by-email", void 0, { email });
1860
1984
  }
1861
- /**
1862
- * List a customer's saved payment methods (vaulted cards).
1863
- *
1864
- * Returns display-only metadata — last4, brand, expiry, default flag,
1865
- * status. The underlying provider token is encrypted at rest and
1866
- * NEVER returned through this API.
1867
- *
1868
- * Apps mode requires `customers:read` and `payments:read` scopes.
1869
- *
1870
- * @param storeId - The store this customer belongs to
1871
- * @param customerId - The customer's ID
1872
- * @returns Array of saved payment methods
1873
- *
1874
- * @example
1875
- * ```typescript
1876
- * const methods = await client.listSavedPaymentMethods(storeId, customerId);
1877
- * methods.forEach((m) => {
1878
- * console.log(`${m.brand} ending in ${m.last4} (expires ${m.expMonth}/${m.expYear})`);
1879
- * });
1880
- * ```
1881
- */
1882
- async listSavedPaymentMethods(storeId, customerId) {
1985
+ async listSavedPaymentMethods(customerIdOrStoreId, maybeCustomerId) {
1986
+ const customerId = this.resolveSavedPaymentMethodsArgs(
1987
+ "listSavedPaymentMethods",
1988
+ customerIdOrStoreId,
1989
+ maybeCustomerId
1990
+ );
1883
1991
  return this.request(
1884
1992
  "GET",
1885
- `/api/stores/${storeId}/customers/${customerId}/payment-methods`
1993
+ `/api/stores/${this.storeId}/customers/${encodePathSegment(customerId)}/payment-methods`
1994
+ );
1995
+ }
1996
+ async removeSavedPaymentMethod(customerIdOrStoreId, paymentMethodIdOrCustomerId, maybePaymentMethodId) {
1997
+ const { customerId, paymentMethodId } = this.resolveRemovePaymentMethodArgs(
1998
+ customerIdOrStoreId,
1999
+ paymentMethodIdOrCustomerId,
2000
+ maybePaymentMethodId
2001
+ );
2002
+ return this.request(
2003
+ "DELETE",
2004
+ `/api/stores/${this.storeId}/customers/${encodePathSegment(customerId)}/payment-methods/${encodePathSegment(paymentMethodId)}`
1886
2005
  );
1887
2006
  }
1888
2007
  /**
1889
- * Remove a customer's saved payment method.
1890
- *
1891
- * Hard-deletes the row. The provider may still hold the underlying
1892
- * token internally — we don't issue a delete-at-provider call because
1893
- * not every provider supports it. From the platform's perspective the
1894
- * token is gone; subsequent charges will fail.
1895
- *
1896
- * Apps mode requires `customers:write` scope.
1897
- *
1898
- * @param storeId - The store this customer belongs to
1899
- * @param customerId - The customer's ID
1900
- * @param paymentMethodId - The saved payment method ID to remove
2008
+ * Internal helper: normalize legacy `(storeId, customerId)` callers to the
2009
+ * new `(customerId)` signature for `listSavedPaymentMethods`.
1901
2010
  *
1902
- * @example
1903
- * ```typescript
1904
- * await client.removeSavedPaymentMethod(storeId, customerId, methodId);
1905
- * ```
2011
+ * Throws if the SDK instance has no `storeId` (these endpoints are
2012
+ * storefront-scoped) and warns when the deprecated overload is detected.
1906
2013
  */
1907
- async removeSavedPaymentMethod(storeId, customerId, paymentMethodId) {
1908
- return this.request(
1909
- "DELETE",
1910
- `/api/stores/${storeId}/customers/${customerId}/payment-methods/${paymentMethodId}`
2014
+ resolveSavedPaymentMethodsArgs(methodName, customerIdOrStoreId, maybeCustomerId) {
2015
+ if (!this.storeId) {
2016
+ throw new BrainerceError(
2017
+ `${methodName}: this method requires a storeId on the SDK instance. Pass \`storeId\` when constructing \`new BrainerceClient({ storeId })\`.`,
2018
+ 400
2019
+ );
2020
+ }
2021
+ if (maybeCustomerId !== void 0) {
2022
+ this.warnDeprecatedStoreIdArg(methodName, customerIdOrStoreId);
2023
+ return maybeCustomerId;
2024
+ }
2025
+ return customerIdOrStoreId;
2026
+ }
2027
+ /**
2028
+ * Internal helper: normalize legacy `(storeId, customerId, paymentMethodId)`
2029
+ * callers to the new `(customerId, paymentMethodId)` signature.
2030
+ */
2031
+ resolveRemovePaymentMethodArgs(customerIdOrStoreId, paymentMethodIdOrCustomerId, maybePaymentMethodId) {
2032
+ if (!this.storeId) {
2033
+ throw new BrainerceError(
2034
+ "removeSavedPaymentMethod: this method requires a storeId on the SDK instance. Pass `storeId` when constructing `new BrainerceClient({ storeId })`.",
2035
+ 400
2036
+ );
2037
+ }
2038
+ if (maybePaymentMethodId !== void 0) {
2039
+ this.warnDeprecatedStoreIdArg("removeSavedPaymentMethod", customerIdOrStoreId);
2040
+ return {
2041
+ customerId: paymentMethodIdOrCustomerId,
2042
+ paymentMethodId: maybePaymentMethodId
2043
+ };
2044
+ }
2045
+ return {
2046
+ customerId: customerIdOrStoreId,
2047
+ paymentMethodId: paymentMethodIdOrCustomerId
2048
+ };
2049
+ }
2050
+ /**
2051
+ * One-shot deprecation warning per (method, mismatch?) — verifies the
2052
+ * caller-supplied storeId matches the SDK config and warns regardless.
2053
+ */
2054
+ warnDeprecatedStoreIdArg(methodName, suppliedStoreId) {
2055
+ if (suppliedStoreId !== this.storeId) {
2056
+ throw new BrainerceError(
2057
+ `${methodName}: supplied storeId "${suppliedStoreId}" does not match the SDK instance storeId "${this.storeId}". Construct a new client per store.`,
2058
+ 400
2059
+ );
2060
+ }
2061
+ console.warn(
2062
+ `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.`
1911
2063
  );
1912
2064
  }
1913
2065
  /**
@@ -1966,12 +2118,33 @@ var BrainerceClient = class {
1966
2118
  * Request a password reset email for a customer
1967
2119
  * Works in vibe-coded, storefront, and admin mode
1968
2120
  *
2121
+ * The `resetUrl` MUST be supplied explicitly in non-browser (SSR / Node)
2122
+ * contexts — auto-deriving it from `window.location.origin` is impossible
2123
+ * there and historically resulted in `undefined` being sent to the backend,
2124
+ * which then bounced the email to a broken link. In browser contexts the
2125
+ * origin is still used as a fallback but the SDK logs a one-time warning
2126
+ * recommending an explicit value so server-rendered + proxied dashboards
2127
+ * don't silently rely on the wrong host.
2128
+ *
1969
2129
  * @param email - Customer email address
1970
2130
  * @param options - Optional settings
1971
- * @param options.resetUrl - Override the auto-detected reset URL (e.g. for BFF proxy callback)
2131
+ * @param options.resetUrl - Reset URL the email links should point to.
2132
+ * Required outside the browser; recommended inside it.
1972
2133
  */
1973
2134
  async forgotPassword(email, options) {
1974
- const resetUrl = options?.resetUrl ?? (typeof window !== "undefined" ? `${window.location.origin}/reset-password` : void 0);
2135
+ let resetUrl = options?.resetUrl;
2136
+ if (!resetUrl) {
2137
+ if (typeof window === "undefined") {
2138
+ throw new BrainerceError(
2139
+ 'forgotPassword: `resetUrl` is required outside the browser. Pass `{ resetUrl: "https://your-site.example/reset-password" }` so the email links to the right host.',
2140
+ 400
2141
+ );
2142
+ }
2143
+ console.warn(
2144
+ "BrainerceClient.forgotPassword: deriving `resetUrl` from `window.location.origin` \u2014 pass `{ resetUrl }` explicitly to avoid wrong-host links behind proxies or in SSR."
2145
+ );
2146
+ resetUrl = `${window.location.origin}/reset-password`;
2147
+ }
1975
2148
  if (this.isVibeCodedMode()) {
1976
2149
  return this.vibeCodedRequest("POST", "/customers/forgot-password", {
1977
2150
  email,
@@ -2154,12 +2327,14 @@ var BrainerceClient = class {
2154
2327
  * // Redirect user to Google
2155
2328
  * window.location.href = authorizationUrl;
2156
2329
  *
2157
- * // On /auth/callback page — the backend handles code exchange and redirects with params:
2330
+ * // On /auth/callback page — exchange the one-time auth_code for the JWT.
2331
+ * // (The backend used to put the JWT directly in the redirect URL; that path
2332
+ * // is deprecated because URL params leak into browser history and logs.)
2158
2333
  * const params = new URLSearchParams(window.location.search);
2159
- * if (params.get('oauth_success') === 'true') {
2160
- * const token = params.get('token');
2161
- * client.setCustomerToken(token);
2162
- * // Also available: customer_id, customer_email, is_new
2334
+ * if (params.get('oauth_success') === 'true' && params.get('auth_code')) {
2335
+ * const result = await client.exchangeOAuthCode(params.get('auth_code')!);
2336
+ * client.setCustomerToken(result.token);
2337
+ * // result.customer, result.isNewCustomer, result.redirectUrl, ...
2163
2338
  * } else if (params.get('oauth_error')) {
2164
2339
  * // Show error
2165
2340
  * }
@@ -2177,7 +2352,7 @@ var BrainerceClient = class {
2177
2352
  params.set("redirectUrl", options.redirectUrl);
2178
2353
  }
2179
2354
  const queryString = params.toString();
2180
- const endpoint = `/oauth/${provider}/authorize${queryString ? `?${queryString}` : ""}`;
2355
+ const endpoint = `/oauth/${encodePathSegment(provider)}/authorize${queryString ? `?${queryString}` : ""}`;
2181
2356
  if (this.isVibeCodedMode()) {
2182
2357
  return this.vibeCodedRequest("GET", endpoint);
2183
2358
  }
@@ -2186,6 +2361,83 @@ var BrainerceClient = class {
2186
2361
  }
2187
2362
  throw new BrainerceError("getOAuthAuthorizeUrl requires vibe-coded or storefront mode", 400);
2188
2363
  }
2364
+ /**
2365
+ * Exchange a one-time `auth_code` (returned in the post-OAuth redirect URL)
2366
+ * for the customer JWT. Use this on the `/auth/callback` storefront page
2367
+ * after reading `auth_code` from `window.location.search`.
2368
+ *
2369
+ * The code is single-use and expires 2 minutes after the OAuth callback
2370
+ * issued it. A second call with the same code returns 400.
2371
+ *
2372
+ * This replaces the legacy flow where the JWT was placed directly in the
2373
+ * redirect URL (`?token=...`). The legacy URL params still ship behind a
2374
+ * server feature flag during the migration window, but they will be
2375
+ * removed in the next major release — migrate now.
2376
+ *
2377
+ * @param authCode - The single-use code from the `?auth_code=` URL param.
2378
+ *
2379
+ * @example
2380
+ * ```typescript
2381
+ * const params = new URLSearchParams(window.location.search);
2382
+ * const code = params.get('auth_code');
2383
+ * if (code) {
2384
+ * const { token, customer, isNewCustomer, redirectUrl } =
2385
+ * await client.exchangeOAuthCode(code);
2386
+ * client.setCustomerToken(token);
2387
+ * }
2388
+ * ```
2389
+ */
2390
+ async exchangeOAuthCode(authCode) {
2391
+ if (!authCode) {
2392
+ throw new BrainerceError("authCode is required", 400);
2393
+ }
2394
+ const url = `${this.baseUrl}/api/oauth/customer/exchange`;
2395
+ const controller = new AbortController();
2396
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2397
+ try {
2398
+ const headers = {
2399
+ "Content-Type": "application/json",
2400
+ "X-SDK-Version": SDK_VERSION,
2401
+ "ngrok-skip-browser-warning": "true"
2402
+ };
2403
+ if (this.origin) {
2404
+ headers["Origin"] = this.origin;
2405
+ }
2406
+ if (this.locale) {
2407
+ headers["Accept-Language"] = this.locale;
2408
+ }
2409
+ const response = await fetch(url, {
2410
+ method: "POST",
2411
+ headers,
2412
+ body: JSON.stringify({ code: authCode }),
2413
+ signal: controller.signal
2414
+ });
2415
+ clearTimeout(timeoutId);
2416
+ if (!response.ok) {
2417
+ const errorData = await response.json().catch(() => ({}));
2418
+ throw new BrainerceError(
2419
+ errorData.message || `Request failed with status ${response.status}`,
2420
+ response.status,
2421
+ errorData
2422
+ );
2423
+ }
2424
+ const text = await response.text();
2425
+ if (!text) return {};
2426
+ return JSON.parse(text);
2427
+ } catch (error) {
2428
+ clearTimeout(timeoutId);
2429
+ if (error instanceof BrainerceError) {
2430
+ throw error;
2431
+ }
2432
+ if (error instanceof Error) {
2433
+ if (error.name === "AbortError") {
2434
+ throw new BrainerceError("Request timeout", 408);
2435
+ }
2436
+ throw new BrainerceError(error.message, 0);
2437
+ }
2438
+ throw new BrainerceError("Unknown error occurred", 0);
2439
+ }
2440
+ }
2189
2441
  /**
2190
2442
  * Handle OAuth callback - exchange code for customer token (server-to-server)
2191
2443
  *
@@ -2206,7 +2458,7 @@ var BrainerceClient = class {
2206
2458
  throw new BrainerceError("provider is required (e.g., 'GOOGLE', 'FACEBOOK', 'GITHUB')", 400);
2207
2459
  }
2208
2460
  const params = new URLSearchParams({ code, state });
2209
- const endpoint = `/oauth/${provider}/callback?${params.toString()}`;
2461
+ const endpoint = `/oauth/${encodePathSegment(provider)}/callback?${params.toString()}`;
2210
2462
  if (this.isVibeCodedMode()) {
2211
2463
  return this.vibeCodedRequest("GET", endpoint);
2212
2464
  }
@@ -2250,7 +2502,7 @@ var BrainerceClient = class {
2250
2502
  params.set("redirectUrl", options.redirectUrl);
2251
2503
  }
2252
2504
  const queryString = params.toString();
2253
- const endpoint = `/oauth/${provider}/link${queryString ? `?${queryString}` : ""}`;
2505
+ const endpoint = `/oauth/${encodePathSegment(provider)}/link${queryString ? `?${queryString}` : ""}`;
2254
2506
  if (this.isVibeCodedMode()) {
2255
2507
  return this.vibeCodedRequest("POST", endpoint);
2256
2508
  }
@@ -2279,10 +2531,16 @@ var BrainerceClient = class {
2279
2531
  throw new BrainerceError("Customer token is required. Call setCustomerToken() first.", 401);
2280
2532
  }
2281
2533
  if (this.isVibeCodedMode()) {
2282
- return this.vibeCodedRequest("DELETE", `/oauth/${provider}/link`);
2534
+ return this.vibeCodedRequest(
2535
+ "DELETE",
2536
+ `/oauth/${encodePathSegment(provider)}/link`
2537
+ );
2283
2538
  }
2284
2539
  if (this.isStorefrontMode()) {
2285
- return this.storefrontRequest("DELETE", `/oauth/${provider}/link`);
2540
+ return this.storefrontRequest(
2541
+ "DELETE",
2542
+ `/oauth/${encodePathSegment(provider)}/link`
2543
+ );
2286
2544
  }
2287
2545
  throw new BrainerceError("unlinkOAuthProvider requires vibe-coded or storefront mode", 400);
2288
2546
  }
@@ -2349,7 +2607,10 @@ var BrainerceClient = class {
2349
2607
  * Get all addresses for a customer
2350
2608
  */
2351
2609
  async getCustomerAddresses(customerId) {
2352
- return this.request("GET", `/api/v1/customers/${customerId}/addresses`);
2610
+ return this.request(
2611
+ "GET",
2612
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`
2613
+ );
2353
2614
  }
2354
2615
  /**
2355
2616
  * Add an address to a customer
@@ -2371,7 +2632,7 @@ var BrainerceClient = class {
2371
2632
  async addCustomerAddress(customerId, address) {
2372
2633
  return this.request(
2373
2634
  "POST",
2374
- `/api/v1/customers/${customerId}/addresses`,
2635
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`,
2375
2636
  address
2376
2637
  );
2377
2638
  }
@@ -2381,7 +2642,7 @@ var BrainerceClient = class {
2381
2642
  async updateCustomerAddress(customerId, addressId, address) {
2382
2643
  return this.request(
2383
2644
  "PATCH",
2384
- `/api/v1/customers/${customerId}/addresses/${addressId}`,
2645
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`,
2385
2646
  address
2386
2647
  );
2387
2648
  }
@@ -2389,7 +2650,10 @@ var BrainerceClient = class {
2389
2650
  * Delete a customer address
2390
2651
  */
2391
2652
  async deleteCustomerAddress(customerId, addressId) {
2392
- await this.request("DELETE", `/api/v1/customers/${customerId}/addresses/${addressId}`);
2653
+ await this.request(
2654
+ "DELETE",
2655
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`
2656
+ );
2393
2657
  }
2394
2658
  /**
2395
2659
  * Get orders for a customer
@@ -2403,7 +2667,7 @@ var BrainerceClient = class {
2403
2667
  async getCustomerOrders(customerId, params) {
2404
2668
  return this.request(
2405
2669
  "GET",
2406
- `/api/v1/customers/${customerId}/orders`,
2670
+ `/api/v1/customers/${encodePathSegment(customerId)}/orders`,
2407
2671
  void 0,
2408
2672
  { page: params?.page, limit: params?.limit }
2409
2673
  );
@@ -2475,12 +2739,18 @@ var BrainerceClient = class {
2475
2739
  */
2476
2740
  async getCartBySession(sessionToken) {
2477
2741
  if (this.isVibeCodedMode()) {
2478
- return this.vibeCodedRequest("GET", `/cart/session/${sessionToken}`);
2742
+ return this.vibeCodedRequest("GET", `/cart/session/${encodePathSegment(sessionToken)}`);
2479
2743
  }
2480
2744
  if (this.storeId && !this.apiKey) {
2481
- return this.storefrontRequest("GET", `/cart/session/${sessionToken}`);
2745
+ return this.storefrontRequest(
2746
+ "GET",
2747
+ `/cart/session/${encodePathSegment(sessionToken)}`
2748
+ );
2482
2749
  }
2483
- return this.adminRequest("GET", `/api/v1/cart/session/${sessionToken}`);
2750
+ return this.adminRequest(
2751
+ "GET",
2752
+ `/api/v1/cart/session/${encodePathSegment(sessionToken)}`
2753
+ );
2484
2754
  }
2485
2755
  /**
2486
2756
  * Get a cart by customer ID (for authenticated users)
@@ -2493,9 +2763,9 @@ var BrainerceClient = class {
2493
2763
  */
2494
2764
  async getCartByCustomer(customerId) {
2495
2765
  if (this.storeId && !this.apiKey) {
2496
- return this.storefrontRequest("GET", `/cart/customer/${customerId}`);
2766
+ return this.storefrontRequest("GET", `/cart/customer/${encodePathSegment(customerId)}`);
2497
2767
  }
2498
- return this.adminRequest("GET", `/api/v1/cart/customer/${customerId}`);
2768
+ return this.adminRequest("GET", `/api/v1/cart/customer/${encodePathSegment(customerId)}`);
2499
2769
  }
2500
2770
  /**
2501
2771
  * Get a cart by ID
@@ -2525,18 +2795,33 @@ var BrainerceClient = class {
2525
2795
  const queryParams = options?.include?.length ? { include: options.include.join(",") } : void 0;
2526
2796
  if (this.isVibeCodedMode()) {
2527
2797
  return this.withGuards(
2528
- this.vibeCodedRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2798
+ this.vibeCodedRequest(
2799
+ "GET",
2800
+ `/cart/${encodePathSegment(cartId)}`,
2801
+ void 0,
2802
+ queryParams
2803
+ ),
2529
2804
  "cart"
2530
2805
  );
2531
2806
  }
2532
2807
  if (this.storeId && !this.apiKey) {
2533
2808
  return this.withGuards(
2534
- this.storefrontRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2809
+ this.storefrontRequest(
2810
+ "GET",
2811
+ `/cart/${encodePathSegment(cartId)}`,
2812
+ void 0,
2813
+ queryParams
2814
+ ),
2535
2815
  "cart"
2536
2816
  );
2537
2817
  }
2538
2818
  return this.withGuards(
2539
- this.adminRequest("GET", `/api/v1/cart/${cartId}`, void 0, queryParams),
2819
+ this.adminRequest(
2820
+ "GET",
2821
+ `/api/v1/cart/${encodePathSegment(cartId)}`,
2822
+ void 0,
2823
+ queryParams
2824
+ ),
2540
2825
  "cart"
2541
2826
  );
2542
2827
  }
@@ -2592,18 +2877,18 @@ var BrainerceClient = class {
2592
2877
  }
2593
2878
  if (this.isVibeCodedMode()) {
2594
2879
  return this.withGuards(
2595
- this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item),
2880
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2596
2881
  "cart"
2597
2882
  );
2598
2883
  }
2599
2884
  if (this.storeId && !this.apiKey) {
2600
2885
  return this.withGuards(
2601
- this.storefrontRequest("POST", `/cart/${cartId}/items`, item),
2886
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2602
2887
  "cart"
2603
2888
  );
2604
2889
  }
2605
2890
  return this.withGuards(
2606
- this.adminRequest("POST", `/api/v1/cart/${cartId}/items`, item),
2891
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/items`, item),
2607
2892
  "cart"
2608
2893
  );
2609
2894
  }
@@ -2630,18 +2915,30 @@ var BrainerceClient = class {
2630
2915
  }
2631
2916
  if (this.isVibeCodedMode()) {
2632
2917
  return this.withGuards(
2633
- this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2918
+ this.vibeCodedRequest(
2919
+ "PATCH",
2920
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2921
+ data
2922
+ ),
2634
2923
  "cart"
2635
2924
  );
2636
2925
  }
2637
2926
  if (this.storeId && !this.apiKey) {
2638
2927
  return this.withGuards(
2639
- this.storefrontRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2928
+ this.storefrontRequest(
2929
+ "PATCH",
2930
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2931
+ data
2932
+ ),
2640
2933
  "cart"
2641
2934
  );
2642
2935
  }
2643
2936
  return this.withGuards(
2644
- this.adminRequest("PATCH", `/api/v1/cart/${cartId}/items/${itemId}`, data),
2937
+ this.adminRequest(
2938
+ "PATCH",
2939
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2940
+ data
2941
+ ),
2645
2942
  "cart"
2646
2943
  );
2647
2944
  }
@@ -2668,18 +2965,27 @@ var BrainerceClient = class {
2668
2965
  }
2669
2966
  if (this.isVibeCodedMode()) {
2670
2967
  return this.withGuards(
2671
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2968
+ this.vibeCodedRequest(
2969
+ "DELETE",
2970
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2971
+ ),
2672
2972
  "cart"
2673
2973
  );
2674
2974
  }
2675
2975
  if (this.storeId && !this.apiKey) {
2676
2976
  return this.withGuards(
2677
- this.storefrontRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2977
+ this.storefrontRequest(
2978
+ "DELETE",
2979
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2980
+ ),
2678
2981
  "cart"
2679
2982
  );
2680
2983
  }
2681
2984
  return this.withGuards(
2682
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items/${itemId}`),
2985
+ this.adminRequest(
2986
+ "DELETE",
2987
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2988
+ ),
2683
2989
  "cart"
2684
2990
  );
2685
2991
  }
@@ -2700,13 +3006,16 @@ var BrainerceClient = class {
2700
3006
  return this.withGuards(this.localCartToCart(this.getLocalCart()), "cart");
2701
3007
  }
2702
3008
  if (this.isVibeCodedMode()) {
2703
- return this.withGuards(this.vibeCodedRequest("DELETE", `/cart/${cartId}`), "cart");
3009
+ return this.withGuards(
3010
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}`),
3011
+ "cart"
3012
+ );
2704
3013
  }
2705
3014
  if (this.storeId && !this.apiKey) {
2706
- await this.storefrontRequest("DELETE", `/cart/${cartId}/items`);
3015
+ await this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/items`);
2707
3016
  return this.withGuards({}, "cart");
2708
3017
  }
2709
- await this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items`);
3018
+ await this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/items`);
2710
3019
  return this.withGuards({}, "cart");
2711
3020
  }
2712
3021
  /**
@@ -2721,18 +3030,18 @@ var BrainerceClient = class {
2721
3030
  async applyCoupon(cartId, code) {
2722
3031
  if (this.isVibeCodedMode()) {
2723
3032
  return this.withGuards(
2724
- this.vibeCodedRequest("POST", `/cart/${cartId}/coupon`, { code }),
3033
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2725
3034
  "cart"
2726
3035
  );
2727
3036
  }
2728
3037
  if (this.storeId && !this.apiKey) {
2729
3038
  return this.withGuards(
2730
- this.storefrontRequest("POST", `/cart/${cartId}/coupon`, { code }),
3039
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2731
3040
  "cart"
2732
3041
  );
2733
3042
  }
2734
3043
  return this.withGuards(
2735
- this.adminRequest("POST", `/api/v1/cart/${cartId}/coupon`, { code }),
3044
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2736
3045
  "cart"
2737
3046
  );
2738
3047
  }
@@ -2747,18 +3056,18 @@ var BrainerceClient = class {
2747
3056
  async removeCoupon(cartId) {
2748
3057
  if (this.isVibeCodedMode()) {
2749
3058
  return this.withGuards(
2750
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/coupon`),
3059
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2751
3060
  "cart"
2752
3061
  );
2753
3062
  }
2754
3063
  if (this.storeId && !this.apiKey) {
2755
3064
  return this.withGuards(
2756
- this.storefrontRequest("DELETE", `/cart/${cartId}/coupon`),
3065
+ this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2757
3066
  "cart"
2758
3067
  );
2759
3068
  }
2760
3069
  return this.withGuards(
2761
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/coupon`),
3070
+ this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`),
2762
3071
  "cart"
2763
3072
  );
2764
3073
  }
@@ -2783,18 +3092,18 @@ var BrainerceClient = class {
2783
3092
  }
2784
3093
  if (this.isVibeCodedMode()) {
2785
3094
  return this.withGuards(
2786
- this.vibeCodedRequest("POST", `/cart/${cartId}/recalculate`),
3095
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2787
3096
  "cart"
2788
3097
  );
2789
3098
  }
2790
3099
  if (this.storeId && !this.apiKey) {
2791
3100
  return this.withGuards(
2792
- this.storefrontRequest("POST", `/cart/${cartId}/recalculate`),
3101
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2793
3102
  "cart"
2794
3103
  );
2795
3104
  }
2796
3105
  return this.withGuards(
2797
- this.adminRequest("POST", `/api/v1/cart/${cartId}/recalculate`),
3106
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/recalculate`),
2798
3107
  "cart"
2799
3108
  );
2800
3109
  }
@@ -2823,18 +3132,24 @@ var BrainerceClient = class {
2823
3132
  }
2824
3133
  if (this.isVibeCodedMode()) {
2825
3134
  return this.withGuards(
2826
- this.vibeCodedRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3135
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/refresh-snapshots`),
2827
3136
  "cart"
2828
3137
  );
2829
3138
  }
2830
3139
  if (this.storeId && !this.apiKey) {
2831
3140
  return this.withGuards(
2832
- this.storefrontRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3141
+ this.storefrontRequest(
3142
+ "POST",
3143
+ `/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3144
+ ),
2833
3145
  "cart"
2834
3146
  );
2835
3147
  }
2836
3148
  return this.withGuards(
2837
- this.adminRequest("POST", `/api/v1/cart/${cartId}/refresh-snapshots`),
3149
+ this.adminRequest(
3150
+ "POST",
3151
+ `/api/v1/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3152
+ ),
2838
3153
  "cart"
2839
3154
  );
2840
3155
  }
@@ -2863,10 +3178,10 @@ var BrainerceClient = class {
2863
3178
  );
2864
3179
  }
2865
3180
  if (this.isVibeCodedMode()) {
2866
- return this.vibeCodedRequest("POST", `/cart/${cartId}/link`);
3181
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2867
3182
  }
2868
3183
  if (this.storeId && !this.apiKey) {
2869
- return this.storefrontRequest("POST", `/cart/${cartId}/link`);
3184
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2870
3185
  }
2871
3186
  throw new BrainerceError("linkCart is only available in vibe-coded or storefront mode", 400);
2872
3187
  }
@@ -2929,13 +3244,13 @@ var BrainerceClient = class {
2929
3244
  if (this.isVibeCodedMode()) {
2930
3245
  return this.vibeCodedRequest(
2931
3246
  "GET",
2932
- `/products/${productId}/discount-badge`
3247
+ `/products/${encodePathSegment(productId)}/discount-badge`
2933
3248
  );
2934
3249
  }
2935
3250
  if (this.storeId && !this.apiKey) {
2936
3251
  return this.storefrontRequest(
2937
3252
  "GET",
2938
- `/products/${productId}/discount-badge`
3253
+ `/products/${encodePathSegment(productId)}/discount-badge`
2939
3254
  );
2940
3255
  }
2941
3256
  throw new BrainerceError(
@@ -2959,10 +3274,13 @@ var BrainerceClient = class {
2959
3274
  */
2960
3275
  async getCartNudges(cartId) {
2961
3276
  if (this.isVibeCodedMode()) {
2962
- return this.vibeCodedRequest("GET", `/cart/${cartId}/nudges`);
3277
+ return this.vibeCodedRequest("GET", `/cart/${encodePathSegment(cartId)}/nudges`);
2963
3278
  }
2964
3279
  if (this.storeId && !this.apiKey) {
2965
- return this.storefrontRequest("GET", `/cart/${cartId}/nudges`);
3280
+ return this.storefrontRequest(
3281
+ "GET",
3282
+ `/cart/${encodePathSegment(cartId)}/nudges`
3283
+ );
2966
3284
  }
2967
3285
  throw new BrainerceError("getCartNudges() requires vibe-coded or storefront mode", 400);
2968
3286
  }
@@ -2987,7 +3305,7 @@ var BrainerceClient = class {
2987
3305
  if (this.isVibeCodedMode()) {
2988
3306
  return this.vibeCodedRequest(
2989
3307
  "GET",
2990
- `/products/${productId}/recommendations`,
3308
+ `/products/${encodePathSegment(productId)}/recommendations`,
2991
3309
  void 0,
2992
3310
  queryParams
2993
3311
  );
@@ -2995,7 +3313,7 @@ var BrainerceClient = class {
2995
3313
  if (this.storeId && !this.apiKey) {
2996
3314
  return this.storefrontRequest(
2997
3315
  "GET",
2998
- `/products/${productId}/recommendations`,
3316
+ `/products/${encodePathSegment(productId)}/recommendations`,
2999
3317
  void 0,
3000
3318
  queryParams
3001
3319
  );
@@ -3025,7 +3343,7 @@ var BrainerceClient = class {
3025
3343
  if (this.isVibeCodedMode()) {
3026
3344
  return this.vibeCodedRequest(
3027
3345
  "GET",
3028
- `/products/${productId}/reviews`,
3346
+ `/products/${encodePathSegment(productId)}/reviews`,
3029
3347
  void 0,
3030
3348
  queryParams
3031
3349
  );
@@ -3033,7 +3351,7 @@ var BrainerceClient = class {
3033
3351
  if (this.storeId && !this.apiKey) {
3034
3352
  return this.storefrontRequest(
3035
3353
  "GET",
3036
- `/products/${productId}/reviews`,
3354
+ `/products/${encodePathSegment(productId)}/reviews`,
3037
3355
  void 0,
3038
3356
  queryParams
3039
3357
  );
@@ -3057,10 +3375,16 @@ var BrainerceClient = class {
3057
3375
  */
3058
3376
  async getMyProductReview(productId) {
3059
3377
  if (this.isVibeCodedMode()) {
3060
- return this.vibeCodedRequest("GET", `/products/${productId}/reviews/me`);
3378
+ return this.vibeCodedRequest(
3379
+ "GET",
3380
+ `/products/${encodePathSegment(productId)}/reviews/me`
3381
+ );
3061
3382
  }
3062
3383
  if (this.storeId && !this.apiKey) {
3063
- return this.storefrontRequest("GET", `/products/${productId}/reviews/me`);
3384
+ return this.storefrontRequest(
3385
+ "GET",
3386
+ `/products/${encodePathSegment(productId)}/reviews/me`
3387
+ );
3064
3388
  }
3065
3389
  throw new BrainerceError("getMyProductReview() requires vibe-coded or storefront mode", 400);
3066
3390
  }
@@ -3084,10 +3408,18 @@ var BrainerceClient = class {
3084
3408
  */
3085
3409
  async submitProductReview(productId, input) {
3086
3410
  if (this.isVibeCodedMode()) {
3087
- return this.vibeCodedRequest("POST", `/products/${productId}/reviews`, input);
3411
+ return this.vibeCodedRequest(
3412
+ "POST",
3413
+ `/products/${encodePathSegment(productId)}/reviews`,
3414
+ input
3415
+ );
3088
3416
  }
3089
3417
  if (this.storeId && !this.apiKey) {
3090
- return this.storefrontRequest("POST", `/products/${productId}/reviews`, input);
3418
+ return this.storefrontRequest(
3419
+ "POST",
3420
+ `/products/${encodePathSegment(productId)}/reviews`,
3421
+ input
3422
+ );
3091
3423
  }
3092
3424
  throw new BrainerceError("submitProductReview() requires vibe-coded or storefront mode", 400);
3093
3425
  }
@@ -3100,14 +3432,14 @@ var BrainerceClient = class {
3100
3432
  if (this.isVibeCodedMode()) {
3101
3433
  return this.vibeCodedRequest(
3102
3434
  "PATCH",
3103
- `/products/${productId}/reviews/me`,
3435
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3104
3436
  input
3105
3437
  );
3106
3438
  }
3107
3439
  if (this.storeId && !this.apiKey) {
3108
3440
  return this.storefrontRequest(
3109
3441
  "PATCH",
3110
- `/products/${productId}/reviews/me`,
3442
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3111
3443
  input
3112
3444
  );
3113
3445
  }
@@ -3119,11 +3451,17 @@ var BrainerceClient = class {
3119
3451
  */
3120
3452
  async deleteMyProductReview(productId) {
3121
3453
  if (this.isVibeCodedMode()) {
3122
- await this.vibeCodedRequest("DELETE", `/products/${productId}/reviews/me`);
3454
+ await this.vibeCodedRequest(
3455
+ "DELETE",
3456
+ `/products/${encodePathSegment(productId)}/reviews/me`
3457
+ );
3123
3458
  return;
3124
3459
  }
3125
3460
  if (this.storeId && !this.apiKey) {
3126
- await this.storefrontRequest("DELETE", `/products/${productId}/reviews/me`);
3461
+ await this.storefrontRequest(
3462
+ "DELETE",
3463
+ `/products/${encodePathSegment(productId)}/reviews/me`
3464
+ );
3127
3465
  return;
3128
3466
  }
3129
3467
  throw new BrainerceError("deleteMyProductReview() requires vibe-coded or storefront mode", 400);
@@ -3142,7 +3480,7 @@ var BrainerceClient = class {
3142
3480
  if (params?.visibility) queryParams.visibility = params.visibility;
3143
3481
  return this.adminRequest(
3144
3482
  "GET",
3145
- `/api/v1/products/${productId}/reviews`,
3483
+ `/api/v1/products/${encodePathSegment(productId)}/reviews`,
3146
3484
  void 0,
3147
3485
  queryParams
3148
3486
  );
@@ -3154,7 +3492,7 @@ var BrainerceClient = class {
3154
3492
  }
3155
3493
  return this.adminRequest(
3156
3494
  "PATCH",
3157
- `/api/v1/reviews/${reviewId}/hide`,
3495
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/hide`,
3158
3496
  void 0,
3159
3497
  storeId ? { storeId } : void 0
3160
3498
  );
@@ -3166,7 +3504,7 @@ var BrainerceClient = class {
3166
3504
  }
3167
3505
  return this.adminRequest(
3168
3506
  "PATCH",
3169
- `/api/v1/reviews/${reviewId}/show`,
3507
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/show`,
3170
3508
  void 0,
3171
3509
  storeId ? { storeId } : void 0
3172
3510
  );
@@ -3191,7 +3529,7 @@ var BrainerceClient = class {
3191
3529
  if (this.isVibeCodedMode()) {
3192
3530
  return this.vibeCodedRequest(
3193
3531
  "GET",
3194
- `/cart/${cartId}/recommendations`,
3532
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3195
3533
  void 0,
3196
3534
  queryParams
3197
3535
  );
@@ -3199,7 +3537,7 @@ var BrainerceClient = class {
3199
3537
  if (this.storeId && !this.apiKey) {
3200
3538
  return this.storefrontRequest(
3201
3539
  "GET",
3202
- `/cart/${cartId}/recommendations`,
3540
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3203
3541
  void 0,
3204
3542
  queryParams
3205
3543
  );
@@ -3226,10 +3564,16 @@ var BrainerceClient = class {
3226
3564
  */
3227
3565
  async getCartUpgrades(cartId) {
3228
3566
  if (this.isVibeCodedMode()) {
3229
- return this.vibeCodedRequest("GET", `/cart/${cartId}/upgrades`);
3567
+ return this.vibeCodedRequest(
3568
+ "GET",
3569
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3570
+ );
3230
3571
  }
3231
3572
  if (this.storeId && !this.apiKey) {
3232
- return this.storefrontRequest("GET", `/cart/${cartId}/upgrades`);
3573
+ return this.storefrontRequest(
3574
+ "GET",
3575
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3576
+ );
3233
3577
  }
3234
3578
  throw new BrainerceError("getCartUpgrades() requires vibe-coded or storefront mode", 400);
3235
3579
  }
@@ -3251,10 +3595,16 @@ var BrainerceClient = class {
3251
3595
  */
3252
3596
  async getCartBundles(cartId) {
3253
3597
  if (this.isVibeCodedMode()) {
3254
- return this.vibeCodedRequest("GET", `/cart/${cartId}/bundles`);
3598
+ return this.vibeCodedRequest(
3599
+ "GET",
3600
+ `/cart/${encodePathSegment(cartId)}/bundles`
3601
+ );
3255
3602
  }
3256
3603
  if (this.storeId && !this.apiKey) {
3257
- return this.storefrontRequest("GET", `/cart/${cartId}/bundles`);
3604
+ return this.storefrontRequest(
3605
+ "GET",
3606
+ `/cart/${encodePathSegment(cartId)}/bundles`
3607
+ );
3258
3608
  }
3259
3609
  throw new BrainerceError("getCartBundles() requires vibe-coded or storefront mode", 400);
3260
3610
  }
@@ -3266,10 +3616,16 @@ var BrainerceClient = class {
3266
3616
  */
3267
3617
  async getCheckoutBumps(checkoutId) {
3268
3618
  if (this.isVibeCodedMode()) {
3269
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/bumps`);
3619
+ return this.vibeCodedRequest(
3620
+ "GET",
3621
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3622
+ );
3270
3623
  }
3271
3624
  if (this.storeId && !this.apiKey) {
3272
- return this.storefrontRequest("GET", `/checkout/${checkoutId}/bumps`);
3625
+ return this.storefrontRequest(
3626
+ "GET",
3627
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3628
+ );
3273
3629
  }
3274
3630
  throw new BrainerceError("getCheckoutBumps() requires vibe-coded or storefront mode", 400);
3275
3631
  }
@@ -3284,10 +3640,10 @@ var BrainerceClient = class {
3284
3640
  async addOrderBump(cartId, bumpConfigId, variantId) {
3285
3641
  const body = { bumpConfigId, ...variantId && { variantId } };
3286
3642
  if (this.isVibeCodedMode()) {
3287
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bump`, body);
3643
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3288
3644
  }
3289
3645
  if (this.storeId && !this.apiKey) {
3290
- return this.storefrontRequest("POST", `/cart/${cartId}/bump`, body);
3646
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3291
3647
  }
3292
3648
  throw new BrainerceError("addOrderBump() requires vibe-coded or storefront mode", 400);
3293
3649
  }
@@ -3300,10 +3656,16 @@ var BrainerceClient = class {
3300
3656
  */
3301
3657
  async removeOrderBump(cartId, bumpConfigId) {
3302
3658
  if (this.isVibeCodedMode()) {
3303
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3659
+ return this.vibeCodedRequest(
3660
+ "DELETE",
3661
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3662
+ );
3304
3663
  }
3305
3664
  if (this.storeId && !this.apiKey) {
3306
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3665
+ return this.storefrontRequest(
3666
+ "DELETE",
3667
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3668
+ );
3307
3669
  }
3308
3670
  throw new BrainerceError("removeOrderBump() requires vibe-coded or storefront mode", 400);
3309
3671
  }
@@ -3334,10 +3696,14 @@ var BrainerceClient = class {
3334
3696
  ...variantSelections && Object.keys(variantSelections).length > 0 ? { variantSelections } : {}
3335
3697
  };
3336
3698
  if (this.isVibeCodedMode()) {
3337
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bundle`, body);
3699
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bundle`, body);
3338
3700
  }
3339
3701
  if (this.storeId && !this.apiKey) {
3340
- return this.storefrontRequest("POST", `/cart/${cartId}/bundle`, body);
3702
+ return this.storefrontRequest(
3703
+ "POST",
3704
+ `/cart/${encodePathSegment(cartId)}/bundle`,
3705
+ body
3706
+ );
3341
3707
  }
3342
3708
  throw new BrainerceError("addBundleToCart() requires vibe-coded or storefront mode", 400);
3343
3709
  }
@@ -3350,10 +3716,16 @@ var BrainerceClient = class {
3350
3716
  */
3351
3717
  async removeBundleFromCart(cartId, bundleOfferId) {
3352
3718
  if (this.isVibeCodedMode()) {
3353
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3719
+ return this.vibeCodedRequest(
3720
+ "DELETE",
3721
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3722
+ );
3354
3723
  }
3355
3724
  if (this.storeId && !this.apiKey) {
3356
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3725
+ return this.storefrontRequest(
3726
+ "DELETE",
3727
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3728
+ );
3357
3729
  }
3358
3730
  throw new BrainerceError("removeBundleFromCart() requires vibe-coded or storefront mode", 400);
3359
3731
  }
@@ -3939,18 +4311,18 @@ var BrainerceClient = class {
3939
4311
  async getCheckout(checkoutId) {
3940
4312
  if (this.isVibeCodedMode()) {
3941
4313
  return this.withGuards(
3942
- this.vibeCodedRequest("GET", `/checkout/${checkoutId}`),
4314
+ this.vibeCodedRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3943
4315
  "checkout"
3944
4316
  );
3945
4317
  }
3946
4318
  if (this.storeId && !this.apiKey) {
3947
4319
  return this.withGuards(
3948
- this.storefrontRequest("GET", `/checkout/${checkoutId}`),
4320
+ this.storefrontRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3949
4321
  "checkout"
3950
4322
  );
3951
4323
  }
3952
4324
  return this.withGuards(
3953
- this.adminRequest("GET", `/api/v1/checkout/${checkoutId}`),
4325
+ this.adminRequest("GET", `/api/v1/checkout/${encodePathSegment(checkoutId)}`),
3954
4326
  "checkout"
3955
4327
  );
3956
4328
  }
@@ -3973,18 +4345,30 @@ var BrainerceClient = class {
3973
4345
  async applyCheckoutCoupon(checkoutId, code) {
3974
4346
  if (this.isVibeCodedMode()) {
3975
4347
  return this.withGuards(
3976
- this.vibeCodedRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4348
+ this.vibeCodedRequest(
4349
+ "POST",
4350
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4351
+ { code }
4352
+ ),
3977
4353
  "checkout"
3978
4354
  );
3979
4355
  }
3980
4356
  if (this.storeId && !this.apiKey) {
3981
4357
  return this.withGuards(
3982
- this.storefrontRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4358
+ this.storefrontRequest(
4359
+ "POST",
4360
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4361
+ { code }
4362
+ ),
3983
4363
  "checkout"
3984
4364
  );
3985
4365
  }
3986
4366
  return this.withGuards(
3987
- this.adminRequest("POST", `/api/v1/checkout/${checkoutId}/coupon`, { code }),
4367
+ this.adminRequest(
4368
+ "POST",
4369
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`,
4370
+ { code }
4371
+ ),
3988
4372
  "checkout"
3989
4373
  );
3990
4374
  }
@@ -4002,18 +4386,27 @@ var BrainerceClient = class {
4002
4386
  async removeCheckoutCoupon(checkoutId) {
4003
4387
  if (this.isVibeCodedMode()) {
4004
4388
  return this.withGuards(
4005
- this.vibeCodedRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4389
+ this.vibeCodedRequest(
4390
+ "DELETE",
4391
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4392
+ ),
4006
4393
  "checkout"
4007
4394
  );
4008
4395
  }
4009
4396
  if (this.storeId && !this.apiKey) {
4010
4397
  return this.withGuards(
4011
- this.storefrontRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4398
+ this.storefrontRequest(
4399
+ "DELETE",
4400
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4401
+ ),
4012
4402
  "checkout"
4013
4403
  );
4014
4404
  }
4015
4405
  return this.withGuards(
4016
- this.adminRequest("DELETE", `/api/v1/checkout/${checkoutId}/coupon`),
4406
+ this.adminRequest(
4407
+ "DELETE",
4408
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`
4409
+ ),
4017
4410
  "checkout"
4018
4411
  );
4019
4412
  }
@@ -4031,12 +4424,24 @@ var BrainerceClient = class {
4031
4424
  */
4032
4425
  async setCheckoutCustomer(checkoutId, data) {
4033
4426
  if (this.isVibeCodedMode()) {
4034
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4427
+ return this.vibeCodedRequest(
4428
+ "PATCH",
4429
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4430
+ data
4431
+ );
4035
4432
  }
4036
4433
  if (this.storeId && !this.apiKey) {
4037
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4434
+ return this.storefrontRequest(
4435
+ "PATCH",
4436
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4437
+ data
4438
+ );
4038
4439
  }
4039
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/customer`, data);
4440
+ return this.adminRequest(
4441
+ "PATCH",
4442
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/customer`,
4443
+ data
4444
+ );
4040
4445
  }
4041
4446
  /**
4042
4447
  * Get available shipping destinations for this store.
@@ -4104,20 +4509,20 @@ var BrainerceClient = class {
4104
4509
  if (this.isVibeCodedMode()) {
4105
4510
  return this.vibeCodedRequest(
4106
4511
  "PATCH",
4107
- `/checkout/${checkoutId}/shipping-address`,
4512
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4108
4513
  address
4109
4514
  );
4110
4515
  }
4111
4516
  if (this.storeId && !this.apiKey) {
4112
4517
  return this.storefrontRequest(
4113
4518
  "PATCH",
4114
- `/checkout/${checkoutId}/shipping-address`,
4519
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4115
4520
  address
4116
4521
  );
4117
4522
  }
4118
4523
  return this.adminRequest(
4119
4524
  "PATCH",
4120
- `/api/v1/checkout/${checkoutId}/shipping-address`,
4525
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4121
4526
  address
4122
4527
  );
4123
4528
  }
@@ -4135,19 +4540,19 @@ var BrainerceClient = class {
4135
4540
  if (this.isVibeCodedMode()) {
4136
4541
  const result = await this.vibeCodedRequest(
4137
4542
  "GET",
4138
- `/checkout/${checkoutId}/shipping-rates`
4543
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4139
4544
  );
4140
4545
  return result.rates;
4141
4546
  }
4142
4547
  if (this.storeId && !this.apiKey) {
4143
4548
  return this.storefrontRequest(
4144
4549
  "GET",
4145
- `/checkout/${checkoutId}/shipping-rates`
4550
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4146
4551
  );
4147
4552
  }
4148
4553
  return this.adminRequest(
4149
4554
  "GET",
4150
- `/api/v1/checkout/${checkoutId}/shipping-rates`
4555
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4151
4556
  );
4152
4557
  }
4153
4558
  /**
@@ -4162,24 +4567,36 @@ var BrainerceClient = class {
4162
4567
  async selectShippingMethod(checkoutId, shippingRateId) {
4163
4568
  if (this.isVibeCodedMode()) {
4164
4569
  return this.withGuards(
4165
- this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4166
- shippingMethodId: shippingRateId
4167
- }),
4570
+ this.vibeCodedRequest(
4571
+ "PATCH",
4572
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4573
+ {
4574
+ shippingRateId
4575
+ }
4576
+ ),
4168
4577
  "checkout"
4169
4578
  );
4170
4579
  }
4171
4580
  if (this.storeId && !this.apiKey) {
4172
4581
  return this.withGuards(
4173
- this.storefrontRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4174
- shippingRateId
4175
- }),
4582
+ this.storefrontRequest(
4583
+ "PATCH",
4584
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4585
+ {
4586
+ shippingRateId
4587
+ }
4588
+ ),
4176
4589
  "checkout"
4177
4590
  );
4178
4591
  }
4179
4592
  return this.withGuards(
4180
- this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/shipping-method`, {
4181
- shippingRateId
4182
- }),
4593
+ this.adminRequest(
4594
+ "PATCH",
4595
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4596
+ {
4597
+ shippingRateId
4598
+ }
4599
+ ),
4183
4600
  "checkout"
4184
4601
  );
4185
4602
  }
@@ -4218,18 +4635,30 @@ var BrainerceClient = class {
4218
4635
  */
4219
4636
  async setDeliveryType(checkoutId, deliveryType) {
4220
4637
  if (this.isVibeCodedMode()) {
4221
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4222
- deliveryType
4223
- });
4638
+ return this.vibeCodedRequest(
4639
+ "PATCH",
4640
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4641
+ {
4642
+ deliveryType
4643
+ }
4644
+ );
4224
4645
  }
4225
4646
  if (this.storeId && !this.apiKey) {
4226
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4227
- deliveryType
4228
- });
4647
+ return this.storefrontRequest(
4648
+ "PATCH",
4649
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4650
+ {
4651
+ deliveryType
4652
+ }
4653
+ );
4229
4654
  }
4230
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/delivery-type`, {
4231
- deliveryType
4232
- });
4655
+ return this.adminRequest(
4656
+ "PATCH",
4657
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4658
+ {
4659
+ deliveryType
4660
+ }
4661
+ );
4233
4662
  }
4234
4663
  /**
4235
4664
  * Select a pickup location for checkout.
@@ -4251,20 +4680,20 @@ var BrainerceClient = class {
4251
4680
  if (this.isVibeCodedMode()) {
4252
4681
  return this.vibeCodedRequest(
4253
4682
  "PATCH",
4254
- `/checkout/${checkoutId}/pickup-location`,
4683
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4255
4684
  data
4256
4685
  );
4257
4686
  }
4258
4687
  if (this.storeId && !this.apiKey) {
4259
4688
  return this.storefrontRequest(
4260
4689
  "PATCH",
4261
- `/checkout/${checkoutId}/pickup-location`,
4690
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4262
4691
  data
4263
4692
  );
4264
4693
  }
4265
4694
  return this.adminRequest(
4266
4695
  "PATCH",
4267
- `/api/v1/checkout/${checkoutId}/pickup-location`,
4696
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4268
4697
  data
4269
4698
  );
4270
4699
  }
@@ -4296,20 +4725,20 @@ var BrainerceClient = class {
4296
4725
  if (this.isVibeCodedMode()) {
4297
4726
  return this.vibeCodedRequest(
4298
4727
  "PATCH",
4299
- `/checkout/${checkoutId}/billing-address`,
4728
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4300
4729
  address
4301
4730
  );
4302
4731
  }
4303
4732
  if (this.storeId && !this.apiKey) {
4304
4733
  return this.storefrontRequest(
4305
4734
  "PATCH",
4306
- `/checkout/${checkoutId}/billing-address`,
4735
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4307
4736
  address
4308
4737
  );
4309
4738
  }
4310
4739
  return this.adminRequest(
4311
4740
  "PATCH",
4312
- `/api/v1/checkout/${checkoutId}/billing-address`,
4741
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4313
4742
  address
4314
4743
  );
4315
4744
  }
@@ -4328,17 +4757,17 @@ var BrainerceClient = class {
4328
4757
  if (this.isVibeCodedMode()) {
4329
4758
  result = await this.vibeCodedRequest(
4330
4759
  "POST",
4331
- `/checkout/${checkoutId}/complete`
4760
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4332
4761
  );
4333
4762
  } else if (this.storeId && !this.apiKey) {
4334
4763
  result = await this.storefrontRequest(
4335
4764
  "POST",
4336
- `/checkout/${checkoutId}/complete`
4765
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4337
4766
  );
4338
4767
  } else {
4339
4768
  result = await this.adminRequest(
4340
4769
  "POST",
4341
- `/api/v1/checkout/${checkoutId}/complete`
4770
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/complete`
4342
4771
  );
4343
4772
  }
4344
4773
  this.customerCartId = null;
@@ -4356,18 +4785,18 @@ var BrainerceClient = class {
4356
4785
  if (this.isVibeCodedMode()) {
4357
4786
  return this.vibeCodedRequest(
4358
4787
  "GET",
4359
- `/checkout/${checkoutId}/custom-fields`
4788
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4360
4789
  );
4361
4790
  }
4362
4791
  if (this.storeId && !this.apiKey) {
4363
4792
  return this.storefrontRequest(
4364
4793
  "GET",
4365
- `/checkout/${checkoutId}/custom-fields`
4794
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4366
4795
  );
4367
4796
  }
4368
4797
  return this.adminRequest(
4369
4798
  "GET",
4370
- `/api/v1/checkouts/${checkoutId}/custom-fields`
4799
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`
4371
4800
  );
4372
4801
  }
4373
4802
  /**
@@ -4390,20 +4819,20 @@ var BrainerceClient = class {
4390
4819
  if (this.isVibeCodedMode()) {
4391
4820
  return this.vibeCodedRequest(
4392
4821
  "PATCH",
4393
- `/checkout/${checkoutId}/custom-fields`,
4822
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4394
4823
  data
4395
4824
  );
4396
4825
  }
4397
4826
  if (this.storeId && !this.apiKey) {
4398
4827
  return this.storefrontRequest(
4399
4828
  "PATCH",
4400
- `/checkout/${checkoutId}/custom-fields`,
4829
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4401
4830
  data
4402
4831
  );
4403
4832
  }
4404
4833
  return this.adminRequest(
4405
4834
  "PATCH",
4406
- `/api/v1/checkouts/${checkoutId}/custom-fields`,
4835
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`,
4407
4836
  data
4408
4837
  );
4409
4838
  }
@@ -4418,17 +4847,17 @@ var BrainerceClient = class {
4418
4847
  if (this.isVibeCodedMode()) {
4419
4848
  result = await this.vibeCodedRequest(
4420
4849
  "DELETE",
4421
- `/checkout/${checkoutId}`
4850
+ `/checkout/${encodePathSegment(checkoutId)}`
4422
4851
  );
4423
4852
  } else if (this.storeId && !this.apiKey) {
4424
4853
  result = await this.storefrontRequest(
4425
4854
  "DELETE",
4426
- `/checkout/${checkoutId}`
4855
+ `/checkout/${encodePathSegment(checkoutId)}`
4427
4856
  );
4428
4857
  } else {
4429
4858
  result = await this.adminRequest(
4430
4859
  "DELETE",
4431
- `/api/v1/checkout/${checkoutId}`
4860
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}`
4432
4861
  );
4433
4862
  }
4434
4863
  this.clearActiveCheckoutStorage();
@@ -4596,7 +5025,10 @@ var BrainerceClient = class {
4596
5025
  400
4597
5026
  );
4598
5027
  }
4599
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
5028
+ return this.vibeCodedRequest(
5029
+ "GET",
5030
+ `/checkout/${encodePathSegment(checkoutId)}/payment-status`
5031
+ );
4600
5032
  }
4601
5033
  /**
4602
5034
  * Confirm a client-side SDK payment from the frontend.
@@ -4695,7 +5127,7 @@ var BrainerceClient = class {
4695
5127
  const startTime = Date.now();
4696
5128
  let attempts = 0;
4697
5129
  let currentDelay = initialDelayMs;
4698
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5130
+ const sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4699
5131
  while (Date.now() - startTime < maxWaitMs) {
4700
5132
  attempts++;
4701
5133
  const status = await this.getPaymentStatus(checkoutId);
@@ -4720,7 +5152,7 @@ var BrainerceClient = class {
4720
5152
  const remainingTime = maxWaitMs - (Date.now() - startTime);
4721
5153
  const sleepTime = Math.min(currentDelay, remainingTime, 8e3);
4722
5154
  if (sleepTime > 0) {
4723
- await sleep(sleepTime);
5155
+ await sleep2(sleepTime);
4724
5156
  currentDelay = Math.min(currentDelay * 2, 8e3);
4725
5157
  }
4726
5158
  }
@@ -5235,7 +5667,7 @@ var BrainerceClient = class {
5235
5667
  if (data.shippingAddress) {
5236
5668
  const result = await this.vibeCodedRequest(
5237
5669
  "PATCH",
5238
- `/checkout/${checkoutId}/shipping-address`,
5670
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
5239
5671
  data.shippingAddress
5240
5672
  );
5241
5673
  checkout = result.checkout;
@@ -5243,7 +5675,7 @@ var BrainerceClient = class {
5243
5675
  if (data.billingAddress) {
5244
5676
  checkout = await this.vibeCodedRequest(
5245
5677
  "PATCH",
5246
- `/checkout/${checkoutId}/billing-address`,
5678
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
5247
5679
  data.billingAddress
5248
5680
  );
5249
5681
  }
@@ -5277,7 +5709,7 @@ var BrainerceClient = class {
5277
5709
  async completeGuestCheckout(checkoutId, options) {
5278
5710
  const result = await this.vibeCodedRequest(
5279
5711
  "POST",
5280
- `/checkout/${checkoutId}/complete`,
5712
+ `/checkout/${encodePathSegment(checkoutId)}/complete`,
5281
5713
  {}
5282
5714
  );
5283
5715
  if (options?.clearCartOnSuccess !== false) {
@@ -5585,13 +6017,13 @@ var BrainerceClient = class {
5585
6017
  if (this.isVibeCodedMode()) {
5586
6018
  return this.vibeCodedRequest(
5587
6019
  "GET",
5588
- `/customers/me/orders/${orderId}/downloads${qs}`
6020
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5589
6021
  );
5590
6022
  }
5591
6023
  if (this.storeId && !this.apiKey) {
5592
6024
  return this.storefrontRequest(
5593
6025
  "GET",
5594
- `/customers/me/orders/${orderId}/downloads${qs}`
6026
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5595
6027
  );
5596
6028
  }
5597
6029
  throw new BrainerceError(
@@ -5684,14 +6116,14 @@ var BrainerceClient = class {
5684
6116
  if (this.isVibeCodedMode()) {
5685
6117
  return this.vibeCodedRequest(
5686
6118
  "PATCH",
5687
- `/customers/me/addresses/${addressId}`,
6119
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5688
6120
  data
5689
6121
  );
5690
6122
  }
5691
6123
  if (this.storeId && !this.apiKey) {
5692
6124
  return this.storefrontRequest(
5693
6125
  "PATCH",
5694
- `/customers/me/addresses/${addressId}`,
6126
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5695
6127
  data
5696
6128
  );
5697
6129
  }
@@ -5712,11 +6144,17 @@ var BrainerceClient = class {
5712
6144
  );
5713
6145
  }
5714
6146
  if (this.isVibeCodedMode()) {
5715
- await this.vibeCodedRequest("DELETE", `/customers/me/addresses/${addressId}`);
6147
+ await this.vibeCodedRequest(
6148
+ "DELETE",
6149
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6150
+ );
5716
6151
  return;
5717
6152
  }
5718
6153
  if (this.storeId && !this.apiKey) {
5719
- await this.storefrontRequest("DELETE", `/customers/me/addresses/${addressId}`);
6154
+ await this.storefrontRequest(
6155
+ "DELETE",
6156
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6157
+ );
5720
6158
  return;
5721
6159
  }
5722
6160
  throw new BrainerceError(
@@ -5769,7 +6207,10 @@ var BrainerceClient = class {
5769
6207
  * ```
5770
6208
  */
5771
6209
  async getCustomApiIntegration(integrationId) {
5772
- return this.adminRequest("GET", `/api/v1/custom-api/${integrationId}`);
6210
+ return this.adminRequest(
6211
+ "GET",
6212
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6213
+ );
5773
6214
  }
5774
6215
  /**
5775
6216
  * Create a new Custom API integration
@@ -5812,7 +6253,7 @@ var BrainerceClient = class {
5812
6253
  async updateCustomApiIntegration(integrationId, data) {
5813
6254
  return this.adminRequest(
5814
6255
  "PATCH",
5815
- `/api/v1/custom-api/${integrationId}`,
6256
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`,
5816
6257
  data
5817
6258
  );
5818
6259
  }
@@ -5826,7 +6267,10 @@ var BrainerceClient = class {
5826
6267
  * ```
5827
6268
  */
5828
6269
  async deleteCustomApiIntegration(integrationId) {
5829
- await this.adminRequest("DELETE", `/api/v1/custom-api/${integrationId}`);
6270
+ await this.adminRequest(
6271
+ "DELETE",
6272
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6273
+ );
5830
6274
  }
5831
6275
  /**
5832
6276
  * Test connection to a Custom API
@@ -5845,7 +6289,7 @@ var BrainerceClient = class {
5845
6289
  async testCustomApiConnection(integrationId) {
5846
6290
  return this.adminRequest(
5847
6291
  "POST",
5848
- `/api/v1/custom-api/${integrationId}/test`
6292
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}/test`
5849
6293
  );
5850
6294
  }
5851
6295
  // -------------------- Inventory Reservations --------------------
@@ -5966,7 +6410,10 @@ var BrainerceClient = class {
5966
6410
  * Requires Admin mode (apiKey)
5967
6411
  */
5968
6412
  async getCategory(categoryId) {
5969
- return this.adminRequest("GET", `/api/v1/categories/${categoryId}`);
6413
+ return this.adminRequest(
6414
+ "GET",
6415
+ `/api/v1/categories/${encodePathSegment(categoryId)}`
6416
+ );
5970
6417
  }
5971
6418
  /**
5972
6419
  * Create a new category
@@ -5989,14 +6436,18 @@ var BrainerceClient = class {
5989
6436
  * Requires Admin mode (apiKey)
5990
6437
  */
5991
6438
  async updateCategory(categoryId, data) {
5992
- return this.adminRequest("PATCH", `/api/v1/categories/${categoryId}`, data);
6439
+ return this.adminRequest(
6440
+ "PATCH",
6441
+ `/api/v1/categories/${encodePathSegment(categoryId)}`,
6442
+ data
6443
+ );
5993
6444
  }
5994
6445
  /**
5995
6446
  * Delete a category
5996
6447
  * Requires Admin mode (apiKey)
5997
6448
  */
5998
6449
  async deleteCategory(categoryId) {
5999
- await this.adminRequest("DELETE", `/api/v1/categories/${categoryId}`);
6450
+ await this.adminRequest("DELETE", `/api/v1/categories/${encodePathSegment(categoryId)}`);
6000
6451
  }
6001
6452
  // -------------------- Taxonomy: Brands (Admin) --------------------
6002
6453
  // These methods require Admin mode (apiKey)
@@ -6012,7 +6463,7 @@ var BrainerceClient = class {
6012
6463
  * Requires Admin mode (apiKey)
6013
6464
  */
6014
6465
  async getBrand(brandId) {
6015
- return this.adminRequest("GET", `/api/v1/brands/${brandId}`);
6466
+ return this.adminRequest("GET", `/api/v1/brands/${encodePathSegment(brandId)}`);
6016
6467
  }
6017
6468
  /**
6018
6469
  * Create a new brand
@@ -6035,14 +6486,14 @@ var BrainerceClient = class {
6035
6486
  * Requires Admin mode (apiKey)
6036
6487
  */
6037
6488
  async updateBrand(brandId, data) {
6038
- return this.adminRequest("PATCH", `/api/v1/brands/${brandId}`, data);
6489
+ return this.adminRequest("PATCH", `/api/v1/brands/${encodePathSegment(brandId)}`, data);
6039
6490
  }
6040
6491
  /**
6041
6492
  * Delete a brand
6042
6493
  * Requires Admin mode (apiKey)
6043
6494
  */
6044
6495
  async deleteBrand(brandId) {
6045
- await this.adminRequest("DELETE", `/api/v1/brands/${brandId}`);
6496
+ await this.adminRequest("DELETE", `/api/v1/brands/${encodePathSegment(brandId)}`);
6046
6497
  }
6047
6498
  // -------------------- Taxonomy: Tags (Admin) --------------------
6048
6499
  // These methods require Admin mode (apiKey)
@@ -6058,7 +6509,7 @@ var BrainerceClient = class {
6058
6509
  * Requires Admin mode (apiKey)
6059
6510
  */
6060
6511
  async getTag(tagId) {
6061
- return this.adminRequest("GET", `/api/v1/tags/${tagId}`);
6512
+ return this.adminRequest("GET", `/api/v1/tags/${encodePathSegment(tagId)}`);
6062
6513
  }
6063
6514
  /**
6064
6515
  * Create a new tag
@@ -6080,14 +6531,14 @@ var BrainerceClient = class {
6080
6531
  * Requires Admin mode (apiKey)
6081
6532
  */
6082
6533
  async updateTag(tagId, data) {
6083
- return this.adminRequest("PATCH", `/api/v1/tags/${tagId}`, data);
6534
+ return this.adminRequest("PATCH", `/api/v1/tags/${encodePathSegment(tagId)}`, data);
6084
6535
  }
6085
6536
  /**
6086
6537
  * Delete a tag
6087
6538
  * Requires Admin mode (apiKey)
6088
6539
  */
6089
6540
  async deleteTag(tagId) {
6090
- await this.adminRequest("DELETE", `/api/v1/tags/${tagId}`);
6541
+ await this.adminRequest("DELETE", `/api/v1/tags/${encodePathSegment(tagId)}`);
6091
6542
  }
6092
6543
  // -------------------- Taxonomy: Attributes (Admin) --------------------
6093
6544
  // These methods require Admin mode (apiKey)
@@ -6108,7 +6559,10 @@ var BrainerceClient = class {
6108
6559
  * Requires Admin mode (apiKey)
6109
6560
  */
6110
6561
  async getAttribute(attributeId) {
6111
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}`);
6562
+ return this.adminRequest(
6563
+ "GET",
6564
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`
6565
+ );
6112
6566
  }
6113
6567
  /**
6114
6568
  * Create a new attribute
@@ -6131,21 +6585,28 @@ var BrainerceClient = class {
6131
6585
  * Requires Admin mode (apiKey)
6132
6586
  */
6133
6587
  async updateAttribute(attributeId, data) {
6134
- return this.adminRequest("PATCH", `/api/v1/attributes/${attributeId}`, data);
6588
+ return this.adminRequest(
6589
+ "PATCH",
6590
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`,
6591
+ data
6592
+ );
6135
6593
  }
6136
6594
  /**
6137
6595
  * Delete an attribute
6138
6596
  * Requires Admin mode (apiKey)
6139
6597
  */
6140
6598
  async deleteAttribute(attributeId) {
6141
- await this.adminRequest("DELETE", `/api/v1/attributes/${attributeId}`);
6599
+ await this.adminRequest("DELETE", `/api/v1/attributes/${encodePathSegment(attributeId)}`);
6142
6600
  }
6143
6601
  /**
6144
6602
  * Get all options for an attribute
6145
6603
  * Requires Admin mode (apiKey)
6146
6604
  */
6147
6605
  async getAttributeOptions(attributeId) {
6148
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}/options`);
6606
+ return this.adminRequest(
6607
+ "GET",
6608
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`
6609
+ );
6149
6610
  }
6150
6611
  /**
6151
6612
  * Create a new option for an attribute
@@ -6163,7 +6624,7 @@ var BrainerceClient = class {
6163
6624
  async createAttributeOption(attributeId, data) {
6164
6625
  return this.adminRequest(
6165
6626
  "POST",
6166
- `/api/v1/attributes/${attributeId}/options`,
6627
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`,
6167
6628
  data
6168
6629
  );
6169
6630
  }
@@ -6174,7 +6635,7 @@ var BrainerceClient = class {
6174
6635
  async updateAttributeOption(attributeId, optionId, data) {
6175
6636
  return this.adminRequest(
6176
6637
  "PATCH",
6177
- `/api/v1/attributes/${attributeId}/options/${optionId}`,
6638
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`,
6178
6639
  data
6179
6640
  );
6180
6641
  }
@@ -6185,7 +6646,7 @@ var BrainerceClient = class {
6185
6646
  async deleteAttributeOption(attributeId, optionId) {
6186
6647
  await this.adminRequest(
6187
6648
  "DELETE",
6188
- `/api/v1/attributes/${attributeId}/options/${optionId}`
6649
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`
6189
6650
  );
6190
6651
  }
6191
6652
  // -------------------- Modifier Groups (Admin) --------------------
@@ -6214,7 +6675,7 @@ var BrainerceClient = class {
6214
6675
  async listModifierGroups(storeId, params) {
6215
6676
  return this.adminRequest(
6216
6677
  "GET",
6217
- `/api/stores/${storeId}/modifier-groups`,
6678
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6218
6679
  void 0,
6219
6680
  params
6220
6681
  );
@@ -6229,7 +6690,7 @@ var BrainerceClient = class {
6229
6690
  async getModifierGroup(storeId, groupId) {
6230
6691
  return this.adminRequest(
6231
6692
  "GET",
6232
- `/api/stores/${storeId}/modifier-groups/${groupId}`
6693
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6233
6694
  );
6234
6695
  }
6235
6696
  /**
@@ -6251,7 +6712,11 @@ var BrainerceClient = class {
6251
6712
  * ```
6252
6713
  */
6253
6714
  async createModifierGroup(storeId, data) {
6254
- return this.adminRequest("POST", `/api/stores/${storeId}/modifier-groups`, data);
6715
+ return this.adminRequest(
6716
+ "POST",
6717
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6718
+ data
6719
+ );
6255
6720
  }
6256
6721
  /**
6257
6722
  * Update a modifier group's metadata or selection rules. Pass `status: 'archived'`
@@ -6261,7 +6726,7 @@ var BrainerceClient = class {
6261
6726
  async updateModifierGroup(storeId, groupId, data) {
6262
6727
  return this.adminRequest(
6263
6728
  "PATCH",
6264
- `/api/stores/${storeId}/modifier-groups/${groupId}`,
6729
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`,
6265
6730
  data
6266
6731
  );
6267
6732
  }
@@ -6272,7 +6737,10 @@ var BrainerceClient = class {
6272
6737
  * Requires Admin mode (apiKey).
6273
6738
  */
6274
6739
  async deleteModifierGroup(storeId, groupId) {
6275
- await this.adminRequest("DELETE", `/api/stores/${storeId}/modifier-groups/${groupId}`);
6740
+ await this.adminRequest(
6741
+ "DELETE",
6742
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6743
+ );
6276
6744
  }
6277
6745
  /**
6278
6746
  * Create a modifier inside a group (e.g., "Olives" inside the "Toppings" group).
@@ -6296,7 +6764,7 @@ var BrainerceClient = class {
6296
6764
  async createModifier(storeId, groupId, data) {
6297
6765
  return this.adminRequest(
6298
6766
  "POST",
6299
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers`,
6767
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers`,
6300
6768
  data
6301
6769
  );
6302
6770
  }
@@ -6307,7 +6775,7 @@ var BrainerceClient = class {
6307
6775
  async updateModifier(storeId, groupId, modifierId, data) {
6308
6776
  return this.adminRequest(
6309
6777
  "PATCH",
6310
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`,
6778
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`,
6311
6779
  data
6312
6780
  );
6313
6781
  }
@@ -6319,7 +6787,7 @@ var BrainerceClient = class {
6319
6787
  async deleteModifier(storeId, groupId, modifierId) {
6320
6788
  await this.adminRequest(
6321
6789
  "DELETE",
6322
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`
6790
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`
6323
6791
  );
6324
6792
  }
6325
6793
  /**
@@ -6338,7 +6806,7 @@ var BrainerceClient = class {
6338
6806
  async toggleModifierAvailability(storeId, groupId, modifierId, available) {
6339
6807
  return this.adminRequest(
6340
6808
  "POST",
6341
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}/availability-toggle`,
6809
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}/availability-toggle`,
6342
6810
  { available }
6343
6811
  );
6344
6812
  }
@@ -6359,7 +6827,7 @@ var BrainerceClient = class {
6359
6827
  async attachModifierGroup(storeId, productId, data) {
6360
6828
  return this.adminRequest(
6361
6829
  "POST",
6362
- `/api/stores/${storeId}/products/${productId}/modifier-groups`,
6830
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups`,
6363
6831
  data
6364
6832
  );
6365
6833
  }
@@ -6372,7 +6840,7 @@ var BrainerceClient = class {
6372
6840
  async updateAttachment(storeId, productId, attachmentId, data) {
6373
6841
  return this.adminRequest(
6374
6842
  "PATCH",
6375
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`,
6843
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`,
6376
6844
  data
6377
6845
  );
6378
6846
  }
@@ -6383,7 +6851,7 @@ var BrainerceClient = class {
6383
6851
  async detachModifierGroup(storeId, productId, attachmentId) {
6384
6852
  await this.adminRequest(
6385
6853
  "DELETE",
6386
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`
6854
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`
6387
6855
  );
6388
6856
  }
6389
6857
  // -------------------- Shipping: Zones and Rates (Admin) --------------------
@@ -6405,7 +6873,10 @@ var BrainerceClient = class {
6405
6873
  * Requires Admin mode (apiKey)
6406
6874
  */
6407
6875
  async getShippingZone(zoneId) {
6408
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}`);
6876
+ return this.adminRequest(
6877
+ "GET",
6878
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`
6879
+ );
6409
6880
  }
6410
6881
  /**
6411
6882
  * Create a new shipping zone
@@ -6428,21 +6899,28 @@ var BrainerceClient = class {
6428
6899
  * Requires Admin mode (apiKey)
6429
6900
  */
6430
6901
  async updateShippingZone(zoneId, data) {
6431
- return this.adminRequest("PATCH", `/api/v1/shipping/zones/${zoneId}`, data);
6902
+ return this.adminRequest(
6903
+ "PATCH",
6904
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`,
6905
+ data
6906
+ );
6432
6907
  }
6433
6908
  /**
6434
6909
  * Delete a shipping zone
6435
6910
  * Requires Admin mode (apiKey)
6436
6911
  */
6437
6912
  async deleteShippingZone(zoneId) {
6438
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}`);
6913
+ await this.adminRequest("DELETE", `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`);
6439
6914
  }
6440
6915
  /**
6441
6916
  * Get all shipping rates for a zone
6442
6917
  * Requires Admin mode (apiKey)
6443
6918
  */
6444
6919
  async getZoneShippingRates(zoneId) {
6445
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}/rates`);
6920
+ return this.adminRequest(
6921
+ "GET",
6922
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`
6923
+ );
6446
6924
  }
6447
6925
  /**
6448
6926
  * Create a new shipping rate for a zone
@@ -6462,7 +6940,7 @@ var BrainerceClient = class {
6462
6940
  async createZoneShippingRate(zoneId, data) {
6463
6941
  return this.adminRequest(
6464
6942
  "POST",
6465
- `/api/v1/shipping/zones/${zoneId}/rates`,
6943
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`,
6466
6944
  data
6467
6945
  );
6468
6946
  }
@@ -6473,7 +6951,7 @@ var BrainerceClient = class {
6473
6951
  async updateZoneShippingRate(zoneId, rateId, data) {
6474
6952
  return this.adminRequest(
6475
6953
  "PATCH",
6476
- `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`,
6954
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`,
6477
6955
  data
6478
6956
  );
6479
6957
  }
@@ -6482,7 +6960,149 @@ var BrainerceClient = class {
6482
6960
  * Requires Admin mode (apiKey)
6483
6961
  */
6484
6962
  async deleteZoneShippingRate(zoneId, rateId) {
6485
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`);
6963
+ await this.adminRequest(
6964
+ "DELETE",
6965
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`
6966
+ );
6967
+ }
6968
+ // -------------------- Regions (Admin mode, apiKey) --------------------
6969
+ // Multi-region commerce. storeId is derived from the api_key — do not pass it.
6970
+ // Requires the `regions:read` / `regions:write` scopes on the key.
6971
+ /** List the store's regions (paginated). */
6972
+ async getRegions() {
6973
+ return this.adminRequest("GET", "/api/v1/regions");
6974
+ }
6975
+ async getRegion(regionId) {
6976
+ return this.adminRequest("GET", `/api/v1/regions/${encodePathSegment(regionId)}`);
6977
+ }
6978
+ async createRegion(data) {
6979
+ return this.adminRequest("POST", "/api/v1/regions", data);
6980
+ }
6981
+ async updateRegion(regionId, data) {
6982
+ return this.adminRequest(
6983
+ "PATCH",
6984
+ `/api/v1/regions/${encodePathSegment(regionId)}`,
6985
+ data
6986
+ );
6987
+ }
6988
+ async deleteRegion(regionId) {
6989
+ await this.adminRequest("DELETE", `/api/v1/regions/${encodePathSegment(regionId)}`);
6990
+ }
6991
+ async setDefaultRegion(regionId) {
6992
+ return this.adminRequest(
6993
+ "PATCH",
6994
+ `/api/v1/regions/${encodePathSegment(regionId)}/set-default`
6995
+ );
6996
+ }
6997
+ /** Replace the region's enabled payment providers (AppInstallation IDs). */
6998
+ async updateRegionPaymentProviders(regionId, providerIds) {
6999
+ return this.adminRequest(
7000
+ "PUT",
7001
+ `/api/v1/regions/${encodePathSegment(regionId)}/payment-providers`,
7002
+ { providerIds }
7003
+ );
7004
+ }
7005
+ async addRegionCountries(regionId, countries) {
7006
+ return this.adminRequest(
7007
+ "POST",
7008
+ `/api/v1/regions/${encodePathSegment(regionId)}/countries`,
7009
+ { countries }
7010
+ );
7011
+ }
7012
+ async removeRegionCountry(regionId, countryCode) {
7013
+ return this.adminRequest(
7014
+ "DELETE",
7015
+ `/api/v1/regions/${encodePathSegment(regionId)}/countries/${encodePathSegment(countryCode)}`
7016
+ );
7017
+ }
7018
+ /** Installed payment providers compatible with this region's countries. */
7019
+ async getRegionCompatibleProviders(regionId) {
7020
+ return this.adminRequest(
7021
+ "GET",
7022
+ `/api/v1/regions/${encodePathSegment(regionId)}/compatible-providers`
7023
+ );
7024
+ }
7025
+ // -------------------- Regions (Storefront mode, public — no apiKey) --------------------
7026
+ // storeId-based, no auth. Call these from a storefront to detect the buyer's
7027
+ // region (story S1), then pair with detectRegion(). Admin/api-key callers use
7028
+ // getRegions()/getRegion() instead.
7029
+ /**
7030
+ * List the store's ACTIVE regions (public, no apiKey). Requires storeId mode.
7031
+ * Returns only storefront-safe fields (no internal flags). Default region first.
7032
+ */
7033
+ async getStoreRegions() {
7034
+ return this.storefrontRequest("GET", "/regions");
7035
+ }
7036
+ /**
7037
+ * Get one active public region plus its enabled payment providers (public).
7038
+ * Requires storeId mode. Throws 404 if the region is inactive or not found.
7039
+ */
7040
+ async getStoreRegion(regionId) {
7041
+ return this.storefrontRequest(
7042
+ "GET",
7043
+ `/regions/${encodePathSegment(regionId)}`
7044
+ );
7045
+ }
7046
+ /**
7047
+ * Client-side region detection — no network call. Returns the region whose
7048
+ * `countries` includes `country`, else the default region, else null.
7049
+ */
7050
+ detectRegion(country, regions) {
7051
+ const code = country.toUpperCase();
7052
+ return regions.find((r) => r.countries.includes(code)) ?? regions.find((r) => r.isDefault) ?? null;
7053
+ }
7054
+ // -------------------- Tax Classes (Storefront mode, public — no apiKey) --------------------
7055
+ /**
7056
+ * List the store's tax classes (public, no apiKey — storeId mode). Storefront-
7057
+ * safe fields only (id/name/slug/description/isDefault) for transparency UIs
7058
+ * such as a "9% VAT" badge. Admin/api-key callers use getTaxClasses().
7059
+ */
7060
+ async getStoreTaxClasses() {
7061
+ return this.storefrontRequest("GET", "/tax-classes");
7062
+ }
7063
+ // -------------------- Tax Classes (Admin mode, apiKey) --------------------
7064
+ // Requires the `tax-classes:read` / `tax-classes:write` scopes on the key.
7065
+ /** List the store's tax classes. */
7066
+ async getTaxClasses() {
7067
+ return this.adminRequest("GET", "/api/v1/tax-classes");
7068
+ }
7069
+ /** Get a tax class with its dependent counts (products/variants/categories/rates). */
7070
+ async getTaxClass(id) {
7071
+ return this.adminRequest("GET", `/api/v1/tax-classes/${encodePathSegment(id)}`);
7072
+ }
7073
+ async createTaxClass(data) {
7074
+ return this.adminRequest("POST", "/api/v1/tax-classes", data);
7075
+ }
7076
+ async updateTaxClass(id, data) {
7077
+ return this.adminRequest(
7078
+ "PATCH",
7079
+ `/api/v1/tax-classes/${encodePathSegment(id)}`,
7080
+ data
7081
+ );
7082
+ }
7083
+ async deleteTaxClass(id) {
7084
+ await this.adminRequest("DELETE", `/api/v1/tax-classes/${encodePathSegment(id)}`);
7085
+ }
7086
+ async setDefaultTaxClass(id) {
7087
+ return this.adminRequest(
7088
+ "PATCH",
7089
+ `/api/v1/tax-classes/${encodePathSegment(id)}/set-default`
7090
+ );
7091
+ }
7092
+ /** Bulk-assign this tax class to products / variants / categories. */
7093
+ async assignTaxClass(id, data) {
7094
+ return this.adminRequest(
7095
+ "POST",
7096
+ `/api/v1/tax-classes/${encodePathSegment(id)}/assign`,
7097
+ data
7098
+ );
7099
+ }
7100
+ /** Merge this tax class into another, moving all FKs, then delete it. */
7101
+ async mergeTaxClasses(id, targetId) {
7102
+ await this.adminRequest(
7103
+ "POST",
7104
+ `/api/v1/tax-classes/${encodePathSegment(id)}/merge-into/${encodePathSegment(targetId)}`
7105
+ );
6486
7106
  }
6487
7107
  // -------------------- Tax: Rates --------------------
6488
7108
  // These methods require Admin mode (apiKey)
@@ -6498,7 +7118,7 @@ var BrainerceClient = class {
6498
7118
  * Requires Admin mode (apiKey)
6499
7119
  */
6500
7120
  async getTaxRate(rateId) {
6501
- return this.adminRequest("GET", `/api/v1/tax/rates/${rateId}`);
7121
+ return this.adminRequest("GET", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6502
7122
  }
6503
7123
  /**
6504
7124
  * Create a new tax rate
@@ -6523,14 +7143,18 @@ var BrainerceClient = class {
6523
7143
  * Requires Admin mode (apiKey)
6524
7144
  */
6525
7145
  async updateTaxRate(rateId, data) {
6526
- return this.adminRequest("PATCH", `/api/v1/tax/rates/${rateId}`, data);
7146
+ return this.adminRequest(
7147
+ "PATCH",
7148
+ `/api/v1/tax/rates/${encodePathSegment(rateId)}`,
7149
+ data
7150
+ );
6527
7151
  }
6528
7152
  /**
6529
7153
  * Delete a tax rate
6530
7154
  * Requires Admin mode (apiKey)
6531
7155
  */
6532
7156
  async deleteTaxRate(rateId) {
6533
- await this.adminRequest("DELETE", `/api/v1/tax/rates/${rateId}`);
7157
+ await this.adminRequest("DELETE", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6534
7158
  }
6535
7159
  // -------------------- Metafields: Definitions --------------------
6536
7160
  // These methods require Admin mode (apiKey)
@@ -6586,7 +7210,7 @@ var BrainerceClient = class {
6586
7210
  async getMetafieldDefinition(definitionId) {
6587
7211
  return this.adminRequest(
6588
7212
  "GET",
6589
- `/api/v1/metafield-definitions/${definitionId}`
7213
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
6590
7214
  );
6591
7215
  }
6592
7216
  /**
@@ -6613,7 +7237,7 @@ var BrainerceClient = class {
6613
7237
  async updateMetafieldDefinition(definitionId, data) {
6614
7238
  return this.adminRequest(
6615
7239
  "PATCH",
6616
- `/api/v1/metafield-definitions/${definitionId}`,
7240
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`,
6617
7241
  data
6618
7242
  );
6619
7243
  }
@@ -6622,7 +7246,10 @@ var BrainerceClient = class {
6622
7246
  * Requires Admin mode (apiKey)
6623
7247
  */
6624
7248
  async deleteMetafieldDefinition(definitionId) {
6625
- await this.adminRequest("DELETE", `/api/v1/metafield-definitions/${definitionId}`);
7249
+ await this.adminRequest(
7250
+ "DELETE",
7251
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
7252
+ );
6626
7253
  }
6627
7254
  /**
6628
7255
  * Replace the platform publishing configuration on a metafield definition.
@@ -6646,7 +7273,7 @@ var BrainerceClient = class {
6646
7273
  async setMetafieldPlatforms(definitionId, data) {
6647
7274
  return this.adminRequest(
6648
7275
  "PUT",
6649
- `/api/v1/metafield-definitions/${definitionId}/platforms`,
7276
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/platforms`,
6650
7277
  data
6651
7278
  );
6652
7279
  }
@@ -6665,7 +7292,7 @@ var BrainerceClient = class {
6665
7292
  async publishMetafieldDefinitionToVibeCodedSite(definitionId, vibeCodedConnectionId) {
6666
7293
  return this.adminRequest(
6667
7294
  "POST",
6668
- `/api/v1/metafield-definitions/${definitionId}/publish-vibe-coded`,
7295
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/publish-vibe-coded`,
6669
7296
  { vibeCodedConnectionId }
6670
7297
  );
6671
7298
  }
@@ -6673,7 +7300,7 @@ var BrainerceClient = class {
6673
7300
  async unpublishMetafieldDefinitionFromVibeCodedSite(definitionId, vibeCodedConnectionId) {
6674
7301
  return this.adminRequest(
6675
7302
  "POST",
6676
- `/api/v1/metafield-definitions/${definitionId}/unpublish-vibe-coded`,
7303
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/unpublish-vibe-coded`,
6677
7304
  { vibeCodedConnectionId }
6678
7305
  );
6679
7306
  }
@@ -6681,7 +7308,7 @@ var BrainerceClient = class {
6681
7308
  async publishCategoryToVibeCodedSite(categoryId, vibeCodedConnectionId) {
6682
7309
  return this.adminRequest(
6683
7310
  "POST",
6684
- `/api/v1/categories/${categoryId}/publish-vibe-coded`,
7311
+ `/api/v1/categories/${encodePathSegment(categoryId)}/publish-vibe-coded`,
6685
7312
  { vibeCodedConnectionId }
6686
7313
  );
6687
7314
  }
@@ -6689,7 +7316,7 @@ var BrainerceClient = class {
6689
7316
  async unpublishCategoryFromVibeCodedSite(categoryId, vibeCodedConnectionId) {
6690
7317
  return this.adminRequest(
6691
7318
  "POST",
6692
- `/api/v1/categories/${categoryId}/unpublish-vibe-coded`,
7319
+ `/api/v1/categories/${encodePathSegment(categoryId)}/unpublish-vibe-coded`,
6693
7320
  { vibeCodedConnectionId }
6694
7321
  );
6695
7322
  }
@@ -6697,7 +7324,7 @@ var BrainerceClient = class {
6697
7324
  async publishTagToVibeCodedSite(tagId, vibeCodedConnectionId) {
6698
7325
  return this.adminRequest(
6699
7326
  "POST",
6700
- `/api/v1/tags/${tagId}/publish-vibe-coded`,
7327
+ `/api/v1/tags/${encodePathSegment(tagId)}/publish-vibe-coded`,
6701
7328
  { vibeCodedConnectionId }
6702
7329
  );
6703
7330
  }
@@ -6705,7 +7332,7 @@ var BrainerceClient = class {
6705
7332
  async unpublishTagFromVibeCodedSite(tagId, vibeCodedConnectionId) {
6706
7333
  return this.adminRequest(
6707
7334
  "POST",
6708
- `/api/v1/tags/${tagId}/unpublish-vibe-coded`,
7335
+ `/api/v1/tags/${encodePathSegment(tagId)}/unpublish-vibe-coded`,
6709
7336
  { vibeCodedConnectionId }
6710
7337
  );
6711
7338
  }
@@ -6713,7 +7340,7 @@ var BrainerceClient = class {
6713
7340
  async publishBrandToVibeCodedSite(brandId, vibeCodedConnectionId) {
6714
7341
  return this.adminRequest(
6715
7342
  "POST",
6716
- `/api/v1/brands/${brandId}/publish-vibe-coded`,
7343
+ `/api/v1/brands/${encodePathSegment(brandId)}/publish-vibe-coded`,
6717
7344
  { vibeCodedConnectionId }
6718
7345
  );
6719
7346
  }
@@ -6721,7 +7348,7 @@ var BrainerceClient = class {
6721
7348
  async unpublishBrandFromVibeCodedSite(brandId, vibeCodedConnectionId) {
6722
7349
  return this.adminRequest(
6723
7350
  "POST",
6724
- `/api/v1/brands/${brandId}/unpublish-vibe-coded`,
7351
+ `/api/v1/brands/${encodePathSegment(brandId)}/unpublish-vibe-coded`,
6725
7352
  { vibeCodedConnectionId }
6726
7353
  );
6727
7354
  }
@@ -6747,7 +7374,7 @@ var BrainerceClient = class {
6747
7374
  async setDefinitionProducts(definitionId, data) {
6748
7375
  return this.adminRequest(
6749
7376
  "PATCH",
6750
- `/api/v1/metafield-definitions/${definitionId}/products`,
7377
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/products`,
6751
7378
  data
6752
7379
  );
6753
7380
  }
@@ -6760,7 +7387,7 @@ var BrainerceClient = class {
6760
7387
  async getProductMetafields(productId) {
6761
7388
  return this.adminRequest(
6762
7389
  "GET",
6763
- `/api/v1/products/${productId}/metafields`
7390
+ `/api/v1/products/${encodePathSegment(productId)}/metafields`
6764
7391
  );
6765
7392
  }
6766
7393
  /**
@@ -6777,7 +7404,7 @@ var BrainerceClient = class {
6777
7404
  async setProductMetafield(productId, definitionId, data) {
6778
7405
  return this.adminRequest(
6779
7406
  "PUT",
6780
- `/api/v1/products/${productId}/metafields/${definitionId}`,
7407
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`,
6781
7408
  data
6782
7409
  );
6783
7410
  }
@@ -6788,7 +7415,7 @@ var BrainerceClient = class {
6788
7415
  async deleteProductMetafield(productId, definitionId) {
6789
7416
  await this.adminRequest(
6790
7417
  "DELETE",
6791
- `/api/v1/products/${productId}/metafields/${definitionId}`
7418
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`
6792
7419
  );
6793
7420
  }
6794
7421
  // -------------------- Product Customization Fields (Admin) --------------------
@@ -6799,7 +7426,7 @@ var BrainerceClient = class {
6799
7426
  async getProductCustomizationFields(productId) {
6800
7427
  return this.adminRequest(
6801
7428
  "GET",
6802
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`
7429
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`
6803
7430
  );
6804
7431
  }
6805
7432
  /**
@@ -6810,7 +7437,7 @@ var BrainerceClient = class {
6810
7437
  async setProductCustomizationFields(productId, definitionIds) {
6811
7438
  return this.adminRequest(
6812
7439
  "PATCH",
6813
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`,
7440
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`,
6814
7441
  { definitionIds }
6815
7442
  );
6816
7443
  }
@@ -6890,26 +7517,33 @@ var BrainerceClient = class {
6890
7517
  async resendTeamInvitation(invitationId) {
6891
7518
  return this.adminRequest(
6892
7519
  "POST",
6893
- `/api/v1/team/invitations/${invitationId}/resend`
7520
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}/resend`
6894
7521
  );
6895
7522
  }
6896
7523
  /**
6897
7524
  * @deprecated Use `revokeStoreInvitation(storeId, invitationId)` instead.
6898
7525
  */
6899
7526
  async revokeTeamInvitation(invitationId) {
6900
- await this.adminRequest("DELETE", `/api/v1/team/invitations/${invitationId}`);
7527
+ await this.adminRequest(
7528
+ "DELETE",
7529
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}`
7530
+ );
6901
7531
  }
6902
7532
  /**
6903
7533
  * @deprecated Use `updateStoreMember(storeId, memberId, data)` instead.
6904
7534
  */
6905
7535
  async updateTeamMemberRole(memberId, data) {
6906
- return this.adminRequest("PATCH", `/api/v1/team/members/${memberId}/role`, data);
7536
+ return this.adminRequest(
7537
+ "PATCH",
7538
+ `/api/v1/team/members/${encodePathSegment(memberId)}/role`,
7539
+ data
7540
+ );
6907
7541
  }
6908
7542
  /**
6909
7543
  * @deprecated Use `removeStoreMember(storeId, memberId)` instead.
6910
7544
  */
6911
7545
  async removeTeamMember(memberId) {
6912
- await this.adminRequest("DELETE", `/api/v1/team/members/${memberId}`);
7546
+ await this.adminRequest("DELETE", `/api/v1/team/members/${encodePathSegment(memberId)}`);
6913
7547
  }
6914
7548
  // -------------------- Store Team Management (Admin) --------------------
6915
7549
  // Store-level team management. Each store has its own team with roles and permissions.
@@ -6923,7 +7557,10 @@ var BrainerceClient = class {
6923
7557
  * ```
6924
7558
  */
6925
7559
  async getStoreTeam(storeId) {
6926
- return this.adminRequest("GET", `/api/v1/stores/${storeId}/team`);
7560
+ return this.adminRequest(
7561
+ "GET",
7562
+ `/api/v1/stores/${encodePathSegment(storeId)}/team`
7563
+ );
6927
7564
  }
6928
7565
  /**
6929
7566
  * Invite a new member to a store
@@ -6934,13 +7571,16 @@ var BrainerceClient = class {
6934
7571
  * const invitation = await client.inviteStoreMember('store_id', {
6935
7572
  * email: 'newmember@example.com',
6936
7573
  * role: 'MANAGER', // 'MANAGER' | 'STAFF' | 'VIEWER'
7574
+ * // Optional: restrict to specific vibe-coded channels (connectionId, vc_*).
7575
+ * // Omit or pass [] for unrestricted access to all channels.
7576
+ * salesChannelIds: ['vc_abc123', 'vc_def456'],
6937
7577
  * });
6938
7578
  * ```
6939
7579
  */
6940
7580
  async inviteStoreMember(storeId, data) {
6941
7581
  return this.adminRequest(
6942
7582
  "POST",
6943
- `/api/v1/stores/${storeId}/team/invite`,
7583
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invite`,
6944
7584
  data
6945
7585
  );
6946
7586
  }
@@ -6962,7 +7602,33 @@ var BrainerceClient = class {
6962
7602
  async updateStoreMember(storeId, memberId, data) {
6963
7603
  return this.adminRequest(
6964
7604
  "PATCH",
6965
- `/api/v1/stores/${storeId}/team/${memberId}`,
7605
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`,
7606
+ data
7607
+ );
7608
+ }
7609
+ /**
7610
+ * Replace the set of vibe-coded sales channels a store member is restricted to.
7611
+ * Channels are identified by their public `connectionId` (`vc_*` format). Pass
7612
+ * an empty array to clear all restrictions (member becomes unrestricted).
7613
+ * Requires Admin mode (apiKey) and MANAGE_TEAM permission
7614
+ *
7615
+ * @example
7616
+ * ```typescript
7617
+ * // Restrict to two vibe-coded channels
7618
+ * await client.updateStoreMemberSalesChannels('store_id', 'member_id', {
7619
+ * salesChannelIds: ['vc_abc123', 'vc_def456'],
7620
+ * });
7621
+ *
7622
+ * // Clear all restrictions (unrestricted access)
7623
+ * await client.updateStoreMemberSalesChannels('store_id', 'member_id', {
7624
+ * salesChannelIds: [],
7625
+ * });
7626
+ * ```
7627
+ */
7628
+ async updateStoreMemberSalesChannels(storeId, memberId, data) {
7629
+ return this.adminRequest(
7630
+ "PATCH",
7631
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}/sales-channels`,
6966
7632
  data
6967
7633
  );
6968
7634
  }
@@ -6971,7 +7637,10 @@ var BrainerceClient = class {
6971
7637
  * Requires Admin mode (apiKey) and MANAGE_TEAM permission
6972
7638
  */
6973
7639
  async removeStoreMember(storeId, memberId) {
6974
- await this.adminRequest("DELETE", `/api/v1/stores/${storeId}/team/${memberId}`);
7640
+ await this.adminRequest(
7641
+ "DELETE",
7642
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`
7643
+ );
6975
7644
  }
6976
7645
  /**
6977
7646
  * Resend a store invitation email
@@ -6980,7 +7649,7 @@ var BrainerceClient = class {
6980
7649
  async resendStoreInvitation(storeId, invitationId) {
6981
7650
  return this.adminRequest(
6982
7651
  "POST",
6983
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}/resend`
7652
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}/resend`
6984
7653
  );
6985
7654
  }
6986
7655
  /**
@@ -6990,7 +7659,7 @@ var BrainerceClient = class {
6990
7659
  async revokeStoreInvitation(storeId, invitationId) {
6991
7660
  await this.adminRequest(
6992
7661
  "DELETE",
6993
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}`
7662
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}`
6994
7663
  );
6995
7664
  }
6996
7665
  /**
@@ -6998,14 +7667,20 @@ var BrainerceClient = class {
6998
7667
  * Used on the invitation acceptance page
6999
7668
  */
7000
7669
  async getStoreInvitationByToken(token) {
7001
- return this.request("GET", `/api/v1/store-invitations/${token}`);
7670
+ return this.request(
7671
+ "GET",
7672
+ `/api/v1/store-invitations/${encodePathSegment(token)}`
7673
+ );
7002
7674
  }
7003
7675
  /**
7004
7676
  * Accept a store invitation
7005
7677
  * Requires Admin mode (apiKey)
7006
7678
  */
7007
7679
  async acceptStoreInvitation(token) {
7008
- await this.adminRequest("POST", `/api/v1/store-invitations/${token}/accept`);
7680
+ await this.adminRequest(
7681
+ "POST",
7682
+ `/api/v1/store-invitations/${encodePathSegment(token)}/accept`
7683
+ );
7009
7684
  }
7010
7685
  /**
7011
7686
  * Get all stores accessible to the current user (owned + member of)
@@ -7038,7 +7713,7 @@ var BrainerceClient = class {
7038
7713
  async getMyStorePermissions(storeId) {
7039
7714
  return this.adminRequest(
7040
7715
  "GET",
7041
- `/api/v1/me/stores/${storeId}/permissions`
7716
+ `/api/v1/me/stores/${encodePathSegment(storeId)}/permissions`
7042
7717
  );
7043
7718
  }
7044
7719
  // -------------------- Email Settings & Templates (Admin) --------------------
@@ -7071,7 +7746,10 @@ var BrainerceClient = class {
7071
7746
  * Requires Admin mode (apiKey)
7072
7747
  */
7073
7748
  async getEmailTemplate(templateId) {
7074
- return this.adminRequest("GET", `/api/v1/email/templates/${templateId}`);
7749
+ return this.adminRequest(
7750
+ "GET",
7751
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7752
+ );
7075
7753
  }
7076
7754
  /**
7077
7755
  * Create a new email template
@@ -7095,14 +7773,21 @@ var BrainerceClient = class {
7095
7773
  * Requires Admin mode (apiKey)
7096
7774
  */
7097
7775
  async updateEmailTemplate(templateId, data) {
7098
- return this.adminRequest("PUT", `/api/v1/email/templates/${templateId}`, data);
7776
+ return this.adminRequest(
7777
+ "PUT",
7778
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`,
7779
+ data
7780
+ );
7099
7781
  }
7100
7782
  /**
7101
7783
  * Delete an email template
7102
7784
  * Requires Admin mode (apiKey)
7103
7785
  */
7104
7786
  async deleteEmailTemplate(templateId) {
7105
- await this.adminRequest("DELETE", `/api/v1/email/templates/${templateId}`);
7787
+ await this.adminRequest(
7788
+ "DELETE",
7789
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7790
+ );
7106
7791
  }
7107
7792
  /**
7108
7793
  * Preview an email template with sample data
@@ -7111,7 +7796,7 @@ var BrainerceClient = class {
7111
7796
  async previewEmailTemplate(templateId, data) {
7112
7797
  return this.adminRequest(
7113
7798
  "POST",
7114
- `/api/v1/email/templates/${templateId}/preview`,
7799
+ `/api/v1/email/templates/${encodePathSegment(templateId)}/preview`,
7115
7800
  data || {}
7116
7801
  );
7117
7802
  }
@@ -7132,9 +7817,13 @@ var BrainerceClient = class {
7132
7817
  * @param resolution - 'MERGE' to link to existing product, 'CREATE_NEW' to create new product
7133
7818
  */
7134
7819
  async resolveSyncConflict(conflictId, resolution) {
7135
- return this.adminRequest("POST", `/api/v1/sync-conflicts/${conflictId}/resolve`, {
7136
- resolution
7137
- });
7820
+ return this.adminRequest(
7821
+ "POST",
7822
+ `/api/v1/sync-conflicts/${encodePathSegment(conflictId)}/resolve`,
7823
+ {
7824
+ resolution
7825
+ }
7826
+ );
7138
7827
  }
7139
7828
  // -------------------- Metafield Conflicts (Admin) --------------------
7140
7829
  // These methods require Admin mode (apiKey)
@@ -7155,7 +7844,7 @@ var BrainerceClient = class {
7155
7844
  async resolveMetafieldConflict(conflictId, data) {
7156
7845
  return this.adminRequest(
7157
7846
  "POST",
7158
- `/api/v1/metafield-conflicts/${conflictId}/resolve`,
7847
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/resolve`,
7159
7848
  data
7160
7849
  );
7161
7850
  }
@@ -7166,7 +7855,7 @@ var BrainerceClient = class {
7166
7855
  async ignoreMetafieldConflict(conflictId) {
7167
7856
  return this.adminRequest(
7168
7857
  "POST",
7169
- `/api/v1/metafield-conflicts/${conflictId}/ignore`
7858
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/ignore`
7170
7859
  );
7171
7860
  }
7172
7861
  // -------------------- OAuth Provider Configuration (Admin) --------------------
@@ -7183,7 +7872,10 @@ var BrainerceClient = class {
7183
7872
  * Requires Admin mode (apiKey)
7184
7873
  */
7185
7874
  async getOAuthProvider(provider) {
7186
- return this.adminRequest("GET", `/api/v1/oauth-providers/${provider}`);
7875
+ return this.adminRequest(
7876
+ "GET",
7877
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7878
+ );
7187
7879
  }
7188
7880
  /**
7189
7881
  * Configure an OAuth provider for customer login
@@ -7209,7 +7901,7 @@ var BrainerceClient = class {
7209
7901
  async updateOAuthProvider(provider, data) {
7210
7902
  return this.adminRequest(
7211
7903
  "PATCH",
7212
- `/api/v1/oauth-providers/${provider}`,
7904
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`,
7213
7905
  data
7214
7906
  );
7215
7907
  }
@@ -7218,7 +7910,10 @@ var BrainerceClient = class {
7218
7910
  * Requires Admin mode (apiKey)
7219
7911
  */
7220
7912
  async deleteOAuthProvider(provider) {
7221
- await this.adminRequest("DELETE", `/api/v1/oauth-providers/${provider}`);
7913
+ await this.adminRequest(
7914
+ "DELETE",
7915
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7916
+ );
7222
7917
  }
7223
7918
  };
7224
7919
  var BrainerceError = class extends Error {
@@ -7315,7 +8010,7 @@ var ALLOWED_PAYMENT_HOSTS = [
7315
8010
  // Brainerce-hosted payment embeds (backend payment-embed proxy at
7316
8011
  // `/api/payment/embed/...` that fronts provider apps' embed shells —
7317
8012
  // e.g. cardcom-payments OpenFields wrapper). The match also covers
7318
- // subdomains like `api.brainerce.com`, `staging.brainerce.com`.
8013
+ // every brainerce.com subdomain (api., docs., …).
7319
8014
  "brainerce.com"
7320
8015
  ];
7321
8016
  function isAllowedPaymentUrl(url, options) {
@@ -7434,7 +8129,9 @@ function getProductPriceInfo(product) {
7434
8129
  if (!product) {
7435
8130
  return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
7436
8131
  }
7437
- const resolvedBasePrice = parseFloat(product.basePrice) === 0 && product.priceMin ? product.priceMin : product.basePrice;
8132
+ const parsedBase = parseFloat(product.basePrice);
8133
+ const baseIsUsable = typeof product.basePrice === "string" && product.basePrice.length > 0 && !isNaN(parsedBase) && parsedBase > 0;
8134
+ const resolvedBasePrice = !baseIsUsable && product.priceMin ? product.priceMin : product.basePrice;
7438
8135
  if (product.discount) {
7439
8136
  const ruleOriginal = parseFloat(product.discount.originalPrice) || 0;
7440
8137
  const ruleDiscounted = parseFloat(product.discount.discountedPrice) || 0;