@viu/emporix-sdk 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/category.cjs +49 -8
- package/dist/category.cjs.map +1 -1
- package/dist/category.d.cts +24 -3
- package/dist/category.d.ts +24 -3
- package/dist/category.js +1 -1
- package/dist/{chunk-4BJUCCKJ.js → chunk-AUVJ5V47.js} +51 -10
- package/dist/chunk-AUVJ5V47.js.map +1 -0
- package/dist/index.cjs +50 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4BJUCCKJ.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @viu/emporix-sdk
|
|
2
2
|
|
|
3
|
+
## 2.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#96](https://github.com/viuteam/emporix-sdk/pull/96) [`da1113a`](https://github.com/viuteam/emporix-sdk/commit/da1113a07f70dceb9f1cb732b28462ccb3671f4a) Thanks [@amnael1](https://github.com/amnael1)! - Fix and extend the Category service for catalogue + hierarchy browsing. Several
|
|
8
|
+
methods targeted routes that don't exist on the deployed category service
|
|
9
|
+
(verified against a live tenant):
|
|
10
|
+
- **`categories.productsIn(...)`** requested a non-existent
|
|
11
|
+
`/categories/{id}/products` route (always 404). It now resolves products via
|
|
12
|
+
category **assignments** (`/categories/{id}/assignments` → keep `PRODUCT`
|
|
13
|
+
refs → `/products/search`), preserving its `PaginatedItems<Product>` contract;
|
|
14
|
+
categories with no products return an empty page instead of throwing.
|
|
15
|
+
- **`categories.tree()`** pointed at a non-existent `/categories/{...}Tree`
|
|
16
|
+
route. It now reads `/category-trees` and returns the catalogue's **root
|
|
17
|
+
categories** (`Promise<Category[]>`) for top-level navigation. (Return type
|
|
18
|
+
changed from the previous nested-node shape; the `rootId` argument is removed.)
|
|
19
|
+
- **New `categories.subcategories(categoryId)`** (+ React `useSubcategories`):
|
|
20
|
+
a category's direct child categories, resolved from `CATEGORY` assignment refs
|
|
21
|
+
(mirrors `productsIn`). Returns `[]` when there are none.
|
|
22
|
+
|
|
23
|
+
React `useCategoryTree()` now returns `Category[]` (root categories) and takes no
|
|
24
|
+
`rootId`.
|
|
25
|
+
|
|
3
26
|
## 2.6.0
|
|
4
27
|
|
|
5
28
|
### Minor Changes
|
package/dist/category.cjs
CHANGED
|
@@ -43,26 +43,67 @@ var CategoryService = class {
|
|
|
43
43
|
const pageSize = params.pageSize ?? 50;
|
|
44
44
|
return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth));
|
|
45
45
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
46
|
+
/**
|
|
47
|
+
* The catalogue's **root categories** — the published category trees
|
|
48
|
+
* (`GET /category-trees`). Use these for top-level storefront navigation;
|
|
49
|
+
* drill into a node's children with {@link subcategories}.
|
|
50
|
+
*/
|
|
51
|
+
async tree(auth = ANON) {
|
|
48
52
|
return this.ctx.http.request({
|
|
49
53
|
method: "GET",
|
|
50
|
-
path: `/category/${this.ctx.tenant}/
|
|
51
|
-
|
|
54
|
+
path: `/category/${this.ctx.tenant}/category-trees`,
|
|
55
|
+
auth
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Direct child categories of a category (for hierarchy drill-down). Mirrors
|
|
60
|
+
* {@link productsIn}: reads the category's **assignments** and keeps the
|
|
61
|
+
* `CATEGORY` references, resolving them to full categories. Returns an empty
|
|
62
|
+
* array when the category has no child categories.
|
|
63
|
+
*/
|
|
64
|
+
async subcategories(categoryId, params = {}, auth = ANON) {
|
|
65
|
+
const pageNumber = params.pageNumber ?? 1;
|
|
66
|
+
const pageSize = params.pageSize ?? 50;
|
|
67
|
+
const assignments = await this.ctx.http.request({
|
|
68
|
+
method: "GET",
|
|
69
|
+
path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
|
|
70
|
+
query: { pageNumber, pageSize },
|
|
52
71
|
auth
|
|
53
72
|
});
|
|
73
|
+
const categoryIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "CATEGORY" ? a.ref.id : void 0).filter((id) => Boolean(id));
|
|
74
|
+
if (categoryIds.length === 0) return [];
|
|
75
|
+
return this.searchByIds(categoryIds, {}, auth);
|
|
54
76
|
}
|
|
55
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* One page of products in a category. The category service exposes products
|
|
79
|
+
* as **assignments** (`/categories/{id}/assignments`) — references, not full
|
|
80
|
+
* products — so this fetches a page of assignments, keeps the `PRODUCT`
|
|
81
|
+
* references, and resolves them to full products via `/products/search`.
|
|
82
|
+
* `hasNextPage` reflects the assignments page (the source of truth for
|
|
83
|
+
* pagination).
|
|
84
|
+
*/
|
|
56
85
|
async productsIn(categoryId, params = {}, auth = ANON) {
|
|
57
86
|
const pageNumber = params.pageNumber ?? 1;
|
|
58
87
|
const pageSize = params.pageSize ?? 50;
|
|
59
|
-
const
|
|
88
|
+
const assignments = await this.ctx.http.request({
|
|
60
89
|
method: "GET",
|
|
61
|
-
path: `/category/${this.ctx.tenant}/categories/${categoryId}/
|
|
90
|
+
path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
|
|
62
91
|
query: { pageNumber, pageSize },
|
|
63
92
|
auth
|
|
64
93
|
});
|
|
65
|
-
|
|
94
|
+
const hasNextPage = assignments.length === pageSize;
|
|
95
|
+
const productIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "PRODUCT" ? a.ref.id : void 0).filter((id) => Boolean(id));
|
|
96
|
+
if (productIds.length === 0) {
|
|
97
|
+
return { items: [], pageNumber, pageSize, hasNextPage };
|
|
98
|
+
}
|
|
99
|
+
const items = await this.ctx.http.request({
|
|
100
|
+
method: "POST",
|
|
101
|
+
path: `/product/${this.ctx.tenant}/products/search`,
|
|
102
|
+
query: { pageSize: productIds.length },
|
|
103
|
+
auth,
|
|
104
|
+
body: { q: `id:(${productIds.join(",")})` }
|
|
105
|
+
});
|
|
106
|
+
return { items, pageNumber, pageSize, hasNextPage };
|
|
66
107
|
}
|
|
67
108
|
/**
|
|
68
109
|
* Bulk fetch by id. POSTs `/categories/search` with `q="id:(id1,id2,…)"`,
|
package/dist/category.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/context.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\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 { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\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 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 /** 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 /** Fetches the category tree, optionally rooted at `rootId`. */\n async tree(rootId?: string, auth: AuthContext = ANON): Promise<CategoryNode> {\n return this.ctx.http.request<CategoryNode>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/tree`,\n query: rootId ? { rootId } : {},\n auth,\n });\n }\n\n /** One page of products in a category. */\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 items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}/products`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\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
|
+
{"version":3,"sources":["../src/core/context.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\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 { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\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 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 /** 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 });\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"]}
|
package/dist/category.d.cts
CHANGED
|
@@ -292,9 +292,30 @@ declare class CategoryService {
|
|
|
292
292
|
listAll(params?: {
|
|
293
293
|
pageSize?: number;
|
|
294
294
|
}, auth?: AuthContext): AsyncIterable<Category>;
|
|
295
|
-
/**
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
/**
|
|
296
|
+
* The catalogue's **root categories** — the published category trees
|
|
297
|
+
* (`GET /category-trees`). Use these for top-level storefront navigation;
|
|
298
|
+
* drill into a node's children with {@link subcategories}.
|
|
299
|
+
*/
|
|
300
|
+
tree(auth?: AuthContext): Promise<Category[]>;
|
|
301
|
+
/**
|
|
302
|
+
* Direct child categories of a category (for hierarchy drill-down). Mirrors
|
|
303
|
+
* {@link productsIn}: reads the category's **assignments** and keeps the
|
|
304
|
+
* `CATEGORY` references, resolving them to full categories. Returns an empty
|
|
305
|
+
* array when the category has no child categories.
|
|
306
|
+
*/
|
|
307
|
+
subcategories(categoryId: string, params?: {
|
|
308
|
+
pageNumber?: number;
|
|
309
|
+
pageSize?: number;
|
|
310
|
+
}, auth?: AuthContext): Promise<Category[]>;
|
|
311
|
+
/**
|
|
312
|
+
* One page of products in a category. The category service exposes products
|
|
313
|
+
* as **assignments** (`/categories/{id}/assignments`) — references, not full
|
|
314
|
+
* products — so this fetches a page of assignments, keeps the `PRODUCT`
|
|
315
|
+
* references, and resolves them to full products via `/products/search`.
|
|
316
|
+
* `hasNextPage` reflects the assignments page (the source of truth for
|
|
317
|
+
* pagination).
|
|
318
|
+
*/
|
|
298
319
|
productsIn(categoryId: string, params?: {
|
|
299
320
|
pageNumber?: number;
|
|
300
321
|
pageSize?: number;
|
package/dist/category.d.ts
CHANGED
|
@@ -292,9 +292,30 @@ declare class CategoryService {
|
|
|
292
292
|
listAll(params?: {
|
|
293
293
|
pageSize?: number;
|
|
294
294
|
}, auth?: AuthContext): AsyncIterable<Category>;
|
|
295
|
-
/**
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
/**
|
|
296
|
+
* The catalogue's **root categories** — the published category trees
|
|
297
|
+
* (`GET /category-trees`). Use these for top-level storefront navigation;
|
|
298
|
+
* drill into a node's children with {@link subcategories}.
|
|
299
|
+
*/
|
|
300
|
+
tree(auth?: AuthContext): Promise<Category[]>;
|
|
301
|
+
/**
|
|
302
|
+
* Direct child categories of a category (for hierarchy drill-down). Mirrors
|
|
303
|
+
* {@link productsIn}: reads the category's **assignments** and keeps the
|
|
304
|
+
* `CATEGORY` references, resolving them to full categories. Returns an empty
|
|
305
|
+
* array when the category has no child categories.
|
|
306
|
+
*/
|
|
307
|
+
subcategories(categoryId: string, params?: {
|
|
308
|
+
pageNumber?: number;
|
|
309
|
+
pageSize?: number;
|
|
310
|
+
}, auth?: AuthContext): Promise<Category[]>;
|
|
311
|
+
/**
|
|
312
|
+
* One page of products in a category. The category service exposes products
|
|
313
|
+
* as **assignments** (`/categories/{id}/assignments`) — references, not full
|
|
314
|
+
* products — so this fetches a page of assignments, keeps the `PRODUCT`
|
|
315
|
+
* references, and resolves them to full products via `/products/search`.
|
|
316
|
+
* `hasNextPage` reflects the assignments page (the source of truth for
|
|
317
|
+
* pagination).
|
|
318
|
+
*/
|
|
298
319
|
productsIn(categoryId: string, params?: {
|
|
299
320
|
pageNumber?: number;
|
|
300
321
|
pageSize?: number;
|
package/dist/category.js
CHANGED
|
@@ -32,26 +32,67 @@ var CategoryService = class {
|
|
|
32
32
|
const pageSize = params.pageSize ?? 50;
|
|
33
33
|
return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth));
|
|
34
34
|
}
|
|
35
|
-
/**
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The catalogue's **root categories** — the published category trees
|
|
37
|
+
* (`GET /category-trees`). Use these for top-level storefront navigation;
|
|
38
|
+
* drill into a node's children with {@link subcategories}.
|
|
39
|
+
*/
|
|
40
|
+
async tree(auth = ANON) {
|
|
37
41
|
return this.ctx.http.request({
|
|
38
42
|
method: "GET",
|
|
39
|
-
path: `/category/${this.ctx.tenant}/
|
|
40
|
-
|
|
43
|
+
path: `/category/${this.ctx.tenant}/category-trees`,
|
|
44
|
+
auth
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Direct child categories of a category (for hierarchy drill-down). Mirrors
|
|
49
|
+
* {@link productsIn}: reads the category's **assignments** and keeps the
|
|
50
|
+
* `CATEGORY` references, resolving them to full categories. Returns an empty
|
|
51
|
+
* array when the category has no child categories.
|
|
52
|
+
*/
|
|
53
|
+
async subcategories(categoryId, params = {}, auth = ANON) {
|
|
54
|
+
const pageNumber = params.pageNumber ?? 1;
|
|
55
|
+
const pageSize = params.pageSize ?? 50;
|
|
56
|
+
const assignments = await this.ctx.http.request({
|
|
57
|
+
method: "GET",
|
|
58
|
+
path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
|
|
59
|
+
query: { pageNumber, pageSize },
|
|
41
60
|
auth
|
|
42
61
|
});
|
|
62
|
+
const categoryIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "CATEGORY" ? a.ref.id : void 0).filter((id) => Boolean(id));
|
|
63
|
+
if (categoryIds.length === 0) return [];
|
|
64
|
+
return this.searchByIds(categoryIds, {}, auth);
|
|
43
65
|
}
|
|
44
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* One page of products in a category. The category service exposes products
|
|
68
|
+
* as **assignments** (`/categories/{id}/assignments`) — references, not full
|
|
69
|
+
* products — so this fetches a page of assignments, keeps the `PRODUCT`
|
|
70
|
+
* references, and resolves them to full products via `/products/search`.
|
|
71
|
+
* `hasNextPage` reflects the assignments page (the source of truth for
|
|
72
|
+
* pagination).
|
|
73
|
+
*/
|
|
45
74
|
async productsIn(categoryId, params = {}, auth = ANON) {
|
|
46
75
|
const pageNumber = params.pageNumber ?? 1;
|
|
47
76
|
const pageSize = params.pageSize ?? 50;
|
|
48
|
-
const
|
|
77
|
+
const assignments = await this.ctx.http.request({
|
|
49
78
|
method: "GET",
|
|
50
|
-
path: `/category/${this.ctx.tenant}/categories/${categoryId}/
|
|
79
|
+
path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
|
|
51
80
|
query: { pageNumber, pageSize },
|
|
52
81
|
auth
|
|
53
82
|
});
|
|
54
|
-
|
|
83
|
+
const hasNextPage = assignments.length === pageSize;
|
|
84
|
+
const productIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "PRODUCT" ? a.ref.id : void 0).filter((id) => Boolean(id));
|
|
85
|
+
if (productIds.length === 0) {
|
|
86
|
+
return { items: [], pageNumber, pageSize, hasNextPage };
|
|
87
|
+
}
|
|
88
|
+
const items = await this.ctx.http.request({
|
|
89
|
+
method: "POST",
|
|
90
|
+
path: `/product/${this.ctx.tenant}/products/search`,
|
|
91
|
+
query: { pageSize: productIds.length },
|
|
92
|
+
auth,
|
|
93
|
+
body: { q: `id:(${productIds.join(",")})` }
|
|
94
|
+
});
|
|
95
|
+
return { items, pageNumber, pageSize, hasNextPage };
|
|
55
96
|
}
|
|
56
97
|
/**
|
|
57
98
|
* Bulk fetch by id. POSTs `/categories/search` with `q="id:(id1,id2,…)"`,
|
|
@@ -82,5 +123,5 @@ var CategoryService = class {
|
|
|
82
123
|
};
|
|
83
124
|
|
|
84
125
|
export { CategoryService };
|
|
85
|
-
//# sourceMappingURL=chunk-
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
126
|
+
//# sourceMappingURL=chunk-AUVJ5V47.js.map
|
|
127
|
+
//# sourceMappingURL=chunk-AUVJ5V47.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/category.ts"],"names":[],"mappings":"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","file":"chunk-AUVJ5V47.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\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 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 /** 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 });\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"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1124,26 +1124,67 @@ var CategoryService = class {
|
|
|
1124
1124
|
const pageSize = params.pageSize ?? 50;
|
|
1125
1125
|
return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth2));
|
|
1126
1126
|
}
|
|
1127
|
-
/**
|
|
1128
|
-
|
|
1127
|
+
/**
|
|
1128
|
+
* The catalogue's **root categories** — the published category trees
|
|
1129
|
+
* (`GET /category-trees`). Use these for top-level storefront navigation;
|
|
1130
|
+
* drill into a node's children with {@link subcategories}.
|
|
1131
|
+
*/
|
|
1132
|
+
async tree(auth2 = ANON2) {
|
|
1129
1133
|
return this.ctx.http.request({
|
|
1130
1134
|
method: "GET",
|
|
1131
|
-
path: `/category/${this.ctx.tenant}/
|
|
1132
|
-
|
|
1135
|
+
path: `/category/${this.ctx.tenant}/category-trees`,
|
|
1136
|
+
auth: auth2
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Direct child categories of a category (for hierarchy drill-down). Mirrors
|
|
1141
|
+
* {@link productsIn}: reads the category's **assignments** and keeps the
|
|
1142
|
+
* `CATEGORY` references, resolving them to full categories. Returns an empty
|
|
1143
|
+
* array when the category has no child categories.
|
|
1144
|
+
*/
|
|
1145
|
+
async subcategories(categoryId, params = {}, auth2 = ANON2) {
|
|
1146
|
+
const pageNumber = params.pageNumber ?? 1;
|
|
1147
|
+
const pageSize = params.pageSize ?? 50;
|
|
1148
|
+
const assignments = await this.ctx.http.request({
|
|
1149
|
+
method: "GET",
|
|
1150
|
+
path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
|
|
1151
|
+
query: { pageNumber, pageSize },
|
|
1133
1152
|
auth: auth2
|
|
1134
1153
|
});
|
|
1154
|
+
const categoryIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "CATEGORY" ? a.ref.id : void 0).filter((id) => Boolean(id));
|
|
1155
|
+
if (categoryIds.length === 0) return [];
|
|
1156
|
+
return this.searchByIds(categoryIds, {}, auth2);
|
|
1135
1157
|
}
|
|
1136
|
-
/**
|
|
1158
|
+
/**
|
|
1159
|
+
* One page of products in a category. The category service exposes products
|
|
1160
|
+
* as **assignments** (`/categories/{id}/assignments`) — references, not full
|
|
1161
|
+
* products — so this fetches a page of assignments, keeps the `PRODUCT`
|
|
1162
|
+
* references, and resolves them to full products via `/products/search`.
|
|
1163
|
+
* `hasNextPage` reflects the assignments page (the source of truth for
|
|
1164
|
+
* pagination).
|
|
1165
|
+
*/
|
|
1137
1166
|
async productsIn(categoryId, params = {}, auth2 = ANON2) {
|
|
1138
1167
|
const pageNumber = params.pageNumber ?? 1;
|
|
1139
1168
|
const pageSize = params.pageSize ?? 50;
|
|
1140
|
-
const
|
|
1169
|
+
const assignments = await this.ctx.http.request({
|
|
1141
1170
|
method: "GET",
|
|
1142
|
-
path: `/category/${this.ctx.tenant}/categories/${categoryId}/
|
|
1171
|
+
path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
|
|
1143
1172
|
query: { pageNumber, pageSize },
|
|
1144
1173
|
auth: auth2
|
|
1145
1174
|
});
|
|
1146
|
-
|
|
1175
|
+
const hasNextPage = assignments.length === pageSize;
|
|
1176
|
+
const productIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "PRODUCT" ? a.ref.id : void 0).filter((id) => Boolean(id));
|
|
1177
|
+
if (productIds.length === 0) {
|
|
1178
|
+
return { items: [], pageNumber, pageSize, hasNextPage };
|
|
1179
|
+
}
|
|
1180
|
+
const items = await this.ctx.http.request({
|
|
1181
|
+
method: "POST",
|
|
1182
|
+
path: `/product/${this.ctx.tenant}/products/search`,
|
|
1183
|
+
query: { pageSize: productIds.length },
|
|
1184
|
+
auth: auth2,
|
|
1185
|
+
body: { q: `id:(${productIds.join(",")})` }
|
|
1186
|
+
});
|
|
1187
|
+
return { items, pageNumber, pageSize, hasNextPage };
|
|
1147
1188
|
}
|
|
1148
1189
|
/**
|
|
1149
1190
|
* Bulk fetch by id. POSTs `/categories/search` with `q="id:(id1,id2,…)"`,
|
|
@@ -4973,7 +5014,7 @@ var ApprovalService = class {
|
|
|
4973
5014
|
};
|
|
4974
5015
|
|
|
4975
5016
|
// package.json
|
|
4976
|
-
var version = "2.
|
|
5017
|
+
var version = "2.7.0";
|
|
4977
5018
|
|
|
4978
5019
|
// src/version.ts
|
|
4979
5020
|
var SDK_VERSION = version;
|