brainerce 1.27.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -202,6 +202,26 @@ function encodePathSegment(value) {
202
202
  }
203
203
  return encodeURIComponent(normalized);
204
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
+ }
205
225
  var BrainerceClient = class {
206
226
  constructor(options) {
207
227
  this.customerToken = null;
@@ -635,7 +655,7 @@ var BrainerceClient = class {
635
655
  /**
636
656
  * Make a request to the Admin API (requires apiKey)
637
657
  */
638
- async adminRequest(method, path, body, queryParams) {
658
+ async adminRequest(method, path, body, queryParams, responseType = "json") {
639
659
  if (!this.apiKey) {
640
660
  throw new BrainerceError(
641
661
  "This operation requires an API key. Initialize with apiKey instead of storeId.",
@@ -650,52 +670,64 @@ var BrainerceClient = class {
650
670
  }
651
671
  });
652
672
  }
653
- const controller = new AbortController();
654
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
655
- try {
656
- const headers = {
657
- Authorization: `Bearer ${this.apiKey}`,
658
- "Content-Type": "application/json",
659
- "X-SDK-Version": SDK_VERSION,
660
- "ngrok-skip-browser-warning": "true"
661
- };
662
- if (this.origin) {
663
- headers["Origin"] = this.origin;
664
- }
665
- if (this.locale) {
666
- headers["Accept-Language"] = this.locale;
667
- }
668
- const response = await fetch(url.toString(), {
669
- method,
670
- headers,
671
- body: body ? JSON.stringify(body) : void 0,
672
- signal: controller.signal
673
- });
674
- clearTimeout(timeoutId);
675
- if (!response.ok) {
676
- const errorData = await response.json().catch(() => ({}));
677
- throw new BrainerceError(
678
- errorData.message || `Request failed with status ${response.status}`,
679
- response.status,
680
- errorData
681
- );
682
- }
683
- const text = await response.text();
684
- if (!text) return {};
685
- return JSON.parse(text);
686
- } catch (error) {
687
- clearTimeout(timeoutId);
688
- if (error instanceof BrainerceError) {
689
- throw error;
690
- }
691
- if (error instanceof Error) {
692
- if (error.name === "AbortError") {
693
- 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
+ }
694
703
  }
695
- 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);
696
728
  }
697
- throw new BrainerceError("Unknown error occurred", 0);
698
729
  }
730
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
699
731
  }
700
732
  /**
701
733
  * Make a request to the Vibe-Coded API (public, uses connectionId)
@@ -704,7 +736,7 @@ var BrainerceClient = class {
704
736
  if (!this.connectionId) {
705
737
  throw new BrainerceError("connectionId is required for vibe-coded requests", 400);
706
738
  }
707
- const url = new URL(`${this.baseUrl}/api/vc/${this.connectionId}${path}`);
739
+ const url = new URL(`${this.baseUrl}/api/vc/${encodePathSegment(this.connectionId)}${path}`);
708
740
  if (queryParams) {
709
741
  Object.entries(queryParams).forEach(([key, value]) => {
710
742
  if (value !== void 0) {
@@ -712,70 +744,81 @@ var BrainerceClient = class {
712
744
  }
713
745
  });
714
746
  }
715
- const controller = new AbortController();
716
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
717
- try {
718
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
719
- const headers = {
720
- "X-SDK-Version": SDK_VERSION,
721
- "ngrok-skip-browser-warning": "true"
722
- };
723
- if (!isFormData) {
724
- headers["Content-Type"] = "application/json";
725
- }
726
- if (this.origin) {
727
- headers["Origin"] = this.origin;
728
- }
729
- if (this.locale) {
730
- headers["Accept-Language"] = this.locale;
731
- }
732
- if (headerOverrides) {
733
- Object.assign(headers, headerOverrides);
734
- }
735
- if (this.proxyMode && method !== "GET") {
736
- headers["X-Requested-With"] = "brainerce";
737
- }
738
- if (this.customerToken) {
739
- headers["Authorization"] = `Bearer ${this.customerToken}`;
740
- }
741
- const response = await fetch(url.toString(), {
742
- method,
743
- headers,
744
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
745
- signal: controller.signal
746
- });
747
- clearTimeout(timeoutId);
748
- if (!response.ok) {
749
- const errorData = await response.json().catch(() => ({}));
750
- if (response.status === 401 && this.onAuthError) {
751
- this.onAuthError({
752
- message: errorData.message || "Unauthorized",
753
- statusCode: 401,
754
- path
755
- });
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
+ }
756
788
  }
757
- throw new BrainerceError(
758
- errorData.message || `Request failed with status ${response.status}`,
759
- response.status,
760
- errorData
761
- );
762
- }
763
- const text = await response.text();
764
- if (!text) return {};
765
- return JSON.parse(text);
766
- } catch (error) {
767
- clearTimeout(timeoutId);
768
- if (error instanceof BrainerceError) {
769
- throw error;
770
- }
771
- if (error instanceof Error) {
772
- if (error.name === "AbortError") {
773
- 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
+ );
774
803
  }
775
- 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);
776
819
  }
777
- throw new BrainerceError("Unknown error occurred", 0);
778
820
  }
821
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
779
822
  }
780
823
  /**
781
824
  * Make a request to the Storefront API (public, uses storeId)
@@ -784,7 +827,7 @@ var BrainerceClient = class {
784
827
  if (!this.storeId) {
785
828
  throw new BrainerceError("storeId is required for storefront requests", 400);
786
829
  }
787
- const url = new URL(`${this.baseUrl}/stores/${this.storeId}${path}`);
830
+ const url = new URL(`${this.baseUrl}/stores/${encodePathSegment(this.storeId)}${path}`);
788
831
  if (queryParams) {
789
832
  Object.entries(queryParams).forEach(([key, value]) => {
790
833
  if (value !== void 0) {
@@ -792,67 +835,78 @@ var BrainerceClient = class {
792
835
  }
793
836
  });
794
837
  }
795
- const controller = new AbortController();
796
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
797
- try {
798
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
799
- const headers = {
800
- "X-SDK-Version": SDK_VERSION,
801
- "ngrok-skip-browser-warning": "true"
802
- };
803
- if (!isFormData) {
804
- headers["Content-Type"] = "application/json";
805
- }
806
- if (this.origin) {
807
- headers["Origin"] = this.origin;
808
- }
809
- if (this.locale) {
810
- headers["Accept-Language"] = this.locale;
811
- }
812
- if (headerOverrides) {
813
- Object.assign(headers, headerOverrides);
814
- }
815
- if (this.customerToken) {
816
- headers["Authorization"] = `Bearer ${this.customerToken}`;
817
- }
818
- const response = await fetch(url.toString(), {
819
- method,
820
- headers,
821
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
822
- signal: controller.signal
823
- });
824
- clearTimeout(timeoutId);
825
- if (!response.ok) {
826
- const errorData = await response.json().catch(() => ({}));
827
- if (response.status === 401 && this.onAuthError) {
828
- this.onAuthError({
829
- message: errorData.message || "Unauthorized",
830
- statusCode: 401,
831
- path
832
- });
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
+ }
833
876
  }
834
- throw new BrainerceError(
835
- errorData.message || `Request failed with status ${response.status}`,
836
- response.status,
837
- errorData
838
- );
839
- }
840
- const text = await response.text();
841
- if (!text) return {};
842
- return JSON.parse(text);
843
- } catch (error) {
844
- clearTimeout(timeoutId);
845
- if (error instanceof BrainerceError) {
846
- throw error;
847
- }
848
- if (error instanceof Error) {
849
- if (error.name === "AbortError") {
850
- 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
+ );
851
891
  }
852
- 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);
853
907
  }
854
- throw new BrainerceError("Unknown error occurred", 0);
855
908
  }
909
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
856
910
  }
857
911
  /**
858
912
  * Smart request - uses storefront or admin API based on client mode
@@ -942,6 +996,7 @@ var BrainerceClient = class {
942
996
  // Admin-only params
943
997
  type: params?.type
944
998
  };
999
+ const queryParamsWithRegion = params?.regionId ? { ...queryParams, regionId: params.regionId } : queryParams;
945
1000
  if (this.isVibeCodedMode()) {
946
1001
  return this.vibeCodedRequest(
947
1002
  "GET",
@@ -955,14 +1010,14 @@ var BrainerceClient = class {
955
1010
  "GET",
956
1011
  "/products",
957
1012
  void 0,
958
- queryParams
1013
+ queryParamsWithRegion
959
1014
  );
960
1015
  }
961
1016
  return this.adminRequest(
962
1017
  "GET",
963
1018
  "/api/v1/products",
964
1019
  void 0,
965
- queryParams
1020
+ queryParamsWithRegion
966
1021
  );
967
1022
  }
968
1023
  /**
@@ -971,10 +1026,11 @@ var BrainerceClient = class {
971
1026
  */
972
1027
  async getProduct(productId, options) {
973
1028
  const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
1029
+ const queryParams = options?.regionId ? { regionId: options.regionId } : void 0;
974
1030
  if (this.isVibeCodedMode()) {
975
1031
  return this.vibeCodedRequest(
976
1032
  "GET",
977
- `/products/${productId}`,
1033
+ `/products/${encodePathSegment(productId)}`,
978
1034
  void 0,
979
1035
  void 0,
980
1036
  headerOverrides
@@ -983,13 +1039,18 @@ var BrainerceClient = class {
983
1039
  if (this.storeId && !this.apiKey) {
984
1040
  return this.storefrontRequest(
985
1041
  "GET",
986
- `/products/${productId}`,
987
- void 0,
1042
+ `/products/${encodePathSegment(productId)}`,
988
1043
  void 0,
1044
+ queryParams,
989
1045
  headerOverrides
990
1046
  );
991
1047
  }
992
- 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
+ );
993
1054
  }
994
1055
  /**
995
1056
  * Get a single product by slug
@@ -1107,7 +1168,7 @@ var BrainerceClient = class {
1107
1168
  */
1108
1169
  async getProductAlternates(productId) {
1109
1170
  if (this.storeId && !this.apiKey) {
1110
- return this.storefrontRequest("GET", `/products/${productId}/alternates`);
1171
+ return this.storefrontRequest("GET", `/products/${encodePathSegment(productId)}/alternates`);
1111
1172
  }
1112
1173
  throw new BrainerceError("getProductAlternates is only available in storefront mode", 400);
1113
1174
  }
@@ -1149,7 +1210,7 @@ var BrainerceClient = class {
1149
1210
  * Update an existing product
1150
1211
  */
1151
1212
  async updateProduct(productId, data) {
1152
- return this.request("PATCH", `/api/v1/products/${productId}`, data);
1213
+ return this.request("PATCH", `/api/v1/products/${encodePathSegment(productId)}`, data);
1153
1214
  }
1154
1215
  /**
1155
1216
  * Delete a product
@@ -1177,7 +1238,7 @@ var BrainerceClient = class {
1177
1238
  const queryParams = options?.platforms?.length ? { platforms: options.platforms.join(",") } : void 0;
1178
1239
  return this.request(
1179
1240
  "DELETE",
1180
- `/api/v1/products/${productId}`,
1241
+ `/api/v1/products/${encodePathSegment(productId)}`,
1181
1242
  void 0,
1182
1243
  queryParams
1183
1244
  );
@@ -1192,7 +1253,10 @@ var BrainerceClient = class {
1192
1253
  * ```
1193
1254
  */
1194
1255
  async convertToVariable(productId) {
1195
- 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
+ );
1196
1260
  }
1197
1261
  /**
1198
1262
  * Convert a VARIABLE product to SIMPLE product
@@ -1205,7 +1269,10 @@ var BrainerceClient = class {
1205
1269
  * ```
1206
1270
  */
1207
1271
  async convertToSimple(productId) {
1208
- 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
+ );
1209
1276
  }
1210
1277
  /**
1211
1278
  * Publish a product to specific platforms
@@ -1217,9 +1284,13 @@ var BrainerceClient = class {
1217
1284
  * ```
1218
1285
  */
1219
1286
  async publishProduct(productId, platforms) {
1220
- return this.request("POST", `/api/v1/products/${productId}/publish`, {
1221
- platforms
1222
- });
1287
+ return this.request(
1288
+ "POST",
1289
+ `/api/v1/products/${encodePathSegment(productId)}/publish`,
1290
+ {
1291
+ platforms
1292
+ }
1293
+ );
1223
1294
  }
1224
1295
  // -------------------- Variants --------------------
1225
1296
  /**
@@ -1237,7 +1308,11 @@ var BrainerceClient = class {
1237
1308
  * ```
1238
1309
  */
1239
1310
  async createVariant(productId, data) {
1240
- 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
+ );
1241
1316
  }
1242
1317
  /**
1243
1318
  * Bulk save variants (create, update, delete in one operation)
@@ -1257,7 +1332,7 @@ var BrainerceClient = class {
1257
1332
  async bulkSaveVariants(productId, data) {
1258
1333
  return this.request(
1259
1334
  "POST",
1260
- `/api/v1/products/${productId}/variants/bulk`,
1335
+ `/api/v1/products/${encodePathSegment(productId)}/variants/bulk`,
1261
1336
  data
1262
1337
  );
1263
1338
  }
@@ -1275,7 +1350,7 @@ var BrainerceClient = class {
1275
1350
  async updateVariant(productId, variantId, data) {
1276
1351
  return this.request(
1277
1352
  "PATCH",
1278
- `/api/v1/products/${productId}/variants/${variantId}`,
1353
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`,
1279
1354
  data
1280
1355
  );
1281
1356
  }
@@ -1288,7 +1363,10 @@ var BrainerceClient = class {
1288
1363
  * ```
1289
1364
  */
1290
1365
  async deleteVariant(productId, variantId) {
1291
- 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
+ );
1292
1370
  }
