@viu/emporix-sdk 2.1.0 → 2.2.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 +20 -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.d.cts +1 -1
  7. package/dist/category.d.ts +1 -1
  8. package/dist/checkout.d.cts +1 -1
  9. package/dist/checkout.d.ts +1 -1
  10. package/dist/{chunk-JTJV7WUW.js → chunk-5JHTZBOC.js} +42 -2
  11. package/dist/chunk-5JHTZBOC.js.map +1 -0
  12. package/dist/companies.d.cts +1 -1
  13. package/dist/companies.d.ts +1 -1
  14. package/dist/contacts.d.cts +1 -1
  15. package/dist/contacts.d.ts +1 -1
  16. package/dist/{context-CGuxSb56.d.cts → context-Bs5ZSwds.d.cts} +1 -1
  17. package/dist/{context-CGuxSb56.d.ts → context-Bs5ZSwds.d.ts} +1 -1
  18. package/dist/customer-groups.d.cts +1 -1
  19. package/dist/customer-groups.d.ts +1 -1
  20. package/dist/customer.d.cts +1 -1
  21. package/dist/customer.d.ts +1 -1
  22. package/dist/index.cjs +170 -6
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +121 -3
  25. package/dist/index.d.ts +121 -3
  26. package/dist/index.js +131 -9
  27. package/dist/index.js.map +1 -1
  28. package/dist/locations.d.cts +1 -1
  29. package/dist/locations.d.ts +1 -1
  30. package/dist/media.d.cts +1 -1
  31. package/dist/media.d.ts +1 -1
  32. package/dist/orders.d.cts +1 -1
  33. package/dist/orders.d.ts +1 -1
  34. package/dist/payment.d.cts +1 -1
  35. package/dist/payment.d.ts +1 -1
  36. package/dist/price.d.cts +1 -1
  37. package/dist/price.d.ts +1 -1
  38. package/dist/product.cjs +40 -0
  39. package/dist/product.cjs.map +1 -1
  40. package/dist/product.d.cts +14 -1
  41. package/dist/product.d.ts +14 -1
  42. package/dist/product.js +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-JTJV7WUW.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @viu/emporix-sdk
2
2
 
