@viu/emporix-sdk 2.16.0 → 2.19.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 +33 -0
- package/README.md +19 -0
- package/dist/availability.cjs.map +1 -1
- package/dist/availability.d.cts +94 -8
- package/dist/availability.d.ts +94 -8
- package/dist/availability.js +1 -1
- package/dist/category.cjs +28 -0
- package/dist/category.cjs.map +1 -1
- package/dist/category.d.cts +10 -0
- package/dist/category.d.ts +10 -0
- package/dist/category.js +2 -1
- package/dist/{chunk-62PCCHZ2.js → chunk-36T4YPQJ.js} +7 -2
- package/dist/chunk-36T4YPQJ.js.map +1 -0
- package/dist/{chunk-GIZS4BY3.js → chunk-6XND7SYV.js} +20 -2
- package/dist/chunk-6XND7SYV.js.map +1 -0
- package/dist/{chunk-5VTBLBXJ.js → chunk-FZMP5NQZ.js} +10 -4
- package/dist/chunk-FZMP5NQZ.js.map +1 -0
- package/dist/{chunk-K3VQLW3P.js → chunk-IVCCGJN5.js} +2 -2
- package/dist/chunk-IVCCGJN5.js.map +1 -0
- package/dist/chunk-S5HEIQDK.js +14 -0
- package/dist/chunk-S5HEIQDK.js.map +1 -0
- package/dist/index.cjs +89 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -27
- package/dist/index.d.ts +216 -27
- package/dist/index.js +60 -14
- package/dist/index.js.map +1 -1
- package/dist/orders.cjs +14 -0
- package/dist/orders.cjs.map +1 -1
- package/dist/orders.d.cts +3 -0
- package/dist/orders.d.ts +3 -0
- package/dist/orders.js +2 -1
- package/dist/product.cjs +14 -2
- package/dist/product.cjs.map +1 -1
- package/dist/product.d.cts +7 -2
- package/dist/product.d.ts +7 -2
- package/dist/product.js +2 -1
- package/dist/query-mLQs2WFr.d.cts +28 -0
- package/dist/query-mLQs2WFr.d.ts +28 -0
- package/dist/segment.d.cts +1 -0
- package/dist/segment.d.ts +1 -0
- package/package.json +1 -1
- package/dist/chunk-5VTBLBXJ.js.map +0 -1
- package/dist/chunk-62PCCHZ2.js.map +0 -1
- package/dist/chunk-GIZS4BY3.js.map +0 -1
- package/dist/chunk-K3VQLW3P.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { iterateAll } from './chunk-GWJ2U2CP.js';
|
|
2
|
+
import { resolveQuery } from './chunk-S5HEIQDK.js';
|
|
2
3
|
|
|
3
4
|
// src/services/category.ts
|
|
4
5
|
var ANON = { kind: "anonymous" };
|
|
@@ -28,6 +29,23 @@ var CategoryService = class {
|
|
|
28
29
|
});
|
|
29
30
|
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Searches categories by a `q` filter — a raw Emporix DSL string or a built
|
|
34
|
+
* filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Category does not
|
|
35
|
+
* support `compoundLogicalQuery`, so `or()` filters are rejected.
|
|
36
|
+
*/
|
|
37
|
+
async search(query, params = {}, auth = ANON) {
|
|
38
|
+
const q = resolveQuery(query, { compoundLogicalQuery: false });
|
|
39
|
+
const pageNumber = params.pageNumber ?? 1;
|
|
40
|
+
const pageSize = params.pageSize ?? 50;
|
|
41
|
+
const items = await this.ctx.http.request({
|
|
42
|
+
method: "GET",
|
|
43
|
+
path: `/category/${this.ctx.tenant}/categories`,
|
|
44
|
+
query: { q, pageNumber, pageSize },
|
|
45
|
+
auth
|
|
46
|
+
});
|
|
47
|
+
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
48
|
+
}
|
|
31
49
|
/** Async-iterates every category across pages. */
|
|
32
50
|
listAll(params = {}, auth = ANON) {
|
|
33
51
|
const pageSize = params.pageSize ?? 50;
|
|
@@ -126,5 +144,5 @@ var CategoryService = class {
|
|
|
126
144
|
};
|
|
127
145
|
|
|
128
146
|
export { CategoryService };
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
//# sourceMappingURL=chunk-6XND7SYV.js.map
|
|
148
|
+
//# sourceMappingURL=chunk-6XND7SYV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/category.ts"],"names":[],"mappings":"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","file":"chunk-6XND7SYV.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\nimport type { Product } from \"./product\";\nimport type { Category as GeneratedCategory, CategoryTree } from \"../generated/category\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/** A category as returned by the Category service (all generated fields). */\nexport type Category = GeneratedCategory;\n\n/** The category tree as returned by the Category service. */\nexport type CategoryNode = CategoryTree;\n\n/** Category reads. Default auth: anonymous. */\nexport class CategoryService {\n static readonly channel = \"category\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one category by id. */\n async get(categoryId: string, auth: AuthContext = ANON): Promise<Category> {\n return this.ctx.http.request<Category>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n auth,\n });\n }\n\n /** One page of categories. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Category>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Searches categories by a `q` filter — a raw Emporix DSL string or a built\n * filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Category does not\n * support `compoundLogicalQuery`, so `or()` filters are rejected.\n */\n async search(\n query: QueryFor<\"CATEGORY\">,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Category>> {\n const q = resolveQuery(query, { compoundLogicalQuery: false });\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { q, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every category across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Category> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Category>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /**\n * The catalogue's **root categories** — the published category trees\n * (`GET /category-trees`). Use these for top-level storefront navigation;\n * drill into a node's children with {@link subcategories}.\n */\n async tree(auth: AuthContext = ANON): Promise<Category[]> {\n return this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/category-trees`,\n auth,\n });\n }\n\n /**\n * Direct child categories of a category (for hierarchy drill-down). Mirrors\n * {@link productsIn}: reads the category's **assignments** and keeps the\n * `CATEGORY` references, resolving them to full categories. Returns an empty\n * array when the category has no child categories.\n */\n async subcategories(\n categoryId: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Category[]> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const assignments = await this.ctx.http.request<Array<{ ref?: { id?: string; type?: string } }>>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n query: { pageNumber, pageSize },\n auth,\n });\n const categoryIds = assignments\n .map((a) => (a.ref?.type?.toUpperCase() === \"CATEGORY\" ? a.ref.id : undefined))\n .filter((id): id is string => Boolean(id));\n if (categoryIds.length === 0) return [];\n return this.searchByIds(categoryIds, {}, auth);\n }\n\n /**\n * One page of products in a category. The category service exposes products\n * as **assignments** (`/categories/{id}/assignments`) — references, not full\n * products — so this fetches a page of assignments, keeps the `PRODUCT`\n * references, and resolves them to full products via `/products/search`.\n * `hasNextPage` reflects the assignments page (the source of truth for\n * pagination).\n */\n async productsIn(\n categoryId: 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 assignments = await this.ctx.http.request<Array<{ ref?: { id?: string; type?: string } }>>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n query: { pageNumber, pageSize },\n auth,\n });\n const hasNextPage = assignments.length === pageSize;\n const productIds = assignments\n .map((a) => (a.ref?.type?.toUpperCase() === \"PRODUCT\" ? a.ref.id : undefined))\n .filter((id): id is string => Boolean(id));\n if (productIds.length === 0) {\n return { items: [], pageNumber, pageSize, hasNextPage };\n }\n const items = await this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: productIds.length },\n auth,\n body: { q: `id:(${productIds.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n return { items, pageNumber, pageSize, hasNextPage };\n }\n\n /**\n * Bulk fetch by id. POSTs `/categories/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<Category[]> {\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<Category[]>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `id:(${chunk.join(\",\")})` },\n }),\n ),\n );\n return pages.flat();\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { iterateAll } from './chunk-GWJ2U2CP.js';
|
|
2
|
+
import { resolveQuery } from './chunk-S5HEIQDK.js';
|
|
2
3
|
|
|
3
4
|
// src/services/product.ts
|
|
4
5
|
var ANON = { kind: "anonymous" };
|
|
@@ -45,14 +46,19 @@ var ProductService = class {
|
|
|
45
46
|
const pageSize = params.pageSize ?? 50;
|
|
46
47
|
return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth));
|
|
47
48
|
}
|
|
48
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Searches products by a `q` filter — a raw Emporix DSL string or a built
|
|
51
|
+
* filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Product supports
|
|
52
|
+
* `compoundLogicalQuery`, so `or()` filters are allowed.
|
|
53
|
+
*/
|
|
49
54
|
async search(query, params = {}, auth = ANON) {
|
|
55
|
+
const q = resolveQuery(query, { compoundLogicalQuery: true });
|
|
50
56
|
const pageNumber = params.pageNumber ?? 1;
|
|
51
57
|
const pageSize = params.pageSize ?? 50;
|
|
52
58
|
const items = await this.ctx.http.request({
|
|
53
59
|
method: "GET",
|
|
54
60
|
path: `/product/${this.ctx.tenant}/products`,
|
|
55
|
-
query: { q
|
|
61
|
+
query: { q, pageNumber, pageSize },
|
|
56
62
|
auth
|
|
57
63
|
});
|
|
58
64
|
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
@@ -163,5 +169,5 @@ var ProductService = class {
|
|
|
163
169
|
};
|
|
164
170
|
|
|
165
171
|
export { ProductService };
|
|
166
|
-
//# sourceMappingURL=chunk-
|
|
167
|
-
//# sourceMappingURL=chunk-
|
|
172
|
+
//# sourceMappingURL=chunk-FZMP5NQZ.js.map
|
|
173
|
+
//# sourceMappingURL=chunk-FZMP5NQZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/product.ts"],"names":[],"mappings":"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","file":"chunk-FZMP5NQZ.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\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 static readonly channel = \"product\" as const;\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 /**\n * Searches products by a `q` filter — a raw Emporix DSL string or a built\n * filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Product supports\n * `compoundLogicalQuery`, so `or()` filters are allowed.\n */\n async search(\n query: QueryFor<\"PRODUCT\">,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const q = resolveQuery(query, { compoundLogicalQuery: true });\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, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Free-text product search by name. The product `q` is a `field:value` DSL,\n * so a bare term (e.g. \"in time\") 400s with \"No value for key …\". This builds\n * a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates\n * to {@link search}.\n */\n async searchByName(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const escaped = query.trim().replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return this.search(`name:(~${escaped})`, params, auth);\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 idempotent: true, // pure read over POST — safe to replay on 5xx/429\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 idempotent: true, // pure read over POST — safe to replay on 5xx/429\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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/availability.ts"],"names":[],"mappings":";;;AAkBA,IAAM,IAAA,GAAoB,EAAE,IAAA,EAAM,WAAA,EAAY;AAQvC,IAAM,sBAAN,MAA0B;AAAA,EAE/B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1B,MAAM,IACJ,SAAA,EACA,QAAA,EACA,OAAoB,IAAA,EACpB,IAAA,GAA4B,EAAC,EACN;AACvB,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAsB;AAAA,QAC/C,MAAA,EAAQ,KAAA;AAAA,QACR,IAAA,EAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,cAAA,EAAiB,kBAAA;AAAA,UACrD;AAAA,SACD,CAAA,CAAA,EAAI,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,QACjC;AAAA,OACD,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,oBAAA,IAAwB,IAAA,CAAK,0BAAA,EAA4B;AAC1E,QAAA,OAAO,EAAE,SAAA,EAAW,IAAA,EAAM,QAAA,EAAU,WAAW,IAAA,EAAK;AAAA,MACtD;AACA,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,UAAA,EACA,QAAA,EACA,OAAoB,IAAA,EACpB,IAAA,GAA4B,EAAC,EACJ;AACzB,IAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AACrC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAwB;AAAA,MACxD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,oBAAA,CAAA;AAAA,MACtC,IAAA;AAAA,MACA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,QAAA,EAAU,WAAW,MAAA,EAAO;AAAA,MACrD,IAAA,EAAM,UAAA;AAAA,MACN,UAAA,EAAY;AAAA;AAAA,KACb,CAAA;AACD,IAAA,MAAM,IAAA,uBAAW,GAAA,EAA0B;AAC3C,IAAA,KAAA,MAAW,CAAA,IAAK,OAAO,IAAI,CAAA,CAAE,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC/D,IAAA,OAAO,UAAA,CAAW,GAAA;AAAA,MAChB,CAAC,EAAA,KACC,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK;AAAA,QACd,SAAA,EAAW,EAAA;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,0BAA0B;AAAA;AACpD,KACJ;AAAA,EACF;AACF","file":"chunk-IVCCGJN5.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixNotFoundError } from \"../core/errors\";\nimport type { Availability } from \"./availability-types\";\n\nexport type { Availability } from \"./availability-types\";\n\n/** Shared options for {@link AvailabilityService} reads. */\nexport interface AvailabilityOptions {\n /**\n * When `true`, a product with no availability record resolves to a default\n * `{ available: true }` instead of throwing (single `get`) / being marked\n * unavailable (`getMany`). Off by default — opt in for tenants that sell\n * without stock management.\n */\n defaultAvailableOnNotFound?: boolean;\n}\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/**\n * Reads product availability per site. Default auth is anonymous (like\n * `PriceService.matchByContext`); pass a customer/raw/service context to use a\n * different token. Requires the `availability.availability_view` scope on\n * whichever token is used.\n */\nexport class AvailabilityService {\n static readonly channel = \"availability\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Single product. Resolves the availability record, or — when\n * `opts.defaultAvailableOnNotFound` is set — a default available record on 404.\n */\n async get(\n productId: string,\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability> {\n try {\n return await this.ctx.http.request<Availability>({\n method: \"GET\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n auth,\n });\n } catch (err) {\n if (err instanceof EmporixNotFoundError && opts.defaultAvailableOnNotFound) {\n return { productId, site: siteCode, available: true };\n }\n throw err;\n }\n }\n\n /**\n * Batch read via `POST .../availability/search` (one request). Products with\n * no availability record are absent from the response; each is synthesized as\n * `{ available: false }` (or `{ available: true }` when\n * `opts.defaultAvailableOnNotFound` is set). The result preserves input order\n * and length. An empty `productIds` resolves to `[]` without a request.\n */\n async getMany(\n productIds: string[],\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability[]> {\n if (productIds.length === 0) return [];\n const found = await this.ctx.http.request<Availability[]>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/search`,\n auth,\n query: { site: siteCode, pageSize: productIds.length },\n body: productIds,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n const byId = new Map<string, Availability>();\n for (const a of found) if (a.productId) byId.set(a.productId, a);\n return productIds.map(\n (id) =>\n byId.get(id) ?? {\n productId: id,\n site: siteCode,\n available: Boolean(opts.defaultAvailableOnNotFound),\n },\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/core/query.ts
|
|
2
|
+
function resolveQuery(q, cap) {
|
|
3
|
+
if (typeof q === "string") return q;
|
|
4
|
+
if (q.usesCompound === true && !cap.compoundLogicalQuery) {
|
|
5
|
+
throw new Error(
|
|
6
|
+
"This filter uses or()/compoundLogicalQuery, which the target service does not support. Combine conditions with and() (space-separated AND) instead."
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
return q.toString();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { resolveQuery };
|
|
13
|
+
//# sourceMappingURL=chunk-S5HEIQDK.js.map
|
|
14
|
+
//# sourceMappingURL=chunk-S5HEIQDK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/query.ts"],"names":[],"mappings":";AA4BO,SAAS,YAAA,CAAa,GAAa,GAAA,EAA8B;AACtE,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,EAAA,IAAI,CAAA,CAAE,YAAA,KAAiB,IAAA,IAAQ,CAAC,IAAI,oBAAA,EAAsB;AACxD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,QAAA,EAAS;AACpB","file":"chunk-S5HEIQDK.js","sourcesContent":["/**\n * A built query filter — structurally matched, NOT imported, so the SDK stays\n * decoupled from `@viu/emporix-mixins` (which lists the SDK as an optional\n * peer; a real import would be circular). `@viu/emporix-mixins`' `MixinFilter<E>`\n * satisfies this shape.\n */\nexport interface BuiltQuery<E extends string = string> {\n toString(): string;\n readonly usesCompound?: boolean;\n /** Phantom entity tag — gates which service a filter may be passed to. */\n readonly __entity?: E;\n}\n\n/** A `q` value a service method accepts: a raw DSL string or a built filter for entity `E`. */\nexport type QueryFor<E extends string = string> = string | BuiltQuery<E>;\n\n/** Per-service capability flags consulted by {@link resolveQuery}. */\nexport interface QueryCapability {\n /** Whether the target service supports the `compoundLogicalQuery` (OR) operator. */\n compoundLogicalQuery: boolean;\n}\n\n/**\n * Normalizes a `string | BuiltQuery` into a `q` string and enforces the\n * `compoundLogicalQuery` capability gate: an `or()`-built filter passed to a\n * service that does not support it throws rather than silently producing a\n * query the backend cannot execute.\n */\nexport function resolveQuery(q: QueryFor, cap: QueryCapability): string {\n if (typeof q === \"string\") return q;\n if (q.usesCompound === true && !cap.compoundLogicalQuery) {\n throw new Error(\n \"This filter uses or()/compoundLogicalQuery, which the target service does not support. \" +\n \"Combine conditions with and() (space-separated AND) instead.\",\n );\n }\n return q.toString();\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -783,7 +783,7 @@ var HttpClient = class {
|
|
|
783
783
|
};
|
|
784
784
|
|
|
785
785
|
// package.json
|
|
786
|
-
var version = "2.
|
|
786
|
+
var version = "2.19.0";
|
|
787
787
|
|
|
788
788
|
// src/version.ts
|
|
789
789
|
var SDK_VERSION = version;
|
|
@@ -1071,6 +1071,17 @@ async function* iterateAll(fetchPage, start = 1) {
|
|
|
1071
1071
|
}
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
|
+
// src/core/query.ts
|
|
1075
|
+
function resolveQuery(q, cap) {
|
|
1076
|
+
if (typeof q === "string") return q;
|
|
1077
|
+
if (q.usesCompound === true && !cap.compoundLogicalQuery) {
|
|
1078
|
+
throw new Error(
|
|
1079
|
+
"This filter uses or()/compoundLogicalQuery, which the target service does not support. Combine conditions with and() (space-separated AND) instead."
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
return q.toString();
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1074
1085
|
// src/services/product.ts
|
|
1075
1086
|
var ANON = { kind: "anonymous" };
|
|
1076
1087
|
var ProductService = class {
|
|
@@ -1116,14 +1127,19 @@ var ProductService = class {
|
|
|
1116
1127
|
const pageSize = params.pageSize ?? 50;
|
|
1117
1128
|
return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth2));
|
|
1118
1129
|
}
|
|
1119
|
-
/**
|
|
1130
|
+
/**
|
|
1131
|
+
* Searches products by a `q` filter — a raw Emporix DSL string or a built
|
|
1132
|
+
* filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Product supports
|
|
1133
|
+
* `compoundLogicalQuery`, so `or()` filters are allowed.
|
|
1134
|
+
*/
|
|
1120
1135
|
async search(query, params = {}, auth2 = ANON) {
|
|
1136
|
+
const q = resolveQuery(query, { compoundLogicalQuery: true });
|
|
1121
1137
|
const pageNumber = params.pageNumber ?? 1;
|
|
1122
1138
|
const pageSize = params.pageSize ?? 50;
|
|
1123
1139
|
const items = await this.ctx.http.request({
|
|
1124
1140
|
method: "GET",
|
|
1125
1141
|
path: `/product/${this.ctx.tenant}/products`,
|
|
1126
|
-
query: { q
|
|
1142
|
+
query: { q, pageNumber, pageSize },
|
|
1127
1143
|
auth: auth2
|
|
1128
1144
|
});
|
|
1129
1145
|
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
@@ -1261,6 +1277,23 @@ var CategoryService = class {
|
|
|
1261
1277
|
});
|
|
1262
1278
|
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
1263
1279
|
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Searches categories by a `q` filter — a raw Emporix DSL string or a built
|
|
1282
|
+
* filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Category does not
|
|
1283
|
+
* support `compoundLogicalQuery`, so `or()` filters are rejected.
|
|
1284
|
+
*/
|
|
1285
|
+
async search(query, params = {}, auth2 = ANON2) {
|
|
1286
|
+
const q = resolveQuery(query, { compoundLogicalQuery: false });
|
|
1287
|
+
const pageNumber = params.pageNumber ?? 1;
|
|
1288
|
+
const pageSize = params.pageSize ?? 50;
|
|
1289
|
+
const items = await this.ctx.http.request({
|
|
1290
|
+
method: "GET",
|
|
1291
|
+
path: `/category/${this.ctx.tenant}/categories`,
|
|
1292
|
+
query: { q, pageNumber, pageSize },
|
|
1293
|
+
auth: auth2
|
|
1294
|
+
});
|
|
1295
|
+
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
1296
|
+
}
|
|
1264
1297
|
/** Async-iterates every category across pages. */
|
|
1265
1298
|
listAll(params = {}, auth2 = ANON2) {
|
|
1266
1299
|
const pageSize = params.pageSize ?? 50;
|
|
@@ -2436,6 +2469,9 @@ var OrdersService = class {
|
|
|
2436
2469
|
setIfDefined2(query, "status", opts.status);
|
|
2437
2470
|
setIfDefined2(query, "legalEntityId", opts.legalEntityId);
|
|
2438
2471
|
setIfDefined2(query, "siteCode", opts.siteCode);
|
|
2472
|
+
if (opts.q !== void 0) {
|
|
2473
|
+
setIfDefined2(query, "q", resolveQuery(opts.q, { compoundLogicalQuery: false }));
|
|
2474
|
+
}
|
|
2439
2475
|
const headers = this.saasHeader(opts.saasToken);
|
|
2440
2476
|
const items = await this.ctx.http.request({
|
|
2441
2477
|
method: "GET",
|
|
@@ -2806,6 +2842,8 @@ var RagIndexerService = class {
|
|
|
2806
2842
|
* Schedule a full asynchronous re-index for `type` (default `"PRODUCT"`).
|
|
2807
2843
|
* Resolves once the rebuild is *scheduled* (HTTP 204); there is no progress
|
|
2808
2844
|
* to await or poll. Costly — avoid calling on a hot path.
|
|
2845
|
+
* @deprecated since 2026-06-18, removal 2026-12-01 — use the indexing service:
|
|
2846
|
+
* `client.indexing.createReindexJob({ entityType: "PRODUCT", rag: true })`.
|
|
2809
2847
|
*/
|
|
2810
2848
|
async reindex(type = "PRODUCT", auth2 = SERVICE5) {
|
|
2811
2849
|
await this.ctx.http.request({
|
|
@@ -4766,7 +4804,47 @@ var IndexingService = class {
|
|
|
4766
4804
|
auth: auth2
|
|
4767
4805
|
});
|
|
4768
4806
|
}
|
|
4769
|
-
/**
|
|
4807
|
+
/**
|
|
4808
|
+
* Create a reindex job (replaces {@link reindex}). A `FULL` reindex of the
|
|
4809
|
+
* given `entityType`; set `rag: true` to also rebuild the RAG vector index
|
|
4810
|
+
* (PRODUCT only). Resolves to the created job (`201`) or, when a job for that
|
|
4811
|
+
* `entityType` is already `IN_PROGRESS`, that running job (`200`).
|
|
4812
|
+
*/
|
|
4813
|
+
async createReindexJob(input, auth2 = SERVICE21) {
|
|
4814
|
+
return this.ctx.http.request({
|
|
4815
|
+
method: "POST",
|
|
4816
|
+
path: `${this.base()}/reindex-jobs`,
|
|
4817
|
+
auth: auth2,
|
|
4818
|
+
body: input
|
|
4819
|
+
});
|
|
4820
|
+
}
|
|
4821
|
+
/** List reindex jobs (paginated). */
|
|
4822
|
+
async listReindexJobs(opts = {}, auth2 = SERVICE21) {
|
|
4823
|
+
const pageNumber = opts.pageNumber ?? 1;
|
|
4824
|
+
const pageSize = opts.pageSize ?? 50;
|
|
4825
|
+
const query = { pageNumber, pageSize };
|
|
4826
|
+
if (opts.q !== void 0) query.q = opts.q;
|
|
4827
|
+
const items = await this.ctx.http.request({
|
|
4828
|
+
method: "GET",
|
|
4829
|
+
path: `${this.base()}/reindex-jobs`,
|
|
4830
|
+
query,
|
|
4831
|
+
auth: auth2
|
|
4832
|
+
});
|
|
4833
|
+
return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
|
|
4834
|
+
}
|
|
4835
|
+
/** Fetch one reindex job by id. */
|
|
4836
|
+
async getReindexJob(reindexJobId, auth2 = SERVICE21) {
|
|
4837
|
+
return this.ctx.http.request({
|
|
4838
|
+
method: "GET",
|
|
4839
|
+
path: `${this.base()}/reindex-jobs/${encodeURIComponent(reindexJobId)}`,
|
|
4840
|
+
auth: auth2
|
|
4841
|
+
});
|
|
4842
|
+
}
|
|
4843
|
+
/**
|
|
4844
|
+
* Trigger a reindex.
|
|
4845
|
+
* @deprecated since 2026-06-18, removal 2026-12-01 — use {@link createReindexJob}
|
|
4846
|
+
* (`createReindexJob({ entityType: "PRODUCT" })`), which returns a trackable job.
|
|
4847
|
+
*/
|
|
4770
4848
|
async reindex(input, auth2 = SERVICE21) {
|
|
4771
4849
|
await this.ctx.http.request({ method: "POST", path: `${this.base()}/reindex`, auth: auth2, body: input });
|
|
4772
4850
|
}
|
|
@@ -4951,13 +5029,14 @@ var VendorService = class {
|
|
|
4951
5029
|
auth: auth2
|
|
4952
5030
|
});
|
|
4953
5031
|
}
|
|
4954
|
-
/** Search vendors (`POST /vendors/search`). */
|
|
5032
|
+
/** Search vendors (`POST /vendors/search`). A built filter in `q` is resolved to a string. */
|
|
4955
5033
|
async searchVendors(query, auth2 = SERVICE24) {
|
|
5034
|
+
const body = query.q !== void 0 ? { ...query, q: resolveQuery(query.q, { compoundLogicalQuery: false }) } : query;
|
|
4956
5035
|
return this.ctx.http.request({
|
|
4957
5036
|
method: "POST",
|
|
4958
5037
|
path: `${this.base()}/vendors/search`,
|
|
4959
5038
|
auth: auth2,
|
|
4960
|
-
body
|
|
5039
|
+
body
|
|
4961
5040
|
});
|
|
4962
5041
|
}
|
|
4963
5042
|
/** Create a vendor. */
|
|
@@ -5141,9 +5220,10 @@ var CustomerAdminService = class {
|
|
|
5141
5220
|
...Object.keys(query).length ? { query } : {}
|
|
5142
5221
|
});
|
|
5143
5222
|
}
|
|
5144
|
-
/** Search customers (`POST /customers/search`). */
|
|
5223
|
+
/** Search customers (`POST /customers/search`). A built filter in `q` is resolved to a string. */
|
|
5145
5224
|
async searchCustomers(query, auth2 = SERVICE26) {
|
|
5146
|
-
|
|
5225
|
+
const body = query.q !== void 0 ? { ...query, q: resolveQuery(query.q, { compoundLogicalQuery: false }) } : query;
|
|
5226
|
+
return this.ctx.http.request({ method: "POST", path: `${this.base()}/search`, auth: auth2, body });
|
|
5147
5227
|
}
|
|
5148
5228
|
/** Retrieve a customer profile by number. */
|
|
5149
5229
|
async getCustomer(customerNumber, auth2 = SERVICE26) {
|
|
@@ -5545,6 +5625,7 @@ exports.errorFromResponse = errorFromResponse;
|
|
|
5545
5625
|
exports.iterateAll = iterateAll;
|
|
5546
5626
|
exports.productIdFromYrn = productIdFromYrn;
|
|
5547
5627
|
exports.redact = redact;
|
|
5628
|
+
exports.resolveQuery = resolveQuery;
|
|
5548
5629
|
exports.resolveToken = resolveToken;
|
|
5549
5630
|
exports.validateConfig = validateConfig;
|
|
5550
5631
|
//# sourceMappingURL=index.cjs.map
|