1293
1371
  /**
1294
1372
  * Get inventory for a specific variant
@@ -1302,7 +1380,7 @@ var BrainerceClient = class {
1302
1380
  async getVariantInventory(productId, variantId) {
1303
1381
  return this.request(
1304
1382
  "GET",
1305
- `/api/v1/products/${productId}/variants/${variantId}/inventory`
1383
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`
1306
1384
  );
1307
1385
  }
1308
1386
  /**
@@ -1319,7 +1397,7 @@ var BrainerceClient = class {
1319
1397
  async updateVariantInventory(productId, variantId, data) {
1320
1398
  return this.request(
1321
1399
  "PATCH",
1322
- `/api/v1/products/${productId}/variants/${variantId}/inventory`,
1400
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`,
1323
1401
  data
1324
1402
  );
1325
1403
  }
@@ -1343,7 +1421,10 @@ var BrainerceClient = class {
1343
1421
  * Get a single order by ID
1344
1422
  */
1345
1423
  async getOrder(orderId) {
1346
- 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
+ );
1347
1428
  }
1348
1429
  /**
1349
1430
  * Create a new order
@@ -1356,7 +1437,7 @@ var BrainerceClient = class {
1356
1437
  * Update an order (e.g., change status)
1357
1438
  */
1358
1439
  async updateOrder(orderId, data) {
1359
- return this.request("PATCH", `/api/v1/orders/${orderId}`, data);
1440
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}`, data);
1360
1441
  }
1361
1442
  /**
1362
1443
  * Update order status
@@ -1367,7 +1448,9 @@ var BrainerceClient = class {
1367
1448
  * ```
1368
1449
  */
1369
1450
  async updateOrderStatus(orderId, status) {
1370
- return this.request("PATCH", `/api/v1/orders/${orderId}/status`, { status });
1451
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/status`, {
1452
+ status
1453
+ });
1371
1454
  }
1372
1455
  /**
1373
1456
  * Update order payment method
@@ -1379,9 +1462,13 @@ var BrainerceClient = class {
1379
1462
  * ```
1380
1463
  */
1381
1464
  async updatePaymentMethod(orderId, paymentMethod) {
1382
- return this.request("PATCH", `/api/v1/orders/${orderId}/payment-method`, {
1383
- paymentMethod
1384
- });
1465
+ return this.request(
1466
+ "PATCH",
1467
+ `/api/v1/orders/${encodePathSegment(orderId)}/payment-method`,
1468
+ {
1469
+ paymentMethod
1470
+ }
1471
+ );
1385
1472
  }
1386
1473
  /**
1387
1474
  * Update order notes
@@ -1392,7 +1479,9 @@ var BrainerceClient = class {
1392
1479
  * ```
1393
1480
  */
1394
1481
  async updateOrderNotes(orderId, notes) {
1395
- return this.request("PATCH", `/api/v1/orders/${orderId}/notes`, { notes });
1482
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/notes`, {
1483
+ notes
1484
+ });
1396
1485
  }
1397
1486
  /**
1398
1487
  * Get refunds for an order
@@ -1405,7 +1494,7 @@ var BrainerceClient = class {
1405
1494
  * ```
1406
1495
  */
1407
1496
  async getOrderRefunds(orderId) {
1408
- return this.request("GET", `/api/v1/orders/${orderId}/refunds`);
1497
+ return this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}/refunds`);
1409
1498
  }
1410
1499
  /**
1411
1500
  * Create a refund for an order
@@ -1432,7 +1521,11 @@ var BrainerceClient = class {
1432
1521
  * ```
1433
1522
  */
1434
1523
  async createRefund(orderId, data) {
1435
- 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
+ );
1436
1529
  }
1437
1530
  /**
1438
1531
  * Update order shipping address
@@ -1452,7 +1545,11 @@ var BrainerceClient = class {
1452
1545
  * ```
1453
1546
  */
1454
1547
  async updateOrderShipping(orderId, data) {
1455
- 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
+ );
1456
1553
  }
1457
1554
  /**
1458
1555
  * Cancel an order
@@ -1465,7 +1562,7 @@ var BrainerceClient = class {
1465
1562
  * ```
1466
1563
  */
1467
1564
  async cancelOrder(orderId) {
1468
- return this.request("POST", `/api/v1/orders/${orderId}/cancel`);
1565
+ return this.request("POST", `/api/v1/orders/${encodePathSegment(orderId)}/cancel`);
1469
1566
  }
1470
1567
  /**
1471
1568
  * Fulfill an order (mark as shipped)
@@ -1481,7 +1578,11 @@ var BrainerceClient = class {
1481
1578
  * ```
1482
1579
  */
1483
1580
  async fulfillOrder(orderId, data) {
1484
- 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
+ );
1485
1586
  }
1486
1587
  /**
1487
1588
  * Sync draft orders from connected platforms
@@ -1506,7 +1607,11 @@ var BrainerceClient = class {
1506
1607
  * ```
1507
1608
  */
1508
1609
  async completeDraftOrder(orderId, data) {
1509
- 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
+ );
1510
1615
  }
1511
1616
  /**
1512
1617
  * Send invoice for a draft order
@@ -1523,7 +1628,7 @@ var BrainerceClient = class {
1523
1628
  async sendDraftInvoice(orderId, data) {
1524
1629
  return this.request(
1525
1630
  "POST",
1526
- `/api/v1/orders/${orderId}/send-invoice`,
1631
+ `/api/v1/orders/${encodePathSegment(orderId)}/send-invoice`,
1527
1632
  data || {}
1528
1633
  );
1529
1634
  }
@@ -1536,7 +1641,7 @@ var BrainerceClient = class {
1536
1641
  * ```
1537
1642
  */
1538
1643
  async deleteDraftOrder(orderId) {
1539
- await this.request("DELETE", `/api/v1/orders/${orderId}/draft`);
1644
+ await this.request("DELETE", `/api/v1/orders/${encodePathSegment(orderId)}/draft`);
1540
1645
  }
1541
1646
  /**
1542
1647
  * Update a draft order
@@ -1559,7 +1664,7 @@ var BrainerceClient = class {
1559
1664
  * ```
1560
1665
  */
1561
1666
  async updateDraftOrder(orderId, data) {
1562
- return this.request("PATCH", `/api/v1/orders/${orderId}/draft`, data);
1667
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/draft`, data);
1563
1668
  }
1564
1669
  // -------------------- Inventory --------------------
1565
1670
  /**
@@ -1567,13 +1672,17 @@ var BrainerceClient = class {
1567
1672
  * This will sync inventory to all connected platforms
1568
1673
  */
1569
1674
  async updateInventory(productId, data) {
1570
- 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
+ );
1571
1680
  }
1572
1681
  /**
1573
1682
  * Get current inventory for a product
1574
1683
  */
1575
1684
  async getInventory(productId) {
1576
- return this.request("GET", `/api/v1/inventory/${productId}`);
1685
+ return this.request("GET", `/api/v1/inventory/${encodePathSegment(productId)}`);
1577
1686
  }
1578
1687
  /**
1579
1688
  * Edit inventory manually with reason for audit trail
@@ -1734,7 +1843,7 @@ var BrainerceClient = class {
1734
1843
  * Get the status of a sync job
1735
1844
  */
1736
1845
  async getSyncStatus(jobId) {
1737
- return this.request("GET", `/api/v1/sync/${jobId}`);
1846
+ return this.request("GET", `/api/v1/sync/${encodePathSegment(jobId)}`);
1738
1847
  }
1739
1848
  // -------------------- Coupons --------------------
1740
1849
  /**
@@ -1756,7 +1865,7 @@ var BrainerceClient = class {
1756
1865
  * Get a single coupon by ID
1757
1866
  */
1758
1867
  async getCoupon(couponId) {
1759
- return this.request("GET", `/api/v1/coupons/${couponId}`);
1868
+ return this.request("GET", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1760
1869
  }
1761
1870
  /**
1762
1871
  * Create a new coupon.
@@ -1786,20 +1895,20 @@ var BrainerceClient = class {
1786
1895
  * Update an existing coupon
1787
1896
  */
1788
1897
  async updateCoupon(couponId, data) {
1789
- return this.request("PATCH", `/api/v1/coupons/${couponId}`, data);
1898
+ return this.request("PATCH", `/api/v1/coupons/${encodePathSegment(couponId)}`, data);
1790
1899
  }
1791
1900
  /**
1792
1901
  * Delete a coupon
1793
1902
  */
1794
1903
  async deleteCoupon(couponId) {
1795
- await this.request("DELETE", `/api/v1/coupons/${couponId}`);
1904
+ await this.request("DELETE", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1796
1905
  }
1797
1906
  /**
1798
1907
  * Sync a coupon to all connected platforms.
1799
1908
  * Returns a sync job that can be tracked with getSyncStatus().
1800
1909
  */
1801
1910
  async syncCoupon(couponId) {
1802
- return this.request("POST", `/api/v1/coupons/${couponId}/sync`);
1911
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/sync`);
1803
1912
  }
1804
1913
  /**
1805
1914
  * Publish a coupon to specific platforms.
@@ -1812,7 +1921,9 @@ var BrainerceClient = class {
1812
1921
  * ```
1813
1922
  */
1814
1923
  async publishCoupon(couponId, platforms) {
1815
- return this.request("POST", `/api/v1/coupons/${couponId}/publish`, { platforms });
1924
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/publish`, {
1925
+ platforms
1926
+ });
1816
1927
  }
1817
1928
  /**
1818
1929
  * Get platform capabilities for coupon features.
@@ -1853,13 +1964,17 @@ var BrainerceClient = class {
1853
1964
  * Get a customer by ID
1854
1965
  */
1855
1966
  async getCustomer(customerId) {
1856
- return this.request("GET", `/api/v1/customers/${customerId}`);
1967
+ return this.request("GET", `/api/v1/customers/${encodePathSegment(customerId)}`);
1857
1968
  }
1858
1969
  /**
1859
1970
  * Update a customer
1860
1971
  */
1861
1972
  async updateCustomer(customerId, data) {
1862
- return this.request("PATCH", `/api/v1/customers/${customerId}`, data);
1973
+ return this.request(
1974
+ "PATCH",
1975
+ `/api/v1/customers/${encodePathSegment(customerId)}`,
1976
+ data
1977
+ );
1863
1978
  }
1864
1979
  /**
1865
1980
  * Get a customer by email
@@ -1867,56 +1982,84 @@ var BrainerceClient = class {
1867
1982
  async getCustomerByEmail(email) {
1868
1983
  return this.request("GET", "/api/v1/customers/by-email", void 0, { email });
1869
1984
  }
1870
- /**
1871
- * List a customer's saved payment methods (vaulted cards).
1872
- *
1873
- * Returns display-only metadata — last4, brand, expiry, default flag,
1874
- * status. The underlying provider token is encrypted at rest and
1875
- * NEVER returned through this API.
1876
- *
1877
- * Apps mode requires `customers:read` and `payments:read` scopes.
1878
- *
1879
- * @param storeId - The store this customer belongs to
1880
- * @param customerId - The customer's ID
1881
- * @returns Array of saved payment methods
1882
- *
1883
- * @example
1884
- * ```typescript
1885
- * const methods = await client.listSavedPaymentMethods(storeId, customerId);
1886
- * methods.forEach((m) => {
1887
- * console.log(`${m.brand} ending in ${m.last4} (expires ${m.expMonth}/${m.expYear})`);
1888
- * });
1889
- * ```
1890
- */
1891
- async listSavedPaymentMethods(storeId, customerId) {
1985
+ async listSavedPaymentMethods(customerIdOrStoreId, maybeCustomerId) {
1986
+ const customerId = this.resolveSavedPaymentMethodsArgs(
1987
+ "listSavedPaymentMethods",
1988
+ customerIdOrStoreId,
1989
+ maybeCustomerId
1990
+ );
1892
1991
  return this.request(
1893
1992
  "GET",
1894
- `/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)}`
1895
2005
  );
1896
2006
  }
1897
2007
  /**
1898
- * Remove a customer's saved payment method.
2008
+ * Internal helper: normalize legacy `(storeId, customerId)` callers to the
2009
+ * new `(customerId)` signature for `listSavedPaymentMethods`.
1899
2010
  *
1900
- * Hard-deletes the row. The provider may still hold the underlying
1901
- * token internally we don't issue a delete-at-provider call because
1902
- * not every provider supports it. From the platform's perspective the
1903
- * token is gone; subsequent charges will fail.
1904
- *
1905
- * Apps mode requires `customers:write` scope.
1906
- *
1907
- * @param storeId - The store this customer belongs to
1908
- * @param customerId - The customer's ID
1909
- * @param paymentMethodId - The saved payment method ID to remove
1910
- *
1911
- * @example
1912
- * ```typescript
1913
- * await client.removeSavedPaymentMethod(storeId, customerId, methodId);
1914
- * ```
2011
+ * Throws if the SDK instance has no `storeId` (these endpoints are
2012
+ * storefront-scoped) and warns when the deprecated overload is detected.
1915
2013
  */
1916
- async removeSavedPaymentMethod(storeId, customerId, paymentMethodId) {
1917
- return this.request(
1918
- "DELETE",
1919
- `/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.`
1920
2063
  );
1921
2064
  }
1922
2065
  /**
@@ -1975,12 +2118,33 @@ var BrainerceClient = class {
1975
2118
  * Request a password reset email for a customer
1976
2119
  * Works in vibe-coded, storefront, and admin mode
1977
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
+ *
1978
2129
  * @param email - Customer email address
1979
2130
  * @param options - Optional settings
1980
- * @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.
1981
2133
  */
1982
2134
  async forgotPassword(email, options) {
1983
- 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
+ }
1984
2148
  if (this.isVibeCodedMode()) {
1985
2149
  return this.vibeCodedRequest("POST", "/customers/forgot-password", {
1986
2150
  email,
@@ -2163,12 +2327,14 @@ var BrainerceClient = class {
2163
2327
  * // Redirect user to Google
2164
2328
  * window.location.href = authorizationUrl;
2165
2329
  *
2166
- * // 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.)
2167
2333
  * const params = new URLSearchParams(window.location.search);
2168
- * if (params.get('oauth_success') === 'true') {
2169
- * const token = params.get('token');
2170
- * client.setCustomerToken(token);
2171
- * // 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, ...
2172
2338
  * } else if (params.get('oauth_error')) {
2173
2339
  * // Show error
2174
2340
  * }
@@ -2186,7 +2352,7 @@ var BrainerceClient = class {
2186
2352
  params.set("redirectUrl", options.redirectUrl);
2187
2353
  }
2188
2354
  const queryString = params.toString();
2189
- const endpoint = `/oauth/${provider}/authorize${queryString ? `?${queryString}` : ""}`;
2355
+ const endpoint = `/oauth/${encodePathSegment(provider)}/authorize${queryString ? `?${queryString}` : ""}`;
2190
2356
  if (this.isVibeCodedMode()) {
2191
2357
  return this.vibeCodedRequest("GET", endpoint);
2192
2358
  }
@@ -2195,6 +2361,83 @@ var BrainerceClient = class {
2195
2361
  }
2196
2362
  throw new BrainerceError("getOAuthAuthorizeUrl requires vibe-coded or storefront mode", 400);
2197
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
+ }
2198
2441
  /**
2199
2442
  * Handle OAuth callback - exchange code for customer token (server-to-server)
2200
2443
  *
@@ -2215,7 +2458,7 @@ var BrainerceClient = class {
2215
2458
  throw new BrainerceError("provider is required (e.g., 'GOOGLE', 'FACEBOOK', 'GITHUB')", 400);
2216
2459
  }
2217
2460
  const params = new URLSearchParams({ code, state });
2218
- const endpoint = `/oauth/${provider}/callback?${params.toString()}`;
2461
+ const endpoint = `/oauth/${encodePathSegment(provider)}/callback?${params.toString()}`;
2219
2462
  if (this.isVibeCodedMode()) {
2220
2463
  return this.vibeCodedRequest("GET", endpoint);
2221
2464
  }
@@ -2259,7 +2502,7 @@ var BrainerceClient = class {
2259
2502
  params.set("redirectUrl", options.redirectUrl);
2260
2503
  }
2261
2504
  const queryString = params.toString();
2262
- const endpoint = `/oauth/${provider}/link${queryString ? `?${queryString}` : ""}`;
2505
+ const endpoint = `/oauth/${encodePathSegment(provider)}/link${queryString ? `?${queryString}` : ""}`;
2263
2506
  if (this.isVibeCodedMode()) {
2264
2507
  return this.vibeCodedRequest("POST", endpoint);
2265
2508
  }
@@ -2288,10 +2531,16 @@ var BrainerceClient = class {
2288
2531
  throw new BrainerceError("Customer token is required. Call setCustomerToken() first.", 401);
2289
2532
  }
2290
2533
  if (this.isVibeCodedMode()) {
2291
- return this.vibeCodedRequest("DELETE", `/oauth/${provider}/link`);
2534
+ return this.vibeCodedRequest(
2535
+ "DELETE",
2536
+ `/oauth/${encodePathSegment(provider)}/link`
2537
+ );
2292
2538
  }
2293
2539
  if (this.isStorefrontMode()) {
2294
- return this.storefrontRequest("DELETE", `/oauth/${provider}/link`);
2540
+ return this.storefrontRequest(
2541
+ "DELETE",
2542
+ `/oauth/${encodePathSegment(provider)}/link`
2543
+ );
2295
2544
  }
2296
2545
  throw new BrainerceError("unlinkOAuthProvider requires vibe-coded or storefront mode", 400);
2297
2546
  }
@@ -2358,7 +2607,10 @@ var BrainerceClient = class {
2358
2607
  * Get all addresses for a customer
2359
2608
  */
2360
2609
  async getCustomerAddresses(customerId) {
2361
- return this.request("GET", `/api/v1/customers/${customerId}/addresses`);
2610
+ return this.request(
2611
+ "GET",
2612
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`
2613
+ );
2362
2614
  }
