@01.software/sdk 0.36.0 → 0.37.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.
Files changed (80) hide show
  1. package/README.md +71 -6
  2. package/dist/analytics/react.cjs +33 -9
  3. package/dist/analytics/react.cjs.map +1 -1
  4. package/dist/analytics/react.d.cts +1 -1
  5. package/dist/analytics/react.d.ts +1 -1
  6. package/dist/analytics/react.js +33 -9
  7. package/dist/analytics/react.js.map +1 -1
  8. package/dist/analytics.cjs +30 -8
  9. package/dist/analytics.cjs.map +1 -1
  10. package/dist/analytics.d.cts +6 -0
  11. package/dist/analytics.d.ts +6 -0
  12. package/dist/analytics.js +30 -8
  13. package/dist/analytics.js.map +1 -1
  14. package/dist/client.cjs +94 -114
  15. package/dist/client.cjs.map +1 -1
  16. package/dist/client.d.cts +6 -6
  17. package/dist/client.d.ts +6 -6
  18. package/dist/client.js +94 -114
  19. package/dist/client.js.map +1 -1
  20. package/dist/{collection-client-Bq5Zd7p7.d.ts → collection-client-DyELGUcL.d.ts} +3 -3
  21. package/dist/{collection-client-Cv0D2w1Q.d.cts → collection-client-zOmnxwdA.d.cts} +3 -3
  22. package/dist/{const-DVcM7Ac_.d.cts → const-CK_FPaIn.d.cts} +3 -3
  23. package/dist/{const-BDUKFP9w.d.ts → const-Dqz05oaG.d.ts} +3 -3
  24. package/dist/{image-BDz2-AaO.d.cts → image-BDjHp03R.d.cts} +13 -9
  25. package/dist/{image-BDz2-AaO.d.ts → image-BDjHp03R.d.ts} +13 -9
  26. package/dist/{index-DTSXUYkr.d.ts → index-DRJs7QIh.d.cts} +9 -6
  27. package/dist/{index-BHDKJ6B3.d.cts → index-DTqoUZk_.d.ts} +9 -6
  28. package/dist/index.cjs +172 -132
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +10 -9
  31. package/dist/index.d.ts +10 -9
  32. package/dist/index.js +172 -132
  33. package/dist/index.js.map +1 -1
  34. package/dist/metadata.cjs +5 -3
  35. package/dist/metadata.cjs.map +1 -1
  36. package/dist/metadata.js +5 -3
  37. package/dist/metadata.js.map +1 -1
  38. package/dist/{payload-types-BCui2Oml.d.cts → payload-types-CREOjFNT.d.cts} +281 -108
  39. package/dist/{payload-types-BCui2Oml.d.ts → payload-types-CREOjFNT.d.ts} +281 -108
  40. package/dist/query.cjs +5 -3
  41. package/dist/query.cjs.map +1 -1
  42. package/dist/query.d.cts +5 -5
  43. package/dist/query.d.ts +5 -5
  44. package/dist/query.js +5 -3
  45. package/dist/query.js.map +1 -1
  46. package/dist/realtime.d.cts +2 -2
  47. package/dist/realtime.d.ts +2 -2
  48. package/dist/server.cjs +84 -69
  49. package/dist/server.cjs.map +1 -1
  50. package/dist/server.d.cts +7 -7
  51. package/dist/server.d.ts +7 -7
  52. package/dist/server.js +84 -69
  53. package/dist/server.js.map +1 -1
  54. package/dist/{types-Dib-zdK6.d.cts → types-BWMUr3Zw.d.cts} +195 -71
  55. package/dist/{types-CEzLf3PX.d.cts → types-BkZNhuBh.d.cts} +1 -1
  56. package/dist/{types-3qV6sY7T.d.ts → types-CxzWHspI.d.ts} +1 -1
  57. package/dist/{types-DK9EnLwJ.d.ts → types-DMvVHdb1.d.ts} +195 -71
  58. package/dist/ui/canvas.cjs +15 -5
  59. package/dist/ui/canvas.cjs.map +1 -1
  60. package/dist/ui/canvas.d.cts +1 -1
  61. package/dist/ui/canvas.d.ts +1 -1
  62. package/dist/ui/canvas.js +15 -5
  63. package/dist/ui/canvas.js.map +1 -1
  64. package/dist/ui/form.d.cts +1 -1
  65. package/dist/ui/form.d.ts +1 -1
  66. package/dist/ui/image.cjs +15 -5
  67. package/dist/ui/image.cjs.map +1 -1
  68. package/dist/ui/image.d.cts +1 -1
  69. package/dist/ui/image.d.ts +1 -1
  70. package/dist/ui/image.js +15 -5
  71. package/dist/ui/image.js.map +1 -1
  72. package/dist/ui/video.d.cts +1 -1
  73. package/dist/ui/video.d.ts +1 -1
  74. package/dist/webhook.cjs +5 -1
  75. package/dist/webhook.cjs.map +1 -1
  76. package/dist/webhook.d.cts +4 -4
  77. package/dist/webhook.d.ts +4 -4
  78. package/dist/webhook.js +5 -1
  79. package/dist/webhook.js.map +1 -1
  80. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -807,13 +807,15 @@ var HttpClient = class {
807
807
  };
