@viu/emporix-sdk 2.10.0 → 2.12.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @viu/emporix-sdk
2
2
 
3
+ ## 2.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#116](https://github.com/viuteam/emporix-sdk/pull/116) [`5411502`](https://github.com/viuteam/emporix-sdk/commit/5411502fdde0737ad457812e28a86c505f938282) Thanks [@amnael1](https://github.com/amnael1)! - Add a runtime language switch. `client.setStorefrontContext({ language })` now sets an `Accept-Language` header on every read. React's `useSiteContext()` exposes `language` + `setLanguage(lang)` (modeled on `setCurrency`), persists the choice via `EmporixStorage` (`emporix.language`), mirrors it into the server session context, and keys localized reads (products, categories, segments, cart, shopping lists, orders) by language so the cache never serves stale-language text. A new `initialLanguage` provider prop seeds the active language.
8
+
9
+ ## 2.11.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#114](https://github.com/viuteam/emporix-sdk/pull/114) [`ac2b2c8`](https://github.com/viuteam/emporix-sdk/commit/ac2b2c890521da017b3ef44ff15bdf6b16d69bb9) Thanks [@amnael1](https://github.com/amnael1)! - feat: invoke Emporix cloud functions
14
+
15
+ Adds `client.cloudFunctions.invoke<TRes, TReq>(functionId, { method?, path?,
16
+ body?, query?, headers? }, auth)` — a generic call to tenant cloud functions
17
+ (`/cloud-functions/{tenant}/functions/{id}[/sub]`), with GET/POST/PUT/DELETE and
18
+ service / customer / anonymous / raw auth (default anonymous). Adds the React
19
+ hooks `useInvokeCloudFunction` (mutation, any method) and `useCloudFunction`
20
+ (GET-style query with caching), both with auto-auth (customer-if-token-else-
21
+ anonymous) and an optional override.
22
+
3
23
  ## 2.10.0
4
24
 
5
25
  ### Minor Changes
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
 
3
3
  type DistributionChannel = 'ASSORTMENT' | 'HOME_DELIVERY' | 'PICKUP';
