@viu/emporix-sdk 4.7.1 → 4.8.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
+ ## 4.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#431](https://github.com/viuteam/emporix-sdk/pull/431) [`1321bdd`](https://github.com/viuteam/emporix-sdk/commit/1321bddbb9851eeb719757ed06093c66ea55ae44) Thanks [@amnael1](https://github.com/amnael1)! - Filter the category trees.
8
+
9
+ - **`categories.listTrees(params, auth)`** sends the three filters the specification declares on `GET /category-trees`, which `tree()` never sent. `type` (`STANDARD` or `CLASSIFICATION`) arrived with the 2026-10-26 specification; `categoryIds` and `showUnpublished` were there before. `tree(auth)` keeps working and is `listTrees({}, auth)`. The new `CategoryTreeListParams` type is exported.
10
+ - **`categoryIds`** goes out comma-joined. Emporix reads that like the repeated form, which was checked against a live tenant. An empty list matches nothing and sends no request.
11
+ - **`showUnpublished`** needs `category.category_read_unpublished`. An anonymous token is refused with 403.
12
+ - **`useCategoryTree({ filter })` and `injectCategoryTree({ filter })`** pass a filter through. Angular takes it as a signal. Each filter gets its own cache entry. Without a filter, the cache key is unchanged.
13
+ - **Filter by `type` with care.** On the `viu` tenant on 2026-10-27, 27 trees came back for neither `STANDARD` nor `CLASSIFICATION`, only unfiltered.
14
+
15
+ ## 4.7.2
16
+
17
+ ### Patch Changes
18
+
19
+ - [#427](https://github.com/viuteam/emporix-sdk/pull/427) [`6c56ca9`](https://github.com/viuteam/emporix-sdk/commit/6c56ca9d37727d5565aaa570ee708888efb0834c) Thanks [@viu-release-bot](https://github.com/apps/viu-release-bot)! - chore(sdk): sync generated types with upstream Emporix API specs
20
+
21
+ Updated services: category,label-service,media,reward-points,tax-service
22
+
3
23
  ## 4.7.1
4
24
 
5
25
  ### Patch Changes
package/dist/category.cjs CHANGED
@@ -132,11 +132,36 @@ var CategoryService = class {
132
132
  * `"PRODUCT"` filter behind {@link productsIn} worked fine.
133
133
  * {@link childCategories} hits `/categories/{id}/subcategories` and answers
134
134
  * **404** for a tree root. One call gives you the whole hierarchy.
135
+ *
136
+ * To filter by category type, category ids or publication, use {@link listTrees}.
135
137
  */
136
138
  async tree(auth = ANON) {
139
+ return this.listTrees({}, auth);
140
+ }
141
+ /**
142
+ * The category trees, filtered (`GET /category-trees`). Default auth: anonymous.
143
+ * {@link tree} is this call without filters.
144
+ *
145
+ * - `categoryIds` goes out comma-joined, because the HTTP layer sends one value
146
+ * per key. Emporix reads `a,b` like the repeated `categoryIds=a&categoryIds=b`;
147
+ * both were probed on `viu` on 2026-10-27. An empty list matches nothing and
148
+ * sends no request.
149
+ * - `showUnpublished` needs `category.category_read_unpublished`. An anonymous
150
+ * token does not carry it, and Emporix answers **403**.
151
+ * - Filter by `type` with care. On `viu` on 2026-10-27, 27 trees built from
152
+ * categories that all read `STANDARD` came back for neither `STANDARD` nor
153
+ * `CLASSIFICATION`, only unfiltered.
154
+ */
155
+ async listTrees(params = {}, auth = ANON) {
156
+ if (params.categoryIds?.length === 0) return [];
137
157
  return this.ctx.http.request({
138
158
  method: "GET",
139
159
  path: `/category/${this.ctx.tenant}/category-trees`,
160
+ query: {
161
+ type: params.type,
162
+ categoryIds: params.categoryIds?.join(","),
163
+ showUnpublished: params.showUnpublished
164
+ },
140
165
  auth
141
166
  });
142
167
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/context.ts","../src/core/paged.ts","../src/core/query.ts","../src/services/category.ts"],"names":[],"mappings":"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","file":"category.cjs","sourcesContent":["import type { HttpClient } from \"./http\";\nimport type { TokenProvider, AuthContext } from \"./auth\";\nimport type { Logger } from \"./logger\";\n\n/** Shared dependencies every service facade receives. */\nexport interface ClientContext {\n tenant: string;\n http: HttpClient;\n tokenProvider: TokenProvider;\n logger: Logger;\n}\n\n/**\n * A cursor-paged collection — `pageNumber`/`pageSize` indexing with a\n * `hasNextPage` signal driven by the source page being full. Used by all\n * paginated services and hooks across the SDK.\n */\nexport interface PaginatedItems<T> {\n items: T[];\n pageNumber: number;\n pageSize: number;\n hasNextPage: boolean;\n /**\n * Absolute number of matches, when the caller asked for it and the endpoint\n * answered. Opt-in per call (`totalCount: true`), because Emporix computes it\n * with a second query — see `core/paged.ts`.\n *\n * Always `undefined` in cursor mode: the server ignores the request header\n * and omits the response header there.\n */\n totalCount?: number;\n /**\n * Opaque cursor for the next page, on the endpoints that offer one (today:\n * the schema service's custom instances). Pass it back as the `next` query\n * parameter. Absence means \"this endpoint said nothing\", NOT \"last page\".\n */\n nextCursor?: string;\n /** Opaque cursor for the previous page. Same caveat as {@link nextCursor}. */\n prevCursor?: string;\n}\n\n/** Default `AuthContext` applied by a service when the caller passes none. */\nexport type DefaultAuth = AuthContext | undefined;\n\n/**\n * Async-iterates every item across pages of a `PaginatedItems<T>` source.\n * Stops when the source reports `hasNextPage: false`.\n *\n * @param fetchPage - given a 1-based page number, returns the page.\n * @param start - first page to fetch (default `1`).\n */\nexport async function* iterateAll<T>(\n fetchPage: (pageNumber: number) => Promise<PaginatedItems<T>>,\n start = 1,\n): AsyncIterable<T> {\n let p = start;\n for (;;) {\n const page = await fetchPage(p);\n for (const it of page.items) yield it;\n if (!page.hasNextPage) return;\n p += 1;\n }\n}\n\n","import type { PaginatedItems } from \"./context\";\nimport type { HttpClient, RequestOptions } from \"./http\";\n\n/** Pagination inputs for {@link requestPage}. */\nexport interface PageParams {\n /** 1-based, as Emporix counts. */\n pageNumber: number;\n pageSize: number;\n /**\n * Ask Emporix for the absolute match count via the `X-Total-Count: true`\n * request header.\n *\n * Off by default and opt-in per call, not a client-wide setting: the count\n * costs the server a second query, and defaulting it on would put that cost\n * on every list every storefront issues.\n */\n totalCount?: boolean;\n}\n\n/**\n * Reads a non-negative integer header, or `undefined` when it is missing or is\n * not one. A malformed value must not reach the `hasNextPage` arithmetic —\n * `Number(\"lots\")` is `NaN`, and every comparison against `NaN` is `false`,\n * which would silently report \"last page\" on every page.\n */\nfunction intHeader(headers: Headers, name: string): number | undefined {\n const raw = headers.get(name);\n if (raw === null || raw.trim() === \"\") return undefined;\n const n = Number(raw);\n return Number.isInteger(n) && n >= 0 ? n : undefined;\n}\n\n/**\n * Issues one page of a list endpoint and assembles {@link PaginatedItems} from\n * the body plus Emporix's pagination response headers.\n *\n * Cursors travel in opposite directions: the caller sends one as the `next` or\n * `prev` **query parameter** (so it belongs in `o.query`), and the server\n * returns the following one as the `X-Next-Cursor` **response header**. This\n * helper only ever reads them.\n */\nexport async function requestPage<T>(\n http: HttpClient,\n o: RequestOptions,\n page: PageParams,\n): Promise<PaginatedItems<T>> {\n const { data, headers } = await http.requestWithMeta<T[]>(\n page.totalCount === true\n ? { ...o, headers: { ...(o.headers ?? {}), \"X-Total-Count\": \"true\" } }\n : o,\n );\n\n // A 204 or empty body parses to `undefined`. Facades used to index straight\n // into the result and would throw; an empty page is the honest answer.\n const items = data ?? [];\n const totalCount = intHeader(headers, \"X-Total-Count\");\n const nextCursor = headers.get(\"X-Next-Cursor\") ?? undefined;\n const prevCursor = headers.get(\"X-Prev-Cursor\") ?? undefined;\n\n // Three tiers, most precise first. Tier 1 is ONE-DIRECTIONAL on purpose: only\n // two endpoints in the whole API emit a cursor header, so its absence says\n // nothing at all and has to fall through to the other two.\n const hasNextPage =\n nextCursor !== undefined\n ? true\n : totalCount !== undefined\n ? page.pageNumber * page.pageSize < totalCount\n : items.length === page.pageSize;\n\n // Spread conditionally — `exactOptionalPropertyTypes` rejects an explicit\n // `undefined` for an optional property.\n return {\n items,\n pageNumber: page.pageNumber,\n pageSize: page.pageSize,\n hasNextPage,\n ...(totalCount === undefined ? {} : { totalCount }),\n ...(nextCursor === undefined ? {} : { nextCursor }),\n ...(prevCursor === undefined ? {} : { prevCursor }),\n };\n}\n","/**\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","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport { requestPage } from \"../core/paged\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\nimport type { Product } from \"./product\";\nimport type {\n Category as GeneratedCategory,\n CategoryTree,\n CategoryCreateRequest,\n CategoryUpdateRequest,\n CategoryPartialUpdateRequest,\n CategoryIdResponse,\n CategoryTreeSearchRequest,\n CategoryAssignment as GeneratedCategoryAssignment,\n AssignmentRequest,\n BulkAssignmentRequest,\n BulkAssignmentUpsertRequest,\n BulkAssignmentResponse,\n AssignmentIdResponse,\n} from \"../generated/category\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\nconst SERVICE: AuthContext = { kind: \"service\" };\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/** Body for creating a category (`POST /categories`). */\nexport type CategoryCreateInput = CategoryCreateRequest;\n\n/** Body for a full category replace (`PUT /categories/{id}`). */\nexport type CategoryUpdateInput = CategoryUpdateRequest;\n\n/** Body for a partial category update (`PATCH /categories/{id}`). */\nexport type CategoryPatchInput = CategoryPartialUpdateRequest;\n\n/** Id envelope returned when a category is created. */\nexport type CategoryCreated = CategoryIdResponse;\n\n/** Body for searching category trees (`POST /category-trees/search`). */\nexport type CategoryTreeSearchInput = CategoryTreeSearchRequest;\n\n/** A category assignment (a resource reference bound to a category). */\nexport type CategoryAssignment = GeneratedCategoryAssignment;\n\n/** Body for assigning a single resource to a category. */\nexport type CategoryAssignmentInput = AssignmentRequest;\n\n/** Body for bulk-assigning resources to a category. */\nexport type CategoryAssignmentBulkInput = BulkAssignmentRequest;\n\n/** Body for bulk-upserting assignment references (`ref.id` only). */\nexport type CategoryAssignmentRefBulkInput = BulkAssignmentUpsertRequest;\n\n/** Multi-status result of a bulk assignment operation. */\nexport type CategoryAssignmentBulkResult = BulkAssignmentResponse;\n\n/** Id envelope returned when an assignment is created. */\nexport type CategoryAssignmentCreated = AssignmentIdResponse;\n\n/** Options shared by the category write endpoints (create, update, patch). */\nexport interface CategoryWriteOptions {\n /** Sets the `publish` query flag (needs the `category.category_publish` scope). */\n publish?: boolean;\n /**\n * `Content-Language` for this call, overriding `EmporixConfig.contentLanguage`.\n * Category localized fields are maps whatever it says; the header limits the\n * languages they may contain (`\"de\"`, `\"en,de\"`), and without one the\n * service allows every tenant language.\n */\n contentLanguage?: string;\n}\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; totalCount?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Category>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n return requestPage<Category>(\n this.ctx.http,\n {\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { pageNumber, pageSize },\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\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; totalCount?: boolean } = {},\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 return requestPage<Category>(\n this.ctx.http,\n {\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { q, pageNumber, pageSize },\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\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`).\n *\n * Returns `CategoryNode[]` (the generated `CategoryTree`), not `Category[]`.\n * The two differ: `Category` carries `parentId` and no `subcategories`,\n * `CategoryTree` the reverse, and this endpoint answers with the latter.\n * Measured against a live tenant on 2026-08-04 — every node had\n * `subcategories` or nothing, none had `parentId`.\n *\n * **Children arrive inline in `subcategories`.** Do not reach for\n * {@link subcategories} to drill down: that method reads category-to-category\n * *assignments* (`/categories/{id}/assignments`, filtered to\n * `ref.type === \"CATEGORY\"`), which is a different feature — on the tenant this\n * was measured on, that filter answered empty for every category while the\n * `\"PRODUCT\"` filter behind {@link productsIn} worked fine.\n * {@link childCategories} hits `/categories/{id}/subcategories` and answers\n * **404** for a tree root. One call gives you the whole hierarchy.\n */\n async tree(auth: AuthContext = ANON): Promise<CategoryNode[]> {\n return this.ctx.http.request<CategoryNode[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/category-trees`,\n auth,\n });\n }\n\n /**\n * Rebuild a category tree from its root (`POST /category-trees/{rootCategoryId}/rebuild`).\n * Admin write — defaults to the service token. Returns the rebuilt tree.\n */\n async rebuildTree(rootCategoryId: string, auth: AuthContext = SERVICE): Promise<CategoryNode> {\n return this.ctx.http.request<CategoryNode>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/category-trees/${encodeURIComponent(rootCategoryId)}/rebuild`,\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 * No `totalCount` opt-in here, deliberately. `X-Total-Count` on the\n * assignments request would count **assignments** — including the `CATEGORY`\n * references filtered out below — not the products this returns. A number\n * that is wrong in the way that is hardest to notice. Same reason\n * `segments.listMyProducts` stays on the guess.\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 /** Lists a category's ancestor categories (breadcrumb-up). Default auth: anonymous. */\n async parents(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}/parents`,\n auth,\n });\n }\n\n /**\n * Lists a category's direct child categories via the dedicated\n * `…/subcategories` endpoint. (The older `subcategories()` reads `/assignments`\n * and is kept for backward compatibility.) Default auth: anonymous.\n */\n async childCategories(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}/subcategories`,\n auth,\n });\n }\n\n /** Retrieves one category tree by its root category id. Default auth: anonymous. */\n async getTree(categoryId: string, auth: AuthContext = ANON): Promise<CategoryNode> {\n return this.ctx.http.request<CategoryNode>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/category-trees/${encodeURIComponent(categoryId)}`,\n auth,\n });\n }\n\n // --- Admin write CRUD. Default auth: service. ---\n\n /**\n * Creates a category (`POST /categories`). Default auth: service.\n * `options.publish` sets the `publish` query flag (needs the\n * `category.category_publish` scope).\n */\n async create(\n input: CategoryCreateInput,\n options: CategoryWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<CategoryCreated> {\n return this.ctx.http.request<CategoryCreated>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories`,\n ...(options.publish === undefined ? {} : { query: { publish: String(options.publish) } }),\n ...(options.contentLanguage === undefined\n ? {}\n : { headers: { \"Content-Language\": options.contentLanguage } }),\n body: input,\n auth,\n });\n }\n\n /**\n * Full-replaces a category (`PUT /categories/{categoryId}`). This is an\n * upsert: with a caller-supplied id it may create (201, returns the id) or\n * update an existing one (204, returns nothing). Default auth: service.\n */\n async update(\n categoryId: string,\n input: CategoryUpdateInput,\n options: CategoryWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<CategoryCreated | void> {\n return this.ctx.http.request<CategoryCreated | void>({\n method: \"PUT\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n ...(options.publish === undefined ? {} : { query: { publish: String(options.publish) } }),\n ...(options.contentLanguage === undefined\n ? {}\n : { headers: { \"Content-Language\": options.contentLanguage } }),\n body: input,\n auth,\n });\n }\n\n /**\n * Partially updates a category (`PATCH /categories/{categoryId}`). Default\n * auth: service. `options.publish` sets the `publish` query flag.\n */\n async patch(\n categoryId: string,\n input: CategoryPatchInput,\n options: CategoryWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"PATCH\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n ...(options.publish === undefined ? {} : { query: { publish: String(options.publish) } }),\n ...(options.contentLanguage === undefined\n ? {}\n : { headers: { \"Content-Language\": options.contentLanguage } }),\n body: input,\n auth,\n });\n }\n\n /** Deletes a category (`DELETE /categories/{categoryId}`). Default auth: service. */\n async delete(categoryId: string, auth: AuthContext = SERVICE): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n auth,\n });\n }\n\n /**\n * Searches categories via `POST /categories/search`. Same query capability\n * as {@link search} (`compoundLogicalQuery: false` — Category rejects `or()`\n * filters); the POST body avoids URL-length limits for large `q` filters.\n * `params.showRoots` / `params.showUnpublished` are POST-only flags. Default\n * auth: anonymous.\n */\n async searchByQuery(\n query: QueryFor<\"CATEGORY\">,\n params: { pageNumber?: number; pageSize?: number; sort?: string; showRoots?: boolean; showUnpublished?: boolean; totalCount?: boolean } = {},\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 return requestPage<Category>(\n this.ctx.http,\n {\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/search`,\n query: {\n pageNumber,\n pageSize,\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.showRoots === undefined ? {} : { showRoots: String(params.showRoots) }),\n ...(params.showUnpublished === undefined ? {} : { showUnpublished: String(params.showUnpublished) }),\n },\n body: { q },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\n }\n\n /**\n * Searches category trees via `POST /category-trees/search` — returns the\n * trees that include at least one of the given `categoryIds`. Default auth:\n * anonymous.\n */\n async searchTrees(\n input: CategoryTreeSearchInput,\n options: { showUnpublished?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<CategoryNode[]> {\n return this.ctx.http.request<CategoryNode[]>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/category-trees/search`,\n ...(options.showUnpublished === undefined ? {} : { query: { showUnpublished: String(options.showUnpublished) } }),\n body: input,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n auth,\n });\n }\n\n /**\n * Category ↔ resource assignments. Writes default to service auth. The\n * assignment `ref.type` is `'PRODUCT'` (per the API); category hierarchy is\n * managed via `parentId` on the category, not via assignments.\n */\n readonly assignments = {\n /** One page of a category's assignments. Default auth: anonymous. */\n list: async (\n categoryId: string,\n params: { pageNumber?: number; pageSize?: number; sort?: string; expandSupercategoriesIds?: boolean; showUnpublished?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<CategoryAssignment[]> =>\n this.ctx.http.request<CategoryAssignment[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n query: {\n ...(params.pageNumber === undefined ? {} : { pageNumber: params.pageNumber }),\n ...(params.pageSize === undefined ? {} : { pageSize: params.pageSize }),\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.expandSupercategoriesIds === undefined ? {} : { expandSupercategoriesIds: String(params.expandSupercategoriesIds) }),\n ...(params.showUnpublished === undefined ? {} : { showUnpublished: String(params.showUnpublished) }),\n },\n auth,\n }),\n\n /** Assigns a single resource to a category (`POST …/assignments`). Default auth: service. */\n create: async (categoryId: string, input: CategoryAssignmentInput, auth: AuthContext = SERVICE): Promise<CategoryAssignmentCreated> =>\n this.ctx.http.request<CategoryAssignmentCreated>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n body: input,\n auth,\n }),\n\n /** Bulk-assigns resources to a category (`POST …/assignments/bulk`). Default auth: service. */\n bulkCreate: async (categoryId: string, input: CategoryAssignmentBulkInput, auth: AuthContext = SERVICE): Promise<CategoryAssignmentBulkResult> =>\n this.ctx.http.request<CategoryAssignmentBulkResult>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/bulk`,\n body: input,\n auth,\n }),\n\n /** Removes one assignment by id (`DELETE …/assignments/{assignmentId}`). Default auth: service. */\n remove: async (categoryId: string, assignmentId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/${assignmentId}`,\n auth,\n });\n },\n\n /** Removes all of a category's assignments (`DELETE …/assignments`). Default auth: service. */\n removeAll: async (categoryId: string, options: { assignmentType?: \"PRODUCT\" } = {}, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n ...(options.assignmentType === undefined ? {} : { query: { assignmentType: options.assignmentType } }),\n auth,\n });\n },\n\n /** Upserts an assignment by reference id — no body (`PUT …/assignments/references/{referenceId}`). Default auth: service. */\n upsertByReference: async (categoryId: string, referenceId: string, auth: AuthContext = SERVICE): Promise<CategoryAssignmentCreated> =>\n this.ctx.http.request<CategoryAssignmentCreated>({\n method: \"PUT\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/references/${referenceId}`,\n auth,\n }),\n\n /** Removes an assignment by reference id (`DELETE …/assignments/references/{referenceId}`). Default auth: service. */\n removeByReference: async (categoryId: string, referenceId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/references/${referenceId}`,\n auth,\n });\n },\n\n /** Bulk-upserts assignment references (`PUT …/assignments/references/bulk`). Default auth: service. */\n bulkUpsertByReference: async (categoryId: string, input: CategoryAssignmentRefBulkInput, auth: AuthContext = SERVICE): Promise<CategoryAssignmentBulkResult> =>\n this.ctx.http.request<CategoryAssignmentBulkResult>({\n method: \"PUT\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/references/bulk`,\n body: input,\n auth,\n }),\n\n /**\n * Lists every category assigned to the given reference id — tenant-wide\n * (`GET /assignments/references/{referenceId}`). Default auth: anonymous.\n */\n listCategoriesByReference: async (\n referenceId: string,\n params: { pageNumber?: number; pageSize?: number; sort?: string; showUnpublished?: boolean; expandSupercategoriesIds?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<Category[]> =>\n this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/assignments/references/${referenceId}`,\n query: {\n ...(params.pageNumber === undefined ? {} : { pageNumber: params.pageNumber }),\n ...(params.pageSize === undefined ? {} : { pageSize: params.pageSize }),\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.showUnpublished === undefined ? {} : { showUnpublished: String(params.showUnpublished) }),\n ...(params.expandSupercategoriesIds === undefined ? {} : { expandSupercategoriesIds: String(params.expandSupercategoriesIds) }),\n },\n auth,\n }),\n\n /** Removes all assignments to a given reference id — tenant-wide (`DELETE /assignments/references/{referenceId}`). Default auth: service. */\n removeAllByReference: async (referenceId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/assignments/references/${referenceId}`,\n auth,\n });\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/core/context.ts","../src/core/paged.ts","../src/core/query.ts","../src/services/category.ts"],"names":[],"mappings":"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","file":"category.cjs","sourcesContent":["import type { HttpClient } from \"./http\";\nimport type { TokenProvider, AuthContext } from \"./auth\";\nimport type { Logger } from \"./logger\";\n\n/** Shared dependencies every service facade receives. */\nexport interface ClientContext {\n tenant: string;\n http: HttpClient;\n tokenProvider: TokenProvider;\n logger: Logger;\n}\n\n/**\n * A cursor-paged collection — `pageNumber`/`pageSize` indexing with a\n * `hasNextPage` signal driven by the source page being full. Used by all\n * paginated services and hooks across the SDK.\n */\nexport interface PaginatedItems<T> {\n items: T[];\n pageNumber: number;\n pageSize: number;\n hasNextPage: boolean;\n /**\n * Absolute number of matches, when the caller asked for it and the endpoint\n * answered. Opt-in per call (`totalCount: true`), because Emporix computes it\n * with a second query — see `core/paged.ts`.\n *\n * Always `undefined` in cursor mode: the server ignores the request header\n * and omits the response header there.\n */\n totalCount?: number;\n /**\n * Opaque cursor for the next page, on the endpoints that offer one (today:\n * the schema service's custom instances). Pass it back as the `next` query\n * parameter. Absence means \"this endpoint said nothing\", NOT \"last page\".\n */\n nextCursor?: string;\n /** Opaque cursor for the previous page. Same caveat as {@link nextCursor}. */\n prevCursor?: string;\n}\n\n/** Default `AuthContext` applied by a service when the caller passes none. */\nexport type DefaultAuth = AuthContext | undefined;\n\n/**\n * Async-iterates every item across pages of a `PaginatedItems<T>` source.\n * Stops when the source reports `hasNextPage: false`.\n *\n * @param fetchPage - given a 1-based page number, returns the page.\n * @param start - first page to fetch (default `1`).\n */\nexport async function* iterateAll<T>(\n fetchPage: (pageNumber: number) => Promise<PaginatedItems<T>>,\n start = 1,\n): AsyncIterable<T> {\n let p = start;\n for (;;) {\n const page = await fetchPage(p);\n for (const it of page.items) yield it;\n if (!page.hasNextPage) return;\n p += 1;\n }\n}\n\n","import type { PaginatedItems } from \"./context\";\nimport type { HttpClient, RequestOptions } from \"./http\";\n\n/** Pagination inputs for {@link requestPage}. */\nexport interface PageParams {\n /** 1-based, as Emporix counts. */\n pageNumber: number;\n pageSize: number;\n /**\n * Ask Emporix for the absolute match count via the `X-Total-Count: true`\n * request header.\n *\n * Off by default and opt-in per call, not a client-wide setting: the count\n * costs the server a second query, and defaulting it on would put that cost\n * on every list every storefront issues.\n */\n totalCount?: boolean;\n}\n\n/**\n * Reads a non-negative integer header, or `undefined` when it is missing or is\n * not one. A malformed value must not reach the `hasNextPage` arithmetic —\n * `Number(\"lots\")` is `NaN`, and every comparison against `NaN` is `false`,\n * which would silently report \"last page\" on every page.\n */\nfunction intHeader(headers: Headers, name: string): number | undefined {\n const raw = headers.get(name);\n if (raw === null || raw.trim() === \"\") return undefined;\n const n = Number(raw);\n return Number.isInteger(n) && n >= 0 ? n : undefined;\n}\n\n/**\n * Issues one page of a list endpoint and assembles {@link PaginatedItems} from\n * the body plus Emporix's pagination response headers.\n *\n * Cursors travel in opposite directions: the caller sends one as the `next` or\n * `prev` **query parameter** (so it belongs in `o.query`), and the server\n * returns the following one as the `X-Next-Cursor` **response header**. This\n * helper only ever reads them.\n */\nexport async function requestPage<T>(\n http: HttpClient,\n o: RequestOptions,\n page: PageParams,\n): Promise<PaginatedItems<T>> {\n const { data, headers } = await http.requestWithMeta<T[]>(\n page.totalCount === true\n ? { ...o, headers: { ...(o.headers ?? {}), \"X-Total-Count\": \"true\" } }\n : o,\n );\n\n // A 204 or empty body parses to `undefined`. Facades used to index straight\n // into the result and would throw; an empty page is the honest answer.\n const items = data ?? [];\n const totalCount = intHeader(headers, \"X-Total-Count\");\n const nextCursor = headers.get(\"X-Next-Cursor\") ?? undefined;\n const prevCursor = headers.get(\"X-Prev-Cursor\") ?? undefined;\n\n // Three tiers, most precise first. Tier 1 is ONE-DIRECTIONAL on purpose: only\n // two endpoints in the whole API emit a cursor header, so its absence says\n // nothing at all and has to fall through to the other two.\n const hasNextPage =\n nextCursor !== undefined\n ? true\n : totalCount !== undefined\n ? page.pageNumber * page.pageSize < totalCount\n : items.length === page.pageSize;\n\n // Spread conditionally — `exactOptionalPropertyTypes` rejects an explicit\n // `undefined` for an optional property.\n return {\n items,\n pageNumber: page.pageNumber,\n pageSize: page.pageSize,\n hasNextPage,\n ...(totalCount === undefined ? {} : { totalCount }),\n ...(nextCursor === undefined ? {} : { nextCursor }),\n ...(prevCursor === undefined ? {} : { prevCursor }),\n };\n}\n","/**\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","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport { requestPage } from \"../core/paged\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\nimport type { Product } from \"./product\";\nimport type {\n Category as GeneratedCategory,\n CategoryTree,\n CategoryCreateRequest,\n CategoryUpdateRequest,\n CategoryPartialUpdateRequest,\n CategoryIdResponse,\n CategoryTreeSearchRequest,\n GetCategoryTreeRetrieveCategoryTreeData,\n CategoryAssignment as GeneratedCategoryAssignment,\n AssignmentRequest,\n BulkAssignmentRequest,\n BulkAssignmentUpsertRequest,\n BulkAssignmentResponse,\n AssignmentIdResponse,\n} from \"../generated/category\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\nconst SERVICE: AuthContext = { kind: \"service\" };\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/** Body for creating a category (`POST /categories`). */\nexport type CategoryCreateInput = CategoryCreateRequest;\n\n/** Body for a full category replace (`PUT /categories/{id}`). */\nexport type CategoryUpdateInput = CategoryUpdateRequest;\n\n/** Body for a partial category update (`PATCH /categories/{id}`). */\nexport type CategoryPatchInput = CategoryPartialUpdateRequest;\n\n/** Id envelope returned when a category is created. */\nexport type CategoryCreated = CategoryIdResponse;\n\n/** Body for searching category trees (`POST /category-trees/search`). */\nexport type CategoryTreeSearchInput = CategoryTreeSearchRequest;\n\n/** Filters for listing category trees (`GET /category-trees`). */\nexport type CategoryTreeListParams = NonNullable<GetCategoryTreeRetrieveCategoryTreeData[\"query\"]>;\n\n/** A category assignment (a resource reference bound to a category). */\nexport type CategoryAssignment = GeneratedCategoryAssignment;\n\n/** Body for assigning a single resource to a category. */\nexport type CategoryAssignmentInput = AssignmentRequest;\n\n/** Body for bulk-assigning resources to a category. */\nexport type CategoryAssignmentBulkInput = BulkAssignmentRequest;\n\n/** Body for bulk-upserting assignment references (`ref.id` only). */\nexport type CategoryAssignmentRefBulkInput = BulkAssignmentUpsertRequest;\n\n/** Multi-status result of a bulk assignment operation. */\nexport type CategoryAssignmentBulkResult = BulkAssignmentResponse;\n\n/** Id envelope returned when an assignment is created. */\nexport type CategoryAssignmentCreated = AssignmentIdResponse;\n\n/** Options shared by the category write endpoints (create, update, patch). */\nexport interface CategoryWriteOptions {\n /** Sets the `publish` query flag (needs the `category.category_publish` scope). */\n publish?: boolean;\n /**\n * `Content-Language` for this call, overriding `EmporixConfig.contentLanguage`.\n * Category localized fields are maps whatever it says; the header limits the\n * languages they may contain (`\"de\"`, `\"en,de\"`), and without one the\n * service allows every tenant language.\n */\n contentLanguage?: string;\n}\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; totalCount?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Category>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n return requestPage<Category>(\n this.ctx.http,\n {\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { pageNumber, pageSize },\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\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; totalCount?: boolean } = {},\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 return requestPage<Category>(\n this.ctx.http,\n {\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { q, pageNumber, pageSize },\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\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`).\n *\n * Returns `CategoryNode[]` (the generated `CategoryTree`), not `Category[]`.\n * The two differ: `Category` carries `parentId` and no `subcategories`,\n * `CategoryTree` the reverse, and this endpoint answers with the latter.\n * Measured against a live tenant on 2026-08-04 — every node had\n * `subcategories` or nothing, none had `parentId`.\n *\n * **Children arrive inline in `subcategories`.** Do not reach for\n * {@link subcategories} to drill down: that method reads category-to-category\n * *assignments* (`/categories/{id}/assignments`, filtered to\n * `ref.type === \"CATEGORY\"`), which is a different feature — on the tenant this\n * was measured on, that filter answered empty for every category while the\n * `\"PRODUCT\"` filter behind {@link productsIn} worked fine.\n * {@link childCategories} hits `/categories/{id}/subcategories` and answers\n * **404** for a tree root. One call gives you the whole hierarchy.\n *\n * To filter by category type, category ids or publication, use {@link listTrees}.\n */\n async tree(auth: AuthContext = ANON): Promise<CategoryNode[]> {\n return this.listTrees({}, auth);\n }\n\n /**\n * The category trees, filtered (`GET /category-trees`). Default auth: anonymous.\n * {@link tree} is this call without filters.\n *\n * - `categoryIds` goes out comma-joined, because the HTTP layer sends one value\n * per key. Emporix reads `a,b` like the repeated `categoryIds=a&categoryIds=b`;\n * both were probed on `viu` on 2026-10-27. An empty list matches nothing and\n * sends no request.\n * - `showUnpublished` needs `category.category_read_unpublished`. An anonymous\n * token does not carry it, and Emporix answers **403**.\n * - Filter by `type` with care. On `viu` on 2026-10-27, 27 trees built from\n * categories that all read `STANDARD` came back for neither `STANDARD` nor\n * `CLASSIFICATION`, only unfiltered.\n */\n async listTrees(\n params: CategoryTreeListParams = {},\n auth: AuthContext = ANON,\n ): Promise<CategoryNode[]> {\n if (params.categoryIds?.length === 0) return [];\n return this.ctx.http.request<CategoryNode[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/category-trees`,\n query: {\n type: params.type,\n categoryIds: params.categoryIds?.join(\",\"),\n showUnpublished: params.showUnpublished,\n },\n auth,\n });\n }\n\n /**\n * Rebuild a category tree from its root (`POST /category-trees/{rootCategoryId}/rebuild`).\n * Admin write — defaults to the service token. Returns the rebuilt tree.\n */\n async rebuildTree(rootCategoryId: string, auth: AuthContext = SERVICE): Promise<CategoryNode> {\n return this.ctx.http.request<CategoryNode>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/category-trees/${encodeURIComponent(rootCategoryId)}/rebuild`,\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 * No `totalCount` opt-in here, deliberately. `X-Total-Count` on the\n * assignments request would count **assignments** — including the `CATEGORY`\n * references filtered out below — not the products this returns. A number\n * that is wrong in the way that is hardest to notice. Same reason\n * `segments.listMyProducts` stays on the guess.\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 /** Lists a category's ancestor categories (breadcrumb-up). Default auth: anonymous. */\n async parents(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}/parents`,\n auth,\n });\n }\n\n /**\n * Lists a category's direct child categories via the dedicated\n * `…/subcategories` endpoint. (The older `subcategories()` reads `/assignments`\n * and is kept for backward compatibility.) Default auth: anonymous.\n */\n async childCategories(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}/subcategories`,\n auth,\n });\n }\n\n /** Retrieves one category tree by its root category id. Default auth: anonymous. */\n async getTree(categoryId: string, auth: AuthContext = ANON): Promise<CategoryNode> {\n return this.ctx.http.request<CategoryNode>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/category-trees/${encodeURIComponent(categoryId)}`,\n auth,\n });\n }\n\n // --- Admin write CRUD. Default auth: service. ---\n\n /**\n * Creates a category (`POST /categories`). Default auth: service.\n * `options.publish` sets the `publish` query flag (needs the\n * `category.category_publish` scope).\n */\n async create(\n input: CategoryCreateInput,\n options: CategoryWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<CategoryCreated> {\n return this.ctx.http.request<CategoryCreated>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories`,\n ...(options.publish === undefined ? {} : { query: { publish: String(options.publish) } }),\n ...(options.contentLanguage === undefined\n ? {}\n : { headers: { \"Content-Language\": options.contentLanguage } }),\n body: input,\n auth,\n });\n }\n\n /**\n * Full-replaces a category (`PUT /categories/{categoryId}`). This is an\n * upsert: with a caller-supplied id it may create (201, returns the id) or\n * update an existing one (204, returns nothing). Default auth: service.\n */\n async update(\n categoryId: string,\n input: CategoryUpdateInput,\n options: CategoryWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<CategoryCreated | void> {\n return this.ctx.http.request<CategoryCreated | void>({\n method: \"PUT\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n ...(options.publish === undefined ? {} : { query: { publish: String(options.publish) } }),\n ...(options.contentLanguage === undefined\n ? {}\n : { headers: { \"Content-Language\": options.contentLanguage } }),\n body: input,\n auth,\n });\n }\n\n /**\n * Partially updates a category (`PATCH /categories/{categoryId}`). Default\n * auth: service. `options.publish` sets the `publish` query flag.\n */\n async patch(\n categoryId: string,\n input: CategoryPatchInput,\n options: CategoryWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"PATCH\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n ...(options.publish === undefined ? {} : { query: { publish: String(options.publish) } }),\n ...(options.contentLanguage === undefined\n ? {}\n : { headers: { \"Content-Language\": options.contentLanguage } }),\n body: input,\n auth,\n });\n }\n\n /** Deletes a category (`DELETE /categories/{categoryId}`). Default auth: service. */\n async delete(categoryId: string, auth: AuthContext = SERVICE): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n auth,\n });\n }\n\n /**\n * Searches categories via `POST /categories/search`. Same query capability\n * as {@link search} (`compoundLogicalQuery: false` — Category rejects `or()`\n * filters); the POST body avoids URL-length limits for large `q` filters.\n * `params.showRoots` / `params.showUnpublished` are POST-only flags. Default\n * auth: anonymous.\n */\n async searchByQuery(\n query: QueryFor<\"CATEGORY\">,\n params: { pageNumber?: number; pageSize?: number; sort?: string; showRoots?: boolean; showUnpublished?: boolean; totalCount?: boolean } = {},\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 return requestPage<Category>(\n this.ctx.http,\n {\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/search`,\n query: {\n pageNumber,\n pageSize,\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.showRoots === undefined ? {} : { showRoots: String(params.showRoots) }),\n ...(params.showUnpublished === undefined ? {} : { showUnpublished: String(params.showUnpublished) }),\n },\n body: { q },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\n }\n\n /**\n * Searches category trees via `POST /category-trees/search` — returns the\n * trees that include at least one of the given `categoryIds`. Default auth:\n * anonymous.\n */\n async searchTrees(\n input: CategoryTreeSearchInput,\n options: { showUnpublished?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<CategoryNode[]> {\n return this.ctx.http.request<CategoryNode[]>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/category-trees/search`,\n ...(options.showUnpublished === undefined ? {} : { query: { showUnpublished: String(options.showUnpublished) } }),\n body: input,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n auth,\n });\n }\n\n /**\n * Category ↔ resource assignments. Writes default to service auth. The\n * assignment `ref.type` is `'PRODUCT'` (per the API); category hierarchy is\n * managed via `parentId` on the category, not via assignments.\n */\n readonly assignments = {\n /** One page of a category's assignments. Default auth: anonymous. */\n list: async (\n categoryId: string,\n params: { pageNumber?: number; pageSize?: number; sort?: string; expandSupercategoriesIds?: boolean; showUnpublished?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<CategoryAssignment[]> =>\n this.ctx.http.request<CategoryAssignment[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n query: {\n ...(params.pageNumber === undefined ? {} : { pageNumber: params.pageNumber }),\n ...(params.pageSize === undefined ? {} : { pageSize: params.pageSize }),\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.expandSupercategoriesIds === undefined ? {} : { expandSupercategoriesIds: String(params.expandSupercategoriesIds) }),\n ...(params.showUnpublished === undefined ? {} : { showUnpublished: String(params.showUnpublished) }),\n },\n auth,\n }),\n\n /** Assigns a single resource to a category (`POST …/assignments`). Default auth: service. */\n create: async (categoryId: string, input: CategoryAssignmentInput, auth: AuthContext = SERVICE): Promise<CategoryAssignmentCreated> =>\n this.ctx.http.request<CategoryAssignmentCreated>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n body: input,\n auth,\n }),\n\n /** Bulk-assigns resources to a category (`POST …/assignments/bulk`). Default auth: service. */\n bulkCreate: async (categoryId: string, input: CategoryAssignmentBulkInput, auth: AuthContext = SERVICE): Promise<CategoryAssignmentBulkResult> =>\n this.ctx.http.request<CategoryAssignmentBulkResult>({\n method: \"POST\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/bulk`,\n body: input,\n auth,\n }),\n\n /** Removes one assignment by id (`DELETE …/assignments/{assignmentId}`). Default auth: service. */\n remove: async (categoryId: string, assignmentId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/${assignmentId}`,\n auth,\n });\n },\n\n /** Removes all of a category's assignments (`DELETE …/assignments`). Default auth: service. */\n removeAll: async (categoryId: string, options: { assignmentType?: \"PRODUCT\" } = {}, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,\n ...(options.assignmentType === undefined ? {} : { query: { assignmentType: options.assignmentType } }),\n auth,\n });\n },\n\n /** Upserts an assignment by reference id — no body (`PUT …/assignments/references/{referenceId}`). Default auth: service. */\n upsertByReference: async (categoryId: string, referenceId: string, auth: AuthContext = SERVICE): Promise<CategoryAssignmentCreated> =>\n this.ctx.http.request<CategoryAssignmentCreated>({\n method: \"PUT\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/references/${referenceId}`,\n auth,\n }),\n\n /** Removes an assignment by reference id (`DELETE …/assignments/references/{referenceId}`). Default auth: service. */\n removeByReference: async (categoryId: string, referenceId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/references/${referenceId}`,\n auth,\n });\n },\n\n /** Bulk-upserts assignment references (`PUT …/assignments/references/bulk`). Default auth: service. */\n bulkUpsertByReference: async (categoryId: string, input: CategoryAssignmentRefBulkInput, auth: AuthContext = SERVICE): Promise<CategoryAssignmentBulkResult> =>\n this.ctx.http.request<CategoryAssignmentBulkResult>({\n method: \"PUT\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments/references/bulk`,\n body: input,\n auth,\n }),\n\n /**\n * Lists every category assigned to the given reference id — tenant-wide\n * (`GET /assignments/references/{referenceId}`). Default auth: anonymous.\n */\n listCategoriesByReference: async (\n referenceId: string,\n params: { pageNumber?: number; pageSize?: number; sort?: string; showUnpublished?: boolean; expandSupercategoriesIds?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<Category[]> =>\n this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/assignments/references/${referenceId}`,\n query: {\n ...(params.pageNumber === undefined ? {} : { pageNumber: params.pageNumber }),\n ...(params.pageSize === undefined ? {} : { pageSize: params.pageSize }),\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.showUnpublished === undefined ? {} : { showUnpublished: String(params.showUnpublished) }),\n ...(params.expandSupercategoriesIds === undefined ? {} : { expandSupercategoriesIds: String(params.expandSupercategoriesIds) }),\n },\n auth,\n }),\n\n /** Removes all assignments to a given reference id — tenant-wide (`DELETE /assignments/references/{referenceId}`). Default auth: service. */\n removeAllByReference: async (referenceId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/category/${this.ctx.tenant}/assignments/references/${referenceId}`,\n auth,\n });\n },\n };\n}\n"]}
@@ -566,6 +566,45 @@ type Validity = {
566
566
  */
567
567
  to?: string;
568
568
  };
569
+ type GetCategoryTreeRetrieveCategoryTreeData = {
570
+ body?: never;
571
+ path: {
572
+ /**
573
+ * Your Emporix tenant name.
574
+ *
575
+ * **Note**: The tenant should always be written in lowercase.
576
+ *
577
+ */
578
+ tenant: string;
579
+ };
580
+ query?: {
581
+ /**
582
+ * If set to `true`, not published categories are retrieved as well.
583
+ * Possible values:
584
+ * * `true`
585
+ * * `false`
586
+ *
587
+ * **Note**: To get unpublished categories you need to have `category.category_read_unpublished` scope.
588
+ *
589
+ */
590
+ showUnpublished?: boolean;
591
+ /**
592
+ * List of category IDs. If provided, the response returns only the category trees that include at least one of the specified categories.
593
+ *
594
+ */
595
+ categoryIds?: Array<string>;
596
+ /**
597
+ * Category type used to filter the category trees. If not provided, category trees of all types are returned.
598
+ * You can combine this parameter with `categoryIds` to return trees of the specified type that include at least one of the specified categories.
599
+ * The following category types are available:
600
+ * * `STANDARD`
601
+ * * `CLASSIFICATION`
602
+ *
603
+ */
604
+ type?: 'STANDARD' | 'CLASSIFICATION';
605
+ };
606
+ url: '/category/{tenant}/category-trees';
607
+ };
569
608
 
570
609
  /** A category as returned by the Category service (all generated fields). */
571
610
  type Category = Category$1;
@@ -581,6 +620,8 @@ type CategoryPatchInput = CategoryPartialUpdateRequest;
581
620
  type CategoryCreated = CategoryIdResponse;
582
621
  /** Body for searching category trees (`POST /category-trees/search`). */
583
622
  type CategoryTreeSearchInput = CategoryTreeSearchRequest;
623
+ /** Filters for listing category trees (`GET /category-trees`). */
624
+ type CategoryTreeListParams = NonNullable<GetCategoryTreeRetrieveCategoryTreeData["query"]>;
584
625
  /** A category assignment (a resource reference bound to a category). */
585
626
  type CategoryAssignment = CategoryAssignment$1;
586
627
  /** Body for assigning a single resource to a category. */
@@ -650,8 +691,25 @@ declare class CategoryService {
650
691
  * `"PRODUCT"` filter behind {@link productsIn} worked fine.
651
692
  * {@link childCategories} hits `/categories/{id}/subcategories` and answers
652
693
  * **404** for a tree root. One call gives you the whole hierarchy.
694
+ *
695
+ * To filter by category type, category ids or publication, use {@link listTrees}.
653
696
  */
654
697
  tree(auth?: AuthContext): Promise<CategoryNode[]>;
698
+ /**
699
+ * The category trees, filtered (`GET /category-trees`). Default auth: anonymous.
700
+ * {@link tree} is this call without filters.
701
+ *
702
+ * - `categoryIds` goes out comma-joined, because the HTTP layer sends one value
703
+ * per key. Emporix reads `a,b` like the repeated `categoryIds=a&categoryIds=b`;
704
+ * both were probed on `viu` on 2026-10-27. An empty list matches nothing and
705
+ * sends no request.
706
+ * - `showUnpublished` needs `category.category_read_unpublished`. An anonymous
707
+ * token does not carry it, and Emporix answers **403**.
708
+ * - Filter by `type` with care. On `viu` on 2026-10-27, 27 trees built from
709
+ * categories that all read `STANDARD` came back for neither `STANDARD` nor
710
+ * `CLASSIFICATION`, only unfiltered.
711
+ */
712
+ listTrees(params?: CategoryTreeListParams, auth?: AuthContext): Promise<CategoryNode[]>;
655
713
  /**
656
714
  * Rebuild a category tree from its root (`POST /category-trees/{rootCategoryId}/rebuild`).
657
715
  * Admin write — defaults to the service token. Returns the rebuilt tree.
@@ -792,4 +850,4 @@ declare class CategoryService {
792
850
  };
793
851
  }
794
852
 
795
- export { type Category, type CategoryAssignment, type CategoryAssignmentBulkInput, type CategoryAssignmentBulkResult, type CategoryAssignmentCreated, type CategoryAssignmentInput, type CategoryAssignmentRefBulkInput, type CategoryCreateInput, type CategoryCreated, type CategoryNode, type CategoryPatchInput, CategoryService, type CategoryTreeSearchInput, type CategoryUpdateInput, type CategoryWriteOptions };
853
+ export { type Category, type CategoryAssignment, type CategoryAssignmentBulkInput, type CategoryAssignmentBulkResult, type CategoryAssignmentCreated, type CategoryAssignmentInput, type CategoryAssignmentRefBulkInput, type CategoryCreateInput, type CategoryCreated, type CategoryNode, type CategoryPatchInput, CategoryService, type CategoryTreeListParams, type CategoryTreeSearchInput, type CategoryUpdateInput, type CategoryWriteOptions };
@@ -566,6 +566,45 @@ type Validity = {
566
566
  */
567
567
  to?: string;
568
568
  };
569
+ type GetCategoryTreeRetrieveCategoryTreeData = {
570
+ body?: never;
571
+ path: {
572
+ /**
573
+ * Your Emporix tenant name.
574
+ *
575
+ * **Note**: The tenant should always be written in lowercase.
576
+ *
577
+ */
578
+ tenant: string;
579
+ };
580
+ query?: {
581
+ /**
582
+ * If set to `true`, not published categories are retrieved as well.
583
+ * Possible values:
584
+ * * `true`
585
+ * * `false`
586
+ *
587
+ * **Note**: To get unpublished categories you need to have `category.category_read_unpublished` scope.
588
+ *
589
+ */
590
+ showUnpublished?: boolean;
591
+ /**
592
+ * List of category IDs. If provided, the response returns only the category trees that include at least one of the specified categories.
593
+ *
594
+ */
595
+ categoryIds?: Array<string>;
596
+ /**
597
+ * Category type used to filter the category trees. If not provided, category trees of all types are returned.
598
+ * You can combine this parameter with `categoryIds` to return trees of the specified type that include at least one of the specified categories.
599
+ * The following category types are available:
600
+ * * `STANDARD`
601
+ * * `CLASSIFICATION`
602
+ *
603
+ */
604
+ type?: 'STANDARD' | 'CLASSIFICATION';
605
+ };
606
+ url: '/category/{tenant}/category-trees';
607
+ };
569
608
 
570
609
  /** A category as returned by the Category service (all generated fields). */
571
610
  type Category = Category$1;
@@ -581,6 +620,8 @@ type CategoryPatchInput = CategoryPartialUpdateRequest;
581
620
  type CategoryCreated = CategoryIdResponse;
582
621
  /** Body for searching category trees (`POST /category-trees/search`). */
583
622
  type CategoryTreeSearchInput = CategoryTreeSearchRequest;
623
+ /** Filters for listing category trees (`GET /category-trees`). */
624
+ type CategoryTreeListParams = NonNullable<GetCategoryTreeRetrieveCategoryTreeData["query"]>;
584
625
  /** A category assignment (a resource reference bound to a category). */
585
626
  type CategoryAssignment = CategoryAssignment$1;
586
627
  /** Body for assigning a single resource to a category. */
@@ -650,8 +691,25 @@ declare class CategoryService {
650
691
  * `"PRODUCT"` filter behind {@link productsIn} worked fine.
651
692
  * {@link childCategories} hits `/categories/{id}/subcategories` and answers
652
693
  * **404** for a tree root. One call gives you the whole hierarchy.
694
+ *
695
+ * To filter by category type, category ids or publication, use {@link listTrees}.
653
696
  */
654
697
  tree(auth?: AuthContext): Promise<CategoryNode[]>;
698
+ /**
699
+ * The category trees, filtered (`GET /category-trees`). Default auth: anonymous.
700
+ * {@link tree} is this call without filters.
701
+ *
702
+ * - `categoryIds` goes out comma-joined, because the HTTP layer sends one value
703
+ * per key. Emporix reads `a,b` like the repeated `categoryIds=a&categoryIds=b`;
704
+ * both were probed on `viu` on 2026-10-27. An empty list matches nothing and
705
+ * sends no request.
706
+ * - `showUnpublished` needs `category.category_read_unpublished`. An anonymous
707
+ * token does not carry it, and Emporix answers **403**.
708
+ * - Filter by `type` with care. On `viu` on 2026-10-27, 27 trees built from
709
+ * categories that all read `STANDARD` came back for neither `STANDARD` nor
710
+ * `CLASSIFICATION`, only unfiltered.
711
+ */
712
+ listTrees(params?: CategoryTreeListParams, auth?: AuthContext): Promise<CategoryNode[]>;
655
713
  /**
656
714
  * Rebuild a category tree from its root (`POST /category-trees/{rootCategoryId}/rebuild`).
657
715
  * Admin write — defaults to the service token. Returns the rebuilt tree.
@@ -792,4 +850,4 @@ declare class CategoryService {
792
850
  };
793
851
  }
794
852
 
795
- export { type Category, type CategoryAssignment, type CategoryAssignmentBulkInput, type CategoryAssignmentBulkResult, type CategoryAssignmentCreated, type CategoryAssignmentInput, type CategoryAssignmentRefBulkInput, type CategoryCreateInput, type CategoryCreated, type CategoryNode, type CategoryPatchInput, CategoryService, type CategoryTreeSearchInput, type CategoryUpdateInput, type CategoryWriteOptions };
853
+ export { type Category, type CategoryAssignment, type CategoryAssignmentBulkInput, type CategoryAssignmentBulkResult, type CategoryAssignmentCreated, type CategoryAssignmentInput, type CategoryAssignmentRefBulkInput, type CategoryCreateInput, type CategoryCreated, type CategoryNode, type CategoryPatchInput, CategoryService, type CategoryTreeListParams, type CategoryTreeSearchInput, type CategoryUpdateInput, type CategoryWriteOptions };
package/dist/category.js CHANGED
@@ -1,4 +1,4 @@
1
- export { CategoryService } from './chunk-KJEBG7MP.js';
1
+ export { CategoryService } from './chunk-PYIUJBMS.js';
2
2
  import './chunk-W6SLZNRX.js';
3
3
  import './chunk-S5HEIQDK.js';
4
4
  import './chunk-LKHKFF7B.js';
@@ -85,11 +85,36 @@ var CategoryService = class {
85
85
  * `"PRODUCT"` filter behind {@link productsIn} worked fine.
86
86
  * {@link childCategories} hits `/categories/{id}/subcategories` and answers
87
87
  * **404** for a tree root. One call gives you the whole hierarchy.
88
+ *
89
+ * To filter by category type, category ids or publication, use {@link listTrees}.
88
90
  */
89
91
  async tree(auth = ANON) {
92
+ return this.listTrees({}, auth);
93
+ }
94
+ /**
95
+ * The category trees, filtered (`GET /category-trees`). Default auth: anonymous.
96
+ * {@link tree} is this call without filters.
97
+ *
98
+ * - `categoryIds` goes out comma-joined, because the HTTP layer sends one value
99
+ * per key. Emporix reads `a,b` like the repeated `categoryIds=a&categoryIds=b`;
100
+ * both were probed on `viu` on 2026-10-27. An empty list matches nothing and
101
+ * sends no request.
102
+ * - `showUnpublished` needs `category.category_read_unpublished`. An anonymous
103
+ * token does not carry it, and Emporix answers **403**.
104
+ * - Filter by `type` with care. On `viu` on 2026-10-27, 27 trees built from
105
+ * categories that all read `STANDARD` came back for neither `STANDARD` nor
106
+ * `CLASSIFICATION`, only unfiltered.
107
+ */
108
+ async listTrees(params = {}, auth = ANON) {
109
+ if (params.categoryIds?.length === 0) return [];
90
110
  return this.ctx.http.request({
91
111
  method: "GET",
92
112
  path: `/category/${this.ctx.tenant}/category-trees`,
113
+ query: {
114
+ type: params.type,
115
+ categoryIds: params.categoryIds?.join(","),
116
+ showUnpublished: params.showUnpublished
117
+ },
93
118
  auth
94
119
  });
95
120
  }
@@ -419,5 +444,5 @@ var CategoryService = class {
419
444
  };
420
445
 
421
446
  export { CategoryService };
422
- //# sourceMappingURL=chunk-KJEBG7MP.js.map
423
- //# sourceMappingURL=chunk-KJEBG7MP.js.map
447
+ //# sourceMappingURL=chunk-PYIUJBMS.js.map
448
+ //# sourceMappingURL=chunk-PYIUJBMS.js.map