3
+ ## 2.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#61](https://github.com/viuteam/emporix-sdk/pull/61) [`4a869c9`](https://github.com/viuteam/emporix-sdk/commit/4a869c9aa60cce99b79b41b8470af367e1b4e249) Thanks [@amnael1](https://github.com/amnael1)! - Add Configuration Service bindings: `client.tenantConfig` and
8
+ `client.clientConfig` provide full CRUD (`list`/`get`/`create`/`update`/`delete`)
9
+ over tenant-wide and per-client configuration. Server-side only — these use the
10
+ service (clientCredentials) token and must not be called from a browser.
11
+
12
+ - [#63](https://github.com/viuteam/emporix-sdk/pull/63) [`bb2ce4f`](https://github.com/viuteam/emporix-sdk/commit/bb2ce4f891e50e07cee02e03340d2abe1133fdc0) Thanks [@amnael1](https://github.com/amnael1)! - Add `products.searchByCodes(codes, { chunkSize? })` — bulk-fetch products by
13
+ `code` via `POST /products/search` (`q="code:(…)"`), chunked at 100, analogous
14
+ to `searchByIds`. Codes with query-delimiter characters are dropped with a
15
+ warning. Adds the `useProductsByCodes` React hook (30s stale-time).
16
+
17
+ ### Patch Changes
18
+
19
+ - [#62](https://github.com/viuteam/emporix-sdk/pull/62) [`9747445`](https://github.com/viuteam/emporix-sdk/commit/9747445c13a27319462755c5333c9ae0a4741e68) Thanks [@amnael1](https://github.com/amnael1)! - Report the real package version as `sdkVersion` on every log line instead of the
20
+ hardcoded `0.0.0` placeholder. The version is now read from `package.json` and
21
+ inlined at build time (browser-safe, no runtime filesystem access).
22
+
3
23
  ## 2.1.0
4
24
 
5
25
  ### Minor Changes
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.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-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.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-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.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-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.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-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-Bs5ZSwds.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-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-Bs5ZSwds.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-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.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-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.js';
2
2
 
3
3
  /**
4
4
  * Information about the customer's address.
@@ -82,6 +82,46 @@ var ProductService = class {
82
82
  );
83
83
  return pages.flat();
84
84
  }
85
+ /**
86
+ * Bulk fetch by code. POSTs `/products/search` with `q="code:(c1,c2,…)"`,
87
+ * chunking when the list is larger than `options.chunkSize` (default 100).
88
+ * Duplicate codes are de-duplicated. Codes containing query-delimiter
89
+ * characters (`(`, `)`, `,`, whitespace, `"`) are dropped with a logged
90
+ * warning, because the Emporix `q` syntax uses them as delimiters and does
91
+ * not support escaping them in a plain IN-list. An empty list — or one with
92
+ * no safe codes — short-circuits with no HTTP call. **Order is not
93
+ * guaranteed** across chunks — re-index by `code` if order matters.
94
+ */
95
+ async searchByCodes(codes, options = {}, auth = ANON) {
96
+ const unique = [...new Set(codes)];
97
+ const unsafe = /[(),"\s]/;
98
+ const safe = unique.filter((c) => !unsafe.test(c));
99
+ const dropped = unique.filter((c) => unsafe.test(c));
100
+ if (dropped.length > 0) {
101
+ this.ctx.logger.warn(
102
+ "products.searchByCodes: dropped codes containing query-delimiter characters",
103
+ { dropped }
104
+ );
105
+ }
106
+ if (safe.length === 0) return [];
107
+ const chunkSize = options.chunkSize ?? 100;
108
+ const chunks = [];
109
+ for (let i = 0; i < safe.length; i += chunkSize) {
110
+ chunks.push(safe.slice(i, i + chunkSize));
111
+ }
112
+ const pages = await Promise.all(
113
+ chunks.map(
114
+ (chunk) => this.ctx.http.request({
115
+ method: "POST",
116
+ path: `/product/${this.ctx.tenant}/products/search`,
117
+ query: { pageSize: chunk.length },
118
+ auth,
119
+ body: { q: `code:(${chunk.join(",")})` }
120
+ })
121
+ )
122
+ );
123
+ return pages.flat();
124
+ }
85
125
  /**
86
126
  * Streams the VARIANT children of a PARENT_VARIANT product, page by page,
87
127
  * via the search query `productType:VARIANT parentVariantId:<id>`. Default
@@ -108,5 +148,5 @@ var ProductService = class {
108
148
  };
109
149
 
110
150
  export { ProductService };
111
- //# sourceMappingURL=chunk-JTJV7WUW.js.map
112
- //# sourceMappingURL=chunk-JTJV7WUW.js.map
151
+ //# sourceMappingURL=chunk-5JHTZBOC.js.map
152
+ //# sourceMappingURL=chunk-5JHTZBOC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/product.ts"],"names":[],"mappings":"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","file":"chunk-5JHTZBOC.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n BasicProductWithId,\n BundleProductWithId,\n ParentVariantProductWithId,\n ProductMedia,\n} from \"../generated/product\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/** A product as returned by the Product service (all generated fields). */\nexport type Product = BasicProductWithId | BundleProductWithId | ParentVariantProductWithId;\n\n/** A single product media entry (generated; `ProductMedia` is the list type). */\nexport type Media = ProductMedia[number];\n\n/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */\nexport class ProductService {\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one product by id. */\n async get(\n productId: string,\n _opts?: Record<string, never>,\n auth: AuthContext = ANON,\n ): Promise<Product> {\n return this.ctx.http.request<Product>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n auth,\n });\n }\n\n /** Fetches one product by its code. */\n async getByCode(code: string, auth: AuthContext = ANON): Promise<Product> {\n const rows = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: `code:${code}` },\n auth,\n });\n const first = rows[0];\n if (!first) throw new Error(`No product with code \"${code}\"`);\n return first;\n }\n\n /** One page of products. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every product across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Product>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /** Searches products by free-text query. */\n async search(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: query, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Bulk fetch by id. POSTs `/products/search` with `q=\"id:(id1,id2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default\n * 100). An empty list short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `id` if order matters.\n */\n async searchByIds(\n ids: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n if (ids.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < ids.length; i += chunkSize) {\n chunks.push(ids.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `id:(${chunk.join(\",\")})` },\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Bulk fetch by code. POSTs `/products/search` with `q=\"code:(c1,c2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default 100).\n * Duplicate codes are de-duplicated. Codes containing query-delimiter\n * characters (`(`, `)`, `,`, whitespace, `\"`) are dropped with a logged\n * warning, because the Emporix `q` syntax uses them as delimiters and does\n * not support escaping them in a plain IN-list. An empty list — or one with\n * no safe codes — short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `code` if order matters.\n */\n async searchByCodes(\n codes: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const unique = [...new Set(codes)];\n const unsafe = /[(),\"\\s]/;\n const safe = unique.filter((c) => !unsafe.test(c));\n const dropped = unique.filter((c) => unsafe.test(c));\n if (dropped.length > 0) {\n this.ctx.logger.warn(\n \"products.searchByCodes: dropped codes containing query-delimiter characters\",\n { dropped },\n );\n }\n if (safe.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < safe.length; i += chunkSize) {\n chunks.push(safe.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `code:(${chunk.join(\",\")})` },\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Streams the VARIANT children of a PARENT_VARIANT product, page by page,\n * via the search query `productType:VARIANT parentVariantId:<id>`. Default\n * pageSize 200. The query syntax (space-separated fields = implicit AND) is\n * encapsulated here so consumers don't build it themselves.\n */\n listVariantChildrenAll(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 200;\n const q = `productType:VARIANT parentVariantId:${parentVariantId}`;\n return iterateAll<Product>((pageNumber) => this.search(q, { pageNumber, pageSize }, auth));\n }\n\n /**\n * Resolves ALL VARIANT children of a PARENT_VARIANT product into a flat\n * array (loads every page). Default pageSize 200. Returns `[]` when there are\n * no children — never throws.\n */\n async listVariantChildren(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const out: Product[] = [];\n for await (const child of this.listVariantChildrenAll(parentVariantId, params, auth)) {\n out.push(child);\n }\n return out;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.cjs';
2
2
  import { L as LegalEntity, f as LegalEntityCreate, h as LegalEntityUpdate } from './types.gen-D1QuqPLs.cjs';
3
3
  export { A as AccountLimit, e as CustomerGroupRef, g as LegalEntityType, i as LegalInfo } from './types.gen-D1QuqPLs.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.js';
2
2
  import { L as LegalEntity, f as LegalEntityCreate, h as LegalEntityUpdate } from './types.gen-D1QuqPLs.js';
3
3
  export { A as AccountLimit, e as CustomerGroupRef, g as LegalEntityType, i as LegalInfo } from './types.gen-D1QuqPLs.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.cjs';
2
2
  import { C as ContactAssignment, a as ContactAssignmentCreate, c as ContactAssignmentUpdate } from './types.gen-D1QuqPLs.cjs';
3
3
  export { b as ContactAssignmentType } from './types.gen-D1QuqPLs.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.js';
2
2
  import { C as ContactAssignment, a as ContactAssignmentCreate, c as ContactAssignmentUpdate } from './types.gen-D1QuqPLs.js';
3
3
  export { b as ContactAssignmentType } from './types.gen-D1QuqPLs.js';
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" | "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" | "http" | "auth";
7
7
  /** Arbitrary structured fields attached to a log line. */
8
8
  interface LogFields {
9
9
  [key: string]: unknown;
@@ -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" | "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" | "http" | "auth";
7
7
  /** Arbitrary structured fields attached to a log line. */
8
8
  interface LogFields {
9
9
  [key: string]: unknown;
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.cjs';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.cjs';
2
2
 
3
3
  /**
4
4
  * Hand-written mirror of the minimal IAM Service group shape needed for
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CGuxSb56.js';
1
+ import { C as ClientContext, b as AuthContext } from './context-Bs5ZSwds.js';
2
2
 
3
3
  /**
4
4
  * Hand-written mirror of the minimal IAM Service group shape needed for
@@ -1,4 +1,4 @@
1
- import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-CGuxSb56.cjs';
1
+ import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-Bs5ZSwds.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-CGuxSb56.js';
1
+ import { C as ClientContext, A as AnonymousSession, b as AuthContext } from './context-Bs5ZSwds.js';
2
2
 
3
3
  type AccountId = {
4
4
  /**
package/dist/index.cjs CHANGED
@@ -996,6 +996,46 @@ var ProductService = class {
996
996
  );
997
997
  return pages.flat();
998
998
  }
999
+ /**
1000
+ * Bulk fetch by code. POSTs `/products/search` with `q="code:(c1,c2,…)"`,
1001
+ * chunking when the list is larger than `options.chunkSize` (default 100).
1002
+ * Duplicate codes are de-duplicated. Codes containing query-delimiter
1003
+ * characters (`(`, `)`, `,`, whitespace, `"`) are dropped with a logged
1004
+ * warning, because the Emporix `q` syntax uses them as delimiters and does
1005
+ * not support escaping them in a plain IN-list. An empty list — or one with
1006
+ * no safe codes — short-circuits with no HTTP call. **Order is not
1007
+ * guaranteed** across chunks — re-index by `code` if order matters.
1008
+ */
1009
+ async searchByCodes(codes, options = {}, auth2 = ANON) {
1010
+ const unique = [...new Set(codes)];
1011
+ const unsafe = /[(),"\s]/;
1012
+ const safe = unique.filter((c) => !unsafe.test(c));
1013
+ const dropped = unique.filter((c) => unsafe.test(c));
1014
+ if (dropped.length > 0) {
1015
+ this.ctx.logger.warn(
1016
+ "products.searchByCodes: dropped codes containing query-delimiter characters",
1017
+ { dropped }
1018
+ );
1019
+ }
1020
+ if (safe.length === 0) return [];
1021
+ const chunkSize = options.chunkSize ?? 100;
1022
+ const chunks = [];
1023
+ for (let i = 0; i < safe.length; i += chunkSize) {
1024
+ chunks.push(safe.slice(i, i + chunkSize));
1025
+ }
1026
+ const pages = await Promise.all(
1027
+ chunks.map(
1028
+ (chunk) => this.ctx.http.request({
1029
+ method: "POST",
1030
+ path: `/product/${this.ctx.tenant}/products/search`,
1031
+ query: { pageSize: chunk.length },
1032
+ auth: auth2,
1033
+ body: { q: `code:(${chunk.join(",")})` }
1034
+ })
1035
+ )
1036
+ );
1037
+ return pages.flat();
1038
+ }
999
1039
  /**
1000
1040
  * Streams the VARIANT children of a PARENT_VARIANT product, page by page,
1001
1041
  * via the search query `productType:VARIANT parentVariantId:<id>`. Default
@@ -1880,12 +1920,12 @@ var SessionContextService = class {
1880
1920
  * update). Non-404 errors propagate.
1881
1921
  */
1882
1922
  async patch(input, authCtx = ANON5) {
1883
- let version = input.version;
1884
- if (version === void 0) {
1923
+ let version2 = input.version;
1924
+ if (version2 === void 0) {
1885
1925
  const current = await this.get(authCtx);
1886
1926
  if (current === null) return false;
1887
- version = current.metadata?.version;
1888
- if (version === void 0) {
1927
+ version2 = current.metadata?.version;
1928
+ if (version2 === void 0) {
1889
1929
  throw new Error(
1890
1930
  "SessionContextService.patch: no metadata.version in server response"
1891
1931
  );
@@ -1897,7 +1937,7 @@ var SessionContextService = class {
1897
1937
  path: `/session-context/${this.ctx.tenant}/me/context`,
1898
1938
  body: {
1899
1939
  ...fields,
1900
- metadata: { version }
1940
+ metadata: { version: version2 }
1901
1941
  },
1902
1942
  auth: authCtx
1903
1943
  });
@@ -2232,8 +2272,126 @@ var AvailabilityService = class {
2232
2272
  }
2233
2273
  };
2234
2274
 
2275
+ // src/services/tenant-config.ts
2276
+ var SERVICE3 = { kind: "service" };
2277
+ var TenantConfigService = class {
2278
+ constructor(ctx) {
2279
+ this.ctx = ctx;
2280
+ }
2281
+ ctx;
2282
+ base() {
2283
+ return `/configuration/${this.ctx.tenant}/configurations`;
2284
+ }
2285
+ /** List tenant configurations, optionally filtered by `keys`. */
2286
+ async list(opts = {}, auth2 = SERVICE3) {
2287
+ const query = opts.keys && opts.keys.length > 0 ? { keys: opts.keys.join(",") } : void 0;
2288
+ return this.ctx.http.request({
2289
+ method: "GET",
2290
+ path: this.base(),
2291
+ auth: auth2,
2292
+ ...query ? { query } : {}
2293
+ });
2294
+ }
2295
+ /** Retrieve one tenant configuration by key. */
2296
+ async get(key, auth2 = SERVICE3) {
2297
+ return this.ctx.http.request({
2298
+ method: "GET",
2299
+ path: `${this.base()}/${encodeURIComponent(key)}`,
2300
+ auth: auth2
2301
+ });
2302
+ }
2303
+ /** Create one or more tenant configurations (array in, array out). */
2304
+ async create(drafts, auth2 = SERVICE3) {
2305
+ return this.ctx.http.request({
2306
+ method: "POST",
2307
+ path: this.base(),
2308
+ auth: auth2,
2309
+ body: drafts
2310
+ });
2311
+ }
2312
+ /** Update one tenant configuration by key. */
2313
+ async update(key, draft, auth2 = SERVICE3) {
2314
+ return this.ctx.http.request({
2315
+ method: "PUT",
2316
+ path: `${this.base()}/${encodeURIComponent(key)}`,
2317
+ auth: auth2,
2318
+ body: draft
2319
+ });
2320
+ }
2321
+ /** Delete one tenant configuration by key. */
2322
+ async delete(key, auth2 = SERVICE3) {
2323
+ await this.ctx.http.request({
2324
+ method: "DELETE",
2325
+ path: `${this.base()}/${encodeURIComponent(key)}`,
2326
+ auth: auth2
2327
+ });
2328
+ }
2329
+ };
2330
+
2331
+ // src/services/client-config.ts
2332
+ var SERVICE4 = { kind: "service" };
2333
+ var ClientConfigService = class {
2334
+ constructor(ctx) {
2335
+ this.ctx = ctx;
2336
+ }
2337
+ ctx;
2338
+ base(client) {
2339
+ return `/configuration/${this.ctx.tenant}/clients/${encodeURIComponent(client)}/configurations`;
2340
+ }
2341
+ /** List a client's configurations, optionally filtered by `keys`. */
2342
+ async list(client, opts = {}, auth2 = SERVICE4) {
2343
+ const query = opts.keys && opts.keys.length > 0 ? { keys: opts.keys.join(",") } : void 0;
2344
+ return this.ctx.http.request({
2345
+ method: "GET",
2346
+ path: this.base(client),
2347
+ auth: auth2,
2348
+ ...query ? { query } : {}
2349
+ });
2350
+ }
2351
+ /** Retrieve one client configuration by key. */
2352
+ async get(client, key, auth2 = SERVICE4) {
2353
+ return this.ctx.http.request({
2354
+ method: "GET",
2355
+ path: `${this.base(client)}/${encodeURIComponent(key)}`,
2356
+ auth: auth2
2357
+ });
2358
+ }
2359
+ /** Create one or more client configurations. Injects `client` into each item. */
2360
+ async create(client, drafts, auth2 = SERVICE4) {
2361
+ const body = drafts.map((d) => ({ ...d, client }));
2362
+ return this.ctx.http.request({
2363
+ method: "POST",
2364
+ path: this.base(client),
2365
+ auth: auth2,
2366
+ body
2367
+ });
2368
+ }
2369
+ /** Update one client configuration by key. Injects `client` into the body. */
2370
+ async update(client, key, draft, auth2 = SERVICE4) {
2371
+ return this.ctx.http.request({
2372
+ method: "PUT",
2373
+ path: `${this.base(client)}/${encodeURIComponent(key)}`,
2374
+ auth: auth2,
2375
+ body: { ...draft, client }
2376
+ });
2377
+ }
2378
+ /** Delete one client configuration by key. */
2379
+ async delete(client, key, auth2 = SERVICE4) {
2380
+ await this.ctx.http.request({
2381
+ method: "DELETE",
2382
+ path: `${this.base(client)}/${encodeURIComponent(key)}`,
2383
+ auth: auth2
2384
+ });
2385
+ }
2386
+ };
2387
+
2388
+ // package.json
2389
+ var version = "2.2.0";
2390
+
2391
+ // src/version.ts
2392
+ var SDK_VERSION = version;
2393
+
2235
2394
  // src/client.ts
2236
- var SDK_VERSION = "0.0.0";
2237
2395
  var EmporixClient = class {
2238
2396
  customers;
2239
2397
  products;
@@ -2253,6 +2411,8 @@ var EmporixClient = class {
2253
2411
  orders;
2254
2412
  salesOrders;
2255
2413
  availability;
2414
+ tenantConfig;
2415
+ clientConfig;
2256
2416
  /** The validated tenant this client is bound to. */
2257
2417
  tenant;
2258
2418
  /**
@@ -2323,6 +2483,8 @@ var EmporixClient = class {
2323
2483
  this.orders = new OrdersService(mk("orders"));
2324
2484
  this.salesOrders = new SalesOrdersService(mk("sales-orders"));
2325
2485
  this.availability = new AvailabilityService(mk("availability"));
2486
+ this.tenantConfig = new TenantConfigService(mk("configuration"));
2487
+ this.clientConfig = new ClientConfigService(mk("configuration"));
2326
2488
  }
2327
2489
  /** Sets the runtime log level globally or for one service. */
2328
2490
  setLogLevel(level, opts = {}) {
@@ -2338,6 +2500,7 @@ exports.AvailabilityService = AvailabilityService;
2338
2500
  exports.CartService = CartService;
2339
2501
  exports.CategoryService = CategoryService;
2340
2502
  exports.CheckoutService = CheckoutService;
2503
+ exports.ClientConfigService = ClientConfigService;
2341
2504
  exports.CompaniesService = CompaniesService;
2342
2505
  exports.ContactsService = ContactsService;
2343
2506
  exports.CustomerGroupsService = CustomerGroupsService;
@@ -2365,6 +2528,7 @@ exports.SalesOrdersService = SalesOrdersService;
2365
2528
  exports.SegmentService = SegmentService;
2366
2529
  exports.SessionContextService = SessionContextService;
2367
2530
  exports.SiteService = SiteService;
2531
+ exports.TenantConfigService = TenantConfigService;
2368
2532
  exports.auth = auth;
2369
2533
  exports.createConsoleLogger = createConsoleLogger;
2370
2534
  exports.createNoopLogger = createNoopLogger;