2363
2615
  /**
2364
2616
  * Add an address to a customer
@@ -2380,7 +2632,7 @@ var BrainerceClient = class {
2380
2632
  async addCustomerAddress(customerId, address) {
2381
2633
  return this.request(
2382
2634
  "POST",
2383
- `/api/v1/customers/${customerId}/addresses`,
2635
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`,
2384
2636
  address
2385
2637
  );
2386
2638
  }
@@ -2390,7 +2642,7 @@ var BrainerceClient = class {
2390
2642
  async updateCustomerAddress(customerId, addressId, address) {
2391
2643
  return this.request(
2392
2644
  "PATCH",
2393
- `/api/v1/customers/${customerId}/addresses/${addressId}`,
2645
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`,
2394
2646
  address
2395
2647
  );
2396
2648
  }
@@ -2398,7 +2650,10 @@ var BrainerceClient = class {
2398
2650
  * Delete a customer address
2399
2651
  */
2400
2652
  async deleteCustomerAddress(customerId, addressId) {
2401
- 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
+ );
2402
2657
  }
2403
2658
  /**
2404
2659
  * Get orders for a customer
@@ -2412,7 +2667,7 @@ var BrainerceClient = class {
2412
2667
  async getCustomerOrders(customerId, params) {
2413
2668
  return this.request(
2414
2669
  "GET",
2415
- `/api/v1/customers/${customerId}/orders`,
2670
+ `/api/v1/customers/${encodePathSegment(customerId)}/orders`,
2416
2671
  void 0,
2417
2672
  { page: params?.page, limit: params?.limit }
2418
2673
  );
@@ -2484,12 +2739,18 @@ var BrainerceClient = class {
2484
2739
  */
2485
2740
  async getCartBySession(sessionToken) {
2486
2741
  if (this.isVibeCodedMode()) {
2487
- return this.vibeCodedRequest("GET", `/cart/session/${sessionToken}`);
2742
+ return this.vibeCodedRequest("GET", `/cart/session/${encodePathSegment(sessionToken)}`);
2488
2743
  }
2489
2744
  if (this.storeId && !this.apiKey) {
2490
- return this.storefrontRequest("GET", `/cart/session/${sessionToken}`);
2745
+ return this.storefrontRequest(
2746
+ "GET",
2747
+ `/cart/session/${encodePathSegment(sessionToken)}`
2748
+ );
2491
2749
  }
2492
- return this.adminRequest("GET", `/api/v1/cart/session/${sessionToken}`);
2750
+ return this.adminRequest(
2751
+ "GET",
2752
+ `/api/v1/cart/session/${encodePathSegment(sessionToken)}`
2753
+ );
2493
2754
  }
2494
2755
  /**
2495
2756
  * Get a cart by customer ID (for authenticated users)
@@ -2502,9 +2763,9 @@ var BrainerceClient = class {
2502
2763
  */
2503
2764
  async getCartByCustomer(customerId) {
2504
2765
  if (this.storeId && !this.apiKey) {
2505
- return this.storefrontRequest("GET", `/cart/customer/${customerId}`);
2766
+ return this.storefrontRequest("GET", `/cart/customer/${encodePathSegment(customerId)}`);
2506
2767
  }
2507
- return this.adminRequest("GET", `/api/v1/cart/customer/${customerId}`);
2768
+ return this.adminRequest("GET", `/api/v1/cart/customer/${encodePathSegment(customerId)}`);
2508
2769
  }
2509
2770
  /**
2510
2771
  * Get a cart by ID
@@ -2534,18 +2795,33 @@ var BrainerceClient = class {
2534
2795
  const queryParams = options?.include?.length ? { include: options.include.join(",") } : void 0;
2535
2796
  if (this.isVibeCodedMode()) {
2536
2797
  return this.withGuards(
2537
- this.vibeCodedRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2798
+ this.vibeCodedRequest(
2799
+ "GET",
2800
+ `/cart/${encodePathSegment(cartId)}`,
2801
+ void 0,
2802
+ queryParams
2803
+ ),
2538
2804
  "cart"
2539
2805
  );
2540
2806
  }
2541
2807
  if (this.storeId && !this.apiKey) {
2542
2808
  return this.withGuards(
2543
- this.storefrontRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2809
+ this.storefrontRequest(
2810
+ "GET",
2811
+ `/cart/${encodePathSegment(cartId)}`,
2812
+ void 0,
2813
+ queryParams
2814
+ ),
2544
2815
  "cart"
2545
2816
  );
2546
2817
  }
2547
2818
  return this.withGuards(
2548
- 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
+ ),
2549
2825
  "cart"
2550
2826
  );
2551
2827
  }
@@ -2601,18 +2877,18 @@ var BrainerceClient = class {
2601
2877
  }
2602
2878
  if (this.isVibeCodedMode()) {
2603
2879
  return this.withGuards(
2604
- this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item),
2880
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2605
2881
  "cart"
2606
2882
  );
2607
2883
  }
2608
2884
  if (this.storeId && !this.apiKey) {
2609
2885
  return this.withGuards(
2610
- this.storefrontRequest("POST", `/cart/${cartId}/items`, item),
2886
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2611
2887
  "cart"
2612
2888
  );
2613
2889
  }
2614
2890
  return this.withGuards(
2615
- this.adminRequest("POST", `/api/v1/cart/${cartId}/items`, item),
2891
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/items`, item),
2616
2892
  "cart"
2617
2893
  );
2618
2894
  }
@@ -2639,18 +2915,30 @@ var BrainerceClient = class {
2639
2915
  }
2640
2916
  if (this.isVibeCodedMode()) {
2641
2917
  return this.withGuards(
2642
- this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2918
+ this.vibeCodedRequest(
2919
+ "PATCH",
2920
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2921
+ data
2922
+ ),
2643
2923
  "cart"
2644
2924
  );
2645
2925
  }
2646
2926
  if (this.storeId && !this.apiKey) {
2647
2927
  return this.withGuards(
2648
- this.storefrontRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2928
+ this.storefrontRequest(
2929
+ "PATCH",
2930
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2931
+ data
2932
+ ),
2649
2933
  "cart"
2650
2934
  );
2651
2935
  }
2652
2936
  return this.withGuards(
2653
- 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
+ ),
2654
2942
  "cart"
2655
2943
  );
2656
2944
  }
@@ -2677,18 +2965,27 @@ var BrainerceClient = class {
2677
2965
  }
2678
2966
  if (this.isVibeCodedMode()) {
2679
2967
  return this.withGuards(
2680
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2968
+ this.vibeCodedRequest(
2969
+ "DELETE",
2970
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2971
+ ),
2681
2972
  "cart"
2682
2973
  );
2683
2974
  }
2684
2975
  if (this.storeId && !this.apiKey) {
2685
2976
  return this.withGuards(
2686
- this.storefrontRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2977
+ this.storefrontRequest(
2978
+ "DELETE",
2979
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2980
+ ),
2687
2981
  "cart"
2688
2982
  );
2689
2983
  }
2690
2984
  return this.withGuards(
2691
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items/${itemId}`),
2985
+ this.adminRequest(
2986
+ "DELETE",
2987
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2988
+ ),
2692
2989
  "cart"
2693
2990
  );
2694
2991
  }
@@ -2709,13 +3006,16 @@ var BrainerceClient = class {
2709
3006
  return this.withGuards(this.localCartToCart(this.getLocalCart()), "cart");
2710
3007
  }
2711
3008
  if (this.isVibeCodedMode()) {
2712
- return this.withGuards(this.vibeCodedRequest("DELETE", `/cart/${cartId}`), "cart");
3009
+ return this.withGuards(
3010
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}`),
3011
+ "cart"
3012
+ );
2713
3013
  }
2714
3014
  if (this.storeId && !this.apiKey) {
2715
- await this.storefrontRequest("DELETE", `/cart/${cartId}/items`);
3015
+ await this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/items`);
2716
3016
  return this.withGuards({}, "cart");
2717
3017
  }
2718
- await this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items`);
3018
+ await this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/items`);
2719
3019
  return this.withGuards({}, "cart");
2720
3020
  }
2721
3021
  /**
@@ -2730,18 +3030,18 @@ var BrainerceClient = class {
2730
3030
  async applyCoupon(cartId, code) {
2731
3031
  if (this.isVibeCodedMode()) {
2732
3032
  return this.withGuards(
2733
- this.vibeCodedRequest("POST", `/cart/${cartId}/coupon`, { code }),
3033
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2734
3034
  "cart"
2735
3035
  );
2736
3036
  }
2737
3037
  if (this.storeId && !this.apiKey) {
2738
3038
  return this.withGuards(
2739
- this.storefrontRequest("POST", `/cart/${cartId}/coupon`, { code }),
3039
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2740
3040
  "cart"
2741
3041
  );
2742
3042
  }
2743
3043
  return this.withGuards(
2744
- this.adminRequest("POST", `/api/v1/cart/${cartId}/coupon`, { code }),
3044
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2745
3045
  "cart"
2746
3046
  );
2747
3047
  }
@@ -2756,18 +3056,18 @@ var BrainerceClient = class {
2756
3056
  async removeCoupon(cartId) {
2757
3057
  if (this.isVibeCodedMode()) {
2758
3058
  return this.withGuards(
2759
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/coupon`),
3059
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2760
3060
  "cart"
2761
3061
  );
2762
3062
  }
2763
3063
  if (this.storeId && !this.apiKey) {
2764
3064
  return this.withGuards(
2765
- this.storefrontRequest("DELETE", `/cart/${cartId}/coupon`),
3065
+ this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2766
3066
  "cart"
2767
3067
  );
2768
3068
  }
2769
3069
  return this.withGuards(
2770
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/coupon`),
3070
+ this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`),
2771
3071
  "cart"
2772
3072
  );
2773
3073
  }
@@ -2792,18 +3092,18 @@ var BrainerceClient = class {
2792
3092
  }
2793
3093
  if (this.isVibeCodedMode()) {
2794
3094
  return this.withGuards(
2795
- this.vibeCodedRequest("POST", `/cart/${cartId}/recalculate`),
3095
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2796
3096
  "cart"
2797
3097
  );
2798
3098
  }
2799
3099
  if (this.storeId && !this.apiKey) {
2800
3100
  return this.withGuards(
2801
- this.storefrontRequest("POST", `/cart/${cartId}/recalculate`),
3101
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2802
3102
  "cart"
2803
3103
  );
2804
3104
  }
2805
3105
  return this.withGuards(
2806
- this.adminRequest("POST", `/api/v1/cart/${cartId}/recalculate`),
3106
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/recalculate`),
2807
3107
  "cart"
2808
3108
  );
2809
3109
  }
@@ -2832,18 +3132,24 @@ var BrainerceClient = class {
2832
3132
  }
2833
3133
  if (this.isVibeCodedMode()) {
2834
3134
  return this.withGuards(
2835
- this.vibeCodedRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3135
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/refresh-snapshots`),
2836
3136
  "cart"
2837
3137
  );
2838
3138
  }
2839
3139
  if (this.storeId && !this.apiKey) {
2840
3140
  return this.withGuards(
2841
- this.storefrontRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3141
+ this.storefrontRequest(
3142
+ "POST",
3143
+ `/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3144
+ ),
2842
3145
  "cart"
2843
3146
  );
2844
3147
  }
2845
3148
  return this.withGuards(
2846
- this.adminRequest("POST", `/api/v1/cart/${cartId}/refresh-snapshots`),
3149
+ this.adminRequest(
3150
+ "POST",
3151
+ `/api/v1/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3152
+ ),
2847
3153
  "cart"
2848
3154
  );
2849
3155
  }
@@ -2872,10 +3178,10 @@ var BrainerceClient = class {
2872
3178
  );
2873
3179
  }
2874
3180
  if (this.isVibeCodedMode()) {
2875
- return this.vibeCodedRequest("POST", `/cart/${cartId}/link`);
3181
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2876
3182
  }
2877
3183
  if (this.storeId && !this.apiKey) {
2878
- return this.storefrontRequest("POST", `/cart/${cartId}/link`);
3184
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2879
3185
  }
2880
3186
  throw new BrainerceError("linkCart is only available in vibe-coded or storefront mode", 400);
2881
3187
  }
@@ -2938,13 +3244,13 @@ var BrainerceClient = class {
2938
3244
  if (this.isVibeCodedMode()) {
2939
3245
  return this.vibeCodedRequest(
2940
3246
  "GET",
2941
- `/products/${productId}/discount-badge`
3247
+ `/products/${encodePathSegment(productId)}/discount-badge`
2942
3248
  );
2943
3249
  }
2944
3250
  if (this.storeId && !this.apiKey) {
2945
3251
  return this.storefrontRequest(
2946
3252
  "GET",
2947
- `/products/${productId}/discount-badge`
3253
+ `/products/${encodePathSegment(productId)}/discount-badge`
2948
3254
  );
2949
3255
  }
2950
3256
  throw new BrainerceError(
@@ -2968,10 +3274,13 @@ var BrainerceClient = class {
2968
3274
  */
