@viu/emporix-sdk 2.22.0 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/README.md +16 -6
  3. package/dist/availability.cjs +118 -0
  4. package/dist/availability.cjs.map +1 -1
  5. package/dist/availability.d.cts +178 -2
  6. package/dist/availability.d.ts +178 -2
  7. package/dist/availability.js +1 -1
  8. package/dist/cart.cjs +156 -11
  9. package/dist/cart.cjs.map +1 -1
  10. package/dist/cart.d.cts +177 -4
  11. package/dist/cart.d.ts +177 -4
  12. package/dist/cart.js +1 -1
  13. package/dist/category.cjs +192 -2
  14. package/dist/category.cjs.map +1 -1
  15. package/dist/category.d.cts +399 -2
  16. package/dist/category.d.ts +399 -2
  17. package/dist/category.js +1 -1
  18. package/dist/checkout.d.cts +1 -1
  19. package/dist/checkout.d.ts +1 -1
  20. package/dist/{chunk-HD5RBCM6.js → chunk-27NLS646.js} +10 -2
  21. package/dist/chunk-27NLS646.js.map +1 -0
  22. package/dist/{chunk-MMX5FGMI.js → chunk-6PJFOX3A.js} +109 -2
  23. package/dist/chunk-6PJFOX3A.js.map +1 -0
  24. package/dist/chunk-HWVFF6B2.js +378 -0
  25. package/dist/chunk-HWVFF6B2.js.map +1 -0
  26. package/dist/chunk-LQFRJSVT.js +224 -0
  27. package/dist/chunk-LQFRJSVT.js.map +1 -0
  28. package/dist/chunk-P7G4LOOV.js +264 -0
  29. package/dist/chunk-P7G4LOOV.js.map +1 -0
  30. package/dist/{chunk-44F52KRE.js → chunk-QQMLN76U.js} +27 -2
  31. package/dist/chunk-QQMLN76U.js.map +1 -0
  32. package/dist/chunk-UNW6SFSB.js +363 -0
  33. package/dist/chunk-UNW6SFSB.js.map +1 -0
  34. package/dist/chunk-V3275BA7.js +181 -0
  35. package/dist/chunk-V3275BA7.js.map +1 -0
  36. package/dist/chunk-W2KBVWJ2.js +323 -0
  37. package/dist/chunk-W2KBVWJ2.js.map +1 -0
  38. package/dist/{chunk-5DWCYDQD.js → chunk-YVZ6GOLE.js} +158 -13
  39. package/dist/chunk-YVZ6GOLE.js.map +1 -0
  40. package/dist/chunk-ZOFGDNSX.js +305 -0
  41. package/dist/chunk-ZOFGDNSX.js.map +1 -0
  42. package/dist/companies.cjs +25 -0
  43. package/dist/companies.cjs.map +1 -1
  44. package/dist/companies.d.cts +15 -1
  45. package/dist/companies.d.ts +15 -1
  46. package/dist/companies.js +1 -1
  47. package/dist/contacts.cjs +8 -0
  48. package/dist/contacts.cjs.map +1 -1
  49. package/dist/contacts.d.cts +3 -1
  50. package/dist/contacts.d.ts +3 -1
  51. package/dist/contacts.js +1 -1
  52. package/dist/{context-CfXJcYKP.d.cts → context-DC5gSgKK.d.cts} +18 -0
  53. package/dist/{context-CfXJcYKP.d.ts → context-DC5gSgKK.d.ts} +18 -0
  54. package/dist/customer-groups-BqYsPCA6.d.cts +706 -0
  55. package/dist/customer-groups-CLm6Gu9U.d.ts +706 -0
  56. package/dist/customer-groups.cjs +200 -17
  57. package/dist/customer-groups.cjs.map +1 -1
  58. package/dist/customer-groups.d.cts +2 -110
  59. package/dist/customer-groups.d.ts +2 -110
  60. package/dist/customer-groups.js +1 -1
  61. package/dist/customer.d.cts +1 -1
  62. package/dist/customer.d.ts +1 -1
  63. package/dist/index.cjs +2231 -395
  64. package/dist/index.cjs.map +1 -1
  65. package/dist/index.d.cts +435 -13
  66. package/dist/index.d.ts +435 -13
  67. package/dist/index.js +679 -344
  68. package/dist/index.js.map +1 -1
  69. package/dist/locations.d.cts +1 -1
  70. package/dist/locations.d.ts +1 -1
  71. package/dist/media.d.cts +1 -1
  72. package/dist/media.d.ts +1 -1
  73. package/dist/orders.cjs +160 -2
  74. package/dist/orders.cjs.map +1 -1
  75. package/dist/orders.d.cts +222 -2
  76. package/dist/orders.d.ts +222 -2
  77. package/dist/orders.js +1 -1
  78. package/dist/payment.cjs +107 -0
  79. package/dist/payment.cjs.map +1 -1
  80. package/dist/payment.d.cts +300 -2
  81. package/dist/payment.d.ts +300 -2
  82. package/dist/payment.js +1 -1
  83. package/dist/price.cjs +197 -0
  84. package/dist/price.cjs.map +1 -1
  85. package/dist/price.d.cts +578 -2
  86. package/dist/price.d.ts +578 -2
  87. package/dist/price.js +1 -1
  88. package/dist/product.cjs +190 -0
  89. package/dist/product.cjs.map +1 -1
  90. package/dist/product.d.cts +504 -2
  91. package/dist/product.d.ts +504 -2
  92. package/dist/product.js +1 -1
  93. package/dist/segment.cjs +179 -0
  94. package/dist/segment.cjs.map +1 -1
  95. package/dist/segment.d.cts +182 -2
  96. package/dist/segment.d.ts +182 -2
  97. package/dist/segment.js +1 -1
  98. package/package.json +1 -1
  99. package/dist/chunk-36T4YPQJ.js +0 -106
  100. package/dist/chunk-36T4YPQJ.js.map +0 -1
  101. package/dist/chunk-3BTPX7IJ.js +0 -41
  102. package/dist/chunk-3BTPX7IJ.js.map +0 -1
  103. package/dist/chunk-44F52KRE.js.map +0 -1
  104. package/dist/chunk-5DWCYDQD.js.map +0 -1
  105. package/dist/chunk-A3LYJUD4.js +0 -108
  106. package/dist/chunk-A3LYJUD4.js.map +0 -1
  107. package/dist/chunk-DXOLWAOY.js +0 -188
  108. package/dist/chunk-DXOLWAOY.js.map +0 -1
  109. package/dist/chunk-FZMP5NQZ.js +0 -173
  110. package/dist/chunk-FZMP5NQZ.js.map +0 -1
  111. package/dist/chunk-HD5RBCM6.js.map +0 -1
  112. package/dist/chunk-IVCCGJN5.js +0 -63
  113. package/dist/chunk-IVCCGJN5.js.map +0 -1
  114. package/dist/chunk-MMX5FGMI.js.map +0 -1
  115. package/dist/chunk-NE7MIZPR.js +0 -144
  116. package/dist/chunk-NE7MIZPR.js.map +0 -1