4
4
  type Availability$1 = {
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.js';
2
2
 
3
3
  type DistributionChannel = 'ASSORTMENT' | 'HOME_DELIVERY' | 'PICKUP';
4
4
  type Availability$1 = {
package/dist/cart.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
 
3
3
  /**
4
4
  * Access control identifier that determines who can view or manage the cart.
package/dist/cart.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.js';
2
2
 
3
3
  /**
4
4
  * Access control identifier that determines who can view or manage the cart.
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-CD7F_LHT.cjs';
2
2
  import { Product } from './product.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-CD7F_LHT.js';
2
2
  import { Product } from './product.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
 
3
3
  /**
4
4
  * Information about the customer's address.
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.js';
2
2
 
3
3
  /**
4
4
  * Information about the customer's address.
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
  import { L as LegalEntity, e as LegalEntityCreate, f as LegalEntityUpdate } from './types.gen-C_wOXYZB.cjs';
3
3
  export { A as AccountLimit, d as CustomerGroup, g as LegalInfo } from './types.gen-C_wOXYZB.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.js';
2
2
  import { L as LegalEntity, e as LegalEntityCreate, f as LegalEntityUpdate } from './types.gen-C_wOXYZB.js';
3
3
  export { A as AccountLimit, d as CustomerGroup, g as LegalInfo } from './types.gen-C_wOXYZB.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
  import { C as ContactAssignment, a as ContactAssignmentCreate, b as ContactAssignmentUpdate } from './types.gen-C_wOXYZB.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.js';
2
2
  import { C as ContactAssignment, a as ContactAssignmentCreate, b as ContactAssignmentUpdate } from './types.gen-C_wOXYZB.js';
3
3
 
4
4
  /**
@@ -3,7 +3,7 @@ type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "silent";
3
3
  /** Numeric ordering used for fast comparison. */
4
4
  declare const LEVEL: Record<LogLevel, number>;
5
5
  /** Services that bind their own logger and are independently level-controllable. */
6
- type ServiceName = "customer" | "product" | "category" | "cart" | "checkout" | "payment" | "price" | "media" | "segment" | "site" | "session-context" | "customer-management" | "iam" | "orders" | "sales-orders" | "availability" | "configuration" | "shopping-list" | "ai-rag-indexer" | "sequential-id" | "fee" | "webhook" | "schema" | "ai" | "tax" | "coupon" | "reward-points" | "brand" | "label" | "country" | "currency" | "shipping" | "returns" | "sepa-export" | "indexing" | "unit-handling" | "catalog" | "vendor" | "pick-pack" | "customer-admin" | "approval" | "http" | "auth";
6
+ type ServiceName = "customer" | "product" | "category" | "cart" | "checkout" | "payment" | "price" | "media" | "segment" | "site" | "session-context" | "customer-management" | "iam" | "orders" | "sales-orders" | "availability" | "configuration" | "shopping-list" | "ai-rag-indexer" | "sequential-id" | "fee" | "webhook" | "schema" | "ai" | "tax" | "coupon" | "reward-points" | "brand" | "label" | "country" | "currency" | "shipping" | "returns" | "sepa-export" | "indexing" | "unit-handling" | "catalog" | "vendor" | "pick-pack" | "customer-admin" | "approval" | "cloud-functions" | "http" | "auth";
7
7
  /** Arbitrary structured fields attached to a log line. */
8
8
  interface LogFields {
9
9
  [key: string]: unknown;
@@ -93,6 +93,7 @@ interface StorefrontCredentials {
93
93
  currency?: string;
94
94
  siteCode?: string;
95
95
  targetLocation?: string;
96
+ language?: string;
96
97
  };
97
98
  }
98
99
  /** User-supplied SDK configuration. */
@@ -335,12 +336,21 @@ interface HttpClientOptions {
335
336
  sleep?: (ms: number) => Promise<void>;
336
337
  /** Opt-in customer-token refresher registry (off unless a refresher is set). */
337
338
  customerRefresh?: CustomerRefreshRegistry;
339
+ /**
340
+ * Shared storefront request context. When `language` is set, every request
341
+ * carries `Accept-Language: <language>`. Mutated at runtime via
342
+ * `EmporixClient.setStorefrontContext({ language })`.
343
+ */
344
+ requestContext?: {
345
+ language?: string | undefined;
346
+ };
338
347
  }
339
348
  /** Fetch wrapper: auth resolution, JSON parsing, typed error mapping, logging. */
340
349
  declare class HttpClient {
341
350
  private readonly opts;
342
351
  private readonly sleep;
343
352
  constructor(opts: HttpClientOptions);
353
+ private buildHeaders;
344
354
  request<T = unknown>(o: RequestOptions): Promise<T>;
345
355
  /**
346
356
  * Single-shot fetch that returns the raw {@link Response} unparsed. Used by
@@ -3,7 +3,7 @@ type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "silent";
3
3
  /** Numeric ordering used for fast comparison. */
4
4
  declare const LEVEL: Record<LogLevel, number>;
5
5
  /** Services that bind their own logger and are independently level-controllable. */
6
- type ServiceName = "customer" | "product" | "category" | "cart" | "checkout" | "payment" | "price" | "media" | "segment" | "site" | "session-context" | "customer-management" | "iam" | "orders" | "sales-orders" | "availability" | "configuration" | "shopping-list" | "ai-rag-indexer" | "sequential-id" | "fee" | "webhook" | "schema" | "ai" | "tax" | "coupon" | "reward-points" | "brand" | "label" | "country" | "currency" | "shipping" | "returns" | "sepa-export" | "indexing" | "unit-handling" | "catalog" | "vendor" | "pick-pack" | "customer-admin" | "approval" | "http" | "auth";
6
+ type ServiceName = "customer" | "product" | "category" | "cart" | "checkout" | "payment" | "price" | "media" | "segment" | "site" | "session-context" | "customer-management" | "iam" | "orders" | "sales-orders" | "availability" | "configuration" | "shopping-list" | "ai-rag-indexer" | "sequential-id" | "fee" | "webhook" | "schema" | "ai" | "tax" | "coupon" | "reward-points" | "brand" | "label" | "country" | "currency" | "shipping" | "returns" | "sepa-export" | "indexing" | "unit-handling" | "catalog" | "vendor" | "pick-pack" | "customer-admin" | "approval" | "cloud-functions" | "http" | "auth";
7
7
  /** Arbitrary structured fields attached to a log line. */
8
8
  interface LogFields {
9
9
  [key: string]: unknown;
@@ -93,6 +93,7 @@ interface StorefrontCredentials {
93
93
  currency?: string;
94
94
  siteCode?: string;
95
95
  targetLocation?: string;
96
+ language?: string;
96
97
  };
97
98
  }
98
99
  /** User-supplied SDK configuration. */
@@ -335,12 +336,21 @@ interface HttpClientOptions {
335
336
  sleep?: (ms: number) => Promise<void>;
336
337
  /** Opt-in customer-token refresher registry (off unless a refresher is set). */
337
338
  customerRefresh?: CustomerRefreshRegistry;
339
+ /**
340
+ * Shared storefront request context. When `language` is set, every request
341
+ * carries `Accept-Language: <language>`. Mutated at runtime via
342
+ * `EmporixClient.setStorefrontContext({ language })`.
343
+ */
344
+ requestContext?: {
345
+ language?: string | undefined;
346
+ };
338
347
  }
339
348
  /** Fetch wrapper: auth resolution, JSON parsing, typed error mapping, logging. */
340
349
  declare class HttpClient {
341
350
  private readonly opts;
342
351
  private readonly sleep;
343
352
  constructor(opts: HttpClientOptions);
353
+ private buildHeaders;
344
354
  request<T = unknown>(o: RequestOptions): Promise<T>;
345
355
  /**
346
356
  * Single-shot fetch that returns the raw {@link Response} unparsed. Used by
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
 
3
3
  type AssignmentCreateRequest = {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-CD7F_LHT.js';
2
2
 
3
3
  type AssignmentCreateRequest = {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-BBKOwNW6.cjs';
1
+ import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-CD7F_LHT.cjs';
2
2
 
3
3
  type AccountId = {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-BBKOwNW6.js';
1
+ import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-CD7F_LHT.js';
2
2
 
3
3
  type AccountId = {
4
4
  /**
package/dist/index.cjs CHANGED
@@ -583,6 +583,16 @@ var HttpClient = class {
583
583
  }
584
584
  opts;
585
585
  sleep;
586
+ buildHeaders(o, token, isFormData) {
587
+ return {
588
+ ...this.opts.requestContext?.language ? { "Accept-Language": this.opts.requestContext.language } : {},
589
+ ...o.headers ?? {},
590
+ Authorization: `Bearer ${token}`,
591
+ // JSON bodies: set Content-Type. FormData bodies: let `fetch`
592
+ // emit `multipart/form-data; boundary=...` itself.
593
+ ...o.body !== void 0 && !isFormData ? { "Content-Type": "application/json" } : {}
594
+ };
595
+ }
586
596
  async request(o) {
587
597
  const requestId = `req-${++requestSeq}`;
588
598
  const log = this.opts.logger.child({ requestId });
@@ -611,13 +621,7 @@ var HttpClient = class {
611
621
  const isFormData = typeof FormData !== "undefined" && o.body instanceof FormData;
612
622
  const init = {
613
623
  method: o.method,
614
- headers: {
615
- ...o.headers ?? {},
616
- Authorization: `Bearer ${token}`,
617
- // JSON bodies: set Content-Type. FormData bodies: let `fetch`
618
- // emit `multipart/form-data; boundary=...` itself.
619
- ...o.body !== void 0 && !isFormData ? { "Content-Type": "application/json" } : {}
620
- },
624
+ headers: this.buildHeaders(o, token, isFormData),
621
625
  signal: controller.signal
622
626
  };
623
627
  if (o.body !== void 0) {
@@ -705,11 +709,7 @@ var HttpClient = class {
705
709
  const isFormData = typeof FormData !== "undefined" && o.body instanceof FormData;
706
710
  const init = {
707
711
  method: o.method,
708
- headers: {
709
- ...o.headers ?? {},
710
- Authorization: `Bearer ${token}`,
711
- ...o.body !== void 0 && !isFormData ? { "Content-Type": "application/json" } : {}
712
- },
712
+ headers: this.buildHeaders(o, token, isFormData),
713
713
  signal: controller.signal,
714
714
  ...extra?.redirect ? { redirect: extra.redirect } : {}
715
715
  };
@@ -2902,6 +2902,28 @@ var FeeService = class {
2902
2902
  }
2903
2903
  };
2904
2904
 
2905
+ // src/services/cloud-functions.ts
2906
+ var CloudFunctionsService = class {
2907
+ constructor(ctx) {
2908
+ this.ctx = ctx;
2909
+ }
2910
+ ctx;
2911
+ base() {
2912
+ return `/cloud-functions/${this.ctx.tenant}/functions`;
2913
+ }
2914
+ async invoke(functionId, options = {}, authCtx = auth.anonymous()) {
2915
+ const sub = options.path ? `/${options.path.replace(/^\//, "")}` : "";
2916
+ return this.ctx.http.request({
2917
+ method: options.method ?? "POST",
2918
+ path: `${this.base()}/${functionId}${sub}`,
2919
+ auth: authCtx,
2920
+ ...options.body !== void 0 ? { body: options.body } : {},
2921
+ ...options.query ? { query: options.query } : {},
2922
+ ...options.headers ? { headers: options.headers } : {}
2923
+ });
2924
+ }
2925
+ };
2926
+
2905
2927
  // src/services/webhook.ts
2906
2928
  var SERVICE8 = { kind: "service" };
2907
2929
  var WebhookService = class {
@@ -5074,7 +5096,7 @@ var ApprovalService = class {
5074
5096
  };
5075
5097
 
5076
5098
  // package.json
5077
- var version = "2.10.0";
5099
+ var version = "2.12.0";
5078
5100
 
5079
5101
  // src/version.ts
5080
5102
  var SDK_VERSION = version;
@@ -5105,6 +5127,7 @@ var EmporixClient = class {
5105
5127
  ragIndexer;
5106
5128
  sequentialIds;
5107
5129
  fees;
5130
+ cloudFunctions;
5108
5131
  webhooks;
5109
5132
  schemas;
5110
5133
  ai;
@@ -5142,6 +5165,7 @@ var EmporixClient = class {
5142
5165
  config;
5143
5166
  resolver;
5144
5167
  customerRefresh;
5168
+ requestContext;
5145
5169
  constructor(config) {
5146
5170
  const cfg = validateConfig(config);
5147
5171
  this.tenant = cfg.tenant;
@@ -5165,6 +5189,8 @@ var EmporixClient = class {
5165
5189
  this.tokenProvider = tokenProvider;
5166
5190
  const customerRefresh = new CustomerRefreshRegistry();
5167
5191
  this.customerRefresh = customerRefresh;
5192
+ this.requestContext = { language: cfg.credentials.storefront?.context?.language };
5193
+ const requestContext = this.requestContext;
5168
5194
  const mk = (service) => ({
5169
5195
  tenant: cfg.tenant,
5170
5196
  tokenProvider,
@@ -5175,7 +5201,8 @@ var EmporixClient = class {
5175
5201
  logger: root.child({ service: "http" }),
5176
5202
  retry: cfg.retry,
5177
5203
  timeouts: cfg.timeouts,
5178
- customerRefresh
5204
+ customerRefresh,
5205
+ requestContext
5179
5206
  })
5180
5207
  });
5181
5208
  this.customers = new CustomerService(mk("customer"));
@@ -5205,6 +5232,7 @@ var EmporixClient = class {
5205
5232
  this.ragIndexer = new RagIndexerService(mk("ai-rag-indexer"));
5206
5233
  this.sequentialIds = new SequentialIdService(mk("sequential-id"));
5207
5234
  this.fees = new FeeService(mk("fee"));
5235
+ this.cloudFunctions = new CloudFunctionsService(mk("cloud-functions"));
5208
5236
  this.webhooks = new WebhookService(mk("webhook"));
5209
5237
  this.schemas = new SchemaService(mk("schema"));
5210
5238
  this.ai = new AiService(mk("ai"));
@@ -5232,9 +5260,18 @@ var EmporixClient = class {
5232
5260
  * next request re-mints a token bound to the new context. Use this to switch
5233
5261
  * currency at runtime. Carts are currency-bound — clear the cart after a
5234
5262
  * currency change (the React `setCurrency` does this for you).
5263
+ *
5264
+ * Also sets the storefront `language` (an `Accept-Language` header on every
5265
+ * read); a language-only change does NOT re-mint the token.
5235
5266
  */
5236
5267
  setStorefrontContext(ctx) {
5237
- this.tokenProvider.setAnonymousContext?.(ctx);
5268
+ if (ctx.language !== void 0) {
5269
+ this.requestContext.language = ctx.language || void 0;
5270
+ }
5271
+ const { language: _language, ...priceContext } = ctx;
5272
+ if (Object.keys(priceContext).length > 0) {
5273
+ this.tokenProvider.setAnonymousContext?.(priceContext);
5274
+ }
5238
5275
  }
5239
5276
  /** Sets the runtime log level globally or for one service. */
5240
5277
  setLogLevel(level, opts = {}) {
@@ -5271,6 +5308,7 @@ exports.CatalogService = CatalogService;
5271
5308
  exports.CategoryService = CategoryService;
5272
5309
  exports.CheckoutService = CheckoutService;
5273
5310
  exports.ClientConfigService = ClientConfigService;
5311
+ exports.CloudFunctionsService = CloudFunctionsService;
5274
5312
  exports.CompaniesService = CompaniesService;
5275
5313
  exports.ContactsService = ContactsService;
5276
5314
  exports.CountryService = CountryService;