brainerce 1.27.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -126,6 +126,35 @@ function getDirectionForLocale(locale) {
126
126
  const primary = locale.split("-")[0].toLowerCase();
127
127
  return RTL_LOCALES.has(primary) ? "rtl" : "ltr";
128
128
  }
129
+ function encodePathSegment(value) {
130
+ let normalized = value;
131
+ try {
132
+ normalized = decodeURIComponent(value);
133
+ } catch {
134
+ normalized = value;
135
+ }
136
+ return encodeURIComponent(normalized);
137
+ }
138
+ var MAX_RETRY_AFTER_MS = 6e4;
139
+ function parseRetryAfterMs(response) {
140
+ const header = response.headers.get("retry-after");
141
+ if (!header) return null;
142
+ const trimmed = header.trim();
143
+ if (!trimmed) return null;
144
+ if (/^\d+$/.test(trimmed)) {
145
+ const seconds = parseInt(trimmed, 10);
146
+ if (!Number.isFinite(seconds) || seconds < 0) return null;
147
+ return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
148
+ }
149
+ const target = Date.parse(trimmed);
150
+ if (Number.isNaN(target)) return null;
151
+ const deltaMs = target - Date.now();
152
+ if (deltaMs <= 0) return 0;
153
+ return Math.min(deltaMs, MAX_RETRY_AFTER_MS);
154
+ }
155
+ function sleep(ms) {
156
+ return new Promise((resolve) => setTimeout(resolve, ms));
157
+ }
129
158
  var BrainerceClient = class {
130
159
  constructor(options) {
131
160
  this.customerToken = null;
@@ -341,7 +370,7 @@ var BrainerceClient = class {
341
370
  */
342
371
  getBySlug: async (slug, locale) => {
343
372
  const query = locale ? { locale } : void 0;
344
- const path = `/content/pages/by-slug/${encodeURIComponent(slug)}`;
373
+ const path = `/content/pages/by-slug/${encodePathSegment(slug)}`;
345
374
  const onNotFound = (err) => {
346
375
  if (err instanceof BrainerceError && err.statusCode === 404) return null;
347
376
  throw err;
@@ -559,7 +588,7 @@ var BrainerceClient = class {
559
588
  /**
560
589
  * Make a request to the Admin API (requires apiKey)
561
590
  */
562
- async adminRequest(method, path, body, queryParams) {
591
+ async adminRequest(method, path, body, queryParams, responseType = "json") {
563
592
  if (!this.apiKey) {
564
593
  throw new BrainerceError(
565
594
  "This operation requires an API key. Initialize with apiKey instead of storeId.",
@@ -574,52 +603,64 @@ var BrainerceClient = class {
574
603
  }
575
604
  });
576
605
  }
577
- const controller = new AbortController();
578
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
579
- try {
580
- const headers = {
581
- Authorization: `Bearer ${this.apiKey}`,
582
- "Content-Type": "application/json",
583
- "X-SDK-Version": SDK_VERSION,
584
- "ngrok-skip-browser-warning": "true"
585
- };
586
- if (this.origin) {
587
- headers["Origin"] = this.origin;
588
- }
589
- if (this.locale) {
590
- headers["Accept-Language"] = this.locale;
591
- }
592
- const response = await fetch(url.toString(), {
593
- method,
594
- headers,
595
- body: body ? JSON.stringify(body) : void 0,
596
- signal: controller.signal
597
- });
598
- clearTimeout(timeoutId);
599
- if (!response.ok) {
600
- const errorData = await response.json().catch(() => ({}));
601
- throw new BrainerceError(
602
- errorData.message || `Request failed with status ${response.status}`,
603
- response.status,
604
- errorData
605
- );
606
- }
607
- const text = await response.text();
608
- if (!text) return {};
609
- return JSON.parse(text);
610
- } catch (error) {
611
- clearTimeout(timeoutId);
612
- if (error instanceof BrainerceError) {
613
- throw error;
614
- }
615
- if (error instanceof Error) {
616
- if (error.name === "AbortError") {
617
- throw new BrainerceError("Request timeout", 408);
606
+ const headers = {
607
+ Authorization: `Bearer ${this.apiKey}`,
608
+ "Content-Type": "application/json",
609
+ "X-SDK-Version": SDK_VERSION,
610
+ "ngrok-skip-browser-warning": "true"
611
+ };
612
+ if (this.origin) {
613
+ headers["Origin"] = this.origin;
614
+ }
615
+ if (this.locale) {
616
+ headers["Accept-Language"] = this.locale;
617
+ }
618
+ for (let attempt = 0; attempt < 2; attempt++) {
619
+ const controller = new AbortController();
620
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
621
+ try {
622
+ const response = await fetch(url.toString(), {
623
+ method,
624
+ headers,
625
+ body: body ? JSON.stringify(body) : void 0,
626
+ signal: controller.signal
627
+ });
628
+ clearTimeout(timeoutId);
629
+ if (response.status === 429 && attempt === 0) {
630
+ const retryAfterMs = parseRetryAfterMs(response);
631
+ if (retryAfterMs !== null) {
632
+ await response.text().catch(() => void 0);
633
+ await sleep(retryAfterMs);
634
+ continue;
635
+ }
618
636
  }
619
- throw new BrainerceError(error.message, 0);
637
+ if (!response.ok) {
638
+ const errorData = await response.json().catch(() => ({}));
639
+ throw new BrainerceError(
640
+ errorData.message || `Request failed with status ${response.status}`,
641
+ response.status,
642
+ errorData
643
+ );
644
+ }
645
+ const text = await response.text();
646
+ if (responseType === "text") return text;
647
+ if (!text) return {};
648
+ return JSON.parse(text);
649
+ } catch (error) {
650
+ clearTimeout(timeoutId);
651
+ if (error instanceof BrainerceError) {
652
+ throw error;
653
+ }
654
+ if (error instanceof Error) {
655
+ if (error.name === "AbortError") {
656
+ throw new BrainerceError("Request timeout", 408);
657
+ }
658
+ throw new BrainerceError(error.message, 0);
659
+ }
660
+ throw new BrainerceError("Unknown error occurred", 0);
620
661
  }
621
- throw new BrainerceError("Unknown error occurred", 0);
622
662
  }
663
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
623
664
  }
624
665
  /**
625
666
  * Make a request to the Vibe-Coded API (public, uses connectionId)
@@ -628,7 +669,7 @@ var BrainerceClient = class {
628
669
  if (!this.connectionId) {
629
670
  throw new BrainerceError("connectionId is required for vibe-coded requests", 400);
630
671
  }
631
- const url = new URL(`${this.baseUrl}/api/vc/${this.connectionId}${path}`);
672
+ const url = new URL(`${this.baseUrl}/api/vc/${encodePathSegment(this.connectionId)}${path}`);
632
673
  if (queryParams) {
633
674
  Object.entries(queryParams).forEach(([key, value]) => {
634
675
  if (value !== void 0) {
@@ -636,70 +677,81 @@ var BrainerceClient = class {
636
677
  }
637
678
  });
638
679
  }
639
- const controller = new AbortController();
640
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
641
- try {
642
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
643
- const headers = {
644
- "X-SDK-Version": SDK_VERSION,
645
- "ngrok-skip-browser-warning": "true"
646
- };
647
- if (!isFormData) {
648
- headers["Content-Type"] = "application/json";
649
- }
650
- if (this.origin) {
651
- headers["Origin"] = this.origin;
652
- }
653
- if (this.locale) {
654
- headers["Accept-Language"] = this.locale;
655
- }
656
- if (headerOverrides) {
657
- Object.assign(headers, headerOverrides);
658
- }
659
- if (this.proxyMode && method !== "GET") {
660
- headers["X-Requested-With"] = "brainerce";
661
- }
662
- if (this.customerToken) {
663
- headers["Authorization"] = `Bearer ${this.customerToken}`;
664
- }
665
- const response = await fetch(url.toString(), {
666
- method,
667
- headers,
668
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
669
- signal: controller.signal
670
- });
671
- clearTimeout(timeoutId);
672
- if (!response.ok) {
673
- const errorData = await response.json().catch(() => ({}));
674
- if (response.status === 401 && this.onAuthError) {
675
- this.onAuthError({
676
- message: errorData.message || "Unauthorized",
677
- statusCode: 401,
678
- path
679
- });
680
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
681
+ const headers = {
682
+ "X-SDK-Version": SDK_VERSION,
683
+ "ngrok-skip-browser-warning": "true"
684
+ };
685
+ if (!isFormData) {
686
+ headers["Content-Type"] = "application/json";
687
+ }
688
+ if (this.origin) {
689
+ headers["Origin"] = this.origin;
690
+ }
691
+ if (this.locale) {
692
+ headers["Accept-Language"] = this.locale;
693
+ }
694
+ if (headerOverrides) {
695
+ Object.assign(headers, headerOverrides);
696
+ }
697
+ if (this.proxyMode && method !== "GET") {
698
+ headers["X-Requested-With"] = "brainerce";
699
+ }
700
+ if (this.customerToken) {
701
+ headers["Authorization"] = `Bearer ${this.customerToken}`;
702
+ }
703
+ for (let attempt = 0; attempt < 2; attempt++) {
704
+ const controller = new AbortController();
705
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
706
+ try {
707
+ const response = await fetch(url.toString(), {
708
+ method,
709
+ headers,
710
+ body: body ? isFormData ? body : JSON.stringify(body) : void 0,
711
+ signal: controller.signal
712
+ });
713
+ clearTimeout(timeoutId);
714
+ if (response.status === 429 && attempt === 0) {
715
+ const retryAfterMs = parseRetryAfterMs(response);
716
+ if (retryAfterMs !== null) {
717
+ await response.text().catch(() => void 0);
718
+ await sleep(retryAfterMs);
719
+ continue;
720
+ }
680
721
  }
681
- throw new BrainerceError(
682
- errorData.message || `Request failed with status ${response.status}`,
683
- response.status,
684
- errorData
685
- );
686
- }
687
- const text = await response.text();
688
- if (!text) return {};
689
- return JSON.parse(text);
690
- } catch (error) {
691
- clearTimeout(timeoutId);
692
- if (error instanceof BrainerceError) {
693
- throw error;
694
- }
695
- if (error instanceof Error) {
696
- if (error.name === "AbortError") {
697
- throw new BrainerceError("Request timeout", 408);
722
+ if (!response.ok) {
723
+ const errorData = await response.json().catch(() => ({}));
724
+ if (response.status === 401 && this.onAuthError) {
725
+ this.onAuthError({
726
+ message: errorData.message || "Unauthorized",
727
+ statusCode: 401,
728
+ path
729
+ });
730
+ }
731
+ throw new BrainerceError(
732
+ errorData.message || `Request failed with status ${response.status}`,
733
+ response.status,
734
+ errorData
735
+ );
698
736
  }
699
- throw new BrainerceError(error.message, 0);
737
+ const text = await response.text();
738
+ if (!text) return {};
739
+ return JSON.parse(text);
740
+ } catch (error) {
741
+ clearTimeout(timeoutId);
742
+ if (error instanceof BrainerceError) {
743
+ throw error;
744
+ }
745
+ if (error instanceof Error) {
746
+ if (error.name === "AbortError") {
747
+ throw new BrainerceError("Request timeout", 408);
748
+ }
749
+ throw new BrainerceError(error.message, 0);
750
+ }
751
+ throw new BrainerceError("Unknown error occurred", 0);
700
752
  }
701
- throw new BrainerceError("Unknown error occurred", 0);
702
753
  }
754
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
703
755
  }
704
756
  /**
705
757
  * Make a request to the Storefront API (public, uses storeId)
@@ -708,7 +760,7 @@ var BrainerceClient = class {
708
760
  if (!this.storeId) {
709
761
  throw new BrainerceError("storeId is required for storefront requests", 400);
710
762
  }
711
- const url = new URL(`${this.baseUrl}/stores/${this.storeId}${path}`);
763
+ const url = new URL(`${this.baseUrl}/stores/${encodePathSegment(this.storeId)}${path}`);
712
764
  if (queryParams) {
713
765
  Object.entries(queryParams).forEach(([key, value]) => {
714
766
  if (value !== void 0) {
@@ -716,67 +768,78 @@ var BrainerceClient = class {
716
768
  }
717
769
  });
718
770
  }
719
- const controller = new AbortController();
720
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
721
- try {
722
- const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
723
- const headers = {
724
- "X-SDK-Version": SDK_VERSION,
725
- "ngrok-skip-browser-warning": "true"
726
- };
727
- if (!isFormData) {
728
- headers["Content-Type"] = "application/json";
729
- }
730
- if (this.origin) {
731
- headers["Origin"] = this.origin;
732
- }
733
- if (this.locale) {
734
- headers["Accept-Language"] = this.locale;
735
- }
736
- if (headerOverrides) {
737
- Object.assign(headers, headerOverrides);
738
- }
739
- if (this.customerToken) {
740
- headers["Authorization"] = `Bearer ${this.customerToken}`;
741
- }
742
- const response = await fetch(url.toString(), {
743
- method,
744
- headers,
745
- body: body ? isFormData ? body : JSON.stringify(body) : void 0,
746
- signal: controller.signal
747
- });
748
- clearTimeout(timeoutId);
749
- if (!response.ok) {
750
- const errorData = await response.json().catch(() => ({}));
751
- if (response.status === 401 && this.onAuthError) {
752
- this.onAuthError({
753
- message: errorData.message || "Unauthorized",
754
- statusCode: 401,
755
- path
756
- });
771
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
772
+ const headers = {
773
+ "X-SDK-Version": SDK_VERSION,
774
+ "ngrok-skip-browser-warning": "true"
775
+ };
776
+ if (!isFormData) {
777
+ headers["Content-Type"] = "application/json";
778
+ }
779
+ if (this.origin) {
780
+ headers["Origin"] = this.origin;
781
+ }
782
+ if (this.locale) {
783
+ headers["Accept-Language"] = this.locale;
784
+ }
785
+ if (headerOverrides) {
786
+ Object.assign(headers, headerOverrides);
787
+ }
788
+ if (this.customerToken) {
789
+ headers["Authorization"] = `Bearer ${this.customerToken}`;
790
+ }
791
+ for (let attempt = 0; attempt < 2; attempt++) {
792
+ const controller = new AbortController();
793
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
794
+ try {
795
+ const response = await fetch(url.toString(), {
796
+ method,
797
+ headers,
798
+ body: body ? isFormData ? body : JSON.stringify(body) : void 0,
799
+ signal: controller.signal
800
+ });
801
+ clearTimeout(timeoutId);
802
+ if (response.status === 429 && attempt === 0) {
803
+ const retryAfterMs = parseRetryAfterMs(response);
804
+ if (retryAfterMs !== null) {
805
+ await response.text().catch(() => void 0);
806
+ await sleep(retryAfterMs);
807
+ continue;
808
+ }
757
809
  }
758
- throw new BrainerceError(
759
- errorData.message || `Request failed with status ${response.status}`,
760
- response.status,
761
- errorData
762
- );
763
- }
764
- const text = await response.text();
765
- if (!text) return {};
766
- return JSON.parse(text);
767
- } catch (error) {
768
- clearTimeout(timeoutId);
769
- if (error instanceof BrainerceError) {
770
- throw error;
771
- }
772
- if (error instanceof Error) {
773
- if (error.name === "AbortError") {
774
- throw new BrainerceError("Request timeout", 408);
810
+ if (!response.ok) {
811
+ const errorData = await response.json().catch(() => ({}));
812
+ if (response.status === 401 && this.onAuthError) {
813
+ this.onAuthError({
814
+ message: errorData.message || "Unauthorized",
815
+ statusCode: 401,
816
+ path
817
+ });
818
+ }
819
+ throw new BrainerceError(
820
+ errorData.message || `Request failed with status ${response.status}`,
821
+ response.status,
822
+ errorData
823
+ );
775
824
  }
776
- throw new BrainerceError(error.message, 0);
825
+ const text = await response.text();
826
+ if (!text) return {};
827
+ return JSON.parse(text);
828
+ } catch (error) {
829
+ clearTimeout(timeoutId);
830
+ if (error instanceof BrainerceError) {
831
+ throw error;
832
+ }
833
+ if (error instanceof Error) {
834
+ if (error.name === "AbortError") {
835
+ throw new BrainerceError("Request timeout", 408);
836
+ }
837
+ throw new BrainerceError(error.message, 0);
838
+ }
839
+ throw new BrainerceError("Unknown error occurred", 0);
777
840
  }
778
- throw new BrainerceError("Unknown error occurred", 0);
779
841
  }
842
+ throw new BrainerceError("Rate limited (max retries exceeded)", 429);
780
843
  }
781
844
  /**
782
845
  * Smart request - uses storefront or admin API based on client mode
@@ -866,6 +929,7 @@ var BrainerceClient = class {
866
929
  // Admin-only params
867
930
  type: params?.type
868
931
  };
932
+ const queryParamsWithRegion = params?.regionId ? { ...queryParams, regionId: params.regionId } : queryParams;
869
933
  if (this.isVibeCodedMode()) {
870
934
  return this.vibeCodedRequest(
871
935
  "GET",
@@ -879,14 +943,14 @@ var BrainerceClient = class {
879
943
  "GET",
880
944
  "/products",
881
945
  void 0,
882
- queryParams
946
+ queryParamsWithRegion
883
947
  );
884
948
  }
885
949
  return this.adminRequest(
886
950
  "GET",
887
951
  "/api/v1/products",
888
952
  void 0,
889
- queryParams
953
+ queryParamsWithRegion
890
954
  );
891
955
  }
892
956
  /**
@@ -895,10 +959,11 @@ var BrainerceClient = class {
895
959
  */
896
960
  async getProduct(productId, options) {
897
961
  const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
962
+ const queryParams = options?.regionId ? { regionId: options.regionId } : void 0;
898
963
  if (this.isVibeCodedMode()) {
899
964
  return this.vibeCodedRequest(
900
965
  "GET",
901
- `/products/${productId}`,
966
+ `/products/${encodePathSegment(productId)}`,
902
967
  void 0,
903
968
  void 0,
904
969
  headerOverrides
@@ -907,13 +972,18 @@ var BrainerceClient = class {
907
972
  if (this.storeId && !this.apiKey) {
908
973
  return this.storefrontRequest(
909
974
  "GET",
910
- `/products/${productId}`,
911
- void 0,
975
+ `/products/${encodePathSegment(productId)}`,
912
976
  void 0,
977
+ queryParams,
913
978
  headerOverrides
914
979
  );
915
980
  }
916
- return this.adminRequest("GET", `/api/v1/products/${productId}`);
981
+ return this.adminRequest(
982
+ "GET",
983
+ `/api/v1/products/${encodePathSegment(productId)}`,
984
+ void 0,
985
+ queryParams
986
+ );
917
987
  }
918
988
  /**
919
989
  * Get a single product by slug
@@ -927,7 +997,7 @@ var BrainerceClient = class {
927
997
  */
928
998
  async getProductBySlug(slug, options) {
929
999
  const headerOverrides = options?.locale ? { "Accept-Language": options.locale } : void 0;
930
- const encodedSlug = encodeURIComponent(slug);
1000
+ const encodedSlug = encodePathSegment(slug);
931
1001
  if (this.isVibeCodedMode()) {
932
1002
  return this.vibeCodedRequest(
933
1003
  "GET",
@@ -1031,7 +1101,7 @@ var BrainerceClient = class {
1031
1101
  */
1032
1102
  async getProductAlternates(productId) {
1033
1103
  if (this.storeId && !this.apiKey) {
1034
- return this.storefrontRequest("GET", `/products/${productId}/alternates`);
1104
+ return this.storefrontRequest("GET", `/products/${encodePathSegment(productId)}/alternates`);
1035
1105
  }
1036
1106
  throw new BrainerceError("getProductAlternates is only available in storefront mode", 400);
1037
1107
  }
@@ -1073,7 +1143,7 @@ var BrainerceClient = class {
1073
1143
  * Update an existing product
1074
1144
  */
1075
1145
  async updateProduct(productId, data) {
1076
- return this.request("PATCH", `/api/v1/products/${productId}`, data);
1146
+ return this.request("PATCH", `/api/v1/products/${encodePathSegment(productId)}`, data);
1077
1147
  }
1078
1148
  /**
1079
1149
  * Delete a product
@@ -1101,7 +1171,7 @@ var BrainerceClient = class {
1101
1171
  const queryParams = options?.platforms?.length ? { platforms: options.platforms.join(",") } : void 0;
1102
1172
  return this.request(
1103
1173
  "DELETE",
1104
- `/api/v1/products/${productId}`,
1174
+ `/api/v1/products/${encodePathSegment(productId)}`,
1105
1175
  void 0,
1106
1176
  queryParams
1107
1177
  );
@@ -1116,7 +1186,10 @@ var BrainerceClient = class {
1116
1186
  * ```
1117
1187
  */
1118
1188
  async convertToVariable(productId) {
1119
- return this.request("PATCH", `/api/v1/products/${productId}/convert-to-variable`);
1189
+ return this.request(
1190
+ "PATCH",
1191
+ `/api/v1/products/${encodePathSegment(productId)}/convert-to-variable`
1192
+ );
1120
1193
  }
1121
1194
  /**
1122
1195
  * Convert a VARIABLE product to SIMPLE product
@@ -1129,7 +1202,10 @@ var BrainerceClient = class {
1129
1202
  * ```
1130
1203
  */
1131
1204
  async convertToSimple(productId) {
1132
- return this.request("PATCH", `/api/v1/products/${productId}/convert-to-simple`);
1205
+ return this.request(
1206
+ "PATCH",
1207
+ `/api/v1/products/${encodePathSegment(productId)}/convert-to-simple`
1208
+ );
1133
1209
  }
1134
1210
  /**
1135
1211
  * Publish a product to specific platforms
@@ -1141,9 +1217,13 @@ var BrainerceClient = class {
1141
1217
  * ```
1142
1218
  */
1143
1219
  async publishProduct(productId, platforms) {
1144
- return this.request("POST", `/api/v1/products/${productId}/publish`, {
1145
- platforms
1146
- });
1220
+ return this.request(
1221
+ "POST",
1222
+ `/api/v1/products/${encodePathSegment(productId)}/publish`,
1223
+ {
1224
+ platforms
1225
+ }
1226
+ );
1147
1227
  }
1148
1228
  // -------------------- Variants --------------------
1149
1229
  /**
@@ -1161,7 +1241,11 @@ var BrainerceClient = class {
1161
1241
  * ```
1162
1242
  */
1163
1243
  async createVariant(productId, data) {
1164
- return this.request("POST", `/api/v1/products/${productId}/variants`, data);
1244
+ return this.request(
1245
+ "POST",
1246
+ `/api/v1/products/${encodePathSegment(productId)}/variants`,
1247
+ data
1248
+ );
1165
1249
  }
1166
1250
  /**
1167
1251
  * Bulk save variants (create, update, delete in one operation)
@@ -1181,7 +1265,7 @@ var BrainerceClient = class {
1181
1265
  async bulkSaveVariants(productId, data) {
1182
1266
  return this.request(
1183
1267
  "POST",
1184
- `/api/v1/products/${productId}/variants/bulk`,
1268
+ `/api/v1/products/${encodePathSegment(productId)}/variants/bulk`,
1185
1269
  data
1186
1270
  );
1187
1271
  }
@@ -1199,7 +1283,7 @@ var BrainerceClient = class {
1199
1283
  async updateVariant(productId, variantId, data) {
1200
1284
  return this.request(
1201
1285
  "PATCH",
1202
- `/api/v1/products/${productId}/variants/${variantId}`,
1286
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`,
1203
1287
  data
1204
1288
  );
1205
1289
  }
@@ -1212,7 +1296,10 @@ var BrainerceClient = class {
1212
1296
  * ```
1213
1297
  */
1214
1298
  async deleteVariant(productId, variantId) {
1215
- await this.request("DELETE", `/api/v1/products/${productId}/variants/${variantId}`);
1299
+ await this.request(
1300
+ "DELETE",
1301
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}`
1302
+ );
1216
1303
  }
1217
1304
  /**
1218
1305
  * Get inventory for a specific variant
@@ -1226,7 +1313,7 @@ var BrainerceClient = class {
1226
1313
  async getVariantInventory(productId, variantId) {
1227
1314
  return this.request(
1228
1315
  "GET",
1229
- `/api/v1/products/${productId}/variants/${variantId}/inventory`
1316
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`
1230
1317
  );
1231
1318
  }
1232
1319
  /**
@@ -1243,7 +1330,7 @@ var BrainerceClient = class {
1243
1330
  async updateVariantInventory(productId, variantId, data) {
1244
1331
  return this.request(
1245
1332
  "PATCH",
1246
- `/api/v1/products/${productId}/variants/${variantId}/inventory`,
1333
+ `/api/v1/products/${encodePathSegment(productId)}/variants/${encodePathSegment(variantId)}/inventory`,
1247
1334
  data
1248
1335
  );
1249
1336
  }
@@ -1267,7 +1354,10 @@ var BrainerceClient = class {
1267
1354
  * Get a single order by ID
1268
1355
  */
1269
1356
  async getOrder(orderId) {
1270
- return this.withGuards(this.request("GET", `/api/v1/orders/${orderId}`), "order");
1357
+ return this.withGuards(
1358
+ this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}`),
1359
+ "order"
1360
+ );
1271
1361
  }
1272
1362
  /**
1273
1363
  * Create a new order
@@ -1280,7 +1370,7 @@ var BrainerceClient = class {
1280
1370
  * Update an order (e.g., change status)
1281
1371
  */
1282
1372
  async updateOrder(orderId, data) {
1283
- return this.request("PATCH", `/api/v1/orders/${orderId}`, data);
1373
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}`, data);
1284
1374
  }
1285
1375
  /**
1286
1376
  * Update order status
@@ -1291,7 +1381,9 @@ var BrainerceClient = class {
1291
1381
  * ```
1292
1382
  */
1293
1383
  async updateOrderStatus(orderId, status) {
1294
- return this.request("PATCH", `/api/v1/orders/${orderId}/status`, { status });
1384
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/status`, {
1385
+ status
1386
+ });
1295
1387
  }
1296
1388
  /**
1297
1389
  * Update order payment method
@@ -1303,9 +1395,13 @@ var BrainerceClient = class {
1303
1395
  * ```
1304
1396
  */
1305
1397
  async updatePaymentMethod(orderId, paymentMethod) {
1306
- return this.request("PATCH", `/api/v1/orders/${orderId}/payment-method`, {
1307
- paymentMethod
1308
- });
1398
+ return this.request(
1399
+ "PATCH",
1400
+ `/api/v1/orders/${encodePathSegment(orderId)}/payment-method`,
1401
+ {
1402
+ paymentMethod
1403
+ }
1404
+ );
1309
1405
  }
1310
1406
  /**
1311
1407
  * Update order notes
@@ -1316,7 +1412,9 @@ var BrainerceClient = class {
1316
1412
  * ```
1317
1413
  */
1318
1414
  async updateOrderNotes(orderId, notes) {
1319
- return this.request("PATCH", `/api/v1/orders/${orderId}/notes`, { notes });
1415
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/notes`, {
1416
+ notes
1417
+ });
1320
1418
  }
1321
1419
  /**
1322
1420
  * Get refunds for an order
@@ -1329,7 +1427,7 @@ var BrainerceClient = class {
1329
1427
  * ```
1330
1428
  */
1331
1429
  async getOrderRefunds(orderId) {
1332
- return this.request("GET", `/api/v1/orders/${orderId}/refunds`);
1430
+ return this.request("GET", `/api/v1/orders/${encodePathSegment(orderId)}/refunds`);
1333
1431
  }
1334
1432
  /**
1335
1433
  * Create a refund for an order
@@ -1356,7 +1454,11 @@ var BrainerceClient = class {
1356
1454
  * ```
1357
1455
  */
1358
1456
  async createRefund(orderId, data) {
1359
- return this.request("POST", `/api/v1/orders/${orderId}/refunds`, data);
1457
+ return this.request(
1458
+ "POST",
1459
+ `/api/v1/orders/${encodePathSegment(orderId)}/refunds`,
1460
+ data
1461
+ );
1360
1462
  }
1361
1463
  /**
1362
1464
  * Update order shipping address
@@ -1376,7 +1478,11 @@ var BrainerceClient = class {
1376
1478
  * ```
1377
1479
  */
1378
1480
  async updateOrderShipping(orderId, data) {
1379
- return this.request("PATCH", `/api/v1/orders/${orderId}/shipping`, data);
1481
+ return this.request(
1482
+ "PATCH",
1483
+ `/api/v1/orders/${encodePathSegment(orderId)}/shipping`,
1484
+ data
1485
+ );
1380
1486
  }
1381
1487
  /**
1382
1488
  * Cancel an order
@@ -1389,7 +1495,7 @@ var BrainerceClient = class {
1389
1495
  * ```
1390
1496
  */
1391
1497
  async cancelOrder(orderId) {
1392
- return this.request("POST", `/api/v1/orders/${orderId}/cancel`);
1498
+ return this.request("POST", `/api/v1/orders/${encodePathSegment(orderId)}/cancel`);
1393
1499
  }
1394
1500
  /**
1395
1501
  * Fulfill an order (mark as shipped)
@@ -1405,7 +1511,11 @@ var BrainerceClient = class {
1405
1511
  * ```
1406
1512
  */
1407
1513
  async fulfillOrder(orderId, data) {
1408
- return this.request("POST", `/api/v1/orders/${orderId}/fulfill`, data || {});
1514
+ return this.request(
1515
+ "POST",
1516
+ `/api/v1/orders/${encodePathSegment(orderId)}/fulfill`,
1517
+ data || {}
1518
+ );
1409
1519
  }
1410
1520
  /**
1411
1521
  * Sync draft orders from connected platforms
@@ -1430,7 +1540,11 @@ var BrainerceClient = class {
1430
1540
  * ```
1431
1541
  */
1432
1542
  async completeDraftOrder(orderId, data) {
1433
- return this.request("POST", `/api/v1/orders/${orderId}/complete-draft`, data || {});
1543
+ return this.request(
1544
+ "POST",
1545
+ `/api/v1/orders/${encodePathSegment(orderId)}/complete-draft`,
1546
+ data || {}
1547
+ );
1434
1548
  }
1435
1549
  /**
1436
1550
  * Send invoice for a draft order
@@ -1447,7 +1561,7 @@ var BrainerceClient = class {
1447
1561
  async sendDraftInvoice(orderId, data) {
1448
1562
  return this.request(
1449
1563
  "POST",
1450
- `/api/v1/orders/${orderId}/send-invoice`,
1564
+ `/api/v1/orders/${encodePathSegment(orderId)}/send-invoice`,
1451
1565
  data || {}
1452
1566
  );
1453
1567
  }
@@ -1460,7 +1574,7 @@ var BrainerceClient = class {
1460
1574
  * ```
1461
1575
  */
1462
1576
  async deleteDraftOrder(orderId) {
1463
- await this.request("DELETE", `/api/v1/orders/${orderId}/draft`);
1577
+ await this.request("DELETE", `/api/v1/orders/${encodePathSegment(orderId)}/draft`);
1464
1578
  }
1465
1579
  /**
1466
1580
  * Update a draft order
@@ -1483,7 +1597,7 @@ var BrainerceClient = class {
1483
1597
  * ```
1484
1598
  */
1485
1599
  async updateDraftOrder(orderId, data) {
1486
- return this.request("PATCH", `/api/v1/orders/${orderId}/draft`, data);
1600
+ return this.request("PATCH", `/api/v1/orders/${encodePathSegment(orderId)}/draft`, data);
1487
1601
  }
1488
1602
  // -------------------- Inventory --------------------
1489
1603
  /**
@@ -1491,13 +1605,17 @@ var BrainerceClient = class {
1491
1605
  * This will sync inventory to all connected platforms
1492
1606
  */
1493
1607
  async updateInventory(productId, data) {
1494
- await this.request("PUT", `/api/v1/products/${productId}/inventory`, data);
1608
+ await this.request(
1609
+ "PUT",
1610
+ `/api/v1/products/${encodePathSegment(productId)}/inventory`,
1611
+ data
1612
+ );
1495
1613
  }
1496
1614
  /**
1497
1615
  * Get current inventory for a product
1498
1616
  */
1499
1617
  async getInventory(productId) {
1500
- return this.request("GET", `/api/v1/inventory/${productId}`);
1618
+ return this.request("GET", `/api/v1/inventory/${encodePathSegment(productId)}`);
1501
1619
  }
1502
1620
  /**
1503
1621
  * Edit inventory manually with reason for audit trail
@@ -1658,7 +1776,7 @@ var BrainerceClient = class {
1658
1776
  * Get the status of a sync job
1659
1777
  */
1660
1778
  async getSyncStatus(jobId) {
1661
- return this.request("GET", `/api/v1/sync/${jobId}`);
1779
+ return this.request("GET", `/api/v1/sync/${encodePathSegment(jobId)}`);
1662
1780
  }
1663
1781
  // -------------------- Coupons --------------------
1664
1782
  /**
@@ -1680,7 +1798,7 @@ var BrainerceClient = class {
1680
1798
  * Get a single coupon by ID
1681
1799
  */
1682
1800
  async getCoupon(couponId) {
1683
- return this.request("GET", `/api/v1/coupons/${couponId}`);
1801
+ return this.request("GET", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1684
1802
  }
1685
1803
  /**
1686
1804
  * Create a new coupon.
@@ -1710,20 +1828,20 @@ var BrainerceClient = class {
1710
1828
  * Update an existing coupon
1711
1829
  */
1712
1830
  async updateCoupon(couponId, data) {
1713
- return this.request("PATCH", `/api/v1/coupons/${couponId}`, data);
1831
+ return this.request("PATCH", `/api/v1/coupons/${encodePathSegment(couponId)}`, data);
1714
1832
  }
1715
1833
  /**
1716
1834
  * Delete a coupon
1717
1835
  */
1718
1836
  async deleteCoupon(couponId) {
1719
- await this.request("DELETE", `/api/v1/coupons/${couponId}`);
1837
+ await this.request("DELETE", `/api/v1/coupons/${encodePathSegment(couponId)}`);
1720
1838
  }
1721
1839
  /**
1722
1840
  * Sync a coupon to all connected platforms.
1723
1841
  * Returns a sync job that can be tracked with getSyncStatus().
1724
1842
  */
1725
1843
  async syncCoupon(couponId) {
1726
- return this.request("POST", `/api/v1/coupons/${couponId}/sync`);
1844
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/sync`);
1727
1845
  }
1728
1846
  /**
1729
1847
  * Publish a coupon to specific platforms.
@@ -1736,7 +1854,9 @@ var BrainerceClient = class {
1736
1854
  * ```
1737
1855
  */
1738
1856
  async publishCoupon(couponId, platforms) {
1739
- return this.request("POST", `/api/v1/coupons/${couponId}/publish`, { platforms });
1857
+ return this.request("POST", `/api/v1/coupons/${encodePathSegment(couponId)}/publish`, {
1858
+ platforms
1859
+ });
1740
1860
  }
1741
1861
  /**
1742
1862
  * Get platform capabilities for coupon features.
@@ -1777,13 +1897,17 @@ var BrainerceClient = class {
1777
1897
  * Get a customer by ID
1778
1898
  */
1779
1899
  async getCustomer(customerId) {
1780
- return this.request("GET", `/api/v1/customers/${customerId}`);
1900
+ return this.request("GET", `/api/v1/customers/${encodePathSegment(customerId)}`);
1781
1901
  }
1782
1902
  /**
1783
1903
  * Update a customer
1784
1904
  */
1785
1905
  async updateCustomer(customerId, data) {
1786
- return this.request("PATCH", `/api/v1/customers/${customerId}`, data);
1906
+ return this.request(
1907
+ "PATCH",
1908
+ `/api/v1/customers/${encodePathSegment(customerId)}`,
1909
+ data
1910
+ );
1787
1911
  }
1788
1912
  /**
1789
1913
  * Get a customer by email
@@ -1791,56 +1915,84 @@ var BrainerceClient = class {
1791
1915
  async getCustomerByEmail(email) {
1792
1916
  return this.request("GET", "/api/v1/customers/by-email", void 0, { email });
1793
1917
  }
1794
- /**
1795
- * List a customer's saved payment methods (vaulted cards).
1796
- *
1797
- * Returns display-only metadata — last4, brand, expiry, default flag,
1798
- * status. The underlying provider token is encrypted at rest and
1799
- * NEVER returned through this API.
1800
- *
1801
- * Apps mode requires `customers:read` and `payments:read` scopes.
1802
- *
1803
- * @param storeId - The store this customer belongs to
1804
- * @param customerId - The customer's ID
1805
- * @returns Array of saved payment methods
1806
- *
1807
- * @example
1808
- * ```typescript
1809
- * const methods = await client.listSavedPaymentMethods(storeId, customerId);
1810
- * methods.forEach((m) => {
1811
- * console.log(`${m.brand} ending in ${m.last4} (expires ${m.expMonth}/${m.expYear})`);
1812
- * });
1813
- * ```
1814
- */
1815
- async listSavedPaymentMethods(storeId, customerId) {
1918
+ async listSavedPaymentMethods(customerIdOrStoreId, maybeCustomerId) {
1919
+ const customerId = this.resolveSavedPaymentMethodsArgs(
1920
+ "listSavedPaymentMethods",
1921
+ customerIdOrStoreId,
1922
+ maybeCustomerId
1923
+ );
1816
1924
  return this.request(
1817
1925
  "GET",
1818
- `/api/stores/${storeId}/customers/${customerId}/payment-methods`
1926
+ `/api/stores/${this.storeId}/customers/${encodePathSegment(customerId)}/payment-methods`
1927
+ );
1928
+ }
1929
+ async removeSavedPaymentMethod(customerIdOrStoreId, paymentMethodIdOrCustomerId, maybePaymentMethodId) {
1930
+ const { customerId, paymentMethodId } = this.resolveRemovePaymentMethodArgs(
1931
+ customerIdOrStoreId,
1932
+ paymentMethodIdOrCustomerId,
1933
+ maybePaymentMethodId
1934
+ );
1935
+ return this.request(
1936
+ "DELETE",
1937
+ `/api/stores/${this.storeId}/customers/${encodePathSegment(customerId)}/payment-methods/${encodePathSegment(paymentMethodId)}`
1819
1938
  );
1820
1939
  }
1821
1940
  /**
1822
- * Remove a customer's saved payment method.
1823
- *
1824
- * Hard-deletes the row. The provider may still hold the underlying
1825
- * token internally — we don't issue a delete-at-provider call because
1826
- * not every provider supports it. From the platform's perspective the
1827
- * token is gone; subsequent charges will fail.
1828
- *
1829
- * Apps mode requires `customers:write` scope.
1830
- *
1831
- * @param storeId - The store this customer belongs to
1832
- * @param customerId - The customer's ID
1833
- * @param paymentMethodId - The saved payment method ID to remove
1941
+ * Internal helper: normalize legacy `(storeId, customerId)` callers to the
1942
+ * new `(customerId)` signature for `listSavedPaymentMethods`.
1834
1943
  *
1835
- * @example
1836
- * ```typescript
1837
- * await client.removeSavedPaymentMethod(storeId, customerId, methodId);
1838
- * ```
1944
+ * Throws if the SDK instance has no `storeId` (these endpoints are
1945
+ * storefront-scoped) and warns when the deprecated overload is detected.
1839
1946
  */
1840
- async removeSavedPaymentMethod(storeId, customerId, paymentMethodId) {
1841
- return this.request(
1842
- "DELETE",
1843
- `/api/stores/${storeId}/customers/${customerId}/payment-methods/${paymentMethodId}`
1947
+ resolveSavedPaymentMethodsArgs(methodName, customerIdOrStoreId, maybeCustomerId) {
1948
+ if (!this.storeId) {
1949
+ throw new BrainerceError(
1950
+ `${methodName}: this method requires a storeId on the SDK instance. Pass \`storeId\` when constructing \`new BrainerceClient({ storeId })\`.`,
1951
+ 400
1952
+ );
1953
+ }
1954
+ if (maybeCustomerId !== void 0) {
1955
+ this.warnDeprecatedStoreIdArg(methodName, customerIdOrStoreId);
1956
+ return maybeCustomerId;
1957
+ }
1958
+ return customerIdOrStoreId;
1959
+ }
1960
+ /**
1961
+ * Internal helper: normalize legacy `(storeId, customerId, paymentMethodId)`
1962
+ * callers to the new `(customerId, paymentMethodId)` signature.
1963
+ */
1964
+ resolveRemovePaymentMethodArgs(customerIdOrStoreId, paymentMethodIdOrCustomerId, maybePaymentMethodId) {
1965
+ if (!this.storeId) {
1966
+ throw new BrainerceError(
1967
+ "removeSavedPaymentMethod: this method requires a storeId on the SDK instance. Pass `storeId` when constructing `new BrainerceClient({ storeId })`.",
1968
+ 400
1969
+ );
1970
+ }
1971
+ if (maybePaymentMethodId !== void 0) {
1972
+ this.warnDeprecatedStoreIdArg("removeSavedPaymentMethod", customerIdOrStoreId);
1973
+ return {
1974
+ customerId: paymentMethodIdOrCustomerId,
1975
+ paymentMethodId: maybePaymentMethodId
1976
+ };
1977
+ }
1978
+ return {
1979
+ customerId: customerIdOrStoreId,
1980
+ paymentMethodId: paymentMethodIdOrCustomerId
1981
+ };
1982
+ }
1983
+ /**
1984
+ * One-shot deprecation warning per (method, mismatch?) — verifies the
1985
+ * caller-supplied storeId matches the SDK config and warns regardless.
1986
+ */
1987
+ warnDeprecatedStoreIdArg(methodName, suppliedStoreId) {
1988
+ if (suppliedStoreId !== this.storeId) {
1989
+ throw new BrainerceError(
1990
+ `${methodName}: supplied storeId "${suppliedStoreId}" does not match the SDK instance storeId "${this.storeId}". Construct a new client per store.`,
1991
+ 400
1992
+ );
1993
+ }
1994
+ console.warn(
1995
+ `BrainerceClient.${methodName}: passing \`storeId\` is deprecated \u2014 it is now derived from the SDK config. Remove the leading argument; this overload will be removed in SDK 2.0.`
1844
1996
  );
1845
1997
  }
1846
1998
  /**
@@ -1899,12 +2051,33 @@ var BrainerceClient = class {
1899
2051
  * Request a password reset email for a customer
1900
2052
  * Works in vibe-coded, storefront, and admin mode
1901
2053
  *
2054
+ * The `resetUrl` MUST be supplied explicitly in non-browser (SSR / Node)
2055
+ * contexts — auto-deriving it from `window.location.origin` is impossible
2056
+ * there and historically resulted in `undefined` being sent to the backend,
2057
+ * which then bounced the email to a broken link. In browser contexts the
2058
+ * origin is still used as a fallback but the SDK logs a one-time warning
2059
+ * recommending an explicit value so server-rendered + proxied dashboards
2060
+ * don't silently rely on the wrong host.
2061
+ *
1902
2062
  * @param email - Customer email address
1903
2063
  * @param options - Optional settings
1904
- * @param options.resetUrl - Override the auto-detected reset URL (e.g. for BFF proxy callback)
2064
+ * @param options.resetUrl - Reset URL the email links should point to.
2065
+ * Required outside the browser; recommended inside it.
1905
2066
  */
1906
2067
  async forgotPassword(email, options) {
1907
- const resetUrl = options?.resetUrl ?? (typeof window !== "undefined" ? `${window.location.origin}/reset-password` : void 0);
2068
+ let resetUrl = options?.resetUrl;
2069
+ if (!resetUrl) {
2070
+ if (typeof window === "undefined") {
2071
+ throw new BrainerceError(
2072
+ 'forgotPassword: `resetUrl` is required outside the browser. Pass `{ resetUrl: "https://your-site.example/reset-password" }` so the email links to the right host.',
2073
+ 400
2074
+ );
2075
+ }
2076
+ console.warn(
2077
+ "BrainerceClient.forgotPassword: deriving `resetUrl` from `window.location.origin` \u2014 pass `{ resetUrl }` explicitly to avoid wrong-host links behind proxies or in SSR."
2078
+ );
2079
+ resetUrl = `${window.location.origin}/reset-password`;
2080
+ }
1908
2081
  if (this.isVibeCodedMode()) {
1909
2082
  return this.vibeCodedRequest("POST", "/customers/forgot-password", {
1910
2083
  email,
@@ -2087,12 +2260,14 @@ var BrainerceClient = class {
2087
2260
  * // Redirect user to Google
2088
2261
  * window.location.href = authorizationUrl;
2089
2262
  *
2090
- * // On /auth/callback page — the backend handles code exchange and redirects with params:
2263
+ * // On /auth/callback page — exchange the one-time auth_code for the JWT.
2264
+ * // (The backend used to put the JWT directly in the redirect URL; that path
2265
+ * // is deprecated because URL params leak into browser history and logs.)
2091
2266
  * const params = new URLSearchParams(window.location.search);
2092
- * if (params.get('oauth_success') === 'true') {
2093
- * const token = params.get('token');
2094
- * client.setCustomerToken(token);
2095
- * // Also available: customer_id, customer_email, is_new
2267
+ * if (params.get('oauth_success') === 'true' && params.get('auth_code')) {
2268
+ * const result = await client.exchangeOAuthCode(params.get('auth_code')!);
2269
+ * client.setCustomerToken(result.token);
2270
+ * // result.customer, result.isNewCustomer, result.redirectUrl, ...
2096
2271
  * } else if (params.get('oauth_error')) {
2097
2272
  * // Show error
2098
2273
  * }
@@ -2110,7 +2285,7 @@ var BrainerceClient = class {
2110
2285
  params.set("redirectUrl", options.redirectUrl);
2111
2286
  }
2112
2287
  const queryString = params.toString();
2113
- const endpoint = `/oauth/${provider}/authorize${queryString ? `?${queryString}` : ""}`;
2288
+ const endpoint = `/oauth/${encodePathSegment(provider)}/authorize${queryString ? `?${queryString}` : ""}`;
2114
2289
  if (this.isVibeCodedMode()) {
2115
2290
  return this.vibeCodedRequest("GET", endpoint);
2116
2291
  }
@@ -2119,6 +2294,83 @@ var BrainerceClient = class {
2119
2294
  }
2120
2295
  throw new BrainerceError("getOAuthAuthorizeUrl requires vibe-coded or storefront mode", 400);
2121
2296
  }
2297
+ /**
2298
+ * Exchange a one-time `auth_code` (returned in the post-OAuth redirect URL)
2299
+ * for the customer JWT. Use this on the `/auth/callback` storefront page
2300
+ * after reading `auth_code` from `window.location.search`.
2301
+ *
2302
+ * The code is single-use and expires 2 minutes after the OAuth callback
2303
+ * issued it. A second call with the same code returns 400.
2304
+ *
2305
+ * This replaces the legacy flow where the JWT was placed directly in the
2306
+ * redirect URL (`?token=...`). The legacy URL params still ship behind a
2307
+ * server feature flag during the migration window, but they will be
2308
+ * removed in the next major release — migrate now.
2309
+ *
2310
+ * @param authCode - The single-use code from the `?auth_code=` URL param.
2311
+ *
2312
+ * @example
2313
+ * ```typescript
2314
+ * const params = new URLSearchParams(window.location.search);
2315
+ * const code = params.get('auth_code');
2316
+ * if (code) {
2317
+ * const { token, customer, isNewCustomer, redirectUrl } =
2318
+ * await client.exchangeOAuthCode(code);
2319
+ * client.setCustomerToken(token);
2320
+ * }
2321
+ * ```
2322
+ */
2323
+ async exchangeOAuthCode(authCode) {
2324
+ if (!authCode) {
2325
+ throw new BrainerceError("authCode is required", 400);
2326
+ }
2327
+ const url = `${this.baseUrl}/api/oauth/customer/exchange`;
2328
+ const controller = new AbortController();
2329
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2330
+ try {
2331
+ const headers = {
2332
+ "Content-Type": "application/json",
2333
+ "X-SDK-Version": SDK_VERSION,
2334
+ "ngrok-skip-browser-warning": "true"
2335
+ };
2336
+ if (this.origin) {
2337
+ headers["Origin"] = this.origin;
2338
+ }
2339
+ if (this.locale) {
2340
+ headers["Accept-Language"] = this.locale;
2341
+ }
2342
+ const response = await fetch(url, {
2343
+ method: "POST",
2344
+ headers,
2345
+ body: JSON.stringify({ code: authCode }),
2346
+ signal: controller.signal
2347
+ });
2348
+ clearTimeout(timeoutId);
2349
+ if (!response.ok) {
2350
+ const errorData = await response.json().catch(() => ({}));
2351
+ throw new BrainerceError(
2352
+ errorData.message || `Request failed with status ${response.status}`,
2353
+ response.status,
2354
+ errorData
2355
+ );
2356
+ }
2357
+ const text = await response.text();
2358
+ if (!text) return {};
2359
+ return JSON.parse(text);
2360
+ } catch (error) {
2361
+ clearTimeout(timeoutId);
2362
+ if (error instanceof BrainerceError) {
2363
+ throw error;
2364
+ }
2365
+ if (error instanceof Error) {
2366
+ if (error.name === "AbortError") {
2367
+ throw new BrainerceError("Request timeout", 408);
2368
+ }
2369
+ throw new BrainerceError(error.message, 0);
2370
+ }
2371
+ throw new BrainerceError("Unknown error occurred", 0);
2372
+ }
2373
+ }
2122
2374
  /**
2123
2375
  * Handle OAuth callback - exchange code for customer token (server-to-server)
2124
2376
  *
@@ -2139,7 +2391,7 @@ var BrainerceClient = class {
2139
2391
  throw new BrainerceError("provider is required (e.g., 'GOOGLE', 'FACEBOOK', 'GITHUB')", 400);
2140
2392
  }
2141
2393
  const params = new URLSearchParams({ code, state });
2142
- const endpoint = `/oauth/${provider}/callback?${params.toString()}`;
2394
+ const endpoint = `/oauth/${encodePathSegment(provider)}/callback?${params.toString()}`;
2143
2395
  if (this.isVibeCodedMode()) {
2144
2396
  return this.vibeCodedRequest("GET", endpoint);
2145
2397
  }
@@ -2183,7 +2435,7 @@ var BrainerceClient = class {
2183
2435
  params.set("redirectUrl", options.redirectUrl);
2184
2436
  }
2185
2437
  const queryString = params.toString();
2186
- const endpoint = `/oauth/${provider}/link${queryString ? `?${queryString}` : ""}`;
2438
+ const endpoint = `/oauth/${encodePathSegment(provider)}/link${queryString ? `?${queryString}` : ""}`;
2187
2439
  if (this.isVibeCodedMode()) {
2188
2440
  return this.vibeCodedRequest("POST", endpoint);
2189
2441
  }
@@ -2212,10 +2464,16 @@ var BrainerceClient = class {
2212
2464
  throw new BrainerceError("Customer token is required. Call setCustomerToken() first.", 401);
2213
2465
  }
2214
2466
  if (this.isVibeCodedMode()) {
2215
- return this.vibeCodedRequest("DELETE", `/oauth/${provider}/link`);
2467
+ return this.vibeCodedRequest(
2468
+ "DELETE",
2469
+ `/oauth/${encodePathSegment(provider)}/link`
2470
+ );
2216
2471
  }
2217
2472
  if (this.isStorefrontMode()) {
2218
- return this.storefrontRequest("DELETE", `/oauth/${provider}/link`);
2473
+ return this.storefrontRequest(
2474
+ "DELETE",
2475
+ `/oauth/${encodePathSegment(provider)}/link`
2476
+ );
2219
2477
  }
2220
2478
  throw new BrainerceError("unlinkOAuthProvider requires vibe-coded or storefront mode", 400);
2221
2479
  }
@@ -2282,7 +2540,10 @@ var BrainerceClient = class {
2282
2540
  * Get all addresses for a customer
2283
2541
  */
2284
2542
  async getCustomerAddresses(customerId) {
2285
- return this.request("GET", `/api/v1/customers/${customerId}/addresses`);
2543
+ return this.request(
2544
+ "GET",
2545
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`
2546
+ );
2286
2547
  }
2287
2548
  /**
2288
2549
  * Add an address to a customer
@@ -2304,7 +2565,7 @@ var BrainerceClient = class {
2304
2565
  async addCustomerAddress(customerId, address) {
2305
2566
  return this.request(
2306
2567
  "POST",
2307
- `/api/v1/customers/${customerId}/addresses`,
2568
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses`,
2308
2569
  address
2309
2570
  );
2310
2571
  }
@@ -2314,7 +2575,7 @@ var BrainerceClient = class {
2314
2575
  async updateCustomerAddress(customerId, addressId, address) {
2315
2576
  return this.request(
2316
2577
  "PATCH",
2317
- `/api/v1/customers/${customerId}/addresses/${addressId}`,
2578
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`,
2318
2579
  address
2319
2580
  );
2320
2581
  }
@@ -2322,7 +2583,10 @@ var BrainerceClient = class {
2322
2583
  * Delete a customer address
2323
2584
  */
2324
2585
  async deleteCustomerAddress(customerId, addressId) {
2325
- await this.request("DELETE", `/api/v1/customers/${customerId}/addresses/${addressId}`);
2586
+ await this.request(
2587
+ "DELETE",
2588
+ `/api/v1/customers/${encodePathSegment(customerId)}/addresses/${encodePathSegment(addressId)}`
2589
+ );
2326
2590
  }
2327
2591
  /**
2328
2592
  * Get orders for a customer
@@ -2336,7 +2600,7 @@ var BrainerceClient = class {
2336
2600
  async getCustomerOrders(customerId, params) {
2337
2601
  return this.request(
2338
2602
  "GET",
2339
- `/api/v1/customers/${customerId}/orders`,
2603
+ `/api/v1/customers/${encodePathSegment(customerId)}/orders`,
2340
2604
  void 0,
2341
2605
  { page: params?.page, limit: params?.limit }
2342
2606
  );
@@ -2408,12 +2672,18 @@ var BrainerceClient = class {
2408
2672
  */
2409
2673
  async getCartBySession(sessionToken) {
2410
2674
  if (this.isVibeCodedMode()) {
2411
- return this.vibeCodedRequest("GET", `/cart/session/${sessionToken}`);
2675
+ return this.vibeCodedRequest("GET", `/cart/session/${encodePathSegment(sessionToken)}`);
2412
2676
  }
2413
2677
  if (this.storeId && !this.apiKey) {
2414
- return this.storefrontRequest("GET", `/cart/session/${sessionToken}`);
2678
+ return this.storefrontRequest(
2679
+ "GET",
2680
+ `/cart/session/${encodePathSegment(sessionToken)}`
2681
+ );
2415
2682
  }
2416
- return this.adminRequest("GET", `/api/v1/cart/session/${sessionToken}`);
2683
+ return this.adminRequest(
2684
+ "GET",
2685
+ `/api/v1/cart/session/${encodePathSegment(sessionToken)}`
2686
+ );
2417
2687
  }
2418
2688
  /**
2419
2689
  * Get a cart by customer ID (for authenticated users)
@@ -2426,9 +2696,9 @@ var BrainerceClient = class {
2426
2696
  */
2427
2697
  async getCartByCustomer(customerId) {
2428
2698
  if (this.storeId && !this.apiKey) {
2429
- return this.storefrontRequest("GET", `/cart/customer/${customerId}`);
2699
+ return this.storefrontRequest("GET", `/cart/customer/${encodePathSegment(customerId)}`);
2430
2700
  }
2431
- return this.adminRequest("GET", `/api/v1/cart/customer/${customerId}`);
2701
+ return this.adminRequest("GET", `/api/v1/cart/customer/${encodePathSegment(customerId)}`);
2432
2702
  }
2433
2703
  /**
2434
2704
  * Get a cart by ID
@@ -2458,18 +2728,33 @@ var BrainerceClient = class {
2458
2728
  const queryParams = options?.include?.length ? { include: options.include.join(",") } : void 0;
2459
2729
  if (this.isVibeCodedMode()) {
2460
2730
  return this.withGuards(
2461
- this.vibeCodedRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2731
+ this.vibeCodedRequest(
2732
+ "GET",
2733
+ `/cart/${encodePathSegment(cartId)}`,
2734
+ void 0,
2735
+ queryParams
2736
+ ),
2462
2737
  "cart"
2463
2738
  );
2464
2739
  }
2465
2740
  if (this.storeId && !this.apiKey) {
2466
2741
  return this.withGuards(
2467
- this.storefrontRequest("GET", `/cart/${cartId}`, void 0, queryParams),
2742
+ this.storefrontRequest(
2743
+ "GET",
2744
+ `/cart/${encodePathSegment(cartId)}`,
2745
+ void 0,
2746
+ queryParams
2747
+ ),
2468
2748
  "cart"
2469
2749
  );
2470
2750
  }
2471
2751
  return this.withGuards(
2472
- this.adminRequest("GET", `/api/v1/cart/${cartId}`, void 0, queryParams),
2752
+ this.adminRequest(
2753
+ "GET",
2754
+ `/api/v1/cart/${encodePathSegment(cartId)}`,
2755
+ void 0,
2756
+ queryParams
2757
+ ),
2473
2758
  "cart"
2474
2759
  );
2475
2760
  }
@@ -2525,18 +2810,18 @@ var BrainerceClient = class {
2525
2810
  }
2526
2811
  if (this.isVibeCodedMode()) {
2527
2812
  return this.withGuards(
2528
- this.vibeCodedRequest("POST", `/cart/${cartId}/items`, item),
2813
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2529
2814
  "cart"
2530
2815
  );
2531
2816
  }
2532
2817
  if (this.storeId && !this.apiKey) {
2533
2818
  return this.withGuards(
2534
- this.storefrontRequest("POST", `/cart/${cartId}/items`, item),
2819
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/items`, item),
2535
2820
  "cart"
2536
2821
  );
2537
2822
  }
2538
2823
  return this.withGuards(
2539
- this.adminRequest("POST", `/api/v1/cart/${cartId}/items`, item),
2824
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/items`, item),
2540
2825
  "cart"
2541
2826
  );
2542
2827
  }
@@ -2563,18 +2848,30 @@ var BrainerceClient = class {
2563
2848
  }
2564
2849
  if (this.isVibeCodedMode()) {
2565
2850
  return this.withGuards(
2566
- this.vibeCodedRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2851
+ this.vibeCodedRequest(
2852
+ "PATCH",
2853
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2854
+ data
2855
+ ),
2567
2856
  "cart"
2568
2857
  );
2569
2858
  }
2570
2859
  if (this.storeId && !this.apiKey) {
2571
2860
  return this.withGuards(
2572
- this.storefrontRequest("PATCH", `/cart/${cartId}/items/${itemId}`, data),
2861
+ this.storefrontRequest(
2862
+ "PATCH",
2863
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2864
+ data
2865
+ ),
2573
2866
  "cart"
2574
2867
  );
2575
2868
  }
2576
2869
  return this.withGuards(
2577
- this.adminRequest("PATCH", `/api/v1/cart/${cartId}/items/${itemId}`, data),
2870
+ this.adminRequest(
2871
+ "PATCH",
2872
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`,
2873
+ data
2874
+ ),
2578
2875
  "cart"
2579
2876
  );
2580
2877
  }
@@ -2601,18 +2898,27 @@ var BrainerceClient = class {
2601
2898
  }
2602
2899
  if (this.isVibeCodedMode()) {
2603
2900
  return this.withGuards(
2604
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2901
+ this.vibeCodedRequest(
2902
+ "DELETE",
2903
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2904
+ ),
2605
2905
  "cart"
2606
2906
  );
2607
2907
  }
2608
2908
  if (this.storeId && !this.apiKey) {
2609
2909
  return this.withGuards(
2610
- this.storefrontRequest("DELETE", `/cart/${cartId}/items/${itemId}`),
2910
+ this.storefrontRequest(
2911
+ "DELETE",
2912
+ `/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2913
+ ),
2611
2914
  "cart"
2612
2915
  );
2613
2916
  }
2614
2917
  return this.withGuards(
2615
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items/${itemId}`),
2918
+ this.adminRequest(
2919
+ "DELETE",
2920
+ `/api/v1/cart/${encodePathSegment(cartId)}/items/${encodePathSegment(itemId)}`
2921
+ ),
2616
2922
  "cart"
2617
2923
  );
2618
2924
  }
@@ -2633,13 +2939,16 @@ var BrainerceClient = class {
2633
2939
  return this.withGuards(this.localCartToCart(this.getLocalCart()), "cart");
2634
2940
  }
2635
2941
  if (this.isVibeCodedMode()) {
2636
- return this.withGuards(this.vibeCodedRequest("DELETE", `/cart/${cartId}`), "cart");
2942
+ return this.withGuards(
2943
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}`),
2944
+ "cart"
2945
+ );
2637
2946
  }
2638
2947
  if (this.storeId && !this.apiKey) {
2639
- await this.storefrontRequest("DELETE", `/cart/${cartId}/items`);
2948
+ await this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/items`);
2640
2949
  return this.withGuards({}, "cart");
2641
2950
  }
2642
- await this.adminRequest("DELETE", `/api/v1/cart/${cartId}/items`);
2951
+ await this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/items`);
2643
2952
  return this.withGuards({}, "cart");
2644
2953
  }
2645
2954
  /**
@@ -2654,18 +2963,18 @@ var BrainerceClient = class {
2654
2963
  async applyCoupon(cartId, code) {
2655
2964
  if (this.isVibeCodedMode()) {
2656
2965
  return this.withGuards(
2657
- this.vibeCodedRequest("POST", `/cart/${cartId}/coupon`, { code }),
2966
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2658
2967
  "cart"
2659
2968
  );
2660
2969
  }
2661
2970
  if (this.storeId && !this.apiKey) {
2662
2971
  return this.withGuards(
2663
- this.storefrontRequest("POST", `/cart/${cartId}/coupon`, { code }),
2972
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2664
2973
  "cart"
2665
2974
  );
2666
2975
  }
2667
2976
  return this.withGuards(
2668
- this.adminRequest("POST", `/api/v1/cart/${cartId}/coupon`, { code }),
2977
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`, { code }),
2669
2978
  "cart"
2670
2979
  );
2671
2980
  }
@@ -2680,18 +2989,18 @@ var BrainerceClient = class {
2680
2989
  async removeCoupon(cartId) {
2681
2990
  if (this.isVibeCodedMode()) {
2682
2991
  return this.withGuards(
2683
- this.vibeCodedRequest("DELETE", `/cart/${cartId}/coupon`),
2992
+ this.vibeCodedRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2684
2993
  "cart"
2685
2994
  );
2686
2995
  }
2687
2996
  if (this.storeId && !this.apiKey) {
2688
2997
  return this.withGuards(
2689
- this.storefrontRequest("DELETE", `/cart/${cartId}/coupon`),
2998
+ this.storefrontRequest("DELETE", `/cart/${encodePathSegment(cartId)}/coupon`),
2690
2999
  "cart"
2691
3000
  );
2692
3001
  }
2693
3002
  return this.withGuards(
2694
- this.adminRequest("DELETE", `/api/v1/cart/${cartId}/coupon`),
3003
+ this.adminRequest("DELETE", `/api/v1/cart/${encodePathSegment(cartId)}/coupon`),
2695
3004
  "cart"
2696
3005
  );
2697
3006
  }
@@ -2716,18 +3025,18 @@ var BrainerceClient = class {
2716
3025
  }
2717
3026
  if (this.isVibeCodedMode()) {
2718
3027
  return this.withGuards(
2719
- this.vibeCodedRequest("POST", `/cart/${cartId}/recalculate`),
3028
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2720
3029
  "cart"
2721
3030
  );
2722
3031
  }
2723
3032
  if (this.storeId && !this.apiKey) {
2724
3033
  return this.withGuards(
2725
- this.storefrontRequest("POST", `/cart/${cartId}/recalculate`),
3034
+ this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/recalculate`),
2726
3035
  "cart"
2727
3036
  );
2728
3037
  }
2729
3038
  return this.withGuards(
2730
- this.adminRequest("POST", `/api/v1/cart/${cartId}/recalculate`),
3039
+ this.adminRequest("POST", `/api/v1/cart/${encodePathSegment(cartId)}/recalculate`),
2731
3040
  "cart"
2732
3041
  );
2733
3042
  }
@@ -2756,18 +3065,24 @@ var BrainerceClient = class {
2756
3065
  }
2757
3066
  if (this.isVibeCodedMode()) {
2758
3067
  return this.withGuards(
2759
- this.vibeCodedRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3068
+ this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/refresh-snapshots`),
2760
3069
  "cart"
2761
3070
  );
2762
3071
  }
2763
3072
  if (this.storeId && !this.apiKey) {
2764
3073
  return this.withGuards(
2765
- this.storefrontRequest("POST", `/cart/${cartId}/refresh-snapshots`),
3074
+ this.storefrontRequest(
3075
+ "POST",
3076
+ `/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3077
+ ),
2766
3078
  "cart"
2767
3079
  );
2768
3080
  }
2769
3081
  return this.withGuards(
2770
- this.adminRequest("POST", `/api/v1/cart/${cartId}/refresh-snapshots`),
3082
+ this.adminRequest(
3083
+ "POST",
3084
+ `/api/v1/cart/${encodePathSegment(cartId)}/refresh-snapshots`
3085
+ ),
2771
3086
  "cart"
2772
3087
  );
2773
3088
  }
@@ -2796,10 +3111,10 @@ var BrainerceClient = class {
2796
3111
  );
2797
3112
  }
2798
3113
  if (this.isVibeCodedMode()) {
2799
- return this.vibeCodedRequest("POST", `/cart/${cartId}/link`);
3114
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2800
3115
  }
2801
3116
  if (this.storeId && !this.apiKey) {
2802
- return this.storefrontRequest("POST", `/cart/${cartId}/link`);
3117
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/link`);
2803
3118
  }
2804
3119
  throw new BrainerceError("linkCart is only available in vibe-coded or storefront mode", 400);
2805
3120
  }
@@ -2862,13 +3177,13 @@ var BrainerceClient = class {
2862
3177
  if (this.isVibeCodedMode()) {
2863
3178
  return this.vibeCodedRequest(
2864
3179
  "GET",
2865
- `/products/${productId}/discount-badge`
3180
+ `/products/${encodePathSegment(productId)}/discount-badge`
2866
3181
  );
2867
3182
  }
2868
3183
  if (this.storeId && !this.apiKey) {
2869
3184
  return this.storefrontRequest(
2870
3185
  "GET",
2871
- `/products/${productId}/discount-badge`
3186
+ `/products/${encodePathSegment(productId)}/discount-badge`
2872
3187
  );
2873
3188
  }
2874
3189
  throw new BrainerceError(
@@ -2892,10 +3207,13 @@ var BrainerceClient = class {
2892
3207
  */
2893
3208
  async getCartNudges(cartId) {
2894
3209
  if (this.isVibeCodedMode()) {
2895
- return this.vibeCodedRequest("GET", `/cart/${cartId}/nudges`);
3210
+ return this.vibeCodedRequest("GET", `/cart/${encodePathSegment(cartId)}/nudges`);
2896
3211
  }
2897
3212
  if (this.storeId && !this.apiKey) {
2898
- return this.storefrontRequest("GET", `/cart/${cartId}/nudges`);
3213
+ return this.storefrontRequest(
3214
+ "GET",
3215
+ `/cart/${encodePathSegment(cartId)}/nudges`
3216
+ );
2899
3217
  }
2900
3218
  throw new BrainerceError("getCartNudges() requires vibe-coded or storefront mode", 400);
2901
3219
  }
@@ -2920,7 +3238,7 @@ var BrainerceClient = class {
2920
3238
  if (this.isVibeCodedMode()) {
2921
3239
  return this.vibeCodedRequest(
2922
3240
  "GET",
2923
- `/products/${productId}/recommendations`,
3241
+ `/products/${encodePathSegment(productId)}/recommendations`,
2924
3242
  void 0,
2925
3243
  queryParams
2926
3244
  );
@@ -2928,7 +3246,7 @@ var BrainerceClient = class {
2928
3246
  if (this.storeId && !this.apiKey) {
2929
3247
  return this.storefrontRequest(
2930
3248
  "GET",
2931
- `/products/${productId}/recommendations`,
3249
+ `/products/${encodePathSegment(productId)}/recommendations`,
2932
3250
  void 0,
2933
3251
  queryParams
2934
3252
  );
@@ -2958,7 +3276,7 @@ var BrainerceClient = class {
2958
3276
  if (this.isVibeCodedMode()) {
2959
3277
  return this.vibeCodedRequest(
2960
3278
  "GET",
2961
- `/products/${productId}/reviews`,
3279
+ `/products/${encodePathSegment(productId)}/reviews`,
2962
3280
  void 0,
2963
3281
  queryParams
2964
3282
  );
@@ -2966,7 +3284,7 @@ var BrainerceClient = class {
2966
3284
  if (this.storeId && !this.apiKey) {
2967
3285
  return this.storefrontRequest(
2968
3286
  "GET",
2969
- `/products/${productId}/reviews`,
3287
+ `/products/${encodePathSegment(productId)}/reviews`,
2970
3288
  void 0,
2971
3289
  queryParams
2972
3290
  );
@@ -2990,10 +3308,16 @@ var BrainerceClient = class {
2990
3308
  */
2991
3309
  async getMyProductReview(productId) {
2992
3310
  if (this.isVibeCodedMode()) {
2993
- return this.vibeCodedRequest("GET", `/products/${productId}/reviews/me`);
3311
+ return this.vibeCodedRequest(
3312
+ "GET",
3313
+ `/products/${encodePathSegment(productId)}/reviews/me`
3314
+ );
2994
3315
  }
2995
3316
  if (this.storeId && !this.apiKey) {
2996
- return this.storefrontRequest("GET", `/products/${productId}/reviews/me`);
3317
+ return this.storefrontRequest(
3318
+ "GET",
3319
+ `/products/${encodePathSegment(productId)}/reviews/me`
3320
+ );
2997
3321
  }
2998
3322
  throw new BrainerceError("getMyProductReview() requires vibe-coded or storefront mode", 400);
2999
3323
  }
@@ -3017,10 +3341,18 @@ var BrainerceClient = class {
3017
3341
  */
3018
3342
  async submitProductReview(productId, input) {
3019
3343
  if (this.isVibeCodedMode()) {
3020
- return this.vibeCodedRequest("POST", `/products/${productId}/reviews`, input);
3344
+ return this.vibeCodedRequest(
3345
+ "POST",
3346
+ `/products/${encodePathSegment(productId)}/reviews`,
3347
+ input
3348
+ );
3021
3349
  }
3022
3350
  if (this.storeId && !this.apiKey) {
3023
- return this.storefrontRequest("POST", `/products/${productId}/reviews`, input);
3351
+ return this.storefrontRequest(
3352
+ "POST",
3353
+ `/products/${encodePathSegment(productId)}/reviews`,
3354
+ input
3355
+ );
3024
3356
  }
3025
3357
  throw new BrainerceError("submitProductReview() requires vibe-coded or storefront mode", 400);
3026
3358
  }
@@ -3033,14 +3365,14 @@ var BrainerceClient = class {
3033
3365
  if (this.isVibeCodedMode()) {
3034
3366
  return this.vibeCodedRequest(
3035
3367
  "PATCH",
3036
- `/products/${productId}/reviews/me`,
3368
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3037
3369
  input
3038
3370
  );
3039
3371
  }
3040
3372
  if (this.storeId && !this.apiKey) {
3041
3373
  return this.storefrontRequest(
3042
3374
  "PATCH",
3043
- `/products/${productId}/reviews/me`,
3375
+ `/products/${encodePathSegment(productId)}/reviews/me`,
3044
3376
  input
3045
3377
  );
3046
3378
  }
@@ -3052,11 +3384,17 @@ var BrainerceClient = class {
3052
3384
  */
3053
3385
  async deleteMyProductReview(productId) {
3054
3386
  if (this.isVibeCodedMode()) {
3055
- await this.vibeCodedRequest("DELETE", `/products/${productId}/reviews/me`);
3387
+ await this.vibeCodedRequest(
3388
+ "DELETE",
3389
+ `/products/${encodePathSegment(productId)}/reviews/me`
3390
+ );
3056
3391
  return;
3057
3392
  }
3058
3393
  if (this.storeId && !this.apiKey) {
3059
- await this.storefrontRequest("DELETE", `/products/${productId}/reviews/me`);
3394
+ await this.storefrontRequest(
3395
+ "DELETE",
3396
+ `/products/${encodePathSegment(productId)}/reviews/me`
3397
+ );
3060
3398
  return;
3061
3399
  }
3062
3400
  throw new BrainerceError("deleteMyProductReview() requires vibe-coded or storefront mode", 400);
@@ -3075,7 +3413,7 @@ var BrainerceClient = class {
3075
3413
  if (params?.visibility) queryParams.visibility = params.visibility;
3076
3414
  return this.adminRequest(
3077
3415
  "GET",
3078
- `/api/v1/products/${productId}/reviews`,
3416
+ `/api/v1/products/${encodePathSegment(productId)}/reviews`,
3079
3417
  void 0,
3080
3418
  queryParams
3081
3419
  );
@@ -3087,7 +3425,7 @@ var BrainerceClient = class {
3087
3425
  }
3088
3426
  return this.adminRequest(
3089
3427
  "PATCH",
3090
- `/api/v1/reviews/${reviewId}/hide`,
3428
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/hide`,
3091
3429
  void 0,
3092
3430
  storeId ? { storeId } : void 0
3093
3431
  );
@@ -3099,7 +3437,7 @@ var BrainerceClient = class {
3099
3437
  }
3100
3438
  return this.adminRequest(
3101
3439
  "PATCH",
3102
- `/api/v1/reviews/${reviewId}/show`,
3440
+ `/api/v1/reviews/${encodePathSegment(reviewId)}/show`,
3103
3441
  void 0,
3104
3442
  storeId ? { storeId } : void 0
3105
3443
  );
@@ -3124,7 +3462,7 @@ var BrainerceClient = class {
3124
3462
  if (this.isVibeCodedMode()) {
3125
3463
  return this.vibeCodedRequest(
3126
3464
  "GET",
3127
- `/cart/${cartId}/recommendations`,
3465
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3128
3466
  void 0,
3129
3467
  queryParams
3130
3468
  );
@@ -3132,7 +3470,7 @@ var BrainerceClient = class {
3132
3470
  if (this.storeId && !this.apiKey) {
3133
3471
  return this.storefrontRequest(
3134
3472
  "GET",
3135
- `/cart/${cartId}/recommendations`,
3473
+ `/cart/${encodePathSegment(cartId)}/recommendations`,
3136
3474
  void 0,
3137
3475
  queryParams
3138
3476
  );
@@ -3159,10 +3497,16 @@ var BrainerceClient = class {
3159
3497
  */
3160
3498
  async getCartUpgrades(cartId) {
3161
3499
  if (this.isVibeCodedMode()) {
3162
- return this.vibeCodedRequest("GET", `/cart/${cartId}/upgrades`);
3500
+ return this.vibeCodedRequest(
3501
+ "GET",
3502
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3503
+ );
3163
3504
  }
3164
3505
  if (this.storeId && !this.apiKey) {
3165
- return this.storefrontRequest("GET", `/cart/${cartId}/upgrades`);
3506
+ return this.storefrontRequest(
3507
+ "GET",
3508
+ `/cart/${encodePathSegment(cartId)}/upgrades`
3509
+ );
3166
3510
  }
3167
3511
  throw new BrainerceError("getCartUpgrades() requires vibe-coded or storefront mode", 400);
3168
3512
  }
@@ -3184,10 +3528,16 @@ var BrainerceClient = class {
3184
3528
  */
3185
3529
  async getCartBundles(cartId) {
3186
3530
  if (this.isVibeCodedMode()) {
3187
- return this.vibeCodedRequest("GET", `/cart/${cartId}/bundles`);
3531
+ return this.vibeCodedRequest(
3532
+ "GET",
3533
+ `/cart/${encodePathSegment(cartId)}/bundles`
3534
+ );
3188
3535
  }
3189
3536
  if (this.storeId && !this.apiKey) {
3190
- return this.storefrontRequest("GET", `/cart/${cartId}/bundles`);
3537
+ return this.storefrontRequest(
3538
+ "GET",
3539
+ `/cart/${encodePathSegment(cartId)}/bundles`
3540
+ );
3191
3541
  }
3192
3542
  throw new BrainerceError("getCartBundles() requires vibe-coded or storefront mode", 400);
3193
3543
  }
@@ -3199,10 +3549,16 @@ var BrainerceClient = class {
3199
3549
  */
3200
3550
  async getCheckoutBumps(checkoutId) {
3201
3551
  if (this.isVibeCodedMode()) {
3202
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/bumps`);
3552
+ return this.vibeCodedRequest(
3553
+ "GET",
3554
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3555
+ );
3203
3556
  }
3204
3557
  if (this.storeId && !this.apiKey) {
3205
- return this.storefrontRequest("GET", `/checkout/${checkoutId}/bumps`);
3558
+ return this.storefrontRequest(
3559
+ "GET",
3560
+ `/checkout/${encodePathSegment(checkoutId)}/bumps`
3561
+ );
3206
3562
  }
3207
3563
  throw new BrainerceError("getCheckoutBumps() requires vibe-coded or storefront mode", 400);
3208
3564
  }
@@ -3217,10 +3573,10 @@ var BrainerceClient = class {
3217
3573
  async addOrderBump(cartId, bumpConfigId, variantId) {
3218
3574
  const body = { bumpConfigId, ...variantId && { variantId } };
3219
3575
  if (this.isVibeCodedMode()) {
3220
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bump`, body);
3576
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3221
3577
  }
3222
3578
  if (this.storeId && !this.apiKey) {
3223
- return this.storefrontRequest("POST", `/cart/${cartId}/bump`, body);
3579
+ return this.storefrontRequest("POST", `/cart/${encodePathSegment(cartId)}/bump`, body);
3224
3580
  }
3225
3581
  throw new BrainerceError("addOrderBump() requires vibe-coded or storefront mode", 400);
3226
3582
  }
@@ -3233,10 +3589,16 @@ var BrainerceClient = class {
3233
3589
  */
3234
3590
  async removeOrderBump(cartId, bumpConfigId) {
3235
3591
  if (this.isVibeCodedMode()) {
3236
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3592
+ return this.vibeCodedRequest(
3593
+ "DELETE",
3594
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3595
+ );
3237
3596
  }
3238
3597
  if (this.storeId && !this.apiKey) {
3239
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bump/${bumpConfigId}`);
3598
+ return this.storefrontRequest(
3599
+ "DELETE",
3600
+ `/cart/${encodePathSegment(cartId)}/bump/${encodePathSegment(bumpConfigId)}`
3601
+ );
3240
3602
  }
3241
3603
  throw new BrainerceError("removeOrderBump() requires vibe-coded or storefront mode", 400);
3242
3604
  }
@@ -3267,10 +3629,14 @@ var BrainerceClient = class {
3267
3629
  ...variantSelections && Object.keys(variantSelections).length > 0 ? { variantSelections } : {}
3268
3630
  };
3269
3631
  if (this.isVibeCodedMode()) {
3270
- return this.vibeCodedRequest("POST", `/cart/${cartId}/bundle`, body);
3632
+ return this.vibeCodedRequest("POST", `/cart/${encodePathSegment(cartId)}/bundle`, body);
3271
3633
  }
3272
3634
  if (this.storeId && !this.apiKey) {
3273
- return this.storefrontRequest("POST", `/cart/${cartId}/bundle`, body);
3635
+ return this.storefrontRequest(
3636
+ "POST",
3637
+ `/cart/${encodePathSegment(cartId)}/bundle`,
3638
+ body
3639
+ );
3274
3640
  }
3275
3641
  throw new BrainerceError("addBundleToCart() requires vibe-coded or storefront mode", 400);
3276
3642
  }
@@ -3283,10 +3649,16 @@ var BrainerceClient = class {
3283
3649
  */
3284
3650
  async removeBundleFromCart(cartId, bundleOfferId) {
3285
3651
  if (this.isVibeCodedMode()) {
3286
- return this.vibeCodedRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3652
+ return this.vibeCodedRequest(
3653
+ "DELETE",
3654
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3655
+ );
3287
3656
  }
3288
3657
  if (this.storeId && !this.apiKey) {
3289
- return this.storefrontRequest("DELETE", `/cart/${cartId}/bundle/${bundleOfferId}`);
3658
+ return this.storefrontRequest(
3659
+ "DELETE",
3660
+ `/cart/${encodePathSegment(cartId)}/bundle/${encodePathSegment(bundleOfferId)}`
3661
+ );
3290
3662
  }
3291
3663
  throw new BrainerceError("removeBundleFromCart() requires vibe-coded or storefront mode", 400);
3292
3664
  }
@@ -3872,18 +4244,18 @@ var BrainerceClient = class {
3872
4244
  async getCheckout(checkoutId) {
3873
4245
  if (this.isVibeCodedMode()) {
3874
4246
  return this.withGuards(
3875
- this.vibeCodedRequest("GET", `/checkout/${checkoutId}`),
4247
+ this.vibeCodedRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3876
4248
  "checkout"
3877
4249
  );
3878
4250
  }
3879
4251
  if (this.storeId && !this.apiKey) {
3880
4252
  return this.withGuards(
3881
- this.storefrontRequest("GET", `/checkout/${checkoutId}`),
4253
+ this.storefrontRequest("GET", `/checkout/${encodePathSegment(checkoutId)}`),
3882
4254
  "checkout"
3883
4255
  );
3884
4256
  }
3885
4257
  return this.withGuards(
3886
- this.adminRequest("GET", `/api/v1/checkout/${checkoutId}`),
4258
+ this.adminRequest("GET", `/api/v1/checkout/${encodePathSegment(checkoutId)}`),
3887
4259
  "checkout"
3888
4260
  );
3889
4261
  }
@@ -3906,18 +4278,30 @@ var BrainerceClient = class {
3906
4278
  async applyCheckoutCoupon(checkoutId, code) {
3907
4279
  if (this.isVibeCodedMode()) {
3908
4280
  return this.withGuards(
3909
- this.vibeCodedRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4281
+ this.vibeCodedRequest(
4282
+ "POST",
4283
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4284
+ { code }
4285
+ ),
3910
4286
  "checkout"
3911
4287
  );
3912
4288
  }
3913
4289
  if (this.storeId && !this.apiKey) {
3914
4290
  return this.withGuards(
3915
- this.storefrontRequest("POST", `/checkout/${checkoutId}/coupon`, { code }),
4291
+ this.storefrontRequest(
4292
+ "POST",
4293
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`,
4294
+ { code }
4295
+ ),
3916
4296
  "checkout"
3917
4297
  );
3918
4298
  }
3919
4299
  return this.withGuards(
3920
- this.adminRequest("POST", `/api/v1/checkout/${checkoutId}/coupon`, { code }),
4300
+ this.adminRequest(
4301
+ "POST",
4302
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`,
4303
+ { code }
4304
+ ),
3921
4305
  "checkout"
3922
4306
  );
3923
4307
  }
@@ -3935,18 +4319,27 @@ var BrainerceClient = class {
3935
4319
  async removeCheckoutCoupon(checkoutId) {
3936
4320
  if (this.isVibeCodedMode()) {
3937
4321
  return this.withGuards(
3938
- this.vibeCodedRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4322
+ this.vibeCodedRequest(
4323
+ "DELETE",
4324
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4325
+ ),
3939
4326
  "checkout"
3940
4327
  );
3941
4328
  }
3942
4329
  if (this.storeId && !this.apiKey) {
3943
4330
  return this.withGuards(
3944
- this.storefrontRequest("DELETE", `/checkout/${checkoutId}/coupon`),
4331
+ this.storefrontRequest(
4332
+ "DELETE",
4333
+ `/checkout/${encodePathSegment(checkoutId)}/coupon`
4334
+ ),
3945
4335
  "checkout"
3946
4336
  );
3947
4337
  }
3948
4338
  return this.withGuards(
3949
- this.adminRequest("DELETE", `/api/v1/checkout/${checkoutId}/coupon`),
4339
+ this.adminRequest(
4340
+ "DELETE",
4341
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/coupon`
4342
+ ),
3950
4343
  "checkout"
3951
4344
  );
3952
4345
  }
@@ -3964,12 +4357,24 @@ var BrainerceClient = class {
3964
4357
  */
3965
4358
  async setCheckoutCustomer(checkoutId, data) {
3966
4359
  if (this.isVibeCodedMode()) {
3967
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4360
+ return this.vibeCodedRequest(
4361
+ "PATCH",
4362
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4363
+ data
4364
+ );
3968
4365
  }
3969
4366
  if (this.storeId && !this.apiKey) {
3970
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/customer`, data);
4367
+ return this.storefrontRequest(
4368
+ "PATCH",
4369
+ `/checkout/${encodePathSegment(checkoutId)}/customer`,
4370
+ data
4371
+ );
3971
4372
  }
3972
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/customer`, data);
4373
+ return this.adminRequest(
4374
+ "PATCH",
4375
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/customer`,
4376
+ data
4377
+ );
3973
4378
  }
3974
4379
  /**
3975
4380
  * Get available shipping destinations for this store.
@@ -4037,20 +4442,20 @@ var BrainerceClient = class {
4037
4442
  if (this.isVibeCodedMode()) {
4038
4443
  return this.vibeCodedRequest(
4039
4444
  "PATCH",
4040
- `/checkout/${checkoutId}/shipping-address`,
4445
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4041
4446
  address
4042
4447
  );
4043
4448
  }
4044
4449
  if (this.storeId && !this.apiKey) {
4045
4450
  return this.storefrontRequest(
4046
4451
  "PATCH",
4047
- `/checkout/${checkoutId}/shipping-address`,
4452
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4048
4453
  address
4049
4454
  );
4050
4455
  }
4051
4456
  return this.adminRequest(
4052
4457
  "PATCH",
4053
- `/api/v1/checkout/${checkoutId}/shipping-address`,
4458
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
4054
4459
  address
4055
4460
  );
4056
4461
  }
@@ -4068,19 +4473,19 @@ var BrainerceClient = class {
4068
4473
  if (this.isVibeCodedMode()) {
4069
4474
  const result = await this.vibeCodedRequest(
4070
4475
  "GET",
4071
- `/checkout/${checkoutId}/shipping-rates`
4476
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4072
4477
  );
4073
4478
  return result.rates;
4074
4479
  }
4075
4480
  if (this.storeId && !this.apiKey) {
4076
4481
  return this.storefrontRequest(
4077
4482
  "GET",
4078
- `/checkout/${checkoutId}/shipping-rates`
4483
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4079
4484
  );
4080
4485
  }
4081
4486
  return this.adminRequest(
4082
4487
  "GET",
4083
- `/api/v1/checkout/${checkoutId}/shipping-rates`
4488
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-rates`
4084
4489
  );
4085
4490
  }
4086
4491
  /**
@@ -4095,24 +4500,36 @@ var BrainerceClient = class {
4095
4500
  async selectShippingMethod(checkoutId, shippingRateId) {
4096
4501
  if (this.isVibeCodedMode()) {
4097
4502
  return this.withGuards(
4098
- this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4099
- shippingMethodId: shippingRateId
4100
- }),
4503
+ this.vibeCodedRequest(
4504
+ "PATCH",
4505
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4506
+ {
4507
+ shippingRateId
4508
+ }
4509
+ ),
4101
4510
  "checkout"
4102
4511
  );
4103
4512
  }
4104
4513
  if (this.storeId && !this.apiKey) {
4105
4514
  return this.withGuards(
4106
- this.storefrontRequest("PATCH", `/checkout/${checkoutId}/shipping-method`, {
4107
- shippingRateId
4108
- }),
4515
+ this.storefrontRequest(
4516
+ "PATCH",
4517
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4518
+ {
4519
+ shippingRateId
4520
+ }
4521
+ ),
4109
4522
  "checkout"
4110
4523
  );
4111
4524
  }
4112
4525
  return this.withGuards(
4113
- this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/shipping-method`, {
4114
- shippingRateId
4115
- }),
4526
+ this.adminRequest(
4527
+ "PATCH",
4528
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/shipping-method`,
4529
+ {
4530
+ shippingRateId
4531
+ }
4532
+ ),
4116
4533
  "checkout"
4117
4534
  );
4118
4535
  }
@@ -4151,18 +4568,30 @@ var BrainerceClient = class {
4151
4568
  */
4152
4569
  async setDeliveryType(checkoutId, deliveryType) {
4153
4570
  if (this.isVibeCodedMode()) {
4154
- return this.vibeCodedRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4155
- deliveryType
4156
- });
4571
+ return this.vibeCodedRequest(
4572
+ "PATCH",
4573
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4574
+ {
4575
+ deliveryType
4576
+ }
4577
+ );
4157
4578
  }
4158
4579
  if (this.storeId && !this.apiKey) {
4159
- return this.storefrontRequest("PATCH", `/checkout/${checkoutId}/delivery-type`, {
4160
- deliveryType
4161
- });
4580
+ return this.storefrontRequest(
4581
+ "PATCH",
4582
+ `/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4583
+ {
4584
+ deliveryType
4585
+ }
4586
+ );
4162
4587
  }
4163
- return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/delivery-type`, {
4164
- deliveryType
4165
- });
4588
+ return this.adminRequest(
4589
+ "PATCH",
4590
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/delivery-type`,
4591
+ {
4592
+ deliveryType
4593
+ }
4594
+ );
4166
4595
  }
4167
4596
  /**
4168
4597
  * Select a pickup location for checkout.
@@ -4184,20 +4613,20 @@ var BrainerceClient = class {
4184
4613
  if (this.isVibeCodedMode()) {
4185
4614
  return this.vibeCodedRequest(
4186
4615
  "PATCH",
4187
- `/checkout/${checkoutId}/pickup-location`,
4616
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4188
4617
  data
4189
4618
  );
4190
4619
  }
4191
4620
  if (this.storeId && !this.apiKey) {
4192
4621
  return this.storefrontRequest(
4193
4622
  "PATCH",
4194
- `/checkout/${checkoutId}/pickup-location`,
4623
+ `/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4195
4624
  data
4196
4625
  );
4197
4626
  }
4198
4627
  return this.adminRequest(
4199
4628
  "PATCH",
4200
- `/api/v1/checkout/${checkoutId}/pickup-location`,
4629
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/pickup-location`,
4201
4630
  data
4202
4631
  );
4203
4632
  }
@@ -4229,20 +4658,20 @@ var BrainerceClient = class {
4229
4658
  if (this.isVibeCodedMode()) {
4230
4659
  return this.vibeCodedRequest(
4231
4660
  "PATCH",
4232
- `/checkout/${checkoutId}/billing-address`,
4661
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4233
4662
  address
4234
4663
  );
4235
4664
  }
4236
4665
  if (this.storeId && !this.apiKey) {
4237
4666
  return this.storefrontRequest(
4238
4667
  "PATCH",
4239
- `/checkout/${checkoutId}/billing-address`,
4668
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4240
4669
  address
4241
4670
  );
4242
4671
  }
4243
4672
  return this.adminRequest(
4244
4673
  "PATCH",
4245
- `/api/v1/checkout/${checkoutId}/billing-address`,
4674
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/billing-address`,
4246
4675
  address
4247
4676
  );
4248
4677
  }
@@ -4261,17 +4690,17 @@ var BrainerceClient = class {
4261
4690
  if (this.isVibeCodedMode()) {
4262
4691
  result = await this.vibeCodedRequest(
4263
4692
  "POST",
4264
- `/checkout/${checkoutId}/complete`
4693
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4265
4694
  );
4266
4695
  } else if (this.storeId && !this.apiKey) {
4267
4696
  result = await this.storefrontRequest(
4268
4697
  "POST",
4269
- `/checkout/${checkoutId}/complete`
4698
+ `/checkout/${encodePathSegment(checkoutId)}/complete`
4270
4699
  );
4271
4700
  } else {
4272
4701
  result = await this.adminRequest(
4273
4702
  "POST",
4274
- `/api/v1/checkout/${checkoutId}/complete`
4703
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}/complete`
4275
4704
  );
4276
4705
  }
4277
4706
  this.customerCartId = null;
@@ -4289,18 +4718,18 @@ var BrainerceClient = class {
4289
4718
  if (this.isVibeCodedMode()) {
4290
4719
  return this.vibeCodedRequest(
4291
4720
  "GET",
4292
- `/checkout/${checkoutId}/custom-fields`
4721
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4293
4722
  );
4294
4723
  }
4295
4724
  if (this.storeId && !this.apiKey) {
4296
4725
  return this.storefrontRequest(
4297
4726
  "GET",
4298
- `/checkout/${checkoutId}/custom-fields`
4727
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`
4299
4728
  );
4300
4729
  }
4301
4730
  return this.adminRequest(
4302
4731
  "GET",
4303
- `/api/v1/checkouts/${checkoutId}/custom-fields`
4732
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`
4304
4733
  );
4305
4734
  }
4306
4735
  /**
@@ -4323,20 +4752,20 @@ var BrainerceClient = class {
4323
4752
  if (this.isVibeCodedMode()) {
4324
4753
  return this.vibeCodedRequest(
4325
4754
  "PATCH",
4326
- `/checkout/${checkoutId}/custom-fields`,
4755
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4327
4756
  data
4328
4757
  );
4329
4758
  }
4330
4759
  if (this.storeId && !this.apiKey) {
4331
4760
  return this.storefrontRequest(
4332
4761
  "PATCH",
4333
- `/checkout/${checkoutId}/custom-fields`,
4762
+ `/checkout/${encodePathSegment(checkoutId)}/custom-fields`,
4334
4763
  data
4335
4764
  );
4336
4765
  }
4337
4766
  return this.adminRequest(
4338
4767
  "PATCH",
4339
- `/api/v1/checkouts/${checkoutId}/custom-fields`,
4768
+ `/api/v1/checkouts/${encodePathSegment(checkoutId)}/custom-fields`,
4340
4769
  data
4341
4770
  );
4342
4771
  }
@@ -4351,17 +4780,17 @@ var BrainerceClient = class {
4351
4780
  if (this.isVibeCodedMode()) {
4352
4781
  result = await this.vibeCodedRequest(
4353
4782
  "DELETE",
4354
- `/checkout/${checkoutId}`
4783
+ `/checkout/${encodePathSegment(checkoutId)}`
4355
4784
  );
4356
4785
  } else if (this.storeId && !this.apiKey) {
4357
4786
  result = await this.storefrontRequest(
4358
4787
  "DELETE",
4359
- `/checkout/${checkoutId}`
4788
+ `/checkout/${encodePathSegment(checkoutId)}`
4360
4789
  );
4361
4790
  } else {
4362
4791
  result = await this.adminRequest(
4363
4792
  "DELETE",
4364
- `/api/v1/checkout/${checkoutId}`
4793
+ `/api/v1/checkout/${encodePathSegment(checkoutId)}`
4365
4794
  );
4366
4795
  }
4367
4796
  this.clearActiveCheckoutStorage();
@@ -4529,7 +4958,10 @@ var BrainerceClient = class {
4529
4958
  400
4530
4959
  );
4531
4960
  }
4532
- return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
4961
+ return this.vibeCodedRequest(
4962
+ "GET",
4963
+ `/checkout/${encodePathSegment(checkoutId)}/payment-status`
4964
+ );
4533
4965
  }
4534
4966
  /**
4535
4967
  * Confirm a client-side SDK payment from the frontend.
@@ -4628,7 +5060,7 @@ var BrainerceClient = class {
4628
5060
  const startTime = Date.now();
4629
5061
  let attempts = 0;
4630
5062
  let currentDelay = initialDelayMs;
4631
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5063
+ const sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4632
5064
  while (Date.now() - startTime < maxWaitMs) {
4633
5065
  attempts++;
4634
5066
  const status = await this.getPaymentStatus(checkoutId);
@@ -4653,7 +5085,7 @@ var BrainerceClient = class {
4653
5085
  const remainingTime = maxWaitMs - (Date.now() - startTime);
4654
5086
  const sleepTime = Math.min(currentDelay, remainingTime, 8e3);
4655
5087
  if (sleepTime > 0) {
4656
- await sleep(sleepTime);
5088
+ await sleep2(sleepTime);
4657
5089
  currentDelay = Math.min(currentDelay * 2, 8e3);
4658
5090
  }
4659
5091
  }
@@ -5168,7 +5600,7 @@ var BrainerceClient = class {
5168
5600
  if (data.shippingAddress) {
5169
5601
  const result = await this.vibeCodedRequest(
5170
5602
  "PATCH",
5171
- `/checkout/${checkoutId}/shipping-address`,
5603
+ `/checkout/${encodePathSegment(checkoutId)}/shipping-address`,
5172
5604
  data.shippingAddress
5173
5605
  );
5174
5606
  checkout = result.checkout;
@@ -5176,7 +5608,7 @@ var BrainerceClient = class {
5176
5608
  if (data.billingAddress) {
5177
5609
  checkout = await this.vibeCodedRequest(
5178
5610
  "PATCH",
5179
- `/checkout/${checkoutId}/billing-address`,
5611
+ `/checkout/${encodePathSegment(checkoutId)}/billing-address`,
5180
5612
  data.billingAddress
5181
5613
  );
5182
5614
  }
@@ -5210,7 +5642,7 @@ var BrainerceClient = class {
5210
5642
  async completeGuestCheckout(checkoutId, options) {
5211
5643
  const result = await this.vibeCodedRequest(
5212
5644
  "POST",
5213
- `/checkout/${checkoutId}/complete`,
5645
+ `/checkout/${encodePathSegment(checkoutId)}/complete`,
5214
5646
  {}
5215
5647
  );
5216
5648
  if (options?.clearCartOnSuccess !== false) {
@@ -5518,13 +5950,13 @@ var BrainerceClient = class {
5518
5950
  if (this.isVibeCodedMode()) {
5519
5951
  return this.vibeCodedRequest(
5520
5952
  "GET",
5521
- `/customers/me/orders/${orderId}/downloads${qs}`
5953
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5522
5954
  );
5523
5955
  }
5524
5956
  if (this.storeId && !this.apiKey) {
5525
5957
  return this.storefrontRequest(
5526
5958
  "GET",
5527
- `/customers/me/orders/${orderId}/downloads${qs}`
5959
+ `/customers/me/orders/${encodePathSegment(orderId)}/downloads${qs}`
5528
5960
  );
5529
5961
  }
5530
5962
  throw new BrainerceError(
@@ -5617,14 +6049,14 @@ var BrainerceClient = class {
5617
6049
  if (this.isVibeCodedMode()) {
5618
6050
  return this.vibeCodedRequest(
5619
6051
  "PATCH",
5620
- `/customers/me/addresses/${addressId}`,
6052
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5621
6053
  data
5622
6054
  );
5623
6055
  }
5624
6056
  if (this.storeId && !this.apiKey) {
5625
6057
  return this.storefrontRequest(
5626
6058
  "PATCH",
5627
- `/customers/me/addresses/${addressId}`,
6059
+ `/customers/me/addresses/${encodePathSegment(addressId)}`,
5628
6060
  data
5629
6061
  );
5630
6062
  }
@@ -5645,11 +6077,17 @@ var BrainerceClient = class {
5645
6077
  );
5646
6078
  }
5647
6079
  if (this.isVibeCodedMode()) {
5648
- await this.vibeCodedRequest("DELETE", `/customers/me/addresses/${addressId}`);
6080
+ await this.vibeCodedRequest(
6081
+ "DELETE",
6082
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6083
+ );
5649
6084
  return;
5650
6085
  }
5651
6086
  if (this.storeId && !this.apiKey) {
5652
- await this.storefrontRequest("DELETE", `/customers/me/addresses/${addressId}`);
6087
+ await this.storefrontRequest(
6088
+ "DELETE",
6089
+ `/customers/me/addresses/${encodePathSegment(addressId)}`
6090
+ );
5653
6091
  return;
5654
6092
  }
5655
6093
  throw new BrainerceError(
@@ -5702,7 +6140,10 @@ var BrainerceClient = class {
5702
6140
  * ```
5703
6141
  */
5704
6142
  async getCustomApiIntegration(integrationId) {
5705
- return this.adminRequest("GET", `/api/v1/custom-api/${integrationId}`);
6143
+ return this.adminRequest(
6144
+ "GET",
6145
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6146
+ );
5706
6147
  }
5707
6148
  /**
5708
6149
  * Create a new Custom API integration
@@ -5745,7 +6186,7 @@ var BrainerceClient = class {
5745
6186
  async updateCustomApiIntegration(integrationId, data) {
5746
6187
  return this.adminRequest(
5747
6188
  "PATCH",
5748
- `/api/v1/custom-api/${integrationId}`,
6189
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`,
5749
6190
  data
5750
6191
  );
5751
6192
  }
@@ -5759,7 +6200,10 @@ var BrainerceClient = class {
5759
6200
  * ```
5760
6201
  */
5761
6202
  async deleteCustomApiIntegration(integrationId) {
5762
- await this.adminRequest("DELETE", `/api/v1/custom-api/${integrationId}`);
6203
+ await this.adminRequest(
6204
+ "DELETE",
6205
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}`
6206
+ );
5763
6207
  }
5764
6208
  /**
5765
6209
  * Test connection to a Custom API
@@ -5778,7 +6222,7 @@ var BrainerceClient = class {
5778
6222
  async testCustomApiConnection(integrationId) {
5779
6223
  return this.adminRequest(
5780
6224
  "POST",
5781
- `/api/v1/custom-api/${integrationId}/test`
6225
+ `/api/v1/custom-api/${encodePathSegment(integrationId)}/test`
5782
6226
  );
5783
6227
  }
5784
6228
  // -------------------- Inventory Reservations --------------------
@@ -5899,7 +6343,10 @@ var BrainerceClient = class {
5899
6343
  * Requires Admin mode (apiKey)
5900
6344
  */
5901
6345
  async getCategory(categoryId) {
5902
- return this.adminRequest("GET", `/api/v1/categories/${categoryId}`);
6346
+ return this.adminRequest(
6347
+ "GET",
6348
+ `/api/v1/categories/${encodePathSegment(categoryId)}`
6349
+ );
5903
6350
  }
5904
6351
  /**
5905
6352
  * Create a new category
@@ -5922,14 +6369,18 @@ var BrainerceClient = class {
5922
6369
  * Requires Admin mode (apiKey)
5923
6370
  */
5924
6371
  async updateCategory(categoryId, data) {
5925
- return this.adminRequest("PATCH", `/api/v1/categories/${categoryId}`, data);
6372
+ return this.adminRequest(
6373
+ "PATCH",
6374
+ `/api/v1/categories/${encodePathSegment(categoryId)}`,
6375
+ data
6376
+ );
5926
6377
  }
5927
6378
  /**
5928
6379
  * Delete a category
5929
6380
  * Requires Admin mode (apiKey)
5930
6381
  */
5931
6382
  async deleteCategory(categoryId) {
5932
- await this.adminRequest("DELETE", `/api/v1/categories/${categoryId}`);
6383
+ await this.adminRequest("DELETE", `/api/v1/categories/${encodePathSegment(categoryId)}`);
5933
6384
  }
5934
6385
  // -------------------- Taxonomy: Brands (Admin) --------------------
5935
6386
  // These methods require Admin mode (apiKey)
@@ -5945,7 +6396,7 @@ var BrainerceClient = class {
5945
6396
  * Requires Admin mode (apiKey)
5946
6397
  */
5947
6398
  async getBrand(brandId) {
5948
- return this.adminRequest("GET", `/api/v1/brands/${brandId}`);
6399
+ return this.adminRequest("GET", `/api/v1/brands/${encodePathSegment(brandId)}`);
5949
6400
  }
5950
6401
  /**
5951
6402
  * Create a new brand
@@ -5968,14 +6419,14 @@ var BrainerceClient = class {
5968
6419
  * Requires Admin mode (apiKey)
5969
6420
  */
5970
6421
  async updateBrand(brandId, data) {
5971
- return this.adminRequest("PATCH", `/api/v1/brands/${brandId}`, data);
6422
+ return this.adminRequest("PATCH", `/api/v1/brands/${encodePathSegment(brandId)}`, data);
5972
6423
  }
5973
6424
  /**
5974
6425
  * Delete a brand
5975
6426
  * Requires Admin mode (apiKey)
5976
6427
  */
5977
6428
  async deleteBrand(brandId) {
5978
- await this.adminRequest("DELETE", `/api/v1/brands/${brandId}`);
6429
+ await this.adminRequest("DELETE", `/api/v1/brands/${encodePathSegment(brandId)}`);
5979
6430
  }
5980
6431
  // -------------------- Taxonomy: Tags (Admin) --------------------
5981
6432
  // These methods require Admin mode (apiKey)
@@ -5991,7 +6442,7 @@ var BrainerceClient = class {
5991
6442
  * Requires Admin mode (apiKey)
5992
6443
  */
5993
6444
  async getTag(tagId) {
5994
- return this.adminRequest("GET", `/api/v1/tags/${tagId}`);
6445
+ return this.adminRequest("GET", `/api/v1/tags/${encodePathSegment(tagId)}`);
5995
6446
  }
5996
6447
  /**
5997
6448
  * Create a new tag
@@ -6013,14 +6464,14 @@ var BrainerceClient = class {
6013
6464
  * Requires Admin mode (apiKey)
6014
6465
  */
6015
6466
  async updateTag(tagId, data) {
6016
- return this.adminRequest("PATCH", `/api/v1/tags/${tagId}`, data);
6467
+ return this.adminRequest("PATCH", `/api/v1/tags/${encodePathSegment(tagId)}`, data);
6017
6468
  }
6018
6469
  /**
6019
6470
  * Delete a tag
6020
6471
  * Requires Admin mode (apiKey)
6021
6472
  */
6022
6473
  async deleteTag(tagId) {
6023
- await this.adminRequest("DELETE", `/api/v1/tags/${tagId}`);
6474
+ await this.adminRequest("DELETE", `/api/v1/tags/${encodePathSegment(tagId)}`);
6024
6475
  }
6025
6476
  // -------------------- Taxonomy: Attributes (Admin) --------------------
6026
6477
  // These methods require Admin mode (apiKey)
@@ -6041,7 +6492,10 @@ var BrainerceClient = class {
6041
6492
  * Requires Admin mode (apiKey)
6042
6493
  */
6043
6494
  async getAttribute(attributeId) {
6044
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}`);
6495
+ return this.adminRequest(
6496
+ "GET",
6497
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`
6498
+ );
6045
6499
  }
6046
6500
  /**
6047
6501
  * Create a new attribute
@@ -6064,21 +6518,28 @@ var BrainerceClient = class {
6064
6518
  * Requires Admin mode (apiKey)
6065
6519
  */
6066
6520
  async updateAttribute(attributeId, data) {
6067
- return this.adminRequest("PATCH", `/api/v1/attributes/${attributeId}`, data);
6521
+ return this.adminRequest(
6522
+ "PATCH",
6523
+ `/api/v1/attributes/${encodePathSegment(attributeId)}`,
6524
+ data
6525
+ );
6068
6526
  }
6069
6527
  /**
6070
6528
  * Delete an attribute
6071
6529
  * Requires Admin mode (apiKey)
6072
6530
  */
6073
6531
  async deleteAttribute(attributeId) {
6074
- await this.adminRequest("DELETE", `/api/v1/attributes/${attributeId}`);
6532
+ await this.adminRequest("DELETE", `/api/v1/attributes/${encodePathSegment(attributeId)}`);
6075
6533
  }
6076
6534
  /**
6077
6535
  * Get all options for an attribute
6078
6536
  * Requires Admin mode (apiKey)
6079
6537
  */
6080
6538
  async getAttributeOptions(attributeId) {
6081
- return this.adminRequest("GET", `/api/v1/attributes/${attributeId}/options`);
6539
+ return this.adminRequest(
6540
+ "GET",
6541
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`
6542
+ );
6082
6543
  }
6083
6544
  /**
6084
6545
  * Create a new option for an attribute
@@ -6096,7 +6557,7 @@ var BrainerceClient = class {
6096
6557
  async createAttributeOption(attributeId, data) {
6097
6558
  return this.adminRequest(
6098
6559
  "POST",
6099
- `/api/v1/attributes/${attributeId}/options`,
6560
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options`,
6100
6561
  data
6101
6562
  );
6102
6563
  }
@@ -6107,7 +6568,7 @@ var BrainerceClient = class {
6107
6568
  async updateAttributeOption(attributeId, optionId, data) {
6108
6569
  return this.adminRequest(
6109
6570
  "PATCH",
6110
- `/api/v1/attributes/${attributeId}/options/${optionId}`,
6571
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`,
6111
6572
  data
6112
6573
  );
6113
6574
  }
@@ -6118,7 +6579,7 @@ var BrainerceClient = class {
6118
6579
  async deleteAttributeOption(attributeId, optionId) {
6119
6580
  await this.adminRequest(
6120
6581
  "DELETE",
6121
- `/api/v1/attributes/${attributeId}/options/${optionId}`
6582
+ `/api/v1/attributes/${encodePathSegment(attributeId)}/options/${encodePathSegment(optionId)}`
6122
6583
  );
6123
6584
  }
6124
6585
  // -------------------- Modifier Groups (Admin) --------------------
@@ -6147,7 +6608,7 @@ var BrainerceClient = class {
6147
6608
  async listModifierGroups(storeId, params) {
6148
6609
  return this.adminRequest(
6149
6610
  "GET",
6150
- `/api/stores/${storeId}/modifier-groups`,
6611
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6151
6612
  void 0,
6152
6613
  params
6153
6614
  );
@@ -6162,7 +6623,7 @@ var BrainerceClient = class {
6162
6623
  async getModifierGroup(storeId, groupId) {
6163
6624
  return this.adminRequest(
6164
6625
  "GET",
6165
- `/api/stores/${storeId}/modifier-groups/${groupId}`
6626
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6166
6627
  );
6167
6628
  }
6168
6629
  /**
@@ -6184,7 +6645,11 @@ var BrainerceClient = class {
6184
6645
  * ```
6185
6646
  */
6186
6647
  async createModifierGroup(storeId, data) {
6187
- return this.adminRequest("POST", `/api/stores/${storeId}/modifier-groups`, data);
6648
+ return this.adminRequest(
6649
+ "POST",
6650
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups`,
6651
+ data
6652
+ );
6188
6653
  }
6189
6654
  /**
6190
6655
  * Update a modifier group's metadata or selection rules. Pass `status: 'archived'`
@@ -6194,7 +6659,7 @@ var BrainerceClient = class {
6194
6659
  async updateModifierGroup(storeId, groupId, data) {
6195
6660
  return this.adminRequest(
6196
6661
  "PATCH",
6197
- `/api/stores/${storeId}/modifier-groups/${groupId}`,
6662
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`,
6198
6663
  data
6199
6664
  );
6200
6665
  }
@@ -6205,7 +6670,10 @@ var BrainerceClient = class {
6205
6670
  * Requires Admin mode (apiKey).
6206
6671
  */
6207
6672
  async deleteModifierGroup(storeId, groupId) {
6208
- await this.adminRequest("DELETE", `/api/stores/${storeId}/modifier-groups/${groupId}`);
6673
+ await this.adminRequest(
6674
+ "DELETE",
6675
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}`
6676
+ );
6209
6677
  }
6210
6678
  /**
6211
6679
  * Create a modifier inside a group (e.g., "Olives" inside the "Toppings" group).
@@ -6229,7 +6697,7 @@ var BrainerceClient = class {
6229
6697
  async createModifier(storeId, groupId, data) {
6230
6698
  return this.adminRequest(
6231
6699
  "POST",
6232
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers`,
6700
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers`,
6233
6701
  data
6234
6702
  );
6235
6703
  }
@@ -6240,7 +6708,7 @@ var BrainerceClient = class {
6240
6708
  async updateModifier(storeId, groupId, modifierId, data) {
6241
6709
  return this.adminRequest(
6242
6710
  "PATCH",
6243
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`,
6711
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`,
6244
6712
  data
6245
6713
  );
6246
6714
  }
@@ -6252,7 +6720,7 @@ var BrainerceClient = class {
6252
6720
  async deleteModifier(storeId, groupId, modifierId) {
6253
6721
  await this.adminRequest(
6254
6722
  "DELETE",
6255
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}`
6723
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}`
6256
6724
  );
6257
6725
  }
6258
6726
  /**
@@ -6271,7 +6739,7 @@ var BrainerceClient = class {
6271
6739
  async toggleModifierAvailability(storeId, groupId, modifierId, available) {
6272
6740
  return this.adminRequest(
6273
6741
  "POST",
6274
- `/api/stores/${storeId}/modifier-groups/${groupId}/modifiers/${modifierId}/availability-toggle`,
6742
+ `/api/stores/${encodePathSegment(storeId)}/modifier-groups/${encodePathSegment(groupId)}/modifiers/${encodePathSegment(modifierId)}/availability-toggle`,
6275
6743
  { available }
6276
6744
  );
6277
6745
  }
@@ -6292,7 +6760,7 @@ var BrainerceClient = class {
6292
6760
  async attachModifierGroup(storeId, productId, data) {
6293
6761
  return this.adminRequest(
6294
6762
  "POST",
6295
- `/api/stores/${storeId}/products/${productId}/modifier-groups`,
6763
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups`,
6296
6764
  data
6297
6765
  );
6298
6766
  }
@@ -6305,7 +6773,7 @@ var BrainerceClient = class {
6305
6773
  async updateAttachment(storeId, productId, attachmentId, data) {
6306
6774
  return this.adminRequest(
6307
6775
  "PATCH",
6308
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`,
6776
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`,
6309
6777
  data
6310
6778
  );
6311
6779
  }
@@ -6316,7 +6784,7 @@ var BrainerceClient = class {
6316
6784
  async detachModifierGroup(storeId, productId, attachmentId) {
6317
6785
  await this.adminRequest(
6318
6786
  "DELETE",
6319
- `/api/stores/${storeId}/products/${productId}/modifier-groups/${attachmentId}`
6787
+ `/api/stores/${encodePathSegment(storeId)}/products/${encodePathSegment(productId)}/modifier-groups/${encodePathSegment(attachmentId)}`
6320
6788
  );
6321
6789
  }
6322
6790
  // -------------------- Shipping: Zones and Rates (Admin) --------------------
@@ -6338,7 +6806,10 @@ var BrainerceClient = class {
6338
6806
  * Requires Admin mode (apiKey)
6339
6807
  */
6340
6808
  async getShippingZone(zoneId) {
6341
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}`);
6809
+ return this.adminRequest(
6810
+ "GET",
6811
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`
6812
+ );
6342
6813
  }
6343
6814
  /**
6344
6815
  * Create a new shipping zone
@@ -6361,21 +6832,28 @@ var BrainerceClient = class {
6361
6832
  * Requires Admin mode (apiKey)
6362
6833
  */
6363
6834
  async updateShippingZone(zoneId, data) {
6364
- return this.adminRequest("PATCH", `/api/v1/shipping/zones/${zoneId}`, data);
6835
+ return this.adminRequest(
6836
+ "PATCH",
6837
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`,
6838
+ data
6839
+ );
6365
6840
  }
6366
6841
  /**
6367
6842
  * Delete a shipping zone
6368
6843
  * Requires Admin mode (apiKey)
6369
6844
  */
6370
6845
  async deleteShippingZone(zoneId) {
6371
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}`);
6846
+ await this.adminRequest("DELETE", `/api/v1/shipping/zones/${encodePathSegment(zoneId)}`);
6372
6847
  }
6373
6848
  /**
6374
6849
  * Get all shipping rates for a zone
6375
6850
  * Requires Admin mode (apiKey)
6376
6851
  */
6377
6852
  async getZoneShippingRates(zoneId) {
6378
- return this.adminRequest("GET", `/api/v1/shipping/zones/${zoneId}/rates`);
6853
+ return this.adminRequest(
6854
+ "GET",
6855
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`
6856
+ );
6379
6857
  }
6380
6858
  /**
6381
6859
  * Create a new shipping rate for a zone
@@ -6395,7 +6873,7 @@ var BrainerceClient = class {
6395
6873
  async createZoneShippingRate(zoneId, data) {
6396
6874
  return this.adminRequest(
6397
6875
  "POST",
6398
- `/api/v1/shipping/zones/${zoneId}/rates`,
6876
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates`,
6399
6877
  data
6400
6878
  );
6401
6879
  }
@@ -6406,7 +6884,7 @@ var BrainerceClient = class {
6406
6884
  async updateZoneShippingRate(zoneId, rateId, data) {
6407
6885
  return this.adminRequest(
6408
6886
  "PATCH",
6409
- `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`,
6887
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`,
6410
6888
  data
6411
6889
  );
6412
6890
  }
@@ -6415,7 +6893,149 @@ var BrainerceClient = class {
6415
6893
  * Requires Admin mode (apiKey)
6416
6894
  */
6417
6895
  async deleteZoneShippingRate(zoneId, rateId) {
6418
- await this.adminRequest("DELETE", `/api/v1/shipping/zones/${zoneId}/rates/${rateId}`);
6896
+ await this.adminRequest(
6897
+ "DELETE",
6898
+ `/api/v1/shipping/zones/${encodePathSegment(zoneId)}/rates/${encodePathSegment(rateId)}`
6899
+ );
6900
+ }
6901
+ // -------------------- Regions (Admin mode, apiKey) --------------------
6902
+ // Multi-region commerce. storeId is derived from the api_key — do not pass it.
6903
+ // Requires the `regions:read` / `regions:write` scopes on the key.
6904
+ /** List the store's regions (paginated). */
6905
+ async getRegions() {
6906
+ return this.adminRequest("GET", "/api/v1/regions");
6907
+ }
6908
+ async getRegion(regionId) {
6909
+ return this.adminRequest("GET", `/api/v1/regions/${encodePathSegment(regionId)}`);
6910
+ }
6911
+ async createRegion(data) {
6912
+ return this.adminRequest("POST", "/api/v1/regions", data);
6913
+ }
6914
+ async updateRegion(regionId, data) {
6915
+ return this.adminRequest(
6916
+ "PATCH",
6917
+ `/api/v1/regions/${encodePathSegment(regionId)}`,
6918
+ data
6919
+ );
6920
+ }
6921
+ async deleteRegion(regionId) {
6922
+ await this.adminRequest("DELETE", `/api/v1/regions/${encodePathSegment(regionId)}`);
6923
+ }
6924
+ async setDefaultRegion(regionId) {
6925
+ return this.adminRequest(
6926
+ "PATCH",
6927
+ `/api/v1/regions/${encodePathSegment(regionId)}/set-default`
6928
+ );
6929
+ }
6930
+ /** Replace the region's enabled payment providers (AppInstallation IDs). */
6931
+ async updateRegionPaymentProviders(regionId, providerIds) {
6932
+ return this.adminRequest(
6933
+ "PUT",
6934
+ `/api/v1/regions/${encodePathSegment(regionId)}/payment-providers`,
6935
+ { providerIds }
6936
+ );
6937
+ }
6938
+ async addRegionCountries(regionId, countries) {
6939
+ return this.adminRequest(
6940
+ "POST",
6941
+ `/api/v1/regions/${encodePathSegment(regionId)}/countries`,
6942
+ { countries }
6943
+ );
6944
+ }
6945
+ async removeRegionCountry(regionId, countryCode) {
6946
+ return this.adminRequest(
6947
+ "DELETE",
6948
+ `/api/v1/regions/${encodePathSegment(regionId)}/countries/${encodePathSegment(countryCode)}`
6949
+ );
6950
+ }
6951
+ /** Installed payment providers compatible with this region's countries. */
6952
+ async getRegionCompatibleProviders(regionId) {
6953
+ return this.adminRequest(
6954
+ "GET",
6955
+ `/api/v1/regions/${encodePathSegment(regionId)}/compatible-providers`
6956
+ );
6957
+ }
6958
+ // -------------------- Regions (Storefront mode, public — no apiKey) --------------------
6959
+ // storeId-based, no auth. Call these from a storefront to detect the buyer's
6960
+ // region (story S1), then pair with detectRegion(). Admin/api-key callers use
6961
+ // getRegions()/getRegion() instead.
6962
+ /**
6963
+ * List the store's ACTIVE regions (public, no apiKey). Requires storeId mode.
6964
+ * Returns only storefront-safe fields (no internal flags). Default region first.
6965
+ */
6966
+ async getStoreRegions() {
6967
+ return this.storefrontRequest("GET", "/regions");
6968
+ }
6969
+ /**
6970
+ * Get one active public region plus its enabled payment providers (public).
6971
+ * Requires storeId mode. Throws 404 if the region is inactive or not found.
6972
+ */
6973
+ async getStoreRegion(regionId) {
6974
+ return this.storefrontRequest(
6975
+ "GET",
6976
+ `/regions/${encodePathSegment(regionId)}`
6977
+ );
6978
+ }
6979
+ /**
6980
+ * Client-side region detection — no network call. Returns the region whose
6981
+ * `countries` includes `country`, else the default region, else null.
6982
+ */
6983
+ detectRegion(country, regions) {
6984
+ const code = country.toUpperCase();
6985
+ return regions.find((r) => r.countries.includes(code)) ?? regions.find((r) => r.isDefault) ?? null;
6986
+ }
6987
+ // -------------------- Tax Classes (Storefront mode, public — no apiKey) --------------------
6988
+ /**
6989
+ * List the store's tax classes (public, no apiKey — storeId mode). Storefront-
6990
+ * safe fields only (id/name/slug/description/isDefault) for transparency UIs
6991
+ * such as a "9% VAT" badge. Admin/api-key callers use getTaxClasses().
6992
+ */
6993
+ async getStoreTaxClasses() {
6994
+ return this.storefrontRequest("GET", "/tax-classes");
6995
+ }
6996
+ // -------------------- Tax Classes (Admin mode, apiKey) --------------------
6997
+ // Requires the `tax-classes:read` / `tax-classes:write` scopes on the key.
6998
+ /** List the store's tax classes. */
6999
+ async getTaxClasses() {
7000
+ return this.adminRequest("GET", "/api/v1/tax-classes");
7001
+ }
7002
+ /** Get a tax class with its dependent counts (products/variants/categories/rates). */
7003
+ async getTaxClass(id) {
7004
+ return this.adminRequest("GET", `/api/v1/tax-classes/${encodePathSegment(id)}`);
7005
+ }
7006
+ async createTaxClass(data) {
7007
+ return this.adminRequest("POST", "/api/v1/tax-classes", data);
7008
+ }
7009
+ async updateTaxClass(id, data) {
7010
+ return this.adminRequest(
7011
+ "PATCH",
7012
+ `/api/v1/tax-classes/${encodePathSegment(id)}`,
7013
+ data
7014
+ );
7015
+ }
7016
+ async deleteTaxClass(id) {
7017
+ await this.adminRequest("DELETE", `/api/v1/tax-classes/${encodePathSegment(id)}`);
7018
+ }
7019
+ async setDefaultTaxClass(id) {
7020
+ return this.adminRequest(
7021
+ "PATCH",
7022
+ `/api/v1/tax-classes/${encodePathSegment(id)}/set-default`
7023
+ );
7024
+ }
7025
+ /** Bulk-assign this tax class to products / variants / categories. */
7026
+ async assignTaxClass(id, data) {
7027
+ return this.adminRequest(
7028
+ "POST",
7029
+ `/api/v1/tax-classes/${encodePathSegment(id)}/assign`,
7030
+ data
7031
+ );
7032
+ }
7033
+ /** Merge this tax class into another, moving all FKs, then delete it. */
7034
+ async mergeTaxClasses(id, targetId) {
7035
+ await this.adminRequest(
7036
+ "POST",
7037
+ `/api/v1/tax-classes/${encodePathSegment(id)}/merge-into/${encodePathSegment(targetId)}`
7038
+ );
6419
7039
  }
6420
7040
  // -------------------- Tax: Rates --------------------
6421
7041
  // These methods require Admin mode (apiKey)
@@ -6431,7 +7051,7 @@ var BrainerceClient = class {
6431
7051
  * Requires Admin mode (apiKey)
6432
7052
  */
6433
7053
  async getTaxRate(rateId) {
6434
- return this.adminRequest("GET", `/api/v1/tax/rates/${rateId}`);
7054
+ return this.adminRequest("GET", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6435
7055
  }
6436
7056
  /**
6437
7057
  * Create a new tax rate
@@ -6456,14 +7076,18 @@ var BrainerceClient = class {
6456
7076
  * Requires Admin mode (apiKey)
6457
7077
  */
6458
7078
  async updateTaxRate(rateId, data) {
6459
- return this.adminRequest("PATCH", `/api/v1/tax/rates/${rateId}`, data);
7079
+ return this.adminRequest(
7080
+ "PATCH",
7081
+ `/api/v1/tax/rates/${encodePathSegment(rateId)}`,
7082
+ data
7083
+ );
6460
7084
  }
6461
7085
  /**
6462
7086
  * Delete a tax rate
6463
7087
  * Requires Admin mode (apiKey)
6464
7088
  */
6465
7089
  async deleteTaxRate(rateId) {
6466
- await this.adminRequest("DELETE", `/api/v1/tax/rates/${rateId}`);
7090
+ await this.adminRequest("DELETE", `/api/v1/tax/rates/${encodePathSegment(rateId)}`);
6467
7091
  }
6468
7092
  // -------------------- Metafields: Definitions --------------------
6469
7093
  // These methods require Admin mode (apiKey)
@@ -6519,7 +7143,7 @@ var BrainerceClient = class {
6519
7143
  async getMetafieldDefinition(definitionId) {
6520
7144
  return this.adminRequest(
6521
7145
  "GET",
6522
- `/api/v1/metafield-definitions/${definitionId}`
7146
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
6523
7147
  );
6524
7148
  }
6525
7149
  /**
@@ -6546,7 +7170,7 @@ var BrainerceClient = class {
6546
7170
  async updateMetafieldDefinition(definitionId, data) {
6547
7171
  return this.adminRequest(
6548
7172
  "PATCH",
6549
- `/api/v1/metafield-definitions/${definitionId}`,
7173
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`,
6550
7174
  data
6551
7175
  );
6552
7176
  }
@@ -6555,7 +7179,10 @@ var BrainerceClient = class {
6555
7179
  * Requires Admin mode (apiKey)
6556
7180
  */
6557
7181
  async deleteMetafieldDefinition(definitionId) {
6558
- await this.adminRequest("DELETE", `/api/v1/metafield-definitions/${definitionId}`);
7182
+ await this.adminRequest(
7183
+ "DELETE",
7184
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}`
7185
+ );
6559
7186
  }
6560
7187
  /**
6561
7188
  * Replace the platform publishing configuration on a metafield definition.
@@ -6579,7 +7206,7 @@ var BrainerceClient = class {
6579
7206
  async setMetafieldPlatforms(definitionId, data) {
6580
7207
  return this.adminRequest(
6581
7208
  "PUT",
6582
- `/api/v1/metafield-definitions/${definitionId}/platforms`,
7209
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/platforms`,
6583
7210
  data
6584
7211
  );
6585
7212
  }
@@ -6598,7 +7225,7 @@ var BrainerceClient = class {
6598
7225
  async publishMetafieldDefinitionToVibeCodedSite(definitionId, vibeCodedConnectionId) {
6599
7226
  return this.adminRequest(
6600
7227
  "POST",
6601
- `/api/v1/metafield-definitions/${definitionId}/publish-vibe-coded`,
7228
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/publish-vibe-coded`,
6602
7229
  { vibeCodedConnectionId }
6603
7230
  );
6604
7231
  }
@@ -6606,7 +7233,7 @@ var BrainerceClient = class {
6606
7233
  async unpublishMetafieldDefinitionFromVibeCodedSite(definitionId, vibeCodedConnectionId) {
6607
7234
  return this.adminRequest(
6608
7235
  "POST",
6609
- `/api/v1/metafield-definitions/${definitionId}/unpublish-vibe-coded`,
7236
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/unpublish-vibe-coded`,
6610
7237
  { vibeCodedConnectionId }
6611
7238
  );
6612
7239
  }
@@ -6614,7 +7241,7 @@ var BrainerceClient = class {
6614
7241
  async publishCategoryToVibeCodedSite(categoryId, vibeCodedConnectionId) {
6615
7242
  return this.adminRequest(
6616
7243
  "POST",
6617
- `/api/v1/categories/${categoryId}/publish-vibe-coded`,
7244
+ `/api/v1/categories/${encodePathSegment(categoryId)}/publish-vibe-coded`,
6618
7245
  { vibeCodedConnectionId }
6619
7246
  );
6620
7247
  }
@@ -6622,7 +7249,7 @@ var BrainerceClient = class {
6622
7249
  async unpublishCategoryFromVibeCodedSite(categoryId, vibeCodedConnectionId) {
6623
7250
  return this.adminRequest(
6624
7251
  "POST",
6625
- `/api/v1/categories/${categoryId}/unpublish-vibe-coded`,
7252
+ `/api/v1/categories/${encodePathSegment(categoryId)}/unpublish-vibe-coded`,
6626
7253
  { vibeCodedConnectionId }
6627
7254
  );
6628
7255
  }
@@ -6630,7 +7257,7 @@ var BrainerceClient = class {
6630
7257
  async publishTagToVibeCodedSite(tagId, vibeCodedConnectionId) {
6631
7258
  return this.adminRequest(
6632
7259
  "POST",
6633
- `/api/v1/tags/${tagId}/publish-vibe-coded`,
7260
+ `/api/v1/tags/${encodePathSegment(tagId)}/publish-vibe-coded`,
6634
7261
  { vibeCodedConnectionId }
6635
7262
  );
6636
7263
  }
@@ -6638,7 +7265,7 @@ var BrainerceClient = class {
6638
7265
  async unpublishTagFromVibeCodedSite(tagId, vibeCodedConnectionId) {
6639
7266
  return this.adminRequest(
6640
7267
  "POST",
6641
- `/api/v1/tags/${tagId}/unpublish-vibe-coded`,
7268
+ `/api/v1/tags/${encodePathSegment(tagId)}/unpublish-vibe-coded`,
6642
7269
  { vibeCodedConnectionId }
6643
7270
  );
6644
7271
  }
@@ -6646,7 +7273,7 @@ var BrainerceClient = class {
6646
7273
  async publishBrandToVibeCodedSite(brandId, vibeCodedConnectionId) {
6647
7274
  return this.adminRequest(
6648
7275
  "POST",
6649
- `/api/v1/brands/${brandId}/publish-vibe-coded`,
7276
+ `/api/v1/brands/${encodePathSegment(brandId)}/publish-vibe-coded`,
6650
7277
  { vibeCodedConnectionId }
6651
7278
  );
6652
7279
  }
@@ -6654,7 +7281,7 @@ var BrainerceClient = class {
6654
7281
  async unpublishBrandFromVibeCodedSite(brandId, vibeCodedConnectionId) {
6655
7282
  return this.adminRequest(
6656
7283
  "POST",
6657
- `/api/v1/brands/${brandId}/unpublish-vibe-coded`,
7284
+ `/api/v1/brands/${encodePathSegment(brandId)}/unpublish-vibe-coded`,
6658
7285
  { vibeCodedConnectionId }
6659
7286
  );
6660
7287
  }
@@ -6680,7 +7307,7 @@ var BrainerceClient = class {
6680
7307
  async setDefinitionProducts(definitionId, data) {
6681
7308
  return this.adminRequest(
6682
7309
  "PATCH",
6683
- `/api/v1/metafield-definitions/${definitionId}/products`,
7310
+ `/api/v1/metafield-definitions/${encodePathSegment(definitionId)}/products`,
6684
7311
  data
6685
7312
  );
6686
7313
  }
@@ -6693,7 +7320,7 @@ var BrainerceClient = class {
6693
7320
  async getProductMetafields(productId) {
6694
7321
  return this.adminRequest(
6695
7322
  "GET",
6696
- `/api/v1/products/${productId}/metafields`
7323
+ `/api/v1/products/${encodePathSegment(productId)}/metafields`
6697
7324
  );
6698
7325
  }
6699
7326
  /**
@@ -6710,7 +7337,7 @@ var BrainerceClient = class {
6710
7337
  async setProductMetafield(productId, definitionId, data) {
6711
7338
  return this.adminRequest(
6712
7339
  "PUT",
6713
- `/api/v1/products/${productId}/metafields/${definitionId}`,
7340
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`,
6714
7341
  data
6715
7342
  );
6716
7343
  }
@@ -6721,7 +7348,7 @@ var BrainerceClient = class {
6721
7348
  async deleteProductMetafield(productId, definitionId) {
6722
7349
  await this.adminRequest(
6723
7350
  "DELETE",
6724
- `/api/v1/products/${productId}/metafields/${definitionId}`
7351
+ `/api/v1/products/${encodePathSegment(productId)}/metafields/${encodePathSegment(definitionId)}`
6725
7352
  );
6726
7353
  }
6727
7354
  // -------------------- Product Customization Fields (Admin) --------------------
@@ -6732,7 +7359,7 @@ var BrainerceClient = class {
6732
7359
  async getProductCustomizationFields(productId) {
6733
7360
  return this.adminRequest(
6734
7361
  "GET",
6735
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`
7362
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`
6736
7363
  );
6737
7364
  }
6738
7365
  /**
@@ -6743,7 +7370,7 @@ var BrainerceClient = class {
6743
7370
  async setProductCustomizationFields(productId, definitionIds) {
6744
7371
  return this.adminRequest(
6745
7372
  "PATCH",
6746
- `/api/v1/metafield-definitions/products/${productId}/customization-fields`,
7373
+ `/api/v1/metafield-definitions/products/${encodePathSegment(productId)}/customization-fields`,
6747
7374
  { definitionIds }
6748
7375
  );
6749
7376
  }
@@ -6823,26 +7450,33 @@ var BrainerceClient = class {
6823
7450
  async resendTeamInvitation(invitationId) {
6824
7451
  return this.adminRequest(
6825
7452
  "POST",
6826
- `/api/v1/team/invitations/${invitationId}/resend`
7453
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}/resend`
6827
7454
  );
6828
7455
  }
6829
7456
  /**
6830
7457
  * @deprecated Use `revokeStoreInvitation(storeId, invitationId)` instead.
6831
7458
  */
6832
7459
  async revokeTeamInvitation(invitationId) {
6833
- await this.adminRequest("DELETE", `/api/v1/team/invitations/${invitationId}`);
7460
+ await this.adminRequest(
7461
+ "DELETE",
7462
+ `/api/v1/team/invitations/${encodePathSegment(invitationId)}`
7463
+ );
6834
7464
  }
6835
7465
  /**
6836
7466
  * @deprecated Use `updateStoreMember(storeId, memberId, data)` instead.
6837
7467
  */
6838
7468
  async updateTeamMemberRole(memberId, data) {
6839
- return this.adminRequest("PATCH", `/api/v1/team/members/${memberId}/role`, data);
7469
+ return this.adminRequest(
7470
+ "PATCH",
7471
+ `/api/v1/team/members/${encodePathSegment(memberId)}/role`,
7472
+ data
7473
+ );
6840
7474
  }
6841
7475
  /**
6842
7476
  * @deprecated Use `removeStoreMember(storeId, memberId)` instead.
6843
7477
  */
6844
7478
  async removeTeamMember(memberId) {
6845
- await this.adminRequest("DELETE", `/api/v1/team/members/${memberId}`);
7479
+ await this.adminRequest("DELETE", `/api/v1/team/members/${encodePathSegment(memberId)}`);
6846
7480
  }
6847
7481
  // -------------------- Store Team Management (Admin) --------------------
6848
7482
  // Store-level team management. Each store has its own team with roles and permissions.
@@ -6856,7 +7490,10 @@ var BrainerceClient = class {
6856
7490
  * ```
6857
7491
  */
6858
7492
  async getStoreTeam(storeId) {
6859
- return this.adminRequest("GET", `/api/v1/stores/${storeId}/team`);
7493
+ return this.adminRequest(
7494
+ "GET",
7495
+ `/api/v1/stores/${encodePathSegment(storeId)}/team`
7496
+ );
6860
7497
  }
6861
7498
  /**
6862
7499
  * Invite a new member to a store
@@ -6867,13 +7504,16 @@ var BrainerceClient = class {
6867
7504
  * const invitation = await client.inviteStoreMember('store_id', {
6868
7505
  * email: 'newmember@example.com',
6869
7506
  * role: 'MANAGER', // 'MANAGER' | 'STAFF' | 'VIEWER'
7507
+ * // Optional: restrict to specific vibe-coded channels (connectionId, vc_*).
7508
+ * // Omit or pass [] for unrestricted access to all channels.
7509
+ * salesChannelIds: ['vc_abc123', 'vc_def456'],
6870
7510
  * });
6871
7511
  * ```
6872
7512
  */
6873
7513
  async inviteStoreMember(storeId, data) {
6874
7514
  return this.adminRequest(
6875
7515
  "POST",
6876
- `/api/v1/stores/${storeId}/team/invite`,
7516
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invite`,
6877
7517
  data
6878
7518
  );
6879
7519
  }
@@ -6895,7 +7535,33 @@ var BrainerceClient = class {
6895
7535
  async updateStoreMember(storeId, memberId, data) {
6896
7536
  return this.adminRequest(
6897
7537
  "PATCH",
6898
- `/api/v1/stores/${storeId}/team/${memberId}`,
7538
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`,
7539
+ data
7540
+ );
7541
+ }
7542
+ /**
7543
+ * Replace the set of vibe-coded sales channels a store member is restricted to.
7544
+ * Channels are identified by their public `connectionId` (`vc_*` format). Pass
7545
+ * an empty array to clear all restrictions (member becomes unrestricted).
7546
+ * Requires Admin mode (apiKey) and MANAGE_TEAM permission
7547
+ *
7548
+ * @example
7549
+ * ```typescript
7550
+ * // Restrict to two vibe-coded channels
7551
+ * await client.updateStoreMemberSalesChannels('store_id', 'member_id', {
7552
+ * salesChannelIds: ['vc_abc123', 'vc_def456'],
7553
+ * });
7554
+ *
7555
+ * // Clear all restrictions (unrestricted access)
7556
+ * await client.updateStoreMemberSalesChannels('store_id', 'member_id', {
7557
+ * salesChannelIds: [],
7558
+ * });
7559
+ * ```
7560
+ */
7561
+ async updateStoreMemberSalesChannels(storeId, memberId, data) {
7562
+ return this.adminRequest(
7563
+ "PATCH",
7564
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}/sales-channels`,
6899
7565
  data
6900
7566
  );
6901
7567
  }
@@ -6904,7 +7570,10 @@ var BrainerceClient = class {
6904
7570
  * Requires Admin mode (apiKey) and MANAGE_TEAM permission
6905
7571
  */
6906
7572
  async removeStoreMember(storeId, memberId) {
6907
- await this.adminRequest("DELETE", `/api/v1/stores/${storeId}/team/${memberId}`);
7573
+ await this.adminRequest(
7574
+ "DELETE",
7575
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`
7576
+ );
6908
7577
  }
6909
7578
  /**
6910
7579
  * Resend a store invitation email
@@ -6913,7 +7582,7 @@ var BrainerceClient = class {
6913
7582
  async resendStoreInvitation(storeId, invitationId) {
6914
7583
  return this.adminRequest(
6915
7584
  "POST",
6916
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}/resend`
7585
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}/resend`
6917
7586
  );
6918
7587
  }
6919
7588
  /**
@@ -6923,7 +7592,7 @@ var BrainerceClient = class {
6923
7592
  async revokeStoreInvitation(storeId, invitationId) {
6924
7593
  await this.adminRequest(
6925
7594
  "DELETE",
6926
- `/api/v1/stores/${storeId}/team/invitations/${invitationId}`
7595
+ `/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}`
6927
7596
  );
6928
7597
  }
6929
7598
  /**
@@ -6931,14 +7600,20 @@ var BrainerceClient = class {
6931
7600
  * Used on the invitation acceptance page
6932
7601
  */
6933
7602
  async getStoreInvitationByToken(token) {
6934
- return this.request("GET", `/api/v1/store-invitations/${token}`);
7603
+ return this.request(
7604
+ "GET",
7605
+ `/api/v1/store-invitations/${encodePathSegment(token)}`
7606
+ );
6935
7607
  }
6936
7608
  /**
6937
7609
  * Accept a store invitation
6938
7610
  * Requires Admin mode (apiKey)
6939
7611
  */
6940
7612
  async acceptStoreInvitation(token) {
6941
- await this.adminRequest("POST", `/api/v1/store-invitations/${token}/accept`);
7613
+ await this.adminRequest(
7614
+ "POST",
7615
+ `/api/v1/store-invitations/${encodePathSegment(token)}/accept`
7616
+ );
6942
7617
  }
6943
7618
  /**
6944
7619
  * Get all stores accessible to the current user (owned + member of)
@@ -6971,7 +7646,7 @@ var BrainerceClient = class {
6971
7646
  async getMyStorePermissions(storeId) {
6972
7647
  return this.adminRequest(
6973
7648
  "GET",
6974
- `/api/v1/me/stores/${storeId}/permissions`
7649
+ `/api/v1/me/stores/${encodePathSegment(storeId)}/permissions`
6975
7650
  );
6976
7651
  }
6977
7652
  // -------------------- Email Settings & Templates (Admin) --------------------
@@ -7004,7 +7679,10 @@ var BrainerceClient = class {
7004
7679
  * Requires Admin mode (apiKey)
7005
7680
  */
7006
7681
  async getEmailTemplate(templateId) {
7007
- return this.adminRequest("GET", `/api/v1/email/templates/${templateId}`);
7682
+ return this.adminRequest(
7683
+ "GET",
7684
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7685
+ );
7008
7686
  }
7009
7687
  /**
7010
7688
  * Create a new email template
@@ -7028,14 +7706,21 @@ var BrainerceClient = class {
7028
7706
  * Requires Admin mode (apiKey)
7029
7707
  */
7030
7708
  async updateEmailTemplate(templateId, data) {
7031
- return this.adminRequest("PUT", `/api/v1/email/templates/${templateId}`, data);
7709
+ return this.adminRequest(
7710
+ "PUT",
7711
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`,
7712
+ data
7713
+ );
7032
7714
  }
7033
7715
  /**
7034
7716
  * Delete an email template
7035
7717
  * Requires Admin mode (apiKey)
7036
7718
  */
7037
7719
  async deleteEmailTemplate(templateId) {
7038
- await this.adminRequest("DELETE", `/api/v1/email/templates/${templateId}`);
7720
+ await this.adminRequest(
7721
+ "DELETE",
7722
+ `/api/v1/email/templates/${encodePathSegment(templateId)}`
7723
+ );
7039
7724
  }
7040
7725
  /**
7041
7726
  * Preview an email template with sample data
@@ -7044,7 +7729,7 @@ var BrainerceClient = class {
7044
7729
  async previewEmailTemplate(templateId, data) {
7045
7730
  return this.adminRequest(
7046
7731
  "POST",
7047
- `/api/v1/email/templates/${templateId}/preview`,
7732
+ `/api/v1/email/templates/${encodePathSegment(templateId)}/preview`,
7048
7733
  data || {}
7049
7734
  );
7050
7735
  }
@@ -7065,9 +7750,13 @@ var BrainerceClient = class {
7065
7750
  * @param resolution - 'MERGE' to link to existing product, 'CREATE_NEW' to create new product
7066
7751
  */
7067
7752
  async resolveSyncConflict(conflictId, resolution) {
7068
- return this.adminRequest("POST", `/api/v1/sync-conflicts/${conflictId}/resolve`, {
7069
- resolution
7070
- });
7753
+ return this.adminRequest(
7754
+ "POST",
7755
+ `/api/v1/sync-conflicts/${encodePathSegment(conflictId)}/resolve`,
7756
+ {
7757
+ resolution
7758
+ }
7759
+ );
7071
7760
  }
7072
7761
  // -------------------- Metafield Conflicts (Admin) --------------------
7073
7762
  // These methods require Admin mode (apiKey)
@@ -7088,7 +7777,7 @@ var BrainerceClient = class {
7088
7777
  async resolveMetafieldConflict(conflictId, data) {
7089
7778
  return this.adminRequest(
7090
7779
  "POST",
7091
- `/api/v1/metafield-conflicts/${conflictId}/resolve`,
7780
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/resolve`,
7092
7781
  data
7093
7782
  );
7094
7783
  }
@@ -7099,7 +7788,7 @@ var BrainerceClient = class {
7099
7788
  async ignoreMetafieldConflict(conflictId) {
7100
7789
  return this.adminRequest(
7101
7790
  "POST",
7102
- `/api/v1/metafield-conflicts/${conflictId}/ignore`
7791
+ `/api/v1/metafield-conflicts/${encodePathSegment(conflictId)}/ignore`
7103
7792
  );
7104
7793
  }
7105
7794
  // -------------------- OAuth Provider Configuration (Admin) --------------------
@@ -7116,7 +7805,10 @@ var BrainerceClient = class {
7116
7805
  * Requires Admin mode (apiKey)
7117
7806
  */
7118
7807
  async getOAuthProvider(provider) {
7119
- return this.adminRequest("GET", `/api/v1/oauth-providers/${provider}`);
7808
+ return this.adminRequest(
7809
+ "GET",
7810
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7811
+ );
7120
7812
  }
7121
7813
  /**
7122
7814
  * Configure an OAuth provider for customer login
@@ -7142,7 +7834,7 @@ var BrainerceClient = class {
7142
7834
  async updateOAuthProvider(provider, data) {
7143
7835
  return this.adminRequest(
7144
7836
  "PATCH",
7145
- `/api/v1/oauth-providers/${provider}`,
7837
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`,
7146
7838
  data
7147
7839
  );
7148
7840
  }
@@ -7151,7 +7843,10 @@ var BrainerceClient = class {
7151
7843
  * Requires Admin mode (apiKey)
7152
7844
  */
7153
7845
  async deleteOAuthProvider(provider) {
7154
- await this.adminRequest("DELETE", `/api/v1/oauth-providers/${provider}`);
7846
+ await this.adminRequest(
7847
+ "DELETE",
7848
+ `/api/v1/oauth-providers/${encodePathSegment(provider)}`
7849
+ );
7155
7850
  }
7156
7851
  };
7157
7852
  var BrainerceError = class extends Error {
@@ -7248,7 +7943,7 @@ var ALLOWED_PAYMENT_HOSTS = [
7248
7943
  // Brainerce-hosted payment embeds (backend payment-embed proxy at
7249
7944
  // `/api/payment/embed/...` that fronts provider apps' embed shells —
7250
7945
  // e.g. cardcom-payments OpenFields wrapper). The match also covers
7251
- // subdomains like `api.brainerce.com`, `staging.brainerce.com`.
7946
+ // every brainerce.com subdomain (api., docs., …).
7252
7947
  "brainerce.com"
7253
7948
  ];
7254
7949
  function isAllowedPaymentUrl(url, options) {
@@ -7367,7 +8062,9 @@ function getProductPriceInfo(product) {
7367
8062
  if (!product) {
7368
8063
  return { price: 0, originalPrice: 0, isOnSale: false, discountAmount: 0, discountPercent: 0 };
7369
8064
  }
7370
- const resolvedBasePrice = parseFloat(product.basePrice) === 0 && product.priceMin ? product.priceMin : product.basePrice;
8065
+ const parsedBase = parseFloat(product.basePrice);
8066
+ const baseIsUsable = typeof product.basePrice === "string" && product.basePrice.length > 0 && !isNaN(parsedBase) && parsedBase > 0;
8067
+ const resolvedBasePrice = !baseIsUsable && product.priceMin ? product.priceMin : product.basePrice;
7371
8068
  if (product.discount) {
7372
8069
  const ruleOriginal = parseFloat(product.discount.originalPrice) || 0;
7373
8070
  const ruleDiscounted = parseFloat(product.discount.discountedPrice) || 0;