808
808
 
809
809
  // src/utils/types.ts
810
- var resolveRelation = (ref) => {
810
+ function resolveRelation(ref) {
811
811
  if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
812
812
  return null;
813
813
  return ref;
814
- };
814
+ }
815
815
 
816
816
  // src/core/metadata/index.ts
817
+ var OPEN_GRAPH_IMAGE_SIZE = "1200";
818
+ var LEGACY_OPEN_GRAPH_IMAGE_SIZE = "1536";
817
819
  function extractSeo(doc) {
818
820
  const seo = doc.seo ?? {};
819
821
  const og = seo.openGraph ?? {};
@@ -857,7 +859,7 @@ function generateMetadata(input, options) {
857
859
  function resolveMetaImage(ref) {
858
860
  const image = resolveRelation(ref);
859
861
  if (!image) return null;
860
- const sized = image.sizes?.["1536"];
862
+ const sized = image.sizes?.[OPEN_GRAPH_IMAGE_SIZE] ?? image.sizes?.[LEGACY_OPEN_GRAPH_IMAGE_SIZE];
861
863
  const url = sized?.url || image.url;
862
864
  if (!url) return null;
863
865
  const width = sized?.url ? sized.width : image.width;
@@ -989,13 +991,16 @@ async function parseApiResponse(response, endpoint) {
989
991
  return data;
990
992
  }
991
993
 
992
- // src/core/community/community-client.ts
993
- var DEFAULT_POST_LIST_SORT = "-lastActivityAt";
994
- var DEFAULT_COMMENT_LIST_SORT = "-createdAt";
995
- var CommunityClient = class {
996
- constructor(options) {
994
+ // src/core/api/customer-scoped-api.ts
995
+ var CustomerScopedApi = class {
996
+ constructor(apiName, options) {
997
+ if (options.requiresCredential !== false && !options.secretKey && !options.customerToken) {
998
+ throw createConfigError(
999
+ `Either secretKey or customerToken is required for ${apiName}.`
1000
+ );
1001
+ }
997
1002
  this.publishableKey = requirePublishableKeyForSecret(
998
- "CommunityClient",
1003
+ apiName,
999
1004
  options.publishableKey,
1000
1005
  options.secretKey
1001
1006
  );
@@ -1005,6 +1010,44 @@ var CommunityClient = class {
1005
1010
  this.onUnauthorized = options.onUnauthorized;
1006
1011
  this.onRequestId = options.onRequestId;
1007
1012
  }
1013
+ async request(endpoint, options) {
1014
+ const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1015
+ try {
1016
+ const response = await httpFetch(endpoint, {
1017
+ method: options.method,
1018
+ apiUrl: this.apiUrl,
1019
+ publishableKey: this.publishableKey,
1020
+ secretKey: this.secretKey,
1021
+ customerToken: token ?? void 0,
1022
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1023
+ ...options.body !== void 0 && {
1024
+ body: JSON.stringify(options.body)
1025
+ },
1026
+ ...options.headers && { headers: options.headers }
1027
+ });
1028
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1029
+ return parseApiResponse(response, endpoint);
1030
+ } catch (err) {
1031
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1032
+ this.onRequestId?.(id);
1033
+ throw err;
1034
+ }
1035
+ }
1036
+ };
1037
+
1038
+ // src/core/community/community-client.ts
1039
+ var DEFAULT_POST_LIST_SORT = "-lastActivityAt";
1040
+ var DEFAULT_COMMENT_LIST_SORT = "-createdAt";
1041
+ function unwrapPayloadDoc(value) {
1042
+ if (value && typeof value === "object" && "doc" in value) {
1043
+ return value.doc;
1044
+ }
1045
+ return value;
1046
+ }
1047
+ var CommunityClient = class extends CustomerScopedApi {
1048
+ constructor(options) {
1049
+ super("CommunityClient", { ...options, requiresCredential: false });
1050
+ }
1008
1051
  buildQuery(params) {
1009
1052
  if (!params) return "";
1010
1053
  const entries = Object.entries(params).filter((e) => e[1] !== void 0).map(([k, v]) => [k, String(v)]);
@@ -1045,27 +1088,14 @@ var CommunityClient = class {
1045
1088
  return `/api/comments?${urlParams.toString()}`;
1046
1089
  }
1047
1090
  async execute(endpoint, method, body) {
1048
- const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1049
- try {
1050
- const response = await httpFetch(endpoint, {
1051
- method,
1052
- apiUrl: this.apiUrl,
1053
- publishableKey: this.publishableKey,
1054
- secretKey: this.secretKey,
1055
- customerToken: token ?? void 0,
1056
- ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1057
- ...body !== void 0 && { body: JSON.stringify(body) }
1058
- });
1059
- this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1060
- return parseApiResponse(response, endpoint);
1061
- } catch (err) {
1062
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1063
- this.onRequestId?.(id);
1064
- throw err;
1065
- }
1091
+ return this.request(endpoint, { method, body });
1092
+ }
1093
+ async executeDoc(endpoint, method, body) {
1094
+ const response = await this.execute(endpoint, method, body);
1095
+ return unwrapPayloadDoc(response);
1066
1096
  }
1067
1097
  createPost(params) {
1068
- return this.execute("/api/posts", "POST", params);
1098
+ return this.executeDoc("/api/posts", "POST", params);
1069
1099
  }
1070
1100
  /**
1071
1101
  * Public post feed. Server applies the same visibility contract as
@@ -1122,7 +1152,7 @@ var CommunityClient = class {
1122
1152
  if (parentId !== void 0) {
1123
1153
  body.parent = parentId;
1124
1154
  }
1125
- return this.execute("/api/comments", "POST", body);
1155
+ return this.executeDoc("/api/comments", "POST", body);
1126
1156
  }
1127
1157
  /**
1128
1158
  * List comments for a post.
@@ -1160,7 +1190,7 @@ var CommunityClient = class {
1160
1190
  }
1161
1191
  updateComment(params) {
1162
1192
  const { commentId, body } = params;
1163
- return this.execute(
1193
+ return this.executeDoc(
1164
1194
  `/api/comments/${commentId}`,
1165
1195
  "PATCH",
1166
1196
  { body }
@@ -1191,7 +1221,7 @@ var CommunityClient = class {
1191
1221
  400
1192
1222
  );
1193
1223
  }
1194
- return this.execute("/api/reactions", "POST", {
1224
+ return this.executeDoc("/api/reactions", "POST", {
1195
1225
  post: postId,
1196
1226
  type: reactionType
1197
1227
  });
@@ -1213,7 +1243,7 @@ var CommunityClient = class {
1213
1243
  400
1214
1244
  );
1215
1245
  }
1216
- return this.execute("/api/reactions", "POST", {
1246
+ return this.executeDoc("/api/reactions", "POST", {
1217
1247
  comment: commentId,
1218
1248
  type: reactionType
1219
1249
  });
@@ -1245,7 +1275,7 @@ var CommunityClient = class {
1245
1275
  }
1246
1276
  // Bookmarks
1247
1277
  addBookmark(params) {
1248
- return this.execute("/api/bookmarks", "POST", {
1278
+ return this.executeDoc("/api/bookmarks", "POST", {
1249
1279
  post: params.postId
1250
1280
  });
1251
1281
  }
@@ -1496,43 +1526,12 @@ var CustomerNamespace = class {
1496
1526
  };
1497
1527
 
1498
1528
  // src/core/api/cart-api.ts
1499
- var CartApi = class {
1529
+ var CartApi = class extends CustomerScopedApi {
1500
1530
  constructor(options) {
1501
- if (!options.secretKey && !options.customerToken) {
1502
- throw createConfigError(
1503
- "Either secretKey or customerToken is required for CartApi."
1504
- );
1505
- }
1506
- this.publishableKey = requirePublishableKeyForSecret(
1507
- "CartApi",
1508
- options.publishableKey,
1509
- options.secretKey
1510
- );
1511
- this.secretKey = options.secretKey;
1512
- this.apiUrl = options.apiUrl;
1513
- this.customerToken = options.customerToken;
1514
- this.onUnauthorized = options.onUnauthorized;
1515
- this.onRequestId = options.onRequestId;
1531
+ super("CartApi", options);
1516
1532
  }
1517
1533
  async execute(endpoint, method, body) {
1518
- const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1519
- try {
1520
- const response = await httpFetch(endpoint, {
1521
- method,
1522
- apiUrl: this.apiUrl,
1523
- publishableKey: this.publishableKey,
1524
- secretKey: this.secretKey,
1525
- customerToken: token ?? void 0,
1526
- ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1527
- ...body !== void 0 && { body: JSON.stringify(body) }
1528
- });
1529
- this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1530
- return parseApiResponse(response, endpoint);
1531
- } catch (err) {
1532
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1533
- this.onRequestId?.(id);
1534
- throw err;
1535
- }
1534
+ return this.request(endpoint, { method, body });
1536
1535
  }
1537
1536
  getCart(cartId) {
1538
1537
  return this.execute(`/api/carts/${cartId}`, "GET");
@@ -1756,15 +1755,24 @@ function splitIdempotencyKey(params) {
1756
1755
  const { idempotencyKey, ...body } = params;
1757
1756
  return { body, idempotencyKey };
1758
1757
  }
1758
+ function normalizeCreateOrderBody(params) {
1759
+ if (params.items !== void 0) {
1760
+ const { idempotencyKey: _idempotencyKey2, items, ...rest } = params;
1761
+ return { ...rest, orderItems: items };
1762
+ }
1763
+ const { idempotencyKey: _idempotencyKey, ...body } = params;
1764
+ return body;
1765
+ }
1759
1766
  var OrderApi = class extends BaseApi {
1760
1767
  constructor(options) {
1761
1768
  super("OrderApi", options);
1762
1769
  }
1763
1770
  createOrder(params) {
1764
- const { body, idempotencyKey } = splitIdempotencyKey(params);
1771
+ const { idempotencyKey } = params;
1772
+ const normalizedBody = normalizeCreateOrderBody(params);
1765
1773
  return this.request(
1766
1774
  "/api/orders/create",
1767
- body,
1775
+ normalizedBody,
1768
1776
  idempotencyRequestOptions(idempotencyKey)
1769
1777
  );
1770
1778
  }
@@ -1826,6 +1834,12 @@ var OrderApi = class extends BaseApi {
1826
1834
  idempotencyRequestOptions(idempotencyKey)
1827
1835
  );
1828
1836
  }
1837
+ prepareFulfillmentOrder(params) {
1838
+ return this.request(
1839
+ "/api/fulfillment-orders/prepare-fulfillment-order",
1840
+ params
1841
+ );
1842
+ }
1829
1843
  updateFulfillment(params) {
1830
1844
  return this.request("/api/orders/update-fulfillment", params);
1831
1845
  }
@@ -1857,6 +1871,18 @@ var OrderApi = class extends BaseApi {
1857
1871
  };
1858
1872
 
1859
1873
  // src/core/commerce/commerce-client.ts
1874
+ var BrowserCommerceApi = class extends CustomerScopedApi {
1875
+ post(endpoint, body, requestOptions) {
1876
+ return this.request(endpoint, {
1877
+ method: "POST",
1878
+ body,
1879
+ headers: requestOptions?.headers
1880
+ });
1881
+ }
1882
+ get(endpoint) {
1883
+ return this.request(endpoint, { method: "GET" });
1884
+ }
1885
+ };
1860
1886
  var CommerceClient = class {
1861
1887
  constructor(options) {
1862
1888
  const cartApi = new CartApi({
@@ -1866,52 +1892,21 @@ var CommerceClient = class {
1866
1892
  onUnauthorized: options.onUnauthorized,
1867
1893
  onRequestId: options.onRequestId
1868
1894
  });
1869
- const execute = async (endpoint, body, requestOptions) => {
1870
- const token = options.customerToken();
1871
- try {
1872
- const response = await httpFetch(endpoint, {
1873
- method: "POST",
1874
- apiUrl: options.apiUrl,
1875
- publishableKey: options.publishableKey,
1876
- customerToken: token ?? void 0,
1877
- ...token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized },
1878
- body: JSON.stringify(body),
1879
- ...requestOptions?.headers && { headers: requestOptions.headers }
1880
- });
1881
- options.onRequestId?.(response.headers.get("x-request-id") ?? null);
1882
- return parseApiResponse(response, endpoint);
1883
- } catch (err) {
1884
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1885
- options.onRequestId?.(id);
1886
- throw err;
1887
- }
1888
- };
1889
- const executeGet = async (endpoint) => {
1890
- const token = options.customerToken();
1891
- try {
1892
- const response = await httpFetch(endpoint, {
1893
- method: "GET",
1894
- apiUrl: options.apiUrl,
1895
- publishableKey: options.publishableKey,
1896
- customerToken: token ?? void 0,
1897
- ...token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized }
1898
- });
1899
- options.onRequestId?.(response.headers.get("x-request-id") ?? null);
1900
- return parseApiResponse(response, endpoint);
1901
- } catch (err) {
1902
- const id = err instanceof SDKError ? err.requestId ?? null : null;
1903
- options.onRequestId?.(id);
1904
- throw err;
1905
- }
1906
- };
1895
+ const api = new BrowserCommerceApi("CommerceClient", {
1896
+ publishableKey: options.publishableKey,
1897
+ apiUrl: options.apiUrl,
1898
+ customerToken: options.customerToken,
1899
+ onUnauthorized: options.onUnauthorized,
1900
+ onRequestId: options.onRequestId
1901
+ });
1907
1902
  this.product = {
1908
- stockCheck: (params) => execute("/api/products/stock-check", params),
1909
- stockSnapshot: (params) => executeGet(stockSnapshotQuery(params)),
1910
- listingGroups: (params) => executeGet(listingGroupsQuery(params)),
1911
- listingGroupsCatalog: (params) => executeGet(listingGroupsCatalogQuery(params)),
1903
+ stockCheck: (params) => api.post("/api/products/stock-check", params),
1904
+ stockSnapshot: (params) => api.get(stockSnapshotQuery(params)),
1905
+ listingGroups: (params) => api.get(listingGroupsQuery(params)),
1906
+ listingGroupsCatalog: (params) => api.get(listingGroupsCatalogQuery(params)),
1912
1907
  detail: async (params) => {
1913
1908
  try {
1914
- const product = await executeGet(productDetailQuery(params));
1909
+ const product = await api.get(productDetailQuery(params));
1915
1910
  return { found: true, product };
1916
1911
  } catch (err) {
1917
1912
  const notFoundResult = productDetailResultFromError(err);
@@ -1921,7 +1916,7 @@ var CommerceClient = class {
1921
1916
  },
1922
1917
  detailCatalog: async (params) => {
1923
1918
  try {
1924
- const product = await executeGet(
1919
+ const product = await api.get(
1925
1920
  productDetailCatalogQuery(params)
1926
1921
  );
1927
1922
  return { found: true, product };
@@ -1944,7 +1939,7 @@ var CommerceClient = class {
1944
1939
  this.orders = {
1945
1940
  checkout: (params) => {
1946
1941
  const { body, idempotencyKey } = splitIdempotencyKey(params);
1947
- return execute(
1942
+ return api.post(
1948
1943
  "/api/orders/checkout",
1949
1944
  body,
1950
1945
  idempotencyRequestOptions(idempotencyKey)
@@ -1953,10 +1948,10 @@ var CommerceClient = class {
1953
1948
  listMine: (params) => options.customerAuth.getMyOrders(params)
1954
1949
  };
1955
1950
  this.discounts = {
1956
- validate: (params) => execute("/api/discounts/validate", params)
1951
+ validate: (params) => api.post("/api/discounts/validate", params)
1957
1952
  };
1958
1953
  this.shipping = {
1959
- calculate: (params) => execute("/api/shipping-policies/calculate", params)
1954
+ calculate: (params) => api.post("/api/shipping-policies/calculate", params)
1960
1955
  };
1961
1956
  }
1962
1957
  };
@@ -2312,7 +2307,7 @@ function getCommerceNotificationIdempotencyKey(event) {
2312
2307
  function defineCommerceEmailConfig(config) {
2313
2308
  return config;
2314
2309
  }
2315
- function createCommerceEmailWebhookHandler(handlers) {
2310
+ function createCommerceNotificationWebhookHandler(handlers) {
2316
2311
  return async (event) => {
2317
2312
  if (!isCommerceNotificationWebhookEvent(event)) {
2318
2313
  await handlers.unhandled?.(event);
@@ -2329,6 +2324,9 @@ function createCommerceEmailWebhookHandler(handlers) {
2329
2324
  });
2330
2325
  };
2331
2326
  }
2327
+ function createCommerceEmailWebhookHandler(handlers) {
2328
+ return createCommerceNotificationWebhookHandler(handlers);
2329
+ }
2332
2330
  function isWebhookCollection(event, collection) {
2333
2331
  return isValidWebhookEvent(event) && event.collection === collection;
2334
2332
  }
@@ -2498,6 +2496,8 @@ var COLLECTIONS = [
2498
2496
  "order-items",
2499
2497
  "returns",
2500
2498
  "return-items",
2499
+ "fulfillment-orders",
2500
+ "fulfillment-order-items",
2501
2501
  "fulfillments",
2502
2502
  "fulfillment-items",
2503
2503
  "transactions",
@@ -4416,6 +4416,12 @@ function maxOfNullable(values) {
4416
4416
  const numbers = values.filter((v) => v !== null);
4417
4417
  return numbers.length === 0 ? null : Math.max(...numbers);
4418
4418
  }
4419
+ var PRODUCT_PLP_FIND_OPTIONS = {
4420
+ joins: {
4421
+ variants: { limit: 200, sort: "_order" },
4422
+ options: { limit: 50, sort: "_order" }
4423
+ }
4424
+ };
4419
4425
  function buildProductListingGroupsByOption(args) {
4420
4426
  const primaryOptionId = args.primaryOptionId ?? void 0;
4421
4427
  if (!primaryOptionId) return [];
@@ -4630,14 +4636,22 @@ function resolveProductGallery(input) {
4630
4636
  }
4631
4637
 
4632
4638
  // src/utils/image.ts
4633
- var IMAGE_SIZES = [384, 768, 1536];
4639
+ var IMAGE_SIZES = [200, 400, 800, 1200, 1600];
4640
+ function imageSizeCandidates(sizes) {
4641
+ const keys = new Set(IMAGE_SIZES);
4642
+ for (const key of Object.keys(sizes)) {
4643
+ const value = Number(key);
4644
+ if (Number.isFinite(value) && value > 0) keys.add(value);
4645
+ }
4646
+ return [...keys].sort((a, b) => a - b);
4647
+ }
4634
4648
  function getImageUrl(image, displayWidth, dpr = 1) {
4635
4649
  const target = displayWidth * dpr;
4636
4650
  const sizes = image.sizes;
4637
4651
  if (sizes) {
4638
- for (const size of IMAGE_SIZES) {
4652
+ for (const size of imageSizeCandidates(sizes)) {
4639
4653
  if (size >= target) {
4640
- const entry = sizes[String(size)];
4654
+ const entry = sizes[`${size}`];
4641
4655
  if (entry?.url) return entry.url;
4642
4656
  }
4643
4657
  }
@@ -4646,16 +4660,18 @@ function getImageUrl(image, displayWidth, dpr = 1) {
4646
4660
  }
4647
4661
  function getImageSrcSet(image) {
4648
4662
  const parts = [];
4663
+ const emittedWidths = /* @__PURE__ */ new Set();
4649
4664
  const sizes = image.sizes;
4650
4665
  if (sizes) {
4651
- for (const size of IMAGE_SIZES) {
4652
- const entry = sizes[String(size)];
4653
- if (entry?.url && entry.width) {
4666
+ for (const size of imageSizeCandidates(sizes)) {
4667
+ const entry = sizes[`${size}`];
4668
+ if (entry?.url && entry.width && !emittedWidths.has(entry.width)) {
4669
+ emittedWidths.add(entry.width);
4654
4670
  parts.push(`${entry.url} ${entry.width}w`);
4655
4671
  }
4656
4672
  }
4657
4673
  }
4658
- if (image.url && image.width) {
4674
+ if (image.url && image.width && !emittedWidths.has(image.width)) {
4659
4675
  parts.push(`${image.url} ${image.width}w`);
4660
4676
  }
4661
4677
  return parts.join(", ");
@@ -4757,6 +4773,27 @@ function createAnalytics(config) {
4757
4773
  const nav = navigator;
4758
4774
  return nav.doNotTrack === "1" || nav.globalPrivacyControl === true;
4759
4775
  }
4776
+ const isLocalHost = (() => {
4777
+ try {
4778
+ const h = location.hostname;
4779
+ return h === "localhost" || h === "127.0.0.1" || h.endsWith(".local");
4780
+ } catch {
4781
+ return false;
4782
+ }
4783
+ })();
4784
+ const mode = config.mode ?? "auto";
4785
+ const sendSuppressed = mode === "development" || mode === "auto" && isLocalHost;
4786
+ let suppressNoticeShown = false;
4787
+ function devSuppressNotice() {
4788
+ if (suppressNoticeShown) return;
4789
+ suppressNoticeShown = true;
4790
+ try {
4791
+ console.info(
4792
+ `[01 analytics] events disabled on local host (mode: '${mode}'). Pass mode: 'production' to send while developing.`
4793
+ );
4794
+ } catch {
4795
+ }
4796
+ }
4760
4797
  let lastPath = null;
4761
4798
  let lastAt = 0;
4762
4799
  const autoTrack = config.autoTrack !== false;
@@ -4787,6 +4824,10 @@ function createAnalytics(config) {
4787
4824
  if (isDntActive()) return;
4788
4825
  const doc = document;
4789
4826
  if (doc.prerendering === true || document.visibilityState === "prerender") return;
4827
+ if (sendSuppressed) {
4828
+ devSuppressNotice();
4829
+ return;
4830
+ }
4790
4831
  const now = Date.now();
4791
4832
  if (pathname === lastPath && now - lastAt < 500) return;
4792
4833
  lastPath = pathname;
@@ -4822,14 +4863,7 @@ function createAnalytics(config) {
4822
4863
  window.addEventListener("load", trackCurrentPath, { once: true });
4823
4864
  }
4824
4865
  }
4825
- const isProduction = (() => {
4826
- try {
4827
- const hostname = location.hostname;
4828
- return hostname !== "localhost" && hostname !== "127.0.0.1" && !hostname.endsWith(".local");
4829
- } catch {
4830
- return true;
4831
- }
4832
- })();
4866
+ const isProduction = !isLocalHost;
4833
4867
  const warnedReasons = /* @__PURE__ */ new Set();
4834
4868
  function devWarn(name, reason) {
4835
4869
  if (isProduction) return;
@@ -4889,6 +4923,10 @@ function createAnalytics(config) {
4889
4923
  return;
4890
4924
  }
4891
4925
  }
4926
+ if (sendSuppressed) {
4927
+ devSuppressNotice();
4928
+ return;
4929
+ }
4892
4930
  const body = JSON.stringify({
4893
4931
  publishableKey: config.publishableKey,
4894
4932
  pathname: location.pathname,
@@ -4943,6 +4981,7 @@ export {
4943
4981
  NotFoundError,
4944
4982
  ORDER_CHANGED_EVENT_TYPE,
4945
4983
  OrderApi,
4984
+ PRODUCT_PLP_FIND_OPTIONS,
4946
4985
  PRODUCT_UPSERT_READONLY_FIELD_REASON,
4947
4986
  PRODUCT_UPSERT_UNKNOWN_FIELD_REASON,
4948
4987
  PermissionError,
@@ -4968,6 +5007,7 @@ export {
4968
5007
  createAuthError,
4969
5008
  createClient2 as createClient,
4970
5009
  createCommerceEmailWebhookHandler,
5010
+ createCommerceNotificationWebhookHandler,
4971
5011
  createConflictError,
4972
5012
  createCustomerAuthWebhookHandler,
4973
5013
  createNotFoundError,