@@ -1,188 +0,0 @@
1
- import { iterateAll } from './chunk-GWJ2U2CP.js';
2
- import { resolveQuery } from './chunk-S5HEIQDK.js';
3
-
4
- // src/services/category.ts
5
- var ANON = { kind: "anonymous" };
6
- var SERVICE = { kind: "service" };
7
- var CategoryService = class {
8
- constructor(ctx) {
9
- this.ctx = ctx;
10
- }
11
- ctx;
12
- static channel = "category";
13
- /** Fetches one category by id. */
14
- async get(categoryId, auth = ANON) {
15
- return this.ctx.http.request({
16
- method: "GET",
17
- path: `/category/${this.ctx.tenant}/categories/${categoryId}`,
18
- auth
19
- });
20
- }
21
- /** One page of categories. */
22
- async list(params = {}, auth = ANON) {
23
- const pageNumber = params.pageNumber ?? 1;
24
- const pageSize = params.pageSize ?? 50;
25
- const items = await this.ctx.http.request({
26
- method: "GET",
27
- path: `/category/${this.ctx.tenant}/categories`,
28
- query: { pageNumber, pageSize },
29
- auth
30
- });
31
- return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
32
- }
33
- /**
34
- * Searches categories by a `q` filter — a raw Emporix DSL string or a built
35
- * filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Category does not
36
- * support `compoundLogicalQuery`, so `or()` filters are rejected.
37
- */
38
- async search(query, params = {}, auth = ANON) {
39
- const q = resolveQuery(query, { compoundLogicalQuery: false });
40
- const pageNumber = params.pageNumber ?? 1;
41
- const pageSize = params.pageSize ?? 50;
42
- const items = await this.ctx.http.request({
43
- method: "GET",
44
- path: `/category/${this.ctx.tenant}/categories`,
45
- query: { q, pageNumber, pageSize },
46
- auth
47
- });
48
- return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
49
- }
50
- /** Async-iterates every category across pages. */
51
- listAll(params = {}, auth = ANON) {
52
- const pageSize = params.pageSize ?? 50;
53
- return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth));
54
- }
55
- /**
56
- * The catalogue's **root categories** — the published category trees
57
- * (`GET /category-trees`). Use these for top-level storefront navigation;
58
- * drill into a node's children with {@link subcategories}.
59
- */
60
- async tree(auth = ANON) {
61
- return this.ctx.http.request({
62
- method: "GET",
63
- path: `/category/${this.ctx.tenant}/category-trees`,
64
- auth
65
- });
66
- }
67
- /**
68
- * Rebuild a category tree from its root (`POST /category-trees/{rootCategoryId}/rebuild`).
69
- * Admin write — defaults to the service token. Returns the rebuilt tree.
70
- */
71
- async rebuildTree(rootCategoryId, auth = SERVICE) {
72
- return this.ctx.http.request({
73
- method: "POST",
74
- path: `/category/${this.ctx.tenant}/category-trees/${encodeURIComponent(rootCategoryId)}/rebuild`,
75
- auth
76
- });
77
- }
78
- /**
79
- * Direct child categories of a category (for hierarchy drill-down). Mirrors
80
- * {@link productsIn}: reads the category's **assignments** and keeps the
81
- * `CATEGORY` references, resolving them to full categories. Returns an empty
82
- * array when the category has no child categories.
83
- */
84
- async subcategories(categoryId, params = {}, auth = ANON) {
85
- const pageNumber = params.pageNumber ?? 1;
86
- const pageSize = params.pageSize ?? 50;
87
- const assignments = await this.ctx.http.request({
88
- method: "GET",
89
- path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
90
- query: { pageNumber, pageSize },
91
- auth
92
- });
93
- const categoryIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "CATEGORY" ? a.ref.id : void 0).filter((id) => Boolean(id));
94
- if (categoryIds.length === 0) return [];
95
- return this.searchByIds(categoryIds, {}, auth);
96
- }
97
- /**
98
- * One page of products in a category. The category service exposes products
99
- * as **assignments** (`/categories/{id}/assignments`) — references, not full
100
- * products — so this fetches a page of assignments, keeps the `PRODUCT`
101
- * references, and resolves them to full products via `/products/search`.
102
- * `hasNextPage` reflects the assignments page (the source of truth for
103
- * pagination).
104
- */
105
- async productsIn(categoryId, params = {}, auth = ANON) {
106
- const pageNumber = params.pageNumber ?? 1;
107
- const pageSize = params.pageSize ?? 50;
108
- const assignments = await this.ctx.http.request({
109
- method: "GET",
110
- path: `/category/${this.ctx.tenant}/categories/${categoryId}/assignments`,
111
- query: { pageNumber, pageSize },
112
- auth
113
- });
114
- const hasNextPage = assignments.length === pageSize;
115
- const productIds = assignments.map((a) => a.ref?.type?.toUpperCase() === "PRODUCT" ? a.ref.id : void 0).filter((id) => Boolean(id));
116
- if (productIds.length === 0) {
117
- return { items: [], pageNumber, pageSize, hasNextPage };
118
- }
119
- const items = await this.ctx.http.request({
120
- method: "POST",
121
- path: `/product/${this.ctx.tenant}/products/search`,
122
- query: { pageSize: productIds.length },
123
- auth,
124
- body: { q: `id:(${productIds.join(",")})` },
125
- idempotent: true
126
- // pure read over POST — safe to replay on 5xx/429
127
- });
128
- return { items, pageNumber, pageSize, hasNextPage };
129
- }
130
- /**
131
- * Bulk fetch by id. POSTs `/categories/search` with `q="id:(id1,id2,…)"`,
132
- * chunking when the list is larger than `options.chunkSize` (default
133
- * 100). An empty list short-circuits with no HTTP call. **Order is not
134
- * guaranteed** across chunks — re-index by `id` if order matters.
135
- */
136
- async searchByIds(ids, options = {}, auth = ANON) {
137
- if (ids.length === 0) return [];
138
- const chunkSize = options.chunkSize ?? 100;
139
- const chunks = [];
140
- for (let i = 0; i < ids.length; i += chunkSize) {
141
- chunks.push(ids.slice(i, i + chunkSize));
142
- }
143
- const pages = await Promise.all(
144
- chunks.map(
145
- (chunk) => this.ctx.http.request({
146
- method: "POST",
147
- path: `/category/${this.ctx.tenant}/categories/search`,
148
- query: { pageSize: chunk.length },
149
- auth,
150
- body: { q: `id:(${chunk.join(",")})` }
151
- })
152
- )
153
- );
154
- return pages.flat();
155
- }
156
- /** Lists a category's ancestor categories (breadcrumb-up). Default auth: anonymous. */
157
- async parents(categoryId, auth = ANON) {
158
- return this.ctx.http.request({
159
- method: "GET",
160
- path: `/category/${this.ctx.tenant}/categories/${categoryId}/parents`,
161
- auth
162
- });
163
- }
164
- /**
165
- * Lists a category's direct child categories via the dedicated
166
- * `…/subcategories` endpoint. (The older `subcategories()` reads `/assignments`
167
- * and is kept for backward compatibility.) Default auth: anonymous.
168
- */
169
- async childCategories(categoryId, auth = ANON) {
170
- return this.ctx.http.request({
171
- method: "GET",
172
- path: `/category/${this.ctx.tenant}/categories/${categoryId}/subcategories`,
173
- auth
174
- });
175
- }
176
- /** Retrieves one category tree by its root category id. Default auth: anonymous. */
177
- async getTree(categoryId, auth = ANON) {
178
- return this.ctx.http.request({
179
- method: "GET",
180
- path: `/category/${this.ctx.tenant}/category-trees/${encodeURIComponent(categoryId)}`,
181
- auth
182
- });
183
- }
184
- };
185
-
186
- export { CategoryService };
187
- //# sourceMappingURL=chunk-DXOLWAOY.js.map
188
- //# sourceMappingURL=chunk-DXOLWAOY.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/category.ts"],"names":[],"mappings":";;;;AAOA,IAAM,IAAA,GAAoB,EAAE,IAAA,EAAM,WAAA,EAAY;AAC9C,IAAM,OAAA,GAAuB,EAAE,IAAA,EAAM,SAAA,EAAU;AASxC,IAAM,kBAAN,MAAsB;AAAA,EAE3B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,UAAA;AAAA;AAAA,EAI1B,MAAM,GAAA,CAAI,UAAA,EAAoB,IAAA,GAAoB,IAAA,EAAyB;AACzE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAkB;AAAA,MACrC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,eAAe,UAAU,CAAA,CAAA;AAAA,MAC3D;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,IAAA,CACJ,MAAA,GAAqD,EAAC,EACtD,OAAoB,IAAA,EACe;AACnC,IAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAoB;AAAA,MACpD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,WAAA,CAAA;AAAA,MAClC,KAAA,EAAO,EAAE,UAAA,EAAY,QAAA,EAAS;AAAA,MAC9B;AAAA,KACD,CAAA;AACD,IAAA,OAAO,EAAE,KAAA,EAAO,UAAA,EAAY,UAAU,WAAA,EAAa,KAAA,CAAM,WAAW,QAAA,EAAS;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAA,CACJ,KAAA,EACA,SAAqD,EAAC,EACtD,OAAoB,IAAA,EACe;AACnC,IAAA,MAAM,IAAI,YAAA,CAAa,KAAA,EAAO,EAAE,oBAAA,EAAsB,OAAO,CAAA;AAC7D,IAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAoB;AAAA,MACpD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,WAAA,CAAA;AAAA,MAClC,KAAA,EAAO,EAAE,CAAA,EAAG,UAAA,EAAY,QAAA,EAAS;AAAA,MACjC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,EAAE,KAAA,EAAO,UAAA,EAAY,UAAU,WAAA,EAAa,KAAA,CAAM,WAAW,QAAA,EAAS;AAAA,EAC/E;AAAA;AAAA,EAGA,OAAA,CAAQ,MAAA,GAAgC,EAAC,EAAG,OAAoB,IAAA,EAA+B;AAC7F,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,OAAO,UAAA,CAAqB,CAAC,UAAA,KAAe,IAAA,CAAK,IAAA,CAAK,EAAE,UAAA,EAAY,QAAA,EAAS,EAAG,IAAI,CAAC,CAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,IAAA,CAAK,IAAA,GAAoB,IAAA,EAA2B;AACxD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAoB;AAAA,MACvC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,eAAA,CAAA;AAAA,MAClC;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAA,CAAY,cAAA,EAAwB,IAAA,GAAoB,OAAA,EAAgC;AAC5F,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAsB;AAAA,MACzC,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,aAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,EAAmB,kBAAA,CAAmB,cAAc,CAAC,CAAA,QAAA,CAAA;AAAA,MACvF;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAA,CACJ,UAAA,EACA,SAAqD,EAAC,EACtD,OAAoB,IAAA,EACC;AACrB,IAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAyD;AAAA,MAC/F,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,eAAe,UAAU,CAAA,YAAA,CAAA;AAAA,MAC3D,KAAA,EAAO,EAAE,UAAA,EAAY,QAAA,EAAS;AAAA,MAC9B;AAAA,KACD,CAAA;AACD,IAAA,MAAM,WAAA,GAAc,YACjB,GAAA,CAAI,CAAC,MAAO,CAAA,CAAE,GAAA,EAAK,MAAM,WAAA,EAAY,KAAM,aAAa,CAAA,CAAE,GAAA,CAAI,KAAK,MAAU,CAAA,CAC7E,OAAO,CAAC,EAAA,KAAqB,OAAA,CAAQ,EAAE,CAAC,CAAA;AAC3C,IAAA,IAAI,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AACtC,IAAA,OAAO,IAAA,CAAK,WAAA,CAAY,WAAA,EAAa,IAAI,IAAI,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,UAAA,CACJ,UAAA,EACA,SAAqD,EAAC,EACtD,OAAoB,IAAA,EACc;AAClC,IAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAyD;AAAA,MAC/F,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,eAAe,UAAU,CAAA,YAAA,CAAA;AAAA,MAC3D,KAAA,EAAO,EAAE,UAAA,EAAY,QAAA,EAAS;AAAA,MAC9B;AAAA,KACD,CAAA;AACD,IAAA,MAAM,WAAA,GAAc,YAAY,MAAA,KAAW,QAAA;AAC3C,IAAA,MAAM,UAAA,GAAa,YAChB,GAAA,CAAI,CAAC,MAAO,CAAA,CAAE,GAAA,EAAK,MAAM,WAAA,EAAY,KAAM,YAAY,CAAA,CAAE,GAAA,CAAI,KAAK,MAAU,CAAA,CAC5E,OAAO,CAAC,EAAA,KAAqB,OAAA,CAAQ,EAAE,CAAC,CAAA;AAC3C,IAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,MAAA,OAAO,EAAE,KAAA,EAAO,EAAC,EAAG,UAAA,EAAY,UAAU,WAAA,EAAY;AAAA,IACxD;AACA,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAmB;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,CAAA;AAAA,MACjC,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,CAAW,MAAA,EAAO;AAAA,MACrC,IAAA;AAAA,MACA,IAAA,EAAM,EAAE,CAAA,EAAG,CAAA,IAAA,EAAO,WAAW,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA,EAAI;AAAA,MAC1C,UAAA,EAAY;AAAA;AAAA,KACb,CAAA;AACD,IAAA,OAAO,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,WAAA,EAAY;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAA,CACJ,GAAA,EACA,UAAkC,EAAC,EACnC,OAAoB,IAAA,EACC;AACrB,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAC9B,IAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,GAAA;AACvC,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,KAAK,SAAA,EAAW;AAC9C,MAAA,MAAA,CAAO,KAAK,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,SAAS,CAAC,CAAA;AAAA,IACzC;AACA,IAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA;AAAA,MAC1B,MAAA,CAAO,GAAA;AAAA,QAAI,CAAC,KAAA,KACV,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAoB;AAAA,UAChC,MAAA,EAAQ,MAAA;AAAA,UACR,IAAA,EAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,kBAAA,CAAA;AAAA,UAClC,KAAA,EAAO,EAAE,QAAA,EAAU,KAAA,CAAM,MAAA,EAAO;AAAA,UAChC,IAAA;AAAA,UACA,IAAA,EAAM,EAAE,CAAA,EAAG,CAAA,IAAA,EAAO,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAI,SACtC;AAAA;AACH,KACF;AACA,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB;AAAA;AAAA,EAGA,MAAM,OAAA,CAAQ,UAAA,EAAoB,IAAA,GAAoB,IAAA,EAA2B;AAC/E,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAoB;AAAA,MACvC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,eAAe,UAAU,CAAA,QAAA,CAAA;AAAA,MAC3D;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAA,CAAgB,UAAA,EAAoB,IAAA,GAAoB,IAAA,EAA2B;AACvF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAoB;AAAA,MACvC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,eAAe,UAAU,CAAA,cAAA,CAAA;AAAA,MAC3D;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAA,CAAQ,UAAA,EAAoB,IAAA,GAAoB,IAAA,EAA6B;AACjF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAsB;AAAA,MACzC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,aAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,EAAmB,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AAAA,MACnF;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"chunk-DXOLWAOY.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\nimport type { Product } from \"./product\";\nimport type { Category as GeneratedCategory, CategoryTree } from \"../generated/category\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\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/** Category reads. Default auth: anonymous. */\nexport class CategoryService {\n static readonly channel = \"category\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one category by id. */\n async get(categoryId: string, auth: AuthContext = ANON): Promise<Category> {\n return this.ctx.http.request<Category>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories/${categoryId}`,\n auth,\n });\n }\n\n /** One page of categories. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Category>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Searches categories by a `q` filter — a raw Emporix DSL string or a built\n * filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Category does not\n * support `compoundLogicalQuery`, so `or()` filters are rejected.\n */\n async search(\n query: QueryFor<\"CATEGORY\">,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Category>> {\n const q = resolveQuery(query, { compoundLogicalQuery: false });\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/categories`,\n query: { q, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every category across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Category> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Category>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /**\n * The catalogue's **root categories** — the published category trees\n * (`GET /category-trees`). Use these for top-level storefront navigation;\n * drill into a node's children with {@link subcategories}.\n */\n async tree(auth: AuthContext = ANON): Promise<Category[]> {\n return this.ctx.http.request<Category[]>({\n method: \"GET\",\n path: `/category/${this.ctx.tenant}/category-trees`,\n auth,\n });\n }\n\n /**\n * 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 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"]}
@@ -1,173 +0,0 @@
1
- import { iterateAll } from './chunk-GWJ2U2CP.js';
2
- import { resolveQuery } from './chunk-S5HEIQDK.js';
3
-
4
- // src/services/product.ts
5
- var ANON = { kind: "anonymous" };
6
- var ProductService = class {
7
- constructor(ctx) {
8
- this.ctx = ctx;
9
- }
10
- ctx;
11
- static channel = "product";
12
- /** Fetches one product by id. */
13
- async get(productId, _opts, auth = ANON) {
14
- return this.ctx.http.request({
15
- method: "GET",
16
- path: `/product/${this.ctx.tenant}/products/${productId}`,
17
- auth
18
- });
19
- }
20
- /** Fetches one product by its code. */
21
- async getByCode(code, auth = ANON) {
22
- const rows = await this.ctx.http.request({
23
- method: "GET",
24
- path: `/product/${this.ctx.tenant}/products`,
25
- query: { q: `code:${code}` },
26
- auth
27
- });
28
- const first = rows[0];
29
- if (!first) throw new Error(`No product with code "${code}"`);
30
- return first;
31
- }
32
- /** One page of products. */
33
- async list(params = {}, auth = ANON) {
34
- const pageNumber = params.pageNumber ?? 1;
35
- const pageSize = params.pageSize ?? 50;
36
- const items = await this.ctx.http.request({
37
- method: "GET",
38
- path: `/product/${this.ctx.tenant}/products`,
39
- query: { pageNumber, pageSize },
40
- auth
41
- });
42
- return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
43
- }
44
- /** Async-iterates every product across pages. */
45
- listAll(params = {}, auth = ANON) {
46
- const pageSize = params.pageSize ?? 50;
47
- return iterateAll((pageNumber) => this.list({ pageNumber, pageSize }, auth));
48
- }
49
- /**
50
- * Searches products by a `q` filter — a raw Emporix DSL string or a built
51
- * filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Product supports
52
- * `compoundLogicalQuery`, so `or()` filters are allowed.
53
- */
54
- async search(query, params = {}, auth = ANON) {
55
- const q = resolveQuery(query, { compoundLogicalQuery: true });
56
- const pageNumber = params.pageNumber ?? 1;
57
- const pageSize = params.pageSize ?? 50;
58
- const items = await this.ctx.http.request({
59
- method: "GET",
60
- path: `/product/${this.ctx.tenant}/products`,
61
- query: { q, pageNumber, pageSize },
62
- auth
63
- });
64
- return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
65
- }
66
- /**
67
- * Free-text product search by name. The product `q` is a `field:value` DSL,
68
- * so a bare term (e.g. "in time") 400s with "No value for key …". This builds
69
- * a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates
70
- * to {@link search}.
71
- */
72
- async searchByName(query, params = {}, auth = ANON) {
73
- const escaped = query.trim().replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
74
- return this.search(`name:(~${escaped})`, params, auth);
75
- }
76
- /**
77
- * Bulk fetch by id. POSTs `/products/search` with `q="id:(id1,id2,…)"`,
78
- * chunking when the list is larger than `options.chunkSize` (default
79
- * 100). An empty list short-circuits with no HTTP call. **Order is not
80
- * guaranteed** across chunks — re-index by `id` if order matters.
81
- */
82
- async searchByIds(ids, options = {}, auth = ANON) {
83
- if (ids.length === 0) return [];
84
- const chunkSize = options.chunkSize ?? 100;
85
- const chunks = [];
86
- for (let i = 0; i < ids.length; i += chunkSize) {
87
- chunks.push(ids.slice(i, i + chunkSize));
88
- }
89
- const pages = await Promise.all(
90
- chunks.map(
91
- (chunk) => this.ctx.http.request({
92
- method: "POST",
93
- path: `/product/${this.ctx.tenant}/products/search`,
94
- query: { pageSize: chunk.length },
95
- auth,
96
- body: { q: `id:(${chunk.join(",")})` },
97
- idempotent: true
98
- // pure read over POST — safe to replay on 5xx/429
99
- })
100
- )
101
- );
102
- return pages.flat();
103
- }
104
- /**
105
- * Bulk fetch by code. POSTs `/products/search` with `q="code:(c1,c2,…)"`,
106
- * chunking when the list is larger than `options.chunkSize` (default 100).
107
- * Duplicate codes are de-duplicated. Codes containing query-delimiter
108
- * characters (`(`, `)`, `,`, whitespace, `"`) are dropped with a logged
109
- * warning, because the Emporix `q` syntax uses them as delimiters and does
110
- * not support escaping them in a plain IN-list. An empty list — or one with
111
- * no safe codes — short-circuits with no HTTP call. **Order is not
112
- * guaranteed** across chunks — re-index by `code` if order matters.
113
- */
114
- async searchByCodes(codes, options = {}, auth = ANON) {
115
- const unique = [...new Set(codes)];
116
- const unsafe = /[(),"\s]/;
117
- const safe = unique.filter((c) => !unsafe.test(c));
118
- const dropped = unique.filter((c) => unsafe.test(c));
119
- if (dropped.length > 0) {
120
- this.ctx.logger.warn(
121
- "products.searchByCodes: dropped codes containing query-delimiter characters",
122
- { dropped }
123
- );
124
- }
125
- if (safe.length === 0) return [];
126
- const chunkSize = options.chunkSize ?? 100;
127
- const chunks = [];
128
- for (let i = 0; i < safe.length; i += chunkSize) {
129
- chunks.push(safe.slice(i, i + chunkSize));
130
- }
131
- const pages = await Promise.all(
132
- chunks.map(
133
- (chunk) => this.ctx.http.request({
134
- method: "POST",
135
- path: `/product/${this.ctx.tenant}/products/search`,
136
- query: { pageSize: chunk.length },
137
- auth,
138
- body: { q: `code:(${chunk.join(",")})` },
139
- idempotent: true
140
- // pure read over POST — safe to replay on 5xx/429
141
- })
142
- )
143
- );
144
- return pages.flat();
145
- }
146
- /**
147
- * Streams the VARIANT children of a PARENT_VARIANT product, page by page,
148
- * via the search query `productType:VARIANT parentVariantId:<id>`. Default
149
- * pageSize 200. The query syntax (space-separated fields = implicit AND) is
150
- * encapsulated here so consumers don't build it themselves.
151
- */
152
- listVariantChildrenAll(parentVariantId, params = {}, auth = ANON) {
153
- const pageSize = params.pageSize ?? 200;
154
- const q = `productType:VARIANT parentVariantId:${parentVariantId}`;
155
- return iterateAll((pageNumber) => this.search(q, { pageNumber, pageSize }, auth));
156
- }
157
- /**
158
- * Resolves ALL VARIANT children of a PARENT_VARIANT product into a flat
159
- * array (loads every page). Default pageSize 200. Returns `[]` when there are
160
- * no children — never throws.
161
- */
162
- async listVariantChildren(parentVariantId, params = {}, auth = ANON) {
163
- const out = [];
164
- for await (const child of this.listVariantChildrenAll(parentVariantId, params, auth)) {
165
- out.push(child);
166
- }
167
- return out;
168
- }
169
- };
170
-
171
- export { ProductService };
172
- //# sourceMappingURL=chunk-FZMP5NQZ.js.map
173
- //# sourceMappingURL=chunk-FZMP5NQZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/product.ts"],"names":[],"mappings":"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","file":"chunk-FZMP5NQZ.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\nimport type {\n BasicProductWithId,\n BundleProductWithId,\n ParentVariantProductWithId,\n ProductMedia,\n} from \"../generated/product\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/** A product as returned by the Product service (all generated fields). */\nexport type Product = BasicProductWithId | BundleProductWithId | ParentVariantProductWithId;\n\n/** A single product media entry (generated; `ProductMedia` is the list type). */\nexport type Media = ProductMedia[number];\n\n/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */\nexport class ProductService {\n static readonly channel = \"product\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one product by id. */\n async get(\n productId: string,\n _opts?: Record<string, never>,\n auth: AuthContext = ANON,\n ): Promise<Product> {\n return this.ctx.http.request<Product>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n auth,\n });\n }\n\n /** Fetches one product by its code. */\n async getByCode(code: string, auth: AuthContext = ANON): Promise<Product> {\n const rows = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: `code:${code}` },\n auth,\n });\n const first = rows[0];\n if (!first) throw new Error(`No product with code \"${code}\"`);\n return first;\n }\n\n /** One page of products. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every product across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Product>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /**\n * Searches products by a `q` filter — a raw Emporix DSL string or a built\n * filter (e.g. `@viu/emporix-mixins`' `mixinQuery(...)`). Product supports\n * `compoundLogicalQuery`, so `or()` filters are allowed.\n */\n async search(\n query: QueryFor<\"PRODUCT\">,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const q = resolveQuery(query, { compoundLogicalQuery: true });\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Free-text product search by name. The product `q` is a `field:value` DSL,\n * so a bare term (e.g. \"in time\") 400s with \"No value for key …\". This builds\n * a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates\n * to {@link search}.\n */\n async searchByName(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const escaped = query.trim().replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return this.search(`name:(~${escaped})`, params, auth);\n }\n\n /**\n * Bulk fetch by id. POSTs `/products/search` with `q=\"id:(id1,id2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default\n * 100). An empty list short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `id` if order matters.\n */\n async searchByIds(\n ids: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n if (ids.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < ids.length; i += chunkSize) {\n chunks.push(ids.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `id:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Bulk fetch by code. POSTs `/products/search` with `q=\"code:(c1,c2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default 100).\n * Duplicate codes are de-duplicated. Codes containing query-delimiter\n * characters (`(`, `)`, `,`, whitespace, `\"`) are dropped with a logged\n * warning, because the Emporix `q` syntax uses them as delimiters and does\n * not support escaping them in a plain IN-list. An empty list — or one with\n * no safe codes — short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `code` if order matters.\n */\n async searchByCodes(\n codes: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const unique = [...new Set(codes)];\n const unsafe = /[(),\"\\s]/;\n const safe = unique.filter((c) => !unsafe.test(c));\n const dropped = unique.filter((c) => unsafe.test(c));\n if (dropped.length > 0) {\n this.ctx.logger.warn(\n \"products.searchByCodes: dropped codes containing query-delimiter characters\",\n { dropped },\n );\n }\n if (safe.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < safe.length; i += chunkSize) {\n chunks.push(safe.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `code:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Streams the VARIANT children of a PARENT_VARIANT product, page by page,\n * via the search query `productType:VARIANT parentVariantId:<id>`. Default\n * pageSize 200. The query syntax (space-separated fields = implicit AND) is\n * encapsulated here so consumers don't build it themselves.\n */\n listVariantChildrenAll(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 200;\n const q = `productType:VARIANT parentVariantId:${parentVariantId}`;\n return iterateAll<Product>((pageNumber) => this.search(q, { pageNumber, pageSize }, auth));\n }\n\n /**\n * Resolves ALL VARIANT children of a PARENT_VARIANT product into a flat\n * array (loads every page). Default pageSize 200. Returns `[]` when there are\n * no children — never throws.\n */\n async listVariantChildren(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const out: Product[] = [];\n for await (const child of this.listVariantChildrenAll(parentVariantId, params, auth)) {\n out.push(child);\n }\n return out;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/contacts.ts"],"names":[],"mappings":";AAeO,IAAM,kBAAN,MAAsB;AAAA,EAE3B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,qBAAA;AAAA,EAGlB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,oBAAA,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,cAAA,CAAe,aAAA,EAAuB,IAAA,EAAiD;AAC3F,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA6B;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,KAAA,EAAO,EAAE,aAAA,EAAc;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,KAAA,EAAgC,IAAA,EAA4C;AACvF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAA,CACJ,mBAAA,EACA,KAAA,EACA,IAAA,EAC4B;AAC5B,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA2B;AAAA,MAC9C,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,mBAAmB,CAAA,CAAA;AAAA,MAC3C,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,QAAA,CAAS,mBAAA,EAA6B,IAAA,EAAkC;AAC5E,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,mBAAmB,CAAA,CAAA;AAAA,MAC3C;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"chunk-HD5RBCM6.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n ContactAssignment,\n ContactAssignmentCreate,\n ContactAssignmentUpdate,\n} from \"../generated/customer-management\";\n\n/**\n * Manages contact assignments linking customers to legal entities.\n *\n * `listForCompany` requires `customermanagement.contactassignment_read`;\n * `assign`/`update`/`unassign` require `_manage`. The query param\n * `legalEntityId` scopes the list to one company.\n */\nexport class ContactsService {\n static readonly channel = \"customer-management\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/customer-management/${this.ctx.tenant}/contact-assignments`;\n }\n\n /** Lists contact assignments for one legal entity. */\n async listForCompany(legalEntityId: string, auth: AuthContext): Promise<ContactAssignment[]> {\n return this.ctx.http.request<ContactAssignment[]>({\n method: \"GET\",\n path: this.base(),\n query: { legalEntityId },\n auth,\n });\n }\n\n /** Creates a contact assignment. */\n async assign(input: ContactAssignmentCreate, auth: AuthContext): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input,\n });\n }\n\n /**\n * Updates a contact assignment via `PUT …/contact-assignments/{id}` (upsert /\n * full replace). The live API rejects `PATCH` on this path with 405; send the\n * complete entity, as the server replaces the resource. The body stays typed\n * as a partial of `ContactAssignmentUpdate` for backward compatibility.\n */\n async update(\n contactAssignmentId: string,\n patch: Partial<ContactAssignmentUpdate>,\n auth: AuthContext,\n ): Promise<ContactAssignment> {\n return this.ctx.http.request<ContactAssignment>({\n method: \"PUT\",\n path: `${this.base()}/${contactAssignmentId}`,\n auth,\n body: patch,\n });\n }\n\n /** Deletes a contact assignment. */\n async unassign(contactAssignmentId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${contactAssignmentId}`,\n auth,\n });\n }\n}\n"]}
@@ -1,63 +0,0 @@
1
- import { EmporixNotFoundError } from './chunk-UWGGF4MC.js';
2
-
3
- // src/services/availability.ts
4
- var ANON = { kind: "anonymous" };
5
- var AvailabilityService = class {
6
- constructor(ctx) {
7
- this.ctx = ctx;
8
- }
9
- ctx;
10
- static channel = "availability";
11
- /**
12
- * Single product. Resolves the availability record, or — when
13
- * `opts.defaultAvailableOnNotFound` is set — a default available record on 404.
14
- */
15
- async get(productId, siteCode, auth = ANON, opts = {}) {
16
- try {
17
- return await this.ctx.http.request({
18
- method: "GET",
19
- path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(
20
- productId
21
- )}/${encodeURIComponent(siteCode)}`,
22
- auth
23
- });
24
- } catch (err) {
25
- if (err instanceof EmporixNotFoundError && opts.defaultAvailableOnNotFound) {
26
- return { productId, site: siteCode, available: true };
27
- }
28
- throw err;
29
- }
30
- }
31
- /**
32
- * Batch read via `POST .../availability/search` (one request). Products with
33
- * no availability record are absent from the response; each is synthesized as
34
- * `{ available: false }` (or `{ available: true }` when
35
- * `opts.defaultAvailableOnNotFound` is set). The result preserves input order
36
- * and length. An empty `productIds` resolves to `[]` without a request.
37
- */
38
- async getMany(productIds, siteCode, auth = ANON, opts = {}) {
39
- if (productIds.length === 0) return [];
40
- const found = await this.ctx.http.request({
41
- method: "POST",
42
- path: `/availability/${this.ctx.tenant}/availability/search`,
43
- auth,
44
- query: { site: siteCode, pageSize: productIds.length },
45
- body: productIds,
46
- idempotent: true
47
- // pure read over POST — safe to replay on 5xx/429
48
- });
49
- const byId = /* @__PURE__ */ new Map();
50
- for (const a of found) if (a.productId) byId.set(a.productId, a);
51
- return productIds.map(
52
- (id) => byId.get(id) ?? {
53
- productId: id,
54
- site: siteCode,
55
- available: Boolean(opts.defaultAvailableOnNotFound)
56
- }
57
- );
58
- }
59
- };
60
-
61
- export { AvailabilityService };
62
- //# sourceMappingURL=chunk-IVCCGJN5.js.map
63
- //# sourceMappingURL=chunk-IVCCGJN5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/availability.ts"],"names":[],"mappings":";;;AAkBA,IAAM,IAAA,GAAoB,EAAE,IAAA,EAAM,WAAA,EAAY;AAQvC,IAAM,sBAAN,MAA0B;AAAA,EAE/B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1B,MAAM,IACJ,SAAA,EACA,QAAA,EACA,OAAoB,IAAA,EACpB,IAAA,GAA4B,EAAC,EACN;AACvB,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAsB;AAAA,QAC/C,MAAA,EAAQ,KAAA;AAAA,QACR,IAAA,EAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,cAAA,EAAiB,kBAAA;AAAA,UACrD;AAAA,SACD,CAAA,CAAA,EAAI,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,QACjC;AAAA,OACD,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,oBAAA,IAAwB,IAAA,CAAK,0BAAA,EAA4B;AAC1E,QAAA,OAAO,EAAE,SAAA,EAAW,IAAA,EAAM,QAAA,EAAU,WAAW,IAAA,EAAK;AAAA,MACtD;AACA,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,UAAA,EACA,QAAA,EACA,OAAoB,IAAA,EACpB,IAAA,GAA4B,EAAC,EACJ;AACzB,IAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AACrC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAwB;AAAA,MACxD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,oBAAA,CAAA;AAAA,MACtC,IAAA;AAAA,MACA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,QAAA,EAAU,WAAW,MAAA,EAAO;AAAA,MACrD,IAAA,EAAM,UAAA;AAAA,MACN,UAAA,EAAY;AAAA;AAAA,KACb,CAAA;AACD,IAAA,MAAM,IAAA,uBAAW,GAAA,EAA0B;AAC3C,IAAA,KAAA,MAAW,CAAA,IAAK,OAAO,IAAI,CAAA,CAAE,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC/D,IAAA,OAAO,UAAA,CAAW,GAAA;AAAA,MAChB,CAAC,EAAA,KACC,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK;AAAA,QACd,SAAA,EAAW,EAAA;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,0BAA0B;AAAA;AACpD,KACJ;AAAA,EACF;AACF","file":"chunk-IVCCGJN5.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixNotFoundError } from \"../core/errors\";\nimport type { Availability } from \"./availability-types\";\n\nexport type { Availability } from \"./availability-types\";\n\n/** Shared options for {@link AvailabilityService} reads. */\nexport interface AvailabilityOptions {\n /**\n * When `true`, a product with no availability record resolves to a default\n * `{ available: true }` instead of throwing (single `get`) / being marked\n * unavailable (`getMany`). Off by default — opt in for tenants that sell\n * without stock management.\n */\n defaultAvailableOnNotFound?: boolean;\n}\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/**\n * Reads product availability per site. Default auth is anonymous (like\n * `PriceService.matchByContext`); pass a customer/raw/service context to use a\n * different token. Requires the `availability.availability_view` scope on\n * whichever token is used.\n */\nexport class AvailabilityService {\n static readonly channel = \"availability\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Single product. Resolves the availability record, or — when\n * `opts.defaultAvailableOnNotFound` is set — a default available record on 404.\n */\n async get(\n productId: string,\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability> {\n try {\n return await this.ctx.http.request<Availability>({\n method: \"GET\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n auth,\n });\n } catch (err) {\n if (err instanceof EmporixNotFoundError && opts.defaultAvailableOnNotFound) {\n return { productId, site: siteCode, available: true };\n }\n throw err;\n }\n }\n\n /**\n * Batch read via `POST .../availability/search` (one request). Products with\n * no availability record are absent from the response; each is synthesized as\n * `{ available: false }` (or `{ available: true }` when\n * `opts.defaultAvailableOnNotFound` is set). The result preserves input order\n * and length. An empty `productIds` resolves to `[]` without a request.\n */\n async getMany(\n productIds: string[],\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability[]> {\n if (productIds.length === 0) return [];\n const found = await this.ctx.http.request<Availability[]>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/search`,\n auth,\n query: { site: siteCode, pageSize: productIds.length },\n body: productIds,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n const byId = new Map<string, Availability>();\n for (const a of found) if (a.productId) byId.set(a.productId, a);\n return productIds.map(\n (id) =>\n byId.get(id) ?? {\n productId: id,\n site: siteCode,\n available: Boolean(opts.defaultAvailableOnNotFound),\n },\n );\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/auth.ts","../src/services/payment.ts"],"names":[],"mappings":"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","file":"chunk-MMX5FGMI.js","sourcesContent":["import type { ResolvedConfig, ServiceCredentials } from \"./config\";\nimport { EmporixAuthError, EmporixTimeoutError, EmporixNetworkError } from \"./errors\";\n\n/** Which token a call should use. */\nexport type AuthKind = \"service\" | \"customer\" | \"anonymous\" | \"raw\";\n\n/** Caller-supplied, per-call auth selector. Never stored on the client. */\nexport type AuthContext =\n | { kind: \"service\"; credentials?: string }\n | { kind: \"anonymous\" }\n | { kind: \"customer\"; token: string }\n | { kind: \"raw\"; token: string };\n\n/**\n * Supplies a fresh customer token when a `customer`-kind request 401s. The host\n * (e.g. EmporixProvider) implements this; the SDK never refreshes the\n * caller-owned customer token unless a refresher is registered.\n */\nexport interface CustomerTokenRefresher {\n /**\n * Called on a `customer`-kind 401. Receives the token that just failed;\n * returns a fresh customer token to retry with, or `null` to give up (the\n * 401 then propagates as EmporixAuthError).\n */\n refresh(expiredToken: string): Promise<string | null>;\n}\n\n/** An obtained anonymous storefront session. */\nexport interface AnonymousSession {\n accessToken: string;\n refreshToken: string;\n sessionId: string;\n expiresIn: number;\n}\n\n/**\n * Persistence callback for anonymous sessions. `read` is called once on the\n * first need for an anonymous token to bootstrap a possibly-existing session;\n * `write` is called after every successful login or refresh. `write(null)`\n * means the SDK is invalidating the stored session.\n */\nexport interface AnonymousSessionStore {\n read(): { refreshToken: string; sessionId: string } | null;\n write(session: { refreshToken: string; sessionId: string } | null): void;\n}\n\n/** Supplies SDK-managed tokens (service/custom + anonymous). May be user-injected. */\nexport interface TokenProvider {\n /** Service/custom client-credentials token for the named credential set. */\n getToken(credentialSet: string): Promise<string>;\n /** Cached anonymous storefront session (preserves sessionId across refreshes). */\n getAnonymousToken(): Promise<AnonymousSession>;\n /** Refresh the anonymous session, preserving sessionId. */\n refreshAnonymous?(): Promise<AnonymousSession>;\n /** Invalidate a cached SDK-managed token so the next call re-auths. */\n invalidate?(credentialSet: string): void;\n /** Invalidate the cached anonymous session entirely (next call re-logs in). */\n invalidateAnonymous?(): void;\n /**\n * Mark the anonymous access token stale but keep the refresh token, so the\n * next {@link getAnonymousToken} refreshes (preserving sessionId) rather\n * than starting a brand-new session.\n */\n expireAnonymous?(): void;\n /**\n * Install a persistence adapter for the anonymous session. The host (e.g.\n * `EmporixProvider`) calls this at construction so the SDK can bootstrap\n * an existing session and persist refreshes. Idempotent: a later call\n * replaces the previous adapter.\n */\n attachAnonymousStore?(store: AnonymousSessionStore): void;\n /**\n * Override the storefront context (currency/site/country) used for the next\n * anonymous login, then invalidate the current anonymous session so it\n * re-mints with the new context. No-op for providers without anon support.\n */\n setAnonymousContext?(ctx: {\n currency?: string;\n siteCode?: string;\n targetLocation?: string;\n }): void;\n /**\n * Subscribe to token-refresh events. Optional — implementations may no-op.\n * Returns an unsubscribe function. `DefaultTokenProvider` emits for the\n * anonymous-login / anonymous-refresh paths.\n */\n onRefresh?(\n listener: (event: { kind: \"anonymous\" | \"customer\"; success: boolean }) => void,\n ): () => void;\n}\n\n/** Tiny constructors for {@link AuthContext}. */\nexport const auth = {\n /** Service/custom credential set (default `backend`). */\n service: (credentials?: string): AuthContext =>\n credentials === undefined ? { kind: \"service\" } : { kind: \"service\", credentials },\n /** Cached anonymous storefront token. */\n anonymous: (): AuthContext => ({ kind: \"anonymous\" }),\n /** Caller-owned customer bearer token. */\n customer: (token: string): AuthContext => ({ kind: \"customer\", token }),\n /** Exact token, no transformation (SSO / token-exchange). */\n raw: (token: string): AuthContext => ({ kind: \"raw\", token }),\n};\n\n/** Resolves an {@link AuthContext} to a concrete bearer token. */\nexport async function resolveToken(ctx: AuthContext, provider: TokenProvider): Promise<string> {\n switch (ctx.kind) {\n case \"service\":\n return provider.getToken(ctx.credentials ?? \"backend\");\n case \"anonymous\":\n return (await provider.getAnonymousToken()).accessToken;\n case \"customer\":\n case \"raw\":\n return ctx.token;\n }\n}\n\n/**\n * Late-bindable, single-flight holder for an optional\n * {@link CustomerTokenRefresher}. Single-flight is required because Emporix\n * rotates the refresh token on each refresh — concurrent refreshes would\n * invalidate each other. Off (returns `null`) until a refresher is set.\n */\nexport class CustomerRefreshRegistry {\n private refresher: CustomerTokenRefresher | null = null;\n private inflight: Promise<string | null> | null = null;\n\n set(refresher: CustomerTokenRefresher | null): void {\n this.refresher = refresher;\n }\n\n get enabled(): boolean {\n return this.refresher !== null;\n }\n\n /** Concurrent callers share one in-flight refresh. */\n refresh(expiredToken: string): Promise<string | null> {\n if (!this.refresher) return Promise.resolve(null);\n if (this.inflight) return this.inflight;\n const p = Promise.resolve(this.refresher.refresh(expiredToken)).finally(() => {\n this.inflight = null;\n });\n this.inflight = p;\n return p;\n }\n}\n\ninterface CacheEntry {\n token: string;\n expiresAt: number;\n obtainedAt: number;\n}\n\n/** SDK-owned token provider: client-credentials service tokens + anonymous session. */\nexport class DefaultTokenProvider implements TokenProvider {\n private readonly serviceCache = new Map<string, CacheEntry>();\n private readonly serviceLocks = new Map<string, Promise<string>>();\n private anon: (AnonymousSession & { expiresAt: number }) | undefined;\n private anonLock: Promise<AnonymousSession> | undefined;\n private anonStore?: AnonymousSessionStore;\n private contextOverride:\n | { currency?: string; siteCode?: string; targetLocation?: string }\n | undefined;\n private readonly refreshListeners = new Set<\n (event: { kind: \"anonymous\" | \"customer\"; success: boolean }) => void\n >();\n\n constructor(private readonly cfg: ResolvedConfig) {}\n\n onRefresh(\n listener: (event: { kind: \"anonymous\" | \"customer\"; success: boolean }) => void,\n ): () => void {\n this.refreshListeners.add(listener);\n return () => {\n this.refreshListeners.delete(listener);\n };\n }\n\n private notifyRefresh(kind: \"anonymous\" | \"customer\", success: boolean): void {\n for (const l of this.refreshListeners) {\n try {\n l({ kind, success });\n } catch {\n // Never let a telemetry listener break the auth path.\n }\n }\n }\n\n attachAnonymousStore(store: AnonymousSessionStore): void {\n this.anonStore = store;\n // Bootstrap `this.anon` from the store if we don't have it yet. The seeded\n // session has expiresAt = 0 so the next getAnonymousToken triggers a refresh\n // (which preserves sessionId) instead of a fresh login.\n if (!this.anon) {\n const persisted = store.read();\n if (persisted) {\n this.anon = {\n accessToken: \"\",\n refreshToken: persisted.refreshToken,\n sessionId: persisted.sessionId,\n expiresIn: 0,\n expiresAt: 0,\n };\n }\n }\n }\n\n private creds(set: string): ServiceCredentials {\n if (set === \"backend\") {\n const b = this.cfg.credentials.backend;\n if (!b?.clientId || !b.secret) {\n throw new EmporixAuthError(\n \"A 'service' AuthContext was used but credentials.backend is not configured\",\n );\n }\n return b;\n }\n const c = this.cfg.credentials.custom?.[set];\n if (!c) throw new Error(`Unknown credential set \"${set}\"`);\n return c;\n }\n\n private fresh(e: CacheEntry | undefined): boolean {\n if (!e) return false;\n const now = Date.now();\n if (now - e.obtainedAt >= this.cfg.cache.maxLifetimeSeconds * 1000) return false;\n return now < e.expiresAt;\n }\n\n async getToken(set: string): Promise<string> {\n // Surface an unknown credential set before entering the cache/lock path.\n this.creds(set);\n const cached = this.serviceCache.get(set);\n if (this.fresh(cached)) return cached!.token;\n const inflight = this.serviceLocks.get(set);\n if (inflight) return inflight;\n const p = this.requestServiceToken(set).finally(() => this.serviceLocks.delete(set));\n this.serviceLocks.set(set, p);\n return p;\n }\n\n /**\n * fetch with the configured read timeout. Token endpoints sit in front of\n * single-flight locks — one hung call would otherwise block every request\n * on this credential set forever.\n */\n private async boundedFetch(url: string | URL, init: RequestInit = {}): Promise<Response> {\n const ms = this.cfg.timeouts?.readMs ?? 60_000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), ms);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n throw new EmporixTimeoutError(`token request timed out after ${ms}ms`);\n }\n throw new EmporixNetworkError(`token request network failure: ${(err as Error).message}`);\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async requestServiceToken(set: string): Promise<string> {\n const c = this.creds(set);\n const body = new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: c.clientId,\n client_secret: c.secret,\n });\n if (c.scope) body.set(\"scope\", c.scope);\n const res = await this.boundedFetch(`${this.cfg.host}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body,\n });\n const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n throw new EmporixAuthError(`Token request failed for \"${set}\"`, res.status, json);\n }\n const obtainedAt = Date.now();\n const ttl = Number((json.expires_in as number | undefined) ?? 3600);\n this.serviceCache.set(set, {\n token: json.access_token as string,\n obtainedAt,\n expiresAt: obtainedAt + (ttl - this.cfg.cache.expirationBufferSeconds) * 1000,\n });\n return this.serviceCache.get(set)!.token;\n }\n\n invalidate(set: string): void {\n this.serviceCache.delete(set);\n }\n\n private anonFresh(): boolean {\n return !!this.anon && Date.now() < this.anon.expiresAt;\n }\n\n async getAnonymousToken(): Promise<AnonymousSession> {\n if (this.anonFresh()) return this.stripExpiry(this.anon!);\n if (this.anonLock) return this.anonLock;\n // Token expired but a refresh token survives → refresh to keep the same\n // sessionId; only fall back to a brand-new login if the refresh fails.\n const canRefresh = !!this.anon?.refreshToken;\n const obtain = canRefresh\n ? this.fetchAnonymous(\"refresh\").catch(() => this.fetchAnonymous(\"login\"))\n : this.fetchAnonymous(\"login\");\n const p = obtain.finally(() => {\n this.anonLock = undefined;\n });\n this.anonLock = p;\n return p;\n }\n\n /** Refreshes the anonymous session, preserving its sessionId. */\n async refreshAnonymous(): Promise<AnonymousSession> {\n if (!this.anon) return this.getAnonymousToken();\n return this.fetchAnonymous(\"refresh\");\n }\n\n invalidateAnonymous(): void {\n this.anon = undefined;\n this.anonStore?.write(null);\n }\n\n setAnonymousContext(ctx: {\n currency?: string;\n siteCode?: string;\n targetLocation?: string;\n }): void {\n const base = this.contextOverride ?? this.cfg.credentials.storefront?.context ?? {};\n this.contextOverride = { ...base, ...ctx };\n this.invalidateAnonymous();\n }\n\n /** Force a stale access token while keeping the refresh token + sessionId. */\n expireAnonymous(): void {\n if (this.anon) this.anon = { ...this.anon, expiresAt: 0 };\n }\n\n private stripExpiry(s: AnonymousSession & { expiresAt: number }): AnonymousSession {\n const { expiresAt: _expiresAt, ...rest } = s;\n return rest;\n }\n\n private async fetchAnonymous(mode: \"login\" | \"refresh\"): Promise<AnonymousSession> {\n const sf = this.cfg.credentials.storefront;\n if (!sf?.clientId) {\n throw new Error(\"credentials.storefront.clientId is required for anonymous tokens\");\n }\n const url = new URL(`${this.cfg.host}/customerlogin/auth/anonymous/${mode}`);\n url.searchParams.set(\"tenant\", this.cfg.tenant);\n url.searchParams.set(\"client_id\", sf.clientId);\n // Context is the runtime override (set via setAnonymousContext) if present,\n // else the config-fixed context.\n const c = this.contextOverride ?? sf.context;\n if (c?.currency) url.searchParams.set(\"currency\", c.currency);\n if (c?.siteCode) url.searchParams.set(\"siteCode\", c.siteCode);\n if (c?.targetLocation) url.searchParams.set(\"targetLocation\", c.targetLocation);\n if (mode === \"refresh\" && this.anon) {\n url.searchParams.set(\"refresh_token\", this.anon.refreshToken);\n }\n try {\n const res = await this.boundedFetch(url, { method: \"GET\" });\n const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n this.notifyRefresh(\"anonymous\", false);\n throw new EmporixAuthError(`Anonymous token ${mode} failed`, res.status, json);\n }\n const obtainedAt = Date.now();\n this.anon = {\n accessToken: json.access_token as string,\n refreshToken: json.refresh_token as string,\n sessionId: json.sessionId as string,\n expiresIn: json.expires_in as number,\n expiresAt:\n obtainedAt +\n ((json.expires_in as number) - this.cfg.cache.expirationBufferSeconds) * 1000,\n };\n this.anonStore?.write({\n refreshToken: this.anon.refreshToken,\n sessionId: this.anon.sessionId,\n });\n this.notifyRefresh(\"anonymous\", true);\n return this.stripExpiry(this.anon);\n } catch (err) {\n // Re-throw EmporixAuthError as-is; for non-Emporix errors (network), also notify.\n if (!(err instanceof EmporixAuthError)) {\n this.notifyRefresh(\"anonymous\", false);\n }\n throw err;\n }\n }\n}\n// Customer-token refreshes happen via client.customers.refresh() and don't\n// route through this TokenProvider — only the anonymous flow notifies.\n// React-side useCustomerSession.refresh emits its own telemetry event in a\n// follow-up if needed.\n","import type { ClientContext } from \"../core/context\";\nimport { auth, type AuthContext } from \"../core/auth\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type {\n PaymentModeFrontendResponse,\n AuthorizePaymentRequest,\n InitializePaymentRequest,\n InitializePaymentResponse,\n} from \"../generated/payment\";\n\nconst ANON: AuthContext = auth.anonymous();\n\n/** A frontend payment mode (generated). */\nexport type PaymentMode = PaymentModeFrontendResponse;\n\n/** Post-checkout authorize request (generated; caller sends the exact wire shape). */\nexport type AuthorizePaymentInput = AuthorizePaymentRequest;\n\n/** Frontend payment-initialize request (generated). */\nexport type InitializePaymentInput = InitializePaymentRequest;\n\n/** Frontend payment-initialize response (generated). */\nexport type InitializePaymentResult = InitializePaymentResponse;\n\n/** Post-checkout authorize result. */\nexport interface AuthorizePaymentResult {\n successful: boolean;\n paymentTransactionId?: string;\n authorizationToken?: string;\n requiresExternalPayment?: boolean;\n externalPaymentRedirectURL?: string;\n externalPaymentHttpMethod?: string;\n [k: string]: unknown;\n}\n\n/** Payment-Gateway: list frontend payment modes, authorize deferred payments. */\nexport class PaymentGatewayService {\n static readonly channel = \"payment\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Lists configured frontend payment modes. The endpoint requires a bearer\n * token but no customer scope (\"No scope required\"), so it defaults to an\n * anonymous context and works for guests and logged-in customers alike.\n */\n async listPaymentModes(authCtx: AuthContext = ANON): Promise<PaymentMode[]> {\n return this.ctx.http.request<PaymentMode[]>({\n method: \"GET\",\n path: `/payment-gateway/${this.ctx.tenant}/paymentmodes/frontend`,\n auth: authCtx,\n });\n }\n\n /** Authorizes a post-checkout (deferred) payment for an existing order. */\n async authorize(\n input: AuthorizePaymentInput,\n authCtx?: AuthContext,\n ): Promise<AuthorizePaymentResult> {\n return this.ctx.http.request<AuthorizePaymentResult>({\n method: \"POST\",\n path: `/payment-gateway/${this.ctx.tenant}/payment/frontend/authorize`,\n auth: requireCustomer(authCtx),\n body: input,\n });\n }\n\n /** Retrieves a single frontend payment mode by id. Defaults to anonymous (no scope required). */\n async getMode(id: string, authCtx: AuthContext = ANON): Promise<PaymentMode> {\n return this.ctx.http.request<PaymentMode>({\n method: \"GET\",\n path: `/payment-gateway/${this.ctx.tenant}/paymentmodes/frontend/${id}`,\n auth: authCtx,\n });\n }\n\n /** Initializes a payment from the frontend. Defaults to anonymous (no scope required). */\n async initialize(\n input: InitializePaymentInput,\n authCtx: AuthContext = ANON,\n ): Promise<InitializePaymentResult> {\n return this.ctx.http.request<InitializePaymentResult>({\n method: \"POST\",\n path: `/payment-gateway/${this.ctx.tenant}/payment/frontend/initialize`,\n auth: authCtx,\n body: input,\n });\n }\n}\n"]}