2969
3275
  async getCartNudges(cartId) {
2970
3276
  if (this.isVibeCodedMode()) {
2971
- return this.vibeCodedRequest("GET", `/cart/${cartId}/nudges`);
3277
+ return this.vibeCodedRequest("GET", `/cart/${encodePathSegment(cartId)}/nudges`);
2972
3278
  }
2973
3279
  if (this.storeId && !this.apiKey) {
2974
- return this.storefrontRequest("GET", `/cart/${cartId}/nudges`);
3280
+ return this.storefrontRequest(
3281
+ "GET",
3282
+ `/cart/${encodePathSegment(cartId)}/nudges`
3283
+ );
2975
3284
  }
2976
3285
  throw new BrainerceError("getCartNudges() requires vibe-coded or storefront mode", 400);
2977
3286
  }
@@ -2996,7 +3305,7 @@ var BrainerceClient = class {
2996
3305
  if (this.isVibeCodedMode()) {
2997
3306
  return this.vibeCodedRequest(
2998
3307
  "GET",
2999
- `/products/${productId}/recommendations`,
3308
+ `/products/${encodePathSegment(productId)}/recommendations`,
3000
3309
  void 0,
3001
3310
  queryParams
3002
3311
  );
@@ -3004,7 +3313,7 @@ var BrainerceClient = class {
3004
3313
  if (this.storeId && !this.apiKey) {
3005
3314
  return this.storefrontRequest(
3006
3315
  "GET",
3007
- `/products/${productId}/recommendations`,
3316
+ `/products/${encodePathSegment(productId)}/recommendations`,
3008
3317
  void 0,
3009
3318
  queryParams
3010
3319
  );
@@ -3034,7 +3343,7 @@ var BrainerceClient = class {
3034
3343
  if (this.isVibeCodedMode()) {
3035
3344
  return this.vibeCodedRequest(
3036
3345
  "GET",
3037
- `/products/${productId}/reviews`,
3346
+ `/products/${encodePathSegment(productId)}/reviews`,
3038
3347
  void 0,
3039
3348
  queryParams
3040
3349
  );
@@ -3042,7 +3351,7 @@ var BrainerceClient = class {
3042
3351
  if (this.storeId && !this.apiKey) {
3043
3352
  return this.storefrontRequest(
3044
3353
  "GET",
3045
- `/products/${productId}/reviews`,
3354
+ `/products/${encodePathSegment(productId)}/reviews`,
3046
3355
  void 0,
3047
3356
  queryParams
3048
3357
  );
@@ -3066,10 +3375,16 @@ var BrainerceClient = class {
3066
3375
  */
3067
3376
  async getMyProductReview(productId) {
3068
3377
  if (this.isVibeCodedMode()) {
3069
- return this.vibeCodedRequest("GET", `/products/${productId}/reviews/me`);
3378
+ return this.vibeCodedRequest(
3379
+ "GET",
3380
+ `/products/${encodePathSegment(productId)}/reviews/me`
3381
+ );
3070
3382
  }
3071
3383
  if (this.storeId && !this.apiKey) {
3072
- return this.storefrontRequest("GET", `/products/${productId}/reviews/me`);
3384
+ return this.storefrontRequest(
3385
+ "GET",
3386
+ `/products/${encodePathSegment(productId)}/reviews/me`
3387
+ );
3073
3388
  }
3074
3389
  throw new BrainerceError("getMyProductReview() requires vibe-coded or storefront mode", 400);
3075
3390
  }
@@ -3093,10 +3408,18 @@ var BrainerceClient = class {
3093
3408
  */
3094
3409
  async submitProductReview(productId, input) {
3095
3410
  if (this.isVibeCodedMode()) {
3096
- return this.vibeCodedRequest("POST", `/products/${productId}/reviews`, input);
3411
+ return this.vibeCodedRequest(
3412
+ "POST",
3413
+ `/products/${encodePathSegment(productId)}/reviews`,
3414
+ input
3415
+ );
3097
3416
  }
3098
3417
  if (this.storeId && !this.apiKey) {
3099
- return this.storefrontRequest("POST", `/products/${productId}/reviews`, input);
3418
+ return this.storefrontRequest(
3419
+ "POST",
3420
+ `/products/${encodePathSegment(productId)}/reviews`,
3421
+ input
3422
+ );
3100
3423
  }
3101
3424
  throw new BrainerceError("submitProductReview() requires vibe-coded or storefront mode", 400);
3102
3425
  }
@@ -3109,14 +3432,14 @@ var BrainerceClient = class {
3109
3432
  if (this.isVibeCodedMode()) {
3110
3433
  return this.vibeCodedRequest(
3111
3434
  "PATCH",
3112
- `/products/${productId}/reviews/me`,
3435
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3113
3436
  input
3114
3437
  );
3115
3438
  }
3116
3439
  if (this.storeId && !this.apiKey) {
3117
3440
  return this.storefrontRequest(
3118
3441
  "PATCH",
3119
- `/products/${productId}/reviews/me`,
3442
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3120
3443
  input
3121
3444
  );
3122
3445
  }
@@ -3128,11 +3451,17 @@ var BrainerceClient = class {
3128
3451
  */
3129
3452
  async deleteMyProductReview(productId) {
3130
3453
  if (this.isVibeCodedMode()) {
3131
- await this.vibeCodedRequest("DELETE", `/products/${productId}/reviews/me`);
3454
+ await this.vibeCodedRequest(
3455
+ "DELETE",
3456
+ `/products/${encodePathSegment(productId)}/reviews/me`
3457
+ );
3132
3458
  return;
3133
3459
  }
3134
3460
  if (this.storeId && !this.apiKey) {
3135
- await this.storefrontRequest("DELETE", `/products/${productId}/reviews/me`);
3461
+ await this.storefrontRequest(
3462
+ "DELETE",
3463
+ `/products/${encodePathSegment(productId)}/reviews/me`
3464
+ );
3136
3465
  return;
3137
3466
  }
3138
3467
  throw new BrainerceError("deleteMyProductReview() requires vibe-coded or storefront mode", 400);
@@ -3151,7 +3480,7 @@ var BrainerceClient = class {
3151
3480
  if (params?.visibility) queryParams.visibility = params.visibility;
3152
3481
  return this.adminRequest(
3153
3482
  "GET",
3154
- `/api/v1/products/${productId}/reviews`,
3483
+ `/api/v1/products/${encodePathSegment(productId)}/reviews`,
3155
3484
  void 0,
3156
3485
  queryParams
3157
3486
  );
@@ -3163,7 +3492,7 @@ var BrainerceClient = class {
3163
3492
  }
3164
3493
  return this.adminRequest(
3165
3494
  "PATCH",
3166
- `/api/v1/reviews/${reviewId}/hide`,
3495
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/hide`,
3167
3496
  void 0,
3168
3497
  storeId ? { storeId } : void 0
3169
3498
  );
@@ -3175,7 +3504,7 @@ var BrainerceClient = class {
3175
3504
  }
3176
3505
  return this.adminRequest(
3177
3506
  "PATCH",
3178
- `/api/v1/reviews/${reviewId}/show`,
3507
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/show`,
3179
3508
  void 0,
3180
3509
  storeId ? { storeId } : void 0
3181
3510
  );
@@ -3200,7 +3529,7 @@ var BrainerceClient = class {
3200
3529
  if (this.isVibeCodedMode()) {
3201
3530
  return this.vibeCodedRequest(
3202
3531
  "GET",
3203
- `/cart/${cartId}/recommendations`,
3532
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3204
3533
  void 0,
3205
3534
  queryParams
3206
3535
  );
@@ -3208,7 +3537,7 @@ var BrainerceClient = class {
3208
3537
  if (this.storeId && !this.apiKey) {
3209
3538
  return this.storefrontRequest(
3210
3539
  "GET",
3211
- `/cart/${cartId}/recommendations`,
3540
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3212
3541
  void 0,
3213
3542
  queryParams
3214
3543
  );
@@ -3235,10 +3564,16 @@ var BrainerceClient = class {
3235
3564
  */
3236
3565
  async getCartUpgrades(cartId) {
3237
3566
  if (this.isVibeCodedMode()) {
3238
- return this.vibeCodedRequest("GET", `/cart/${cartId}/upgrades`);
3567
+ return this.vibeCodedRequest(
3568
+ "GET",
3569
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3570
+ );
3239
3571
  }
3240
3572
  if (this.storeId && !this.apiKey) {
3241
- return this.storefrontRequest("GET", `/cart/${cartId}/upgrades`);
3573
+ return this.storefrontRequest(
3574
+ "GET",
3575
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3576
+ );
3242
3577
  }
3243
3578
  throw new BrainerceError("getCartUpgrades() requires vibe-coded or storefront mode", 400);
3244
3579
  }
@@ -3260,10 +3595,16 @@ var BrainerceClient = class {
3260
3595
  */
3261
3596
  async getCartBundles(cartId) {
3262
3597
  if (this.isVibeCodedMode()) {
3263
- return this.vibeCodedRequest("GET", `/cart/${cartId}/bundles`);
3598
+ return this.vibeCodedRequest(
3599
+ "GET",
3600
+ `/cart/${encodePathSegment(cartId)}/bundles`
3601
+ );
3264
3602
  }
3265
3603
  if (this.storeId && !this.apiKey) {
3266
- return this.storefrontRequest("GET", `/cart/${cartId}/bundles`);
3604
+ return this.storefrontRequest(
3605
+ "GET",
3606
+ `/cart/${encodePathSegment(cartId)}/bundles`
3607
+ );
3267
3608
  }
3268
3609
  throw new BrainerceError("getCartBundles() requires vibe-coded or storefront mode", 400);
3269
3610
  }
@@ -3275,10 +3616,16 @@ var BrainerceClient = class {
3275
3616
  */
3276
3617
  async getCheckoutBumps(checkoutId) {
3277
3618
  if (this.isVibeCodedMode()) {
3278
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/bumps`);
3619
+ return this.vibeCodedRequest(
3620
+ "GET",
3621
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3622
+ );
3279
3623
  }
3280
3624
  if (this.storeId && !this.apiKey) {
3281
- return this.storefrontRequest("GET", `/checkout/${checkoutId}/bumps`);
3625
+ return this.storefrontRequest(
3626
+ "GET",
3627
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3628
+ );
3282
3629
  }
3283
3630
  throw new BrainerceError("getCheckoutBumps() requires vibe-coded or storefront mode", 400);
3284
3631
  }
@@ -3293,10 +3640,10 @@ var BrainerceClient = class {
3293
3640
  async addOrderBump(cartId, bumpConfigId, variantId) {
3294
3641
  const body = { bumpConfigId, ...variantId && { variantId } };
3295
3642
  if (this.isVibeCodedMode()) {
3296
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bump`, body);
3643
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3297
3644
  }
3298
3645
  if (this.storeId && !this.apiKey) {
3299
- return this.storefrontRequest("POST", `/cart/${cartId}/bump`, body);
3646
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3300
3647
  }
3301
3648
  throw new BrainerceError("addOrderBump() requires vibe-coded or storefront mode", 400);
3302
3649
  }
@@ -3309,10 +3656,16 @@ var BrainerceClient = class {
3309
3656
  */
3310
3657
  async removeOrderBump(cartId, bumpConfigId) {
3311
3658
  if (this.isVibeCodedMode()) {
3312
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3659
+ return this.vibeCodedRequest(
3660
+ "DELETE",
3661
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3662
+ );
3313
3663
  }
3314
3664
  if (this.storeId && !this.apiKey) {
3315
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3665
+ return this.storefrontRequest(
3666
+ "DELETE",
3667
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3668
+ );
3316
3669
  }
3317
3670
  throw new BrainerceError("removeOrderBump() requires vibe-coded or storefront mode", 400);
3318
3671
  }
@@ -3343,10 +3696,14 @@ var BrainerceClient = class {
3343
3696
  ...variantSelections && Object.keys(variantSelections).length > 0 ? { variantSelections } : {}
3344
3697
  };
3345
3698
  if (this.isVibeCodedMode()) {
3346
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bundle`, body);
3699
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bundle`, body);
3347
3700
  }
3348
3701
  if (this.storeId && !this.apiKey) {
3349
- return this.storefrontRequest("POST", `/cart/${cartId}/bundle`, body);
3702
+ return this.storefrontRequest(
3703
+ "POST",
3704
+ `/cart/${encodePathSegment(cartId)}/bundle`,
3705
+ body
3706
+ );
3350
3707
  }
3351
3708
  throw new BrainerceError("addBundleToCart() requires vibe-coded or storefront mode", 400);
3352
3709
  }
@@ -3359,10 +3716,16 @@ var BrainerceClient = class {
3359
3716
  */
3360
3717
  async removeBundleFromCart(cartId, bundleOfferId) {
3361
3718
  if (this.isVibeCodedMode()) {
3362
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3719
+ return this.vibeCodedRequest(
3720
+ "DELETE",
3721
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3722
+ );
3363
3723
  }
3364
3724
  if (this.storeId && !this.apiKey) {
3365
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3725
+ return this.storefrontRequest(
3726
+ "DELETE",
3727
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3728
+ );
3366
3729
  }
3367
3730
  throw new BrainerceError("removeBundleFromCart() requires vibe-coded or storefront mode", 400);
3368
3731
  }
@@ -3948,18 +4311,18 @@ var BrainerceClient = class {
3948
4311
  async getCheckout(checkoutId) {
3949
4312
  if (this.isVibeCodedMode()) {
3950
4313
  return this.withGuards(
3951
- this.vibeCodedRequest("GET", `/checkout/${checkoutId}`),
4314
+ this.vibeCodedRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3952
4315
  "checkout"
3953
4316
  );
3954
4317
  }
3955
4318
  if (this.storeId && !this.apiKey) {
3956
4319
  return this.withGuards(
3957
- this.storefrontRequest("GET", `/checkout/${checkoutId}`),
4320
+ this.storefrontRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3958
4321
  "checkout"
3959
4322
  );
3960
4323
  }
3961
4324
  return this.withGuards(
3962
- this.adminRequest("GET", `/api/v1/checkout/${checkoutId}`),
4325
+ this.adminRequest("GET", `/api/v1/checkout/${encodePathSegment(checkoutId)}`),
3963
4326
  "checkout"
3964
4327
  );
3965
4328
  }
@@ -3982,18 +4345,30 @@ var BrainerceClient = class {
3982
4345
  async applyCheckoutCoupon(checkoutId, code) {
3983
4346
  if (this.isVibeCodedMode()) {
3984
4347
  return this.withGuards(
3985
- this.vibeCodedRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4348
+ this.vibeCodedRequest(
4349
+ "POST",
4350
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4351
+ { code }
4352
+ ),
3986
4353
  "checkout"
3987
4354
  );
3988
4355
  }
3989
4356
  if (this.storeId && !this.apiKey) {
3990
4357
  return this.withGuards(
3991
- this.storefrontRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4358
+ this.storefrontRequest(
4359
+ "POST",
4360
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4361
+ { code }
4362
+ ),
3992
4363
  "checkout"
3993
4364
  );
3994
4365
  }
3995
4366
  return this.withGuards(
3996
- this.adminRequest("POST", `/api/v1/checkout/${checkoutId}/coupon`, { code }),
4367
+ this.adminRequest(
4368
+ "POST",
4369
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`,
4370
+ { code }
4371
+ ),
3997
4372
  "checkout"
3998
4373
  );
3999
4374
  }
@@ -4011,18 +4386,27 @@ var BrainerceClient = class {
4011
4386
  async removeCheckoutCoupon(checkoutId) {
4012
4387
  if (this.isVibeCodedMode()) {
4013
4388
  return this.withGuards(
4014
- this.vibeCodedRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4389
+ this.vibeCodedRequest(
4390
+ "DELETE",
4391
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4392
+ ),
4015
4393
  "checkout"
4016
4394
  );
4017
4395
  }
4018
4396
  if (this.storeId && !this.apiKey) {
4019
4397
  return this.withGuards(
4020
- this.storefrontRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4398
+ this.storefrontRequest(
4399
+ "DELETE",
4400
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4401
+ ),
4021
4402
  "checkout"
4022
4403
  );
4023
4404
  }
4024
4405
  return this.withGuards(
4025
- this.adminRequest("DELETE", `/api/v1/checkout/${checkoutId}/coupon`),
4406
+ this.adminRequest(
4407
+ "DELETE",
4408
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`
4409
+ ),
4026
4410
  "checkout"
4027
4411
  );
4028
4412
  }
@@ -4040,12 +4424,24 @@ var BrainerceClient = class {
4040
4424
  */
4041
4425
  async setCheckoutCustomer(checkoutId, data) {
4042
4426
  if (this.isVibeCodedMode()) {
4043
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4427
+ return this.vibeCodedRequest(
4428
+ "PATCH",
4429
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4430
+ data
4431
+ );
4044
4432
  }
4045
4433
  if (this.storeId && !this.apiKey) {
4046
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4434
+ return this.storefrontRequest(
4435
+ "PATCH",
4436
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4437
+ data
4438
+ );
4047
4439
  }
4048
- 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
+ );
4049
4445
  }
4050
4446
  /**
4051
4447
  * Get available shipping destinations for this store.
@@ -4113,20 +4509,20 @@ var BrainerceClient = class {
4113
4509
  if (this.isVibeCodedMode()) {
4114
4510
  return this.vibeCodedRequest(
4115
4511
  "PATCH",
4116
- `/checkout/${checkoutId}/shipping-address`,
4512
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4117
4513
  address
4118
4514
  );
4119
4515
  }
4120
4516
  if (this.storeId && !this.apiKey) {
4121
4517
  return this.storefrontRequest(
4122
4518
  "PATCH",
4123
- `/checkout/${checkoutId}/shipping-address`,
4519
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4124
4520
  address
4125
4521
  );
4126
4522
  }
4127
4523
  return this.adminRequest(
4128
4524
  "PATCH",
4129
- `/api/v1/checkout/${checkoutId}/shipping-address`,
4525
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4130
4526
  address
4131
4527
  );
4132
4528
  }
@@ -4144,19 +4540,19 @@ var BrainerceClient = class {
4144
4540
  if (this.isVibeCodedMode()) {
4145
4541
  const result = await this.vibeCodedRequest(
4146
4542
  "GET",
4147
- `/checkout/${checkoutId}/shipping-rates`
4543
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4148
4544
  );
4149
4545
  return result.rates;
4150
4546
  }
4151
4547
  if (this.storeId && !this.apiKey) {
4152
4548
  return this.storefrontRequest(
4153
4549
  "GET",
4154
- `/checkout/${checkoutId}/shipping-rates`
4550
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4155
4551
  );
4156
4552
  }
4157
4553
  return this.adminRequest(
4158
4554
  "GET",
4159
- `/api/v1/checkout/${checkoutId}/shipping-rates`
4555
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4160
4556
  );
4161
4557
  }
4162
4558
  /**
@@ -4171,24 +4567,36 @@ var BrainerceClient = class {
4171
4567
  async selectShippingMethod(checkoutId, shippingRateId) {
4172
4568
  if (this.isVibeCodedMode()) {
4173
4569
  return this.withGuards(
4174
- this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4175
- shippingMethodId: shippingRateId
4176
- }),
4570
+ this.vibeCodedRequest(
4571
+ "PATCH",
4572
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4573
+ {
4574
+ shippingRateId
4575
+ }
4576
+ ),
4177
4577
  "checkout"
4178
4578
  );
4179
4579
  }
4180
4580
  if (this.storeId && !this.apiKey) {
4181
4581
  return this.withGuards(
4182
- this.storefrontRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4183
- shippingRateId
4184
- }),
4582
+ this.storefrontRequest(
4583
+ "PATCH",
4584
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4585
+ {
4586
+ shippingRateId
4587
+ }
4588
+ ),
4185
4589
  "checkout"
4186
4590
  );
4187
4591
  }
4188
4592
  return this.withGuards(
4189
- this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/shipping-method`, {
4190
- shippingRateId
4191
- }),
4593
+ this.adminRequest(
4594
+ "PATCH",
4595
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4596
+ {
4597
+ shippingRateId
4598
+ }
4599
+ ),
4192
4600
  "checkout"
4193
4601
  );
4194
4602
  }
@@ -4227,18 +4635,30 @@ var BrainerceClient = class {
4227
4635
  */
4228
4636
  async setDeliveryType(checkoutId, deliveryType) {
4229
4637
  if (this.isVibeCodedMode()) {
4230
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4231
- deliveryType
4232
- });
4638
+ return this.vibeCodedRequest(
4639
+ "PATCH",
4640
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4641
+ {
4642
+ deliveryType
4643
+ }
4644
+ );
4233
4645
  }
4234
4646
  if (this.storeId && !this.apiKey) {
4235
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4236
- deliveryType
4237
- });
4647
+ return this.storefrontRequest(
4648
+ "PATCH",
4649
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4650
+ {
4651
+ deliveryType
4652
+ }
4653
+ );
4238
4654
  }
4239
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/delivery-type`, {
4240
- deliveryType
4241
- });
4655
+ return this.adminRequest(
4656
+ "PATCH",
4657
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4658
+ {
4659
+ deliveryType
4660
+ }
4661
+ );
4242
4662
  }
4243
4663
  /**
4244
4664
  * Select a pickup location for checkout.
@@ -4260,20 +4680,20 @@ var BrainerceClient = class {
4260
4680
  if (this.isVibeCodedMode()) {
4261
4681
  return this.vibeCodedRequest(
4262
4682
  "PATCH",
4263
- `/checkout/${checkoutId}/pickup-location`,
4683
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4264
4684
  data
4265
4685
  );
4266
4686
  }
4267
4687
  if (this.storeId && !this.apiKey) {
4268
4688
  return this.storefrontRequest(
4269
4689
  "PATCH",
4270
- `/checkout/${checkoutId}/pickup-location`,
4690
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4271
4691
  data
4272
4692
  );
4273
4693
  }
4274
4694
  return this.adminRequest(
4275
4695
  "PATCH",
4276
- `/api/v1/checkout/${checkoutId}/pickup-location`,
4696
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4277
4697
  data
4278
4698
  );
4279
4699
  }
@@ -4305,20 +4725,20 @@ var BrainerceClient = class {
4305
4725
  if (this.isVibeCodedMode()) {
4306
4726
  return this.vibeCodedRequest(
4307
4727
  "PATCH",
4308
- `/checkout/${checkoutId}/billing-address`,
4728
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4309
4729
  address
4310
4730
  );
4311
4731
  }
4312
4732
  if (this.storeId && !this.apiKey) {
4313
4733
  return this.storefrontRequest(
4314
4734
  "PATCH",
4315
- `/checkout/${checkoutId}/billing-address`,
4735
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4316
4736
  address
4317
4737
  );
4318
4738
  }
4319
4739
  return this.adminRequest(
4320
4740
  "PATCH",
4321
- `/api/v1/checkout/${checkoutId}/billing-address`,
4741
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4322
4742
  address
4323
4743
  );
4324
4744
  }
@@ -4337,17 +4757,17 @@ var BrainerceClient = class {
4337
4757
  if (this.isVibeCodedMode()) {
4338
4758
  result = await this.vibeCodedRequest(
4339
4759
  "POST",
4340
- `/checkout/${checkoutId}/complete`
4760
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4341
4761
  );
4342
4762
  } else if (this.storeId && !this.apiKey) {
4343
4763
  result = await this.storefrontRequest(
4344
4764
  "POST",
4345
- `/checkout/${checkoutId}/complete`
4765
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4346
4766
  );
4347
4767
  } else {
4348
4768
  result = await this.adminRequest(
4349
4769
  "POST",
4350
- `/api/v1/checkout/${checkoutId}/complete`
4770
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/complete`
4351
4771
  );
4352
4772
  }
4353
4773
  this.customerCartId = null;
@@ -4365,18 +4785,18 @@ var BrainerceClient = class {
4365
4785
  if (this.isVibeCodedMode()) {
4366
4786
  return this.vibeCodedRequest(
4367
4787
  "GET",
4368
- `/checkout/${checkoutId}/custom-fields`
4788
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4369
4789
  );
4370
4790
  }
4371
4791
  if (this.storeId && !this.apiKey) {
4372
4792
  return this.storefrontRequest(
4373
4793
  "GET",
4374
- `/checkout/${checkoutId}/custom-fields`
4794
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4375
4795
  );
4376
4796
  }
4377
4797
  return this.adminRequest(
4378
4798
  "GET",
4379
- `/api/v1/checkouts/${checkoutId}/custom-fields`
4799
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`
4380
4800
  );
4381
4801
  }
4382
4802
  /**
@@ -4399,20 +4819,20 @@ var BrainerceClient = class {
4399
4819
  if (this.isVibeCodedMode()) {
4400
4820
  return this.vibeCodedRequest(
4401
4821
  "PATCH",
4402
- `/checkout/${checkoutId}/custom-fields`,
4822
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4403
4823
  data
4404
4824
  );
4405
4825
  }
4406
4826
  if (this.storeId && !this.apiKey) {
4407
4827
  return this.storefrontRequest(
4408
4828
  "PATCH",
4409
- `/checkout/${checkoutId}/custom-fields`,
4829
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4410
4830
  data
4411
4831
  );
4412
4832
  }
4413
4833
  return this.adminRequest(
4414
4834
  "PATCH",
4415
- `/api/v1/checkouts/${checkoutId}/custom-fields`,
4835
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`,
4416
4836
  data
4417
4837
  );
4418
4838
  }
@@ -4427,17 +4847,17 @@ var BrainerceClient = class {
4427
4847
  if (this.isVibeCodedMode()) {
4428
4848
  result = await this.vibeCodedRequest(
4429
4849
  "DELETE",
4430
- `/checkout/${checkoutId}`
4850
+ `/checkout/${encodePathSegment(checkoutId)}`
4431
4851
  );
4432
4852
  } else if (this.storeId && !this.apiKey) {
4433
4853
  result = await this.storefrontRequest(
4434
4854
  "DELETE",
4435
- `/checkout/${checkoutId}`
4855
+ `/checkout/${encodePathSegment(checkoutId)}`
4436
4856
  );
4437
4857
  } else {
4438
4858
  result = await this.adminRequest(
4439
4859
  "DELETE",
4440
- `/api/v1/checkout/${checkoutId}`
4860
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}`
4441
4861
  );
4442
4862
  }
4443
4863
  this.clearActiveCheckoutStorage();
@@ -4605,7 +5025,10 @@ var BrainerceClient = class {
4605
5025
  400
4606
5026
  );
4607
5027
  }
4608
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
5028
+ return this.vibeCodedRequest(
5029
+ "GET",
5030
+ `/checkout/${encodePathSegment(checkoutId)}/payment-status`
5031
+ );
4609
5032
  }
4610
5033
  /**
4611
5034
  * Confirm a client-side SDK payment from the frontend.
@@ -4704,7 +5127,7 @@ var BrainerceClient = class {
4704
5127
  const startTime = Date.now();
4705
5128
  let attempts = 0;
4706
5129
  let currentDelay = initialDelayMs;
4707
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5130
+ const sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4708
5131
  while (Date.now() - startTime < maxWaitMs) {
4709
5132
  attempts++;
4710
5133
  const status = await this.getPaymentStatus(checkoutId);
@@ -4729,7 +5152,7 @@ var BrainerceClient = class {
4729
5152
  const remainingTime = maxWaitMs - (Date.now() - startTime);
4730
5153
  const sleepTime = Math.min(currentDelay, remainingTime, 8e3);
4731
5154
  if (sleepTime > 0) {
4732
- await sleep(sleepTime);
5155
+ await sleep2(sleepTime);
4733
5156
  currentDelay = Math.min(currentDelay * 2, 8e3);
4734
5157
  }
4735
5158
  }
@@ -5244,7 +5667,7 @@ var BrainerceClient = class {
5244
5667
  if (data.shippingAddress) {
5245
5668
  const result = await this.vibeCodedRequest(
5246
5669
  "PATCH",
5247
- `/checkout/${checkoutId}/shipping-address`,
5670
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
5248
5671
  data.shippingAddress
5249
5672
  );
5250
5673
  checkout = result.checkout;
@@ -5252,7 +5675,7 @@ var BrainerceClient = class {
5252
5675
  if (data.billingAddress) {
5253
5676
  checkout = await this.vibeCodedRequest(
5254
5677
  "PATCH",
5255
- `/checkout/${checkoutId}/billing-address`,
5678
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
5256
5679
  data.billingAddress
5257
5680
  );
5258
5681
  }
@@ -5286,7 +5709,7 @@ var BrainerceClient = class {
5286
5709
  async completeGuestCheckout(checkoutId, options) {
5287
5710
  const result = await this.vibeCodedRequest(
5288
5711
  "POST",
5289
- `/checkout/${checkoutId}/complete`,
5712
+ `/checkout/${encodePathSegment(checkoutId)}/complete`,
5290
5713
  {}
5291
5714
  );
5292
5715
  if (options?.clearCartOnSuccess !== false) {
@@ -5594,13 +6017,13 @@ var BrainerceClient = class {
5594
6017
  if (this.isVibeCodedMode()) {
5595
6018
  return this.vibeCodedRequest(
5596
6019
  "GET",
5597
- `/customers/me/orders/${orderId}/downloads${qs}`
6020
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5598
6021
  );
5599
6022
  }
5600
6023
  if (this.storeId && !this.apiKey) {
5601
6024
  return this.storefrontRequest(
5602
6025
  "GET",
5603
- `/customers/me/orders/${orderId}/downloads${qs}`
6026
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5604
6027
  );
5605
6028
  }
5606
6029
  throw new BrainerceError(
@@ -5693,14 +6116,14 @@ var BrainerceClient = class {
5693
6116
  if (this.isVibeCodedMode()) {
5694
6117
  return this.vibeCodedRequest(
5695
6118
  "PATCH",
5696
- `/customers/me/addresses/${addressId}`,
6119
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5697
6120
  data
5698
6121
  );
5699
6122
  }
5700
6123
  if (this.storeId && !this.apiKey) {
5701
6124
  return this.storefrontRequest(
5702
6125
  "PATCH",
5703
- `/customers/me/addresses/${addressId}`,
6126
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5704
6127
  data
5705
6128
  );
5706
6129
  }
@@ -5721,11 +6144,17 @@ var BrainerceClient = class {
5721
6144
  );
5722
6145
  }
5723
6146
  if (this.isVibeCodedMode()) {
5724
- await this.vibeCodedRequest("DELETE", `/customers/me/addresses/${addressId}`);
6147
+ await this.vibeCodedRequest(
6148
+ "DELETE",
6149
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6150
+ );
5725
6151
  return;
5726
6152
  }
5727
6153
  if (this.storeId && !this.apiKey) {
5728
- await this.storefrontRequest("DELETE", `/customers/me/addresses/${addressId}`);
6154
+ await this.storefrontRequest(
6155
+ "DELETE",
6156
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6157
+ );
5729
6158
  return;
5730
6159
  }
5731
6160
  throw new BrainerceError(
@@ -5778,7 +6207,10 @@ var BrainerceClient = class {
5778
6207
  * ```
5779
6208
  */
5780
6209
  async getCustomApiIntegration(integrationId) {
5781
- return this.adminRequest("GET", `/api/v1/custom-api/${integrationId}`);
6210
+ return this.adminRequest(
6211
+ "GET",
6212
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6213
+ );
5782
6214
  }
5783
6215
  /**
5784
6216
  * Create a new Custom API integration
@@ -5821,7 +6253,7 @@ var BrainerceClient = class {
5821
6253
  async updateCustomApiIntegration(integrationId, data) {
5822
6254
  return this.adminRequest(
5823
6255
  "PATCH",
5824
- `/api/v1/custom-api/${integrationId}`,
6256
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`,
5825
6257
  data
5826
6258
  );
5827
6259
  }
@@ -5835,7 +6267,10 @@ var BrainerceClient = class {
5835
6267
  * ```
5836
6268
  */
5837
6269
  async deleteCustomApiIntegration(integrationId) {
5838
- await this.adminRequest("DELETE", `/api/v1/custom-api/${integrationId}`);
6270
+ await this.adminRequest(
6271
+ "DELETE",
6272
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6273
+ );
5839
6274
  }
5840
6275
  /**
5841
6276
  * Test connection to a Custom API
@@ -5854,7 +6289,7 @@ var BrainerceClient = class {
5854
6289
  async testCustomApiConnection(integrationId) {
5855
6290
  return this.adminRequest(
5856
6291
  "POST",
5857
- `/api/v1/custom-api/${integrationId}/test`
6292
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}/test`
5858
6293
  );
5859
6294
  }
5860
6295
  // -------------------- Inventory Reservations --------------------
@@ -5975,7 +6410,10 @@ var BrainerceClient = class {
5975
6410
  * Requires Admin mode (apiKey)
5976
6411
  */
5977
6412
  async getCategory(categoryId) {
5978
- return this.adminRequest("GET", `/api/v1/categories/${categoryId}`);
6413
+ return this.adminRequest(
6414
+ "GET",
6415
+ `/api/v1/categories/${encodePathSegment(categoryId)}`
6416
+ );
5979
6417
  }
5980
6418
  /**
5981
6419
  * Create a new category
@@ -5998,14 +6436,18 @@ var BrainerceClient = class {
5998
6436
  * Requires Admin mode (apiKey)
5999
6437
  */
6000
6438
  async updateCategory(categoryId, data) {
6001
- return this.adminRequest("PATCH", `/api/v1/categories/${categoryId}`, data);
6439
+ return this.adminRequest(
6440
+ "PATCH",
6441
+ `/api/v1/categories/${encodePathSegment(categoryId)}`,
6442
+ data
6443
+ );
6002
6444
  }
6003
6445
  /**
6004
6446
  * Delete a category
6005
6447
  * Requires Admin mode (apiKey)
6006
6448
  */
6007
6449
  async deleteCategory(categoryId) {
6008
- await this.adminRequest("DELETE", `/api/v1/categories/${categoryId}`);
6450
+ await this.adminRequest("DELETE", `/api/v1/categories/${encodePathSegment(categoryId)}`);
6009
6451
  }
6010
6452
  // -------------------- Taxonomy: Brands (Admin) --------------------
6011
6453
  // These methods require Admin mode (apiKey)
@@ -6021,7 +6463,7 @@ var BrainerceClient = class {
6021
6463
  * Requires Admin mode (apiKey)
6022
6464
  */
6023
6465
  async getBrand(brandId) {
6024
- return this.adminRequest("GET", `/api/v1/brands/${brandId}`);
6466
+ return this.adminRequest("GET", `/api/v1/brands/${encodePathSegment(brandId)}`);
6025
6467
  }
6026
6468
  /**
6027
6469
  * Create a new brand
@@ -6044,14 +6486,14 @@ var BrainerceClient = class {
6044
6486
  * Requires Admin mode (apiKey)
6045
6487
  */
6046
6488
  async updateBrand(brandId, data) {
6047
- return this.adminRequest("PATCH", `/api/v1/brands/${brandId}`, data);
6489
+ return this.adminRequest("PATCH", `/api/v1/brands/${encodePathSegment(brandId)}`, data);
6048
6490
  }
6049
6491
  /**
6050
6492
  * Delete a brand
6051
6493
  * Requires Admin mode (apiKey)
6052
6494
  */
6053
6495
  async deleteBrand(brandId) {
6054
- await this.adminRequest("DELETE", `/api/v1/brands/${brandId}`);
6496
+ await this.adminRequest("DELETE", `/api/v1/brands/${encodePathSegment(brandId)}`);
6055
6497
  }
6056
6498
  // -------------------- Taxonomy: Tags (Admin) --------------------
6057
6499
  // These methods require Admin mode (apiKey)
@@ -6067,7 +6509,7 @@ var BrainerceClient = class {
6067
6509
  * Requires Admin mode (apiKey)
6068
6510
  */
6069
6511
  async getTag(tagId) {
6070
- return this.adminRequest("GET", `/api/v1/tags/${tagId}`);
6512
+ return this.adminRequest("GET", `/api/v1/tags/${encodePathSegment(tagId)}`);
6071
6513
  }
6072
6514
  /**
6073
6515
  * Create a new tag
@@ -6089,14 +6531,14 @@ var BrainerceClient = class {
6089
6531
  * Requires Admin mode (apiKey)
6090
6532
  */
6091
6533
  async updateTag(tagId, data) {
6092
- return this.adminRequest("PATCH", `/api/v1/tags/${tagId}`, data);
6534
+ return this.adminRequest("PATCH", `/api/v1/tags/${encodePathSegment(tagId)}`, data);
6093
6535
  }
6094
6536
  /**
6095
6537
  * Delete a tag
6096
6538
  * Requires Admin mode (apiKey)
6097
6539
  */
6098
6540
  async deleteTag(tagId) {
6099
- await this.adminRequest("DELETE", `/api/v1/tags/${tagId}`);
6541
+ await this.adminRequest("DELETE", `/api/v1/tags/${encodePathSegment(tagId)}`);
6100
6542
  }
6101
6543
  // -------------------- Taxonomy: Attributes (Admin) --------------------
6102
6544
  // These methods require Admin mode (apiKey)
@@ -6117,7 +6559,10 @@ var BrainerceClient = class {
6117
6559
  * Requires Admin mode (apiKey)
6118
6560
  */
6119
6561
  async getAttribute(attributeId) {
6120
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}`);
6562
+ return this.adminRequest(
6563
+ "GET",
6564
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`
6565
+ );
6121
6566
  }
6122
6567
  /**
6123
6568
  * Create a new attribute
@@ -6140,21 +6585,28 @@ var BrainerceClient = class {
6140
6585
  * Requires Admin mode (apiKey)
6141
6586
  */
6142
6587
  async updateAttribute(attributeId, data) {
6143
- return this.adminRequest("PATCH", `/api/v1/attributes/${attributeId}`, data);
6588
+ return this.adminRequest(
6589
+ "PATCH",
6590
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`,
6591
+ data
6592
+ );
6144
6593
  }
6145
6594
  /**
6146
6595
  * Delete an attribute
6147
6596
  * Requires Admin mode (apiKey)
6148
6597
  */
6149
6598
  async deleteAttribute(attributeId) {
6150
- await this.adminRequest("DELETE", `/api/v1/attributes/${attributeId}`);
6599
+ await this.adminRequest("DELETE", `/api/v1/attributes/${encodePathSegment(attributeId)}`);
6151
6600
  }
6152
6601
  /**
6153
6602
  * Get all options for an attribute
6154
6603
  * Requires Admin mode (apiKey)
6155
6604
  */
6156
6605
  async getAttributeOptions(attributeId) {
6157
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}/options`);
6606
+ return this.adminRequest(
6607
+ "GET",
6608
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`
6609
+ );
6158
6610
  }
6159
6611
  /**
6160
6612
  * Create a new option for an attribute
@@ -6172,7 +6624,7 @@ var BrainerceClient = class {
6172
6624
  async createAttributeOption(attributeId, data) {
6173
6625
  return this.adminRequest(
6174
6626
  "POST",
6175
- `/api/v1/attributes/${attributeId}/options`,
6627
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`,
6176
6628
  data
6177
6629
  );
6178
6630
  }
@@ -6183,7 +6635,7 @@ var BrainerceClient = class {
6183
6635
  async updateAttributeOption(attributeId, optionId, data) {
6184
6636
  return this.adminRequest(
6185
6637
  "PATCH",
6186
- `/api/v1/attributes/${attributeId}/options/${optionId}`,
6638
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`,
6187
6639
  data
6188
6640
  );
6189
6641
  }
@@ -6194,7 +6646,7 @@ var BrainerceClient = class {
6194
6646
  async deleteAttributeOption(attributeId, optionId) {
6195
6647
  await this.adminRequest(
6196
6648
  "DELETE",
6197
- `/api/v1/attributes/${attributeId}/options/${optionId}`
6649
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`
6198
6650
  );
6199
6651
  }
6200
6652
  // -------------------- Modifier Groups (Admin) --------------------
@@ -6223,7 +6675,7 @@ var BrainerceClient = class {
6223
6675
  async listModifierGroups(storeId, params) {
6224
6676
  return this.adminRequest(
6225
6677
  "GET",
6226
- `/api/stores/${storeId}/modifier-groups`,
6678
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6227
6679
  void 0,
6228
6680
  params
6229
6681
  );
@@ -6238,7 +6690,7 @@ var BrainerceClient = class {
6238
6690
  async getModifierGroup(storeId, groupId) {
6239
6691
  return this.adminRequest(
6240
6692
  "GET",
6241
- `/api/stores/${storeId}/modifier-groups/${groupId}`
6693
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6242
6694
  );
6243
6695
  }
6244
6696
  /**
@@ -6260,7 +6712,11 @@ var BrainerceClient = class {
6260
6712
  * ```
6261
6713
  */
6262
6714
  async createModifierGroup(storeId, data) {
6263
- 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
+ );
6264
6720
  }
6265
6721
  /**
6266
6722
  * Update a modifier group's metadata or selection rules. Pass `status: 'archived'`
@@ -6270,7 +6726,7 @@ var BrainerceClient = class {
6270
6726
  async updateModifierGroup(storeId, groupId, data) {
6271
6727
  return this.adminRequest(
6272
6728
  "PATCH",
6273
- `/api/stores/${storeId}/modifier-groups/${groupId}`,
6729
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`,
6274
6730
  data
6275
6731
  );
6276
6732
  }
@@ -6281,7 +6737,10 @@ var BrainerceClient = class {
6281
6737
  * Requires Admin mode (apiKey).
6282
6738
  */
6283
6739
  async deleteModifierGroup(storeId, groupId) {
6284
- 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
+ );
6285
6744
  }
6286
6745
  /**
6287
6746
  * Create a modifier inside a group (e.g., "Olives" inside the "Toppings" group).
@@ -6305,7 +6764,7 @@ var BrainerceClient = class {
6305
6764
  async createModifier(storeId, groupId, data) {
6306
6765
  return this.adminRequest(
6307
6766
  "POST",
6308
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers`,
6767
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers`,
6309
6768
  data
6310
6769
  );
6311
6770
  }
@@ -6316,7 +6775,7 @@ var BrainerceClient = class {
6316
6775
  async updateModifier(storeId, groupId, modifierId, data) {
6317
6776
  return this.adminRequest(
6318
6777
  "PATCH",
6319
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`,
6778
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`,
6320
6779
  data
6321
6780
  );
6322
6781
  }
@@ -6328,7 +6787,7 @@ var BrainerceClient = class {
6328
6787
  async deleteModifier(storeId, groupId, modifierId) {
6329
6788
  await this.adminRequest(
6330
6789
  "DELETE",
6331
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`
6790
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`
6332
6791
  );
6333
6792
  }
6334
6793
  /**
@@ -6347,7 +6806,7 @@ var BrainerceClient = class {
6347
6806
  async toggleModifierAvailability(storeId, groupId, modifierId, available) {
6348
6807
  return this.adminRequest(
6349
6808
  "POST",
6350
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}/availability-toggle`,
6809
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}/availability-toggle`,
6351
6810
  { available }
6352
6811
  );
6353
6812
  }
@@ -6368,7 +6827,7 @@ var BrainerceClient = class {
6368
6827
  async attachModifierGroup(storeId, productId, data) {
6369
6828
  return this.adminRequest(
6370
6829
  "POST",
6371
- `/api/stores/${storeId}/products/${productId}/modifier-groups`,
6830
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups`,
6372
6831
  data
6373
6832
  );
6374
6833
  }
@@ -6381,7 +6840,7 @@ var BrainerceClient = class {
6381
6840
  async updateAttachment(storeId, productId, attachmentId, data) {
6382
6841
  return this.adminRequest(
6383
6842
  "PATCH",
6384
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`,
6843
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`,
6385
6844
  data
6386
6845
  );
6387
6846
  }
@@ -6392,7 +6851,7 @@ var BrainerceClient = class {
6392
6851
  async detachModifierGroup(storeId, productId, attachmentId) {
6393
6852
  await this.adminRequest(
6394
6853
  "DELETE",
6395
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`
6854
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`
6396
6855
  );
6397
6856
  }
6398
6857
  // -------------------- Shipping: Zones and Rates (Admin) --------------------
@@ -6414,7 +6873,10 @@ var BrainerceClient = class {
6414
6873
  * Requires Admin mode (apiKey)
6415
6874
  */
6416
6875
  async getShippingZone(zoneId) {
6417
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}`);
6876
+ return this.adminRequest(
6877
+ "GET",
6878
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`
6879
+ );
6418
6880
  }
6419
6881
  /**
6420
6882
  * Create a new shipping zone
@@ -6437,21 +6899,28 @@ var BrainerceClient = class {
6437
6899
  * Requires Admin mode (apiKey)
6438
6900
  */
6439
6901
  async updateShippingZone(zoneId, data) {
6440
- 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
+ );
6441
6907
  }
6442
6908
  /**
6443
6909
  * Delete a shipping zone
6444
6910
  * Requires Admin mode (apiKey)
6445
6911
  */
6446
6912
  async deleteShippingZone(zoneId) {
6447
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}`);
6913
+ await this.adminRequest("DELETE", `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`);
6448
6914
  }
6449
6915
  /**
6450
6916
  * Get all shipping rates for a zone
6451
6917
  * Requires Admin mode (apiKey)
6452
6918
  */
6453
6919
  async getZoneShippingRates(zoneId) {
6454
- 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
+ );
6455
6924
  }
6456
6925
  /**
6457
6926
  * Create a new shipping rate for a zone
@@ -6471,7 +6940,7 @@ var BrainerceClient = class {
6471
6940
  async createZoneShippingRate(zoneId, data) {
6472
6941
  return this.adminRequest(
6473
6942
  "POST",
6474
- `/api/v1/shipping/zones/${zoneId}/rates`,
6943
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`,
6475
6944
  data
6476
6945
  );
6477
6946
  }
@@ -6482,7 +6951,7 @@ var BrainerceClient = class {
6482
6951
  async updateZoneShippingRate(zoneId, rateId, data) {
6483
6952
  return this.adminRequest(
6484
6953
  "PATCH",
6485
- `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`,
6954
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`,
6486
6955
  data
6487
6956
  );
6488
6957
  }
@@ -6491,7 +6960,149 @@ var BrainerceClient = class {
6491
6960
  * Requires Admin mode (apiKey)
6492
6961
  */
6493
6962
  async deleteZoneShippingRate(zoneId, rateId) {
6494
- 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
+ );
6495
7106
  }
6496
7107
  // -------------------- Tax: Rates --------------------
6497
7108
  // These methods require Admin mode (apiKey)
@@ -6507,7 +7118,7 @@ var BrainerceClient = class {
6507
7118
  * Requires Admin mode (apiKey)
6508
7119
  */
6509
7120
  async getTaxRate(rateId) {
6510
- return this.adminRequest("GET", `/api/v1/tax/rates/${rateId}`);
7121
+ return this.adminRequest("GET", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6511
7122
  }
6512
7123
  /**
6513
7124
  * Create a new tax rate
@@ -6532,14 +7143,18 @@ var BrainerceClient = class {
6532
7143
  * Requires Admin mode (apiKey)
6533
7144
  */
6534
7145
  async updateTaxRate(rateId, data) {
6535
- 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
+ );
6536
7151
  }
6537
7152
  /**
6538
7153
  * Delete a tax rate
6539
7154
  * Requires Admin mode (apiKey)
6540
7155
  */
6541
7156
  async deleteTaxRate(rateId) {
6542
- await this.adminRequest("DELETE", `/api/v1/tax/rates/${rateId}`);
7157
+ await this.adminRequest("DELETE", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6543
7158
  }
6544
7159
  // -------------------- Metafields: Definitions --------------------
6545
7160
  // These methods require Admin mode (apiKey)
@@ -6595,7 +7210,7 @@ var BrainerceClient = class {
6595
7210
  async getMetafieldDefinition(definitionId) {
6596
7211
  return this.adminRequest(
6597
7212
  "GET",
6598
- `/api/v1/metafield-definitions/${definitionId}`
7213
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
6599
7214
  );
6600
7215
  }
6601
7216
  /**
@@ -6622,7 +7237,7 @@ var BrainerceClient = class {
6622
7237
  async updateMetafieldDefinition(definitionId, data) {
6623
7238
  return this.adminRequest(
6624
7239
  "PATCH",
6625
- `/api/v1/metafield-definitions/${definitionId}`,
7240
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`,
6626
7241
  data
6627
7242
  );
6628
7243
  }
@@ -6631,7 +7246,10 @@ var BrainerceClient = class {
6631
7246
  * Requires Admin mode (apiKey)
6632
7247
  */
6633
7248
  async deleteMetafieldDefinition(definitionId) {
6634
- await this.adminRequest("DELETE", `/api/v1/metafield-definitions/${definitionId}`);
7249
+ await this.adminRequest(
7250
+ "DELETE",
7251
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
7252
+ );
6635
7253
  }
6636
7254
  /**
6637
7255
  * Replace the platform publishing configuration on a metafield definition.
@@ -6655,7 +7273,7 @@ var BrainerceClient = class {
6655
7273
  async setMetafieldPlatforms(definitionId, data) {
6656
7274
  return this.adminRequest(
6657
7275
  "PUT",
6658
- `/api/v1/metafield-definitions/${definitionId}/platforms`,
7276
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/platforms`,
6659
7277
  data
6660
7278
  );
6661
7279
  }
@@ -6674,7 +7292,7 @@ var BrainerceClient = class {
6674
7292
  async publishMetafieldDefinitionToVibeCodedSite(definitionId, vibeCodedConnectionId) {
6675
7293
  return this.adminRequest(
6676
7294
  "POST",
6677
- `/api/v1/metafield-definitions/${definitionId}/publish-vibe-coded`,
7295
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/publish-vibe-coded`,
6678
7296
  { vibeCodedConnectionId }
6679
7297
  );
6680
7298
  }
@@ -6682,7 +7300,7 @@ var BrainerceClient = class {
6682
7300
  async unpublishMetafieldDefinitionFromVibeCodedSite(definitionId, vibeCodedConnectionId) {
6683
7301
  return this.adminRequest(
6684
7302
  "POST",
6685
- `/api/v1/metafield-definitions/${definitionId}/unpublish-vibe-coded`,
7303
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/unpublish-vibe-coded`,
6686
7304
  { vibeCodedConnectionId }
6687
7305
  );
6688
7306
  }
@@ -6690,7 +7308,7 @@ var BrainerceClient = class {
6690
7308
  async publishCategoryToVibeCodedSite(categoryId, vibeCodedConnectionId) {
6691
7309
  return this.adminRequest(
6692
7310
  "POST",
6693
- `/api/v1/categories/${categoryId}/publish-vibe-coded`,
7311
+ `/api/v1/categories/${encodePathSegment(categoryId)}/publish-vibe-coded`,
6694
7312
  { vibeCodedConnectionId }
6695
7313
  );
6696
7314
  }
@@ -6698,7 +7316,7 @@ var BrainerceClient = class {
6698
7316
  async unpublishCategoryFromVibeCodedSite(categoryId, vibeCodedConnectionId) {
6699
7317
  return this.adminRequest(
6700
7318
  "POST",
6701
- `/api/v1/categories/${categoryId}/unpublish-vibe-coded`,
7319
+ `/api/v1/categories/${encodePathSegment(categoryId)}/unpublish-vibe-coded`,
6702
7320
  { vibeCodedConnectionId }
6703
7321
  );
6704
7322
  }
@@ -6706,7 +7324,7 @@ var BrainerceClient = class {
6706
7324
  async publishTagToVibeCodedSite(tagId, vibeCodedConnectionId) {
6707
7325
  return this.adminRequest(
6708
7326
  "POST",
6709
- `/api/v1/tags/${tagId}/publish-vibe-coded`,
7327
+ `/api/v1/tags/${encodePathSegment(tagId)}/publish-vibe-coded`,
6710
7328
  { vibeCodedConnectionId }
6711
7329
  );
6712
7330
  }
@@ -6714,7 +7332,7 @@ var BrainerceClient = class {
6714
7332
  async unpublishTagFromVibeCodedSite(tagId, vibeCodedConnectionId) {
6715
7333
  return this.adminRequest(
6716
7334
  "POST",
6717
- `/api/v1/tags/${tagId}/unpublish-vibe-coded`,
7335
+ `/api/v1/tags/${encodePathSegment(tagId)}/unpublish-vibe-coded`,
6718
7336
  { vibeCodedConnectionId }
6719
7337
  );
6720
7338
  }
@@ -6722,7 +7340,7 @@ var BrainerceClient = class {
6722
7340
  async publishBrandToVibeCodedSite(brandId, vibeCodedConnectionId) {
6723
7341
  return this.adminRequest(
6724
7342
  "POST",
6725
- `/api/v1/brands/${brandId}/publish-vibe-coded`,
7343
+ `/api/v1/brands/${encodePathSegment(brandId)}/publish-vibe-coded`,
6726
7344
  { vibeCodedConnectionId }
6727
7345
  );
6728
7346
  }
@@ -6730,7 +7348,7 @@ var BrainerceClient = class {
6730
7348
  async unpublishBrandFromVibeCodedSite(brandId, vibeCodedConnectionId) {
6731
7349
  return this.adminRequest(
6732
7350
  "POST",
6733
- `/api/v1/brands/${brandId}/unpublish-vibe-coded`,
7351
+ `/api/v1/brands/${encodePathSegment(brandId)}/unpublish-vibe-coded`,
6734
7352
  { vibeCodedConnectionId }
6735
7353
  );
6736
7354
  }
@@ -6756,7 +7374,7 @@ var BrainerceClient = class {
6756
7374
  async setDefinitionProducts(definitionId, data) {
6757
7375
  return this.adminRequest(
6758
7376
  "PATCH",
6759
- `/api/v1/metafield-definitions/${definitionId}/products`,
7377
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/products`,
6760
7378
  data
6761
7379
  );
6762
7380
  }
@@ -6769,7 +7387,7 @@ var BrainerceClient = class {
6769
7387
  async getProductMetafields(productId) {
6770
7388
  return this.adminRequest(
6771
7389
  "GET",
6772
- `/api/v1/products/${productId}/metafields`
7390
+ `/api/v1/products/${encodePathSegment(productId)}/metafields`
6773
7391
  );
6774
7392
  }
6775
7393
  /**
@@ -6786,7 +7404,7 @@ var BrainerceClient = class {
6786
7404
  async setProductMetafield(productId, definitionId, data) {
6787
7405
  return this.adminRequest(
6788
7406
  "PUT",
6789
- `/api/v1/products/${productId}/metafields/${definitionId}`,
7407
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`,
6790
7408
  data
6791
7409
  );
6792
7410
  }
@@ -6797,7 +7415,7 @@ var BrainerceClient = class {
6797
7415
  async deleteProductMetafield(productId, definitionId) {
6798
7416
  await this.adminRequest(
6799
7417
  "DELETE",
6800
- `/api/v1/products/${productId}/metafields/${definitionId}`
7418
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`
6801
7419
  );
6802
7420
  }
6803
7421
  // -------------------- Product Customization Fields (Admin) --------------------
@@ -6808,7 +7426,7 @@ var BrainerceClient = class {
6808
7426
  async getProductCustomizationFields(productId) {
6809
7427
  return this.adminRequest(
6810
7428
  "GET",
6811
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`
7429
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`
6812
7430
  );
6813
7431
  }
6814
7432
  /**
@@ -6819,7 +7437,7 @@ var BrainerceClient = class {
6819
7437
  async setProductCustomizationFields(productId, definitionIds) {
6820
7438
  return this.adminRequest(
6821
7439
  "PATCH",
6822
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`,
7440
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`,
6823
7441
  { definitionIds }
6824
7442
  );
6825
7443
  }
@@ -6899,26 +7517,33 @@ var BrainerceClient = class {
6899
7517
  async resendTeamInvitation(invitationId) {
6900
7518
  return this.adminRequest(
6901
7519
  "POST",
6902
- `/api/v1/team/invitations/${invitationId}/resend`
7520
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}/resend`
6903
7521
  );
6904
7522
  }
6905
7523
  /**
6906
7524
  * @deprecated Use `revokeStoreInvitation(storeId, invitationId)` instead.
6907
7525
  */
6908
7526
  async revokeTeamInvitation(invitationId) {
6909
- await this.adminRequest("DELETE", `/api/v1/team/invitations/${invitationId}`);
7527
+ await this.adminRequest(
7528
+ "DELETE",
7529
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}`
7530
+ );
6910
7531
  }
6911
7532
  /**
6912
7533
  * @deprecated Use `updateStoreMember(storeId, memberId, data)` instead.
6913
7534
  */
6914
7535
  async updateTeamMemberRole(memberId, data) {
6915
- 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
+ );
6916
7541
  }
6917
7542
  /**
6918
7543
  * @deprecated Use `removeStoreMember(storeId, memberId)` instead.
6919
7544
  */
6920
7545
  async removeTeamMember(memberId) {
6921
- await this.adminRequest("DELETE", `/api/v1/team/members/${memberId}`);
7546
+ await this.adminRequest("DELETE", `/api/v1/team/members/${encodePathSegment(memberId)}`);
6922
7547
  }
6923
7548
  // -------------------- Store Team Management (Admin) --------------------
6924
7549
  // Store-level team management. Each store has its own team with roles and permissions.
@@ -6932,7 +7557,10 @@ var BrainerceClient = class {
6932
7557
  * ```
6933
7558
  */
6934
7559
  async getStoreTeam(storeId) {
6935
- return this.adminRequest("GET", `/api/v1/stores/${storeId}/team`);
7560
+ return this.adminRequest(
7561
+ "GET",
7562
+ `/api/v1/stores/${encodePathSegment(storeId)}/team`
7563
+ );
6936
7564
  }
6937
7565
  /**
6938
7566
  * Invite a new member to a store
@@ -6943,13 +7571,16 @@ var BrainerceClient = class {
6943
7571
  * const invitation = await client.inviteStoreMember('store_id', {
6944
7572
  * email: 'newmember@example.com',
6945
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'],
6946
7577
  * });
6947
7578
  * ```
6948
7579
  */
6949
7580
  async inviteStoreMember(storeId, data) {
6950
7581
  return this.adminRequest(
6951
7582
  "POST",
6952
- `/api/v1/stores/${storeId}/team/invite`,
7583
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invite`,
6953
7584
  data
6954
7585
  );
6955
7586
  }
@@ -6971,7 +7602,33 @@ var BrainerceClient = class {
6971
7602
  async updateStoreMember(storeId, memberId, data) {
6972
7603
  return this.adminRequest(
6973
7604
  "PATCH",
6974
- `/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`,
6975
7632
  data
6976
7633
  );
6977
7634
  }
@@ -6980,7 +7637,10 @@ var BrainerceClient = class {
6980
7637
  * Requires Admin mode (apiKey) and MANAGE_TEAM permission
6981
7638
  */
6982
7639
  async removeStoreMember(storeId, memberId) {
6983
- 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
+ );
6984
7644
  }
6985
7645
  /**
6986
7646
  * Resend a store invitation email
@@ -6989,7 +7649,7 @@ var BrainerceClient = class {
6989
7649
  async resendStoreInvitation(storeId, invitationId) {
6990
7650
  return this.adminRequest(
6991
7651
  "POST",
6992
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}/resend`
7652
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}/resend`
6993
7653
  );
6994
7654
  }
6995
7655
  /**
@@ -6999,7 +7659,7 @@ var BrainerceClient = class {
6999
7659
  async revokeStoreInvitation(storeId, invitationId) {
7000
7660
  await this.adminRequest(
7001
7661
  "DELETE",
7002
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}`
7662
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}`
7003
7663
  );
7004
7664
  }
7005
7665
  /**
@@ -7007,14 +7667,20 @@ var BrainerceClient = class {
7007
7667
  * Used on the invitation acceptance page
7008
7668
  */
7009
7669
  async getStoreInvitationByToken(token) {
7010
- return this.request("GET", `/api/v1/store-invitations/${token}`);
7670
+ return this.request(
7671
+ "GET",
7672
+ `/api/v1/store-invitations/${encodePathSegment(token)}`
7673
+ );
7011
7674
  }
7012
7675
  /**
7013
7676
  * Accept a store invitation
7014
7677
  * Requires Admin mode (apiKey)
7015
7678
  */
7016
7679
  async acceptStoreInvitation(token) {
7017
- 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
+ );
7018
7684
  }
7019
7685
  /**
7020
7686
  * Get all stores accessible to the current user (owned + member of)
@@ -7047,7 +7713,7 @@ var BrainerceClient = class {
7047
7713
  async getMyStorePermissions(storeId) {
7048
7714
  return this.adminRequest(
7049
7715
  "GET",
7050
- `/api/v1/me/stores/${storeId}/permissions`
7716
+ `/api/v1/me/stores/${encodePathSegment(storeId)}/permissions`
7051
7717
  );
7052
7718
  }
7053
7719
  // -------------------- Email Settings & Templates (Admin) --------------------
@@ -7080,7 +7746,10 @@ var BrainerceClient = class {
7080
7746
  * Requires Admin mode (apiKey)
7081
7747
  */
7082
7748
  async getEmailTemplate(templateId) {
7083
- return this.adminRequest("GET", `/api/v1/email/templates/${templateId}`);
7749
+ return this.adminRequest(
7750
+ "GET",
7751
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7752
+ );
7084
7753
  }
7085
7754
  /**
7086
7755
  * Create a new email template
@@ -7104,14 +7773,21 @@ var BrainerceClient = class {
7104
7773
  * Requires Admin mode (apiKey)
7105
7774
  */
7106
7775
  async updateEmailTemplate(templateId, data) {
7107
- 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
+ );
7108
7781
  }
7109
7782
  /**
7110
7783
  * Delete an email template
7111
7784
  * Requires Admin mode (apiKey)
7112
7785
  */
7113
7786
  async deleteEmailTemplate(templateId) {
7114
- await this.adminRequest("DELETE", `/api/v1/email/templates/${templateId}`);
7787
+ await this.adminRequest(
7788
+ "DELETE",
7789
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7790
+ );
7115
7791
  }
7116
7792
  /**
7117
7793
  * Preview an email template with sample data
@@ -7120,7 +7796,7 @@ var BrainerceClient = class {
7120
7796
  async previewEmailTemplate(templateId, data) {
7121
7797
  return this.adminRequest(
7122
7798
  "POST",
7123
- `/api/v1/email/templates/${templateId}/preview`,
7799
+ `/api/v1/email/templates/${encodePathSegment(templateId)}/preview`,
7124
7800
  data || {}
7125
7801
  );
7126
7802
  }
@@ -7141,9 +7817,13 @@ var BrainerceClient = class {
7141
7817
  * @param resolution - 'MERGE' to link to existing product, 'CREATE_NEW' to create new product
7142
7818
  */
7143
7819
  async resolveSyncConflict(conflictId, resolution) {
7144
- return this.adminRequest("POST", `/api/v1/sync-conflicts/${conflictId}/resolve`, {
7145
- resolution
7146
- });
7820
+ return this.adminRequest(
7821
+ "POST",
7822
+ `/api/v1/sync-conflicts/${encodePathSegment(conflictId)}/resolve`,
7823
+ {
7824
+ resolution
7825
+ }
7826
+ );
7147
7827
  }
7148
7828
  // -------------------- Metafield Conflicts (Admin) --------------------
7149
7829
  // These methods require Admin mode (apiKey)
@@ -7164,7 +7844,7 @@ var BrainerceClient = class {
7164
7844
  async resolveMetafieldConflict(conflictId, data) {
7165
7845
  return this.adminRequest(
7166
7846
  "POST",
7167
- `/api/v1/metafield-conflicts/${conflictId}/resolve`,
7847
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/resolve`,
7168
7848
  data
7169
7849
  );
7170
7850
  }
@@ -7175,7 +7855,7 @@ var BrainerceClient = class {
7175
7855
  async ignoreMetafieldConflict(conflictId) {
7176
7856
  return this.adminRequest(
7177
7857
  "POST",
7178
- `/api/v1/metafield-conflicts/${conflictId}/ignore`
7858
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/ignore`
7179
7859
  );
7180
7860
  }
7181
7861
  // -------------------- OAuth Provider Configuration (Admin) --------------------
@@ -7192,7 +7872,10 @@ var BrainerceClient = class {
7192
7872
  * Requires Admin mode (apiKey)
7193
7873
  */
7194
7874
  async getOAuthProvider(provider) {
7195
- return this.adminRequest("GET", `/api/v1/oauth-providers/${provider}`);
7875
+ return this.adminRequest(
7876
+ "GET",
7877
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7878
+ );
7196
7879
  }
7197
7880
  /**
7198
7881
  * Configure an OAuth provider for customer login
@@ -7218,7 +7901,7 @@ var BrainerceClient = class {
7218
7901
  async updateOAuthProvider(provider, data) {
7219
7902
  return this.adminRequest(
7220
7903
  "PATCH",
7221
- `/api/v1/oauth-providers/${provider}`,
7904
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`,
7222
7905
  data
7223
7906
  );
7224
7907
  }
@@ -7227,7 +7910,10 @@ var BrainerceClient = class {
7227
7910
  * Requires Admin mode (apiKey)
7228
7911
  */
7229
7912
  async deleteOAuthProvider(provider) {
7230
- await this.adminRequest("DELETE", `/api/v1/oauth-providers/${provider}`);
7913
+ await this.adminRequest(
7914
+ "DELETE",
7915
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7916
+ );
7231
7917
  }
7232
7918
  };
7233
7919
  var BrainerceError = class extends Error {
@@ -7324,7 +8010,7 @@ var ALLOWED_PAYMENT_HOSTS = [
7324
8010
  // Brainerce-hosted payment embeds (backend payment-embed proxy at
7325
8011
  // `/api/payment/embed/...` that fronts provider apps' embed shells —
7326
8012
  // e.g. cardcom-payments OpenFields wrapper). The match also covers
7327
- // subdomains like `api.brainerce.com`, `staging.brainerce.com`.
8013
+ // every brainerce.com subdomain (api., docs., …).
7328
8014
  "brainerce.com"
7329
8015
  ];
7330
8016
  function isAllowedPaymentUrl(url, options) {
@@ -7443,7 +8129,9 @@ function getProductPriceInfo(product) {
7443
8129
  if (!product) {
7444
8130
  return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
7445
8131
  }
7446
- 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;
7447
8135
  if (product.discount) {
7448
8136
  const ruleOriginal = parseFloat(product.discount.originalPrice) || 0;
7449
8137
  const ruleDiscounted = parseFloat(product.discount.discountedPrice) || 0;