@viu/emporix-sdk 2.5.0 → 2.7.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 (46) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/availability.d.cts +1 -1
  3. package/dist/availability.d.ts +1 -1
  4. package/dist/cart.d.cts +1 -1
  5. package/dist/cart.d.ts +1 -1
  6. package/dist/category.cjs +49 -8
  7. package/dist/category.cjs.map +1 -1
  8. package/dist/category.d.cts +25 -4
  9. package/dist/category.d.ts +25 -4
  10. package/dist/category.js +1 -1
  11. package/dist/checkout.d.cts +1 -1
  12. package/dist/checkout.d.ts +1 -1
  13. package/dist/{chunk-4BJUCCKJ.js → chunk-AUVJ5V47.js} +51 -10
  14. package/dist/chunk-AUVJ5V47.js.map +1 -0
  15. package/dist/companies.d.cts +1 -1
  16. package/dist/companies.d.ts +1 -1
  17. package/dist/contacts.d.cts +1 -1
  18. package/dist/contacts.d.ts +1 -1
  19. package/dist/{context-CgUWXqEt.d.cts → context-DJDTlhLW.d.cts} +30 -1
  20. package/dist/{context-CgUWXqEt.d.ts → context-DJDTlhLW.d.ts} +30 -1
  21. package/dist/customer-groups.d.cts +1 -1
  22. package/dist/customer-groups.d.ts +1 -1
  23. package/dist/customer.d.cts +1 -1
  24. package/dist/customer.d.ts +1 -1
  25. package/dist/index.cjs +97 -11
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +11 -3
  28. package/dist/index.d.ts +11 -3
  29. package/dist/index.js +50 -6
  30. package/dist/index.js.map +1 -1
  31. package/dist/locations.d.cts +1 -1
  32. package/dist/locations.d.ts +1 -1
  33. package/dist/media.d.cts +1 -1
  34. package/dist/media.d.ts +1 -1
  35. package/dist/orders.d.cts +1 -1
  36. package/dist/orders.d.ts +1 -1
  37. package/dist/payment.d.cts +1 -1
  38. package/dist/payment.d.ts +1 -1
  39. package/dist/price.d.cts +1 -1
  40. package/dist/price.d.ts +1 -1
  41. package/dist/product.d.cts +1 -1
  42. package/dist/product.d.ts +1 -1
  43. package/dist/segment.d.cts +1 -1
  44. package/dist/segment.d.ts +1 -1
  45. package/package.json +1 -1
  46. package/dist/chunk-4BJUCCKJ.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -366,6 +366,26 @@ async function resolveToken(ctx, provider) {
366
366
  return ctx.token;
367
367
  }
368
368
  }
369
+ var CustomerRefreshRegistry = class {
370
+ refresher = null;
371
+ inflight = null;
372
+ set(refresher) {
373
+ this.refresher = refresher;
374
+ }
375
+ get enabled() {
376
+ return this.refresher !== null;
377
+ }
378
+ /** Concurrent callers share one in-flight refresh. */
379
+ refresh(expiredToken) {
380
+ if (!this.refresher) return Promise.resolve(null);
381
+ if (this.inflight) return this.inflight;
382
+ const p = Promise.resolve(this.refresher.refresh(expiredToken)).finally(() => {
383
+ this.inflight = null;
384
+ });
385
+ this.inflight = p;
386
+ return p;
387
+ }
388
+ };
369
389
  var DefaultTokenProvider = class {
370
390
  constructor(cfg) {
371
391
  this.cfg = cfg;
@@ -567,8 +587,10 @@ var HttpClient = class {
567
587
  const sdkManaged = o.auth.kind === "service" || o.auth.kind === "anonymous";
568
588
  const maxAttempts = this.opts.retry.maxAttempts;
569
589
  let reauthed = false;
590
+ let customerToken = o.auth.kind === "customer" ? o.auth.token : void 0;
591
+ let customerReauthed = false;
570
592
  for (let attempt = 1; ; attempt++) {
571
- const token = await resolveToken(o.auth, this.opts.provider);
593
+ const token = customerToken ?? await resolveToken(o.auth, this.opts.provider);
572
594
  log.debug("http request", {
573
595
  authKind: o.auth.kind,
574
596
  method: o.method,
@@ -620,6 +642,15 @@ var HttpClient = class {
620
642
  log.warn("sdk-managed 401, re-authing once", { authKind: o.auth.kind });
621
643
  continue;
622
644
  }
645
+ if (o.auth.kind === "customer" && !customerReauthed && this.opts.customerRefresh?.enabled) {
646
+ customerReauthed = true;
647
+ const fresh = await this.opts.customerRefresh.refresh(customerToken);
648
+ if (fresh) {
649
+ customerToken = fresh;
650
+ log.warn("customer 401, refreshed once", { authKind: o.auth.kind });
651
+ continue;
652
+ }
653
+ }
623
654
  throw errorFromResponse(res.status, `${o.method} ${o.path} \u2192 401`, parsed);
624
655
  }
625
656
  const retryable = res.status >= 500 || res.status === 429;
@@ -1093,26 +1124,67 @@ var CategoryService = class {
1093
1124
  const pageSize = params.pageSize ?? 50;
1094
1125
  return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth2));
1095
1126
  }
1096
- /** Fetches the category tree, optionally rooted at `rootId`. */
1097
- async tree(rootId, auth2 = ANON2) {
1127
+ /**
1128
+ * The catalogue's **root categories** — the published category trees
1129
+ * (`GET /category-trees`). Use these for top-level storefront navigation;
1130
+ * drill into a node's children with {@link subcategories}.
1131
+ */
1132
+ async tree(auth2 = ANON2) {
1098
1133
  return this.ctx.http.request({
1099
1134
  method: "GET",
1100
- path: `/category/${this.ctx.tenant}/categories/tree`,
1101
- query: rootId ? { rootId } : {},
1135
+ path: `/category/${this.ctx.tenant}/category-trees`,
1136
+ auth: auth2
1137
+ });
1138
+ }
1139
+ /**
1140
+ * Direct child categories of a category (for hierarchy drill-down). Mirrors
1141
+ * {@link productsIn}: reads the category's **assignments** and keeps the
1142
+ * `CATEGORY` references, resolving them to full categories. Returns an empty
1143
+ * array when the category has no child categories.
1144
+ */
1145
+ async subcategories(categoryId, params = {}, auth2 = ANON2) {
1146
+ const pageNumber = params.pageNumber ?? 1;
1147
+ const pageSize = params.pageSize ?? 50;
1148
+ const assignments = await this.ctx.http.request({
1149
+ method: "GET",
1150
+ path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
1151
+ query: { pageNumber, pageSize },
1102
1152
  auth: auth2
1103
1153
  });
1154
+ const categoryIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "CATEGORY" ? a.ref.id : void 0).filter((id) => Boolean(id));
1155
+ if (categoryIds.length === 0) return [];
1156
+ return this.searchByIds(categoryIds, {}, auth2);
1104
1157
  }
1105
- /** One page of products in a category. */
1158
+ /**
1159
+ * One page of products in a category. The category service exposes products
1160
+ * as **assignments** (`/categories/{id}/assignments`) — references, not full
1161
+ * products — so this fetches a page of assignments, keeps the `PRODUCT`
1162
+ * references, and resolves them to full products via `/products/search`.
1163
+ * `hasNextPage` reflects the assignments page (the source of truth for
1164
+ * pagination).
1165
+ */
1106
1166
  async productsIn(categoryId, params = {}, auth2 = ANON2) {
1107
1167
  const pageNumber = params.pageNumber ?? 1;
1108
1168
  const pageSize = params.pageSize ?? 50;
1109
- const items = await this.ctx.http.request({
1169
+ const assignments = await this.ctx.http.request({
1110
1170
  method: "GET",
1111
- path: `/category/${this.ctx.tenant}/categories/${categoryId}/products`,
1171
+ path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
1112
1172
  query: { pageNumber, pageSize },
1113
1173
  auth: auth2
1114
1174
  });
1115
- return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
1175
+ const hasNextPage = assignments.length === pageSize;
1176
+ const productIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "PRODUCT" ? a.ref.id : void 0).filter((id) => Boolean(id));
1177
+ if (productIds.length === 0) {
1178
+ return { items: [], pageNumber, pageSize, hasNextPage };
1179
+ }
1180
+ const items = await this.ctx.http.request({
1181
+ method: "POST",
1182
+ path: `/product/${this.ctx.tenant}/products/search`,
1183
+ query: { pageSize: productIds.length },
1184
+ auth: auth2,
1185
+ body: { q: `id:(${productIds.join(",")})` }
1186
+ });
1187
+ return { items, pageNumber, pageSize, hasNextPage };
1116
1188
  }
1117
1189
  /**
1118
1190
  * Bulk fetch by id. POSTs `/categories/search` with `q="id:(id1,id2,…)"`,
@@ -4942,7 +5014,7 @@ var ApprovalService = class {
4942
5014
  };
4943
5015
 
4944
5016
  // package.json
4945
- var version = "2.5.0";
5017
+ var version = "2.7.0";
4946
5018
 
4947
5019
  // src/version.ts
4948
5020
  var SDK_VERSION = version;
@@ -5009,6 +5081,7 @@ var EmporixClient = class {
5009
5081
  */
5010
5082
  config;
5011
5083
  resolver;
5084
+ customerRefresh;
5012
5085
  constructor(config) {
5013
5086
  const cfg = validateConfig(config);
5014
5087
  this.tenant = cfg.tenant;
@@ -5030,6 +5103,8 @@ var EmporixClient = class {
5030
5103
  });
5031
5104
  const tokenProvider = cfg.tokenProvider ?? new DefaultTokenProvider(cfg);
5032
5105
  this.tokenProvider = tokenProvider;
5106
+ const customerRefresh = new CustomerRefreshRegistry();
5107
+ this.customerRefresh = customerRefresh;
5033
5108
  const mk = (service) => ({
5034
5109
  tenant: cfg.tenant,
5035
5110
  tokenProvider,
@@ -5039,7 +5114,8 @@ var EmporixClient = class {
5039
5114
  provider: tokenProvider,
5040
5115
  logger: root.child({ service: "http" }),
5041
5116
  retry: cfg.retry,
5042
- timeouts: cfg.timeouts
5117
+ timeouts: cfg.timeouts,
5118
+ customerRefresh
5043
5119
  })
5044
5120
  });
5045
5121
  this.customers = new CustomerService(mk("customer"));
@@ -5098,6 +5174,15 @@ var EmporixClient = class {
5098
5174
  getLogLevel(service) {
5099
5175
  return this.resolver.get(service);
5100
5176
  }
5177
+ /**
5178
+ * Registers (or clears with `null`) a customer-token refresher. When set, a
5179
+ * `customer`-kind 401 triggers one refresh-and-retry. Off by default — the
5180
+ * customer token stays caller-owned. The React `EmporixProvider` wires this
5181
+ * automatically via `autoRefreshCustomerToken`.
5182
+ */
5183
+ setCustomerTokenRefresher(refresher) {
5184
+ this.customerRefresh.set(refresher);
5185
+ }
5101
5186
  };
5102
5187
 
5103
5188
  exports.AiService = AiService;
@@ -5116,6 +5201,7 @@ exports.CouponService = CouponService;
5116
5201
  exports.CurrencyService = CurrencyService;
5117
5202
  exports.CustomerAdminService = CustomerAdminService;
5118
5203
  exports.CustomerGroupsService = CustomerGroupsService;
5204
+ exports.CustomerRefreshRegistry = CustomerRefreshRegistry;
5119
5205
  exports.CustomerService = CustomerService;
5120
5206
  exports.DEFAULT_HOST = DEFAULT_HOST;
5121
5207
  exports.DefaultTokenProvider = DefaultTokenProvider;