@viu/emporix-sdk 2.26.0 → 2.28.1
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 +50 -0
- package/dist/{chunk-UNW6SFSB.js → chunk-7W22KLUL.js} +22 -3
- package/dist/chunk-7W22KLUL.js.map +1 -0
- package/dist/index.cjs +34 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +15 -4
- package/dist/index.js.map +1 -1
- package/dist/product.cjs +20 -1
- package/dist/product.cjs.map +1 -1
- package/dist/product.d.cts +10 -0
- package/dist/product.d.ts +10 -0
- package/dist/product.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-UNW6SFSB.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @viu/emporix-sdk
|
|
2
2
|
|
|
3
|
+
## 2.28.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#199](https://github.com/viuteam/emporix-sdk/pull/199) [`5836902`](https://github.com/viuteam/emporix-sdk/commit/58369024a1446bf4213f36403467808fbb371cdd) Thanks [@amnael1](https://github.com/amnael1)! - `products.searchByName` no longer 400s on text a shopper actually types.
|
|
8
|
+
|
|
9
|
+
It escaped regex metacharacters, which is right for the regex but not enough for
|
|
10
|
+
the filter: Emporix parses the `q` DSL's own structure first, so an **escaped**
|
|
11
|
+
paren is still an unbalanced paren to it. `searchByName("Access (")` came back as
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
400 Missing closing parenthesis in value '(~Access \()' of key 'name'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Any search box wired to this crashed on an opening bracket.
|
|
18
|
+
|
|
19
|
+
`(`, `)` and `"` are now **removed** rather than escaped — measured against a live
|
|
20
|
+
tenant on 2026-08-03, those three are the only metacharacters that break this way;
|
|
21
|
+
every other one survives escaping and stays escaped.
|
|
22
|
+
|
|
23
|
+
Two details that follow from it:
|
|
24
|
+
- Removed brackets become a **space**, then runs of whitespace collapse. Dropping
|
|
25
|
+
them outright would turn `Access(JIT)` into one run-together word, and leaving a
|
|
26
|
+
double space behind would put two _literal_ spaces in the regex — matching
|
|
27
|
+
nothing.
|
|
28
|
+
- A query made only of those characters leaves nothing to search for and returns
|
|
29
|
+
an **empty page without a request**, because `name:(~)` is itself a 400.
|
|
30
|
+
|
|
31
|
+
The escaping behaviour for every other character is unchanged, and one existing
|
|
32
|
+
test that asserted `name:(~a\.b\*\(c\))` was updated — it encoded the bug.
|
|
33
|
+
|
|
34
|
+
## 2.28.0
|
|
35
|
+
|
|
36
|
+
### Minor Changes
|
|
37
|
+
|
|
38
|
+
- [#195](https://github.com/viuteam/emporix-sdk/pull/195) [`bda9663`](https://github.com/viuteam/emporix-sdk/commit/bda9663040b3d6c8c33743ced6a3df4b79c81ddb) Thanks [@amnael1](https://github.com/amnael1)! - Export `resolveZone` and `pickFee` alongside the shipping service, plus the
|
|
39
|
+
`ShippingFee` type they use.
|
|
40
|
+
|
|
41
|
+
Both are pure functions — no client, no request — lifted verbatim from the
|
|
42
|
+
storefront demo, where they had no test coverage. They now have ten tests,
|
|
43
|
+
including the `<=` boundary that decides whether a cart total exactly meeting a
|
|
44
|
+
free-shipping threshold gets free shipping.
|
|
45
|
+
- `resolveZone(zones, country)` — the zone whose `shipTo` covers the country,
|
|
46
|
+
else the default zone, else the first.
|
|
47
|
+
- `pickFee(fees, cartTotal)` — the highest `minOrderValue` at or below the
|
|
48
|
+
total, else the first fee.
|
|
49
|
+
|
|
50
|
+
The fee type is exported as `ShippingFee` rather than `Fee`, because the Fee
|
|
51
|
+
service already owns that name at the package root.
|
|
52
|
+
|
|
3
53
|
## 2.26.0
|
|
4
54
|
|
|
5
55
|
### Patch Changes
|
|
@@ -69,9 +69,28 @@ var ProductService = class {
|
|
|
69
69
|
* so a bare term (e.g. "in time") 400s with "No value for key …". This builds
|
|
70
70
|
* a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates
|
|
71
71
|
* to {@link search}.
|
|
72
|
+
*
|
|
73
|
+
* Safe for text a shopper typed: `( ) "` are **removed** rather than escaped,
|
|
74
|
+
* because Emporix parses the filter's own structure before it looks at the
|
|
75
|
+
* regex. `name:(~a \()` is rejected with «Missing closing parenthesis in value»
|
|
76
|
+
* even though the paren is escaped, so a search box would 400 on an opening
|
|
77
|
+
* bracket. Measured against a live tenant on 2026-08-03: of every regex
|
|
78
|
+
* metacharacter only those three break; the rest survive escaping.
|
|
79
|
+
*
|
|
80
|
+
* A query consisting solely of those characters leaves nothing to search for and
|
|
81
|
+
* returns an empty page without a request — `name:(~)` is a 400.
|
|
72
82
|
*/
|
|
73
83
|
async searchByName(query, params = {}, auth = ANON) {
|
|
74
|
-
const
|
|
84
|
+
const term = query.replace(/[()"]/g, " ").replace(/\s+/g, " ").trim();
|
|
85
|
+
if (term === "") {
|
|
86
|
+
return {
|
|
87
|
+
items: [],
|
|
88
|
+
pageNumber: params.pageNumber ?? 1,
|
|
89
|
+
pageSize: params.pageSize ?? 50,
|
|
90
|
+
hasNextPage: false
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const escaped = term.replace(/[.*+?^${}|[\]\\]/g, "\\$&");
|
|
75
94
|
return this.search(`name:(~${escaped})`, params, auth);
|
|
76
95
|
}
|
|
77
96
|
/**
|
|
@@ -359,5 +378,5 @@ var ProductService = class {
|
|
|
359
378
|
};
|
|
360
379
|
|
|
361
380
|
export { ProductService };
|
|
362
|
-
//# sourceMappingURL=chunk-
|
|
363
|
-
//# sourceMappingURL=chunk-
|
|
381
|
+
//# sourceMappingURL=chunk-7W22KLUL.js.map
|
|
382
|
+
//# sourceMappingURL=chunk-7W22KLUL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/product.ts"],"names":[],"mappings":";;;;AAyBA,IAAM,IAAA,GAAoB,EAAE,IAAA,EAAM,WAAA,EAAY;AAC9C,IAAM,OAAA,GAAuB,EAAE,IAAA,EAAM,SAAA,EAAU;AA6DxC,IAAM,iBAAN,MAAqB;AAAA,EAE1B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,SAAA;AAAA;AAAA,EAI1B,MAAM,GAAA,CACJ,SAAA,EACA,KAAA,EACA,OAAoB,IAAA,EACF;AAClB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAiB;AAAA,MACpC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,aAAa,SAAS,CAAA,CAAA;AAAA,MACvD;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAA,CAAU,IAAA,EAAc,IAAA,GAAoB,IAAA,EAAwB;AACxE,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAmB;AAAA,MAClD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,SAAA,CAAA;AAAA,MACjC,KAAA,EAAO,EAAE,CAAA,EAAG,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAA,EAAG;AAAA,MAC3B;AAAA,KACD,CAAA;AACD,IAAA,MAAM,KAAA,GAAQ,KAAK,CAAC,CAAA;AACpB,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAA,CAAG,CAAA;AAC5D,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,IAAA,CACJ,MAAA,GAAqD,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,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAmB;AAAA,MACnD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,SAAA,CAAA;AAAA,MACjC,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,EAGA,OAAA,CAAQ,MAAA,GAAgC,EAAC,EAAG,OAAoB,IAAA,EAA8B;AAC5F,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,OAAO,UAAA,CAAoB,CAAC,UAAA,KAAe,IAAA,CAAK,IAAA,CAAK,EAAE,UAAA,EAAY,QAAA,EAAS,EAAG,IAAI,CAAC,CAAA;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAA,CACJ,KAAA,EACA,SAAqD,EAAC,EACtD,OAAoB,IAAA,EACc;AAClC,IAAA,MAAM,IAAI,YAAA,CAAa,KAAA,EAAO,EAAE,oBAAA,EAAsB,MAAM,CAAA;AAC5D,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,CAAmB;AAAA,MACnD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,SAAA,CAAA;AAAA,MACjC,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,YAAA,CACJ,KAAA,EACA,SAAqD,EAAC,EACtD,OAAoB,IAAA,EACc;AAIlC,IAAA,MAAM,IAAA,GAAO,KAAA,CACV,OAAA,CAAQ,QAAA,EAAU,GAAG,EACrB,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,IAAA,EAAK;AACR,IAAA,IAAI,SAAS,EAAA,EAAI;AAEf,MAAA,OAAO;AAAA,QACL,OAAO,EAAC;AAAA,QACR,UAAA,EAAY,OAAO,UAAA,IAAc,CAAA;AAAA,QACjC,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,QAC7B,WAAA,EAAa;AAAA,OACf;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,mBAAA,EAAqB,MAAM,CAAA;AACxD,IAAA,OAAO,KAAK,MAAA,CAAO,CAAA,OAAA,EAAU,OAAO,CAAA,CAAA,CAAA,EAAK,QAAQ,IAAI,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAA,CACJ,GAAA,EACA,UAAkC,EAAC,EACnC,OAAoB,IAAA,EACA;AACpB,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,CAAmB;AAAA,UAC/B,MAAA,EAAQ,MAAA;AAAA,UACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,CAAA;AAAA,UACjC,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,EAAI;AAAA,UACrC,UAAA,EAAY;AAAA;AAAA,SACb;AAAA;AACH,KACF;AACA,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,aAAA,CACJ,KAAA,EACA,UAAkC,EAAC,EACnC,OAAoB,IAAA,EACA;AACpB,IAAA,MAAM,SAAS,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AACjC,IAAA,MAAM,MAAA,GAAS,UAAA;AACf,IAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,CAAC,MAAM,CAAC,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAA;AACjD,IAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,CAAC,MAAM,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAA;AACnD,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,IAAA,CAAK,IAAI,MAAA,CAAO,IAAA;AAAA,QACd,6EAAA;AAAA,QACA,EAAE,OAAA;AAAQ,OACZ;AAAA,IACF;AACA,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAC/B,IAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,GAAA;AACvC,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,KAAK,SAAA,EAAW;AAC/C,MAAA,MAAA,CAAO,KAAK,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,SAAS,CAAC,CAAA;AAAA,IAC1C;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,CAAmB;AAAA,UAC/B,MAAA,EAAQ,MAAA;AAAA,UACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,CAAA;AAAA,UACjC,KAAA,EAAO,EAAE,QAAA,EAAU,KAAA,CAAM,MAAA,EAAO;AAAA,UAChC,IAAA;AAAA,UACA,IAAA,EAAM,EAAE,CAAA,EAAG,CAAA,MAAA,EAAS,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA,EAAI;AAAA,UACvC,UAAA,EAAY;AAAA;AAAA,SACb;AAAA;AACH,KACF;AACA,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,uBACE,eAAA,EACA,MAAA,GAAgC,EAAC,EACjC,OAAoB,IAAA,EACI;AACxB,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,GAAA;AACpC,IAAA,MAAM,CAAA,GAAI,uCAAuC,eAAe,CAAA,CAAA;AAChE,IAAA,OAAO,UAAA,CAAoB,CAAC,UAAA,KAAe,IAAA,CAAK,MAAA,CAAO,CAAA,EAAG,EAAE,UAAA,EAAY,QAAA,EAAS,EAAG,IAAI,CAAC,CAAA;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAA,CACJ,eAAA,EACA,SAAgC,EAAC,EACjC,OAAoB,IAAA,EACA;AACpB,IAAA,MAAM,MAAiB,EAAC;AACxB,IAAA,WAAA,MAAiB,SAAS,IAAA,CAAK,sBAAA,CAAuB,eAAA,EAAiB,MAAA,EAAQ,IAAI,CAAA,EAAG;AACpF,MAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IAChB;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAA,CACJ,KAAA,EACA,UAA+B,EAAC,EAChC,OAAoB,OAAA,EACK;AACzB,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,GAAI,OAAA,CAAQ,qBAAA,KAA0B,MAAA,GAAY,EAAC,GAAI,EAAE,qBAAA,EAAuB,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA,EAAE;AAAA,MACtH,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,MAC5E,GAAI,OAAA,CAAQ,0BAAA,KAA+B,MAAA,GAAY,EAAC,GAAI,EAAE,0BAAA,EAA4B,MAAA,CAAO,OAAA,CAAQ,0BAA0B,CAAA;AAAE,KACvI;AACA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,SAAA,CAAA;AAAA,MACjC,GAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACjD,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OACJ,SAAA,EACA,KAAA,EACA,UAA+B,EAAC,EAChC,OAAoB,OAAA,EACL;AACf,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,GAAI,OAAA,CAAQ,qBAAA,KAA0B,MAAA,GAAY,EAAC,GAAI,EAAE,qBAAA,EAAuB,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA,EAAE;AAAA,MACtH,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,MAC5E,GAAI,OAAA,CAAQ,0BAAA,KAA+B,MAAA,GAAY,EAAC,GAAI,EAAE,0BAAA,EAA4B,MAAA,CAAO,OAAA,CAAQ,0BAA0B,CAAA;AAAE,KACvI;AACA,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,OAAA;AAAA,MACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,aAAa,SAAS,CAAA,CAAA;AAAA,MACvD,GAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACjD,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QACJ,SAAA,EACA,KAAA,EACA,UAAuD,EAAC,EACxD,OAAoB,OAAA,EACY;AAChC,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,MAC5E,GAAI,OAAA,CAAQ,qBAAA,KAA0B,MAAA,GAAY,EAAC,GAAI,EAAE,qBAAA,EAAuB,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA,EAAE;AAAA,MACtH,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,MAC5E,GAAI,OAAA,CAAQ,0BAAA,KAA+B,MAAA,GAAY,EAAC,GAAI,EAAE,0BAAA,EAA4B,MAAA,CAAO,OAAA,CAAQ,0BAA0B,CAAA;AAAE,KACvI;AACA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA+B;AAAA,MAClD,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,aAAa,SAAS,CAAA,CAAA;AAAA,MACvD,GAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACjD,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,SAAA,EACA,UAAkD,EAAC,EACnD,OAAoB,OAAA,EACL;AACf,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,GAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,GAAY,EAAC,GAAI,EAAE,KAAA,EAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAE;AAAA,MACtE,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA;AAAE,KAC9E;AACA,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,aAAa,SAAS,CAAA,CAAA;AAAA,MACvD,GAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACjD;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAA,CACJ,KAAA,EACA,UAA+B,EAAC,EAChC,OAAoB,OAAA,EACU;AAC9B,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,GAAI,OAAA,CAAQ,qBAAA,KAA0B,MAAA,GAAY,EAAC,GAAI,EAAE,qBAAA,EAAuB,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA,EAAE;AAAA,MACtH,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,MAC5E,GAAI,OAAA,CAAQ,0BAAA,KAA+B,MAAA,GAAY,EAAC,GAAI,EAAE,0BAAA,EAA4B,MAAA,CAAO,OAAA,CAAQ,0BAA0B,CAAA;AAAE,KACvI;AACA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA6B;AAAA,MAChD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,cAAA,CAAA;AAAA,MACjC,GAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACjD,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAA,CACJ,KAAA,EACA,UAA+B,EAAC,EAChC,OAAoB,OAAA,EACU;AAC9B,IAAA,MAAM,KAAA,GAAQ;AAAA,MACZ,GAAI,OAAA,CAAQ,qBAAA,KAA0B,MAAA,GAAY,EAAC,GAAI,EAAE,qBAAA,EAAuB,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA,EAAE;AAAA,MACtH,GAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAE;AAAA,MAC5E,GAAI,OAAA,CAAQ,0BAAA,KAA+B,MAAA,GAAY,EAAC,GAAI,EAAE,0BAAA,EAA4B,MAAA,CAAO,OAAA,CAAQ,0BAA0B,CAAA;AAAE,KACvI;AACA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA6B;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,cAAA,CAAA;AAAA,MACjC,GAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACjD,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAA,CACJ,KAAA,EACA,IAAA,GAAoB,OAAA,EACiB;AACrC,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAoC;AAAA,MACvD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,qBAAA,CAAA;AAAA,MACjC,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,qBAAA,CACJ,MAAA,GAAqD,EAAC,EACtD,OAAoB,IAAA,EACgB;AACpC,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAmC;AAAA,MACtD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,0BAAA,CAAA;AAAA,MACjC,GAAI,MAAA,CAAO,MAAA,KAAW,MAAA,GAAY,EAAC,GAAI,EAAE,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAO,EAAE;AAAA,MAC1E;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,mBAAA,CAAoB,KAAA,EAAe,IAAA,GAAoB,IAAA,EAAwC;AACnG,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAiC;AAAA,MACpD,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,8BAA8B,KAAK,CAAA,CAAA;AAAA,MACpE;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMS,SAAA,GAAY;AAAA;AAAA,IAEnB,IAAA,EAAM,OACJ,MAAA,GAAgF,EAAC,EACjF,OAAoB,IAAA,KAEpB,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA2B;AAAA,MACvC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,kBAAA,CAAA;AAAA,MACjC,KAAA,EAAO;AAAA,QACL,GAAI,OAAO,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,UAAA,EAAY,MAAA,CAAO,UAAA,EAAW;AAAA,QAC3E,GAAI,OAAO,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS;AAAA,QACrE,GAAI,OAAO,IAAA,KAAS,MAAA,GAAY,EAAC,GAAI,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAK;AAAA,QACzD,GAAI,OAAO,CAAA,KAAM,MAAA,GAAY,EAAC,GAAI,EAAE,CAAA,EAAG,MAAA,CAAO,CAAA;AAAE,OAClD;AAAA,MACA;AAAA,KACD,CAAA;AAAA;AAAA,IAGH,GAAA,EAAK,OAAO,UAAA,EAAoB,IAAA,GAAoB,SAClD,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAyB;AAAA,MACrC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,sBAAsB,UAAU,CAAA,CAAA;AAAA,MACjE;AAAA,KACD,CAAA;AAAA;AAAA,IAGH,MAAA,EAAQ,OACN,KAAA,EACA,IAAA,GAAoB,YAEpB,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAgC;AAAA,MAC5C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,kBAAA,CAAA;AAAA,MACjC,IAAA,EAAM,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA;AAAA,IAGH,MAAA,EAAQ,OACN,UAAA,EACA,KAAA,EACA,OAAoB,OAAA,KACF;AAClB,MAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,QAChC,MAAA,EAAQ,KAAA;AAAA,QACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,sBAAsB,UAAU,CAAA,CAAA;AAAA,QACjE,IAAA,EAAM,KAAA;AAAA,QACN;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA;AAAA,IAGA,MAAA,EAAQ,OAAO,UAAA,EAAoB,IAAA,GAAoB,OAAA,KAA2B;AAChF,MAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,QAChC,MAAA,EAAQ,QAAA;AAAA,QACR,MAAM,CAAA,SAAA,EAAY,IAAA,CAAK,GAAA,CAAI,MAAM,sBAAsB,UAAU,CAAA,CAAA;AAAA,QACjE;AAAA,OACD,CAAA;AAAA,IACH;AAAA,GACF;AACF","file":"chunk-7W22KLUL.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 ProductCreateBody,\n ProductUpdateBody,\n ProductPartialUpdateBody,\n ProductBulkCreateBody,\n ProductBulkUpdateBody,\n BulkResponse,\n ResourceLocation,\n DynamicVariantRecalculationRequest,\n DynamicVariantRecalculationResponse,\n DynamicVariantRecalculationJobResponse,\n DynamicVariantRecalculationJobStatus,\n ProductTemplateResponse,\n ProductTemplateCreation,\n ProductTemplateUpdate,\n} from \"../generated/product\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\nconst SERVICE: AuthContext = { kind: \"service\" };\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/** Body for creating a product (`POST /products`) — any of the 5 product shapes. */\nexport type ProductCreateInput = ProductCreateBody;\n\n/** Body for a full product replace (`PUT /products/{id}`). */\nexport type ProductUpdateInput = ProductUpdateBody;\n\n/** Body for a partial product update (`PATCH /products/{id}`). */\nexport type ProductPatchInput = ProductPartialUpdateBody;\n\n/** Id/location envelope returned when a product is created. */\nexport type ProductCreated = ResourceLocation;\n\n/** Body for bulk-creating products (`POST /products/bulk`). */\nexport type ProductBulkCreateInput = ProductBulkCreateBody;\n\n/** Body for bulk-updating products (`PUT /products/bulk`). */\nexport type ProductBulkUpdateInput = ProductBulkUpdateBody;\n\n/** Per-entry result of a bulk product operation (207 Multi-Status). */\nexport type ProductBulkResult = BulkResponse;\n\n/** Body for triggering a dynamic-variant recalculation. */\nexport type ProductRecalculationInput = DynamicVariantRecalculationRequest;\n\n/** Result of triggering a recalculation — created jobs plus skipped product ids. */\nexport type ProductRecalculationResult = DynamicVariantRecalculationResponse;\n\n/** A dynamic-variant recalculation job. */\nexport type ProductRecalculationJob = DynamicVariantRecalculationJobResponse;\n\n/** Status of a recalculation job. */\nexport type ProductRecalculationJobStatus = DynamicVariantRecalculationJobStatus;\n\n/** A product template as returned by the Product service. */\nexport type ProductTemplate = ProductTemplateResponse;\n\n/** Body for creating a product template. */\nexport type ProductTemplateCreateInput = ProductTemplateCreation;\n\n/** Body for updating a product template (`PUT`, full replace). */\nexport type ProductTemplateUpdateInput = ProductTemplateUpdate;\n\n/** Id envelope returned when a product template is created. */\nexport type ProductTemplateCreated = { id?: string };\n\n/** Query flags shared by the product write endpoints. */\nexport interface ProductWriteOptions {\n skipVariantGeneration?: boolean;\n doIndex?: boolean;\n skipRelatedItemsValidation?: boolean;\n}\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 * Safe for text a shopper typed: `( ) \"` are **removed** rather than escaped,\n * because Emporix parses the filter's own structure before it looks at the\n * regex. `name:(~a \\()` is rejected with «Missing closing parenthesis in value»\n * even though the paren is escaped, so a search box would 400 on an opening\n * bracket. Measured against a live tenant on 2026-08-03: of every regex\n * metacharacter only those three break; the rest survive escaping.\n *\n * A query consisting solely of those characters leaves nothing to search for and\n * returns an empty page without a request — `name:(~)` is a 400.\n */\n async searchByName(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n // Replaced by a space rather than dropped, so «Access(JIT)» does not become\n // one run-together word — and then collapsed, because a leftover double space\n // is two LITERAL spaces in the regex and would match nothing.\n const term = query\n .replace(/[()\"]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n if (term === \"\") {\n // Defaults mirror `search`, so the shape matches a real answer.\n return {\n items: [],\n pageNumber: params.pageNumber ?? 1,\n pageSize: params.pageSize ?? 50,\n hasNextPage: false,\n };\n }\n const escaped = term.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 // --- Admin writes. Default auth: service. ---\n\n /**\n * Creates a product (`POST /products`). Default auth: service. Accepts any of\n * the five product shapes (basic, bundle, parent-variant, variant,\n * dynamic-variant).\n */\n async create(\n input: ProductCreateInput,\n options: ProductWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<ProductCreated> {\n const query = {\n ...(options.skipVariantGeneration === undefined ? {} : { skipVariantGeneration: String(options.skipVariantGeneration) }),\n ...(options.doIndex === undefined ? {} : { doIndex: String(options.doIndex) }),\n ...(options.skipRelatedItemsValidation === undefined ? {} : { skipRelatedItemsValidation: String(options.skipRelatedItemsValidation) }),\n };\n return this.ctx.http.request<ProductCreated>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products`,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n body: input,\n auth,\n });\n }\n\n /**\n * Partially updates a product (`PATCH /products/{productId}`). Default auth:\n * service. Use {@link replace} for a full replace (PUT).\n */\n async update(\n productId: string,\n input: ProductPatchInput,\n options: ProductWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<void> {\n const query = {\n ...(options.skipVariantGeneration === undefined ? {} : { skipVariantGeneration: String(options.skipVariantGeneration) }),\n ...(options.doIndex === undefined ? {} : { doIndex: String(options.doIndex) }),\n ...(options.skipRelatedItemsValidation === undefined ? {} : { skipRelatedItemsValidation: String(options.skipRelatedItemsValidation) }),\n };\n await this.ctx.http.request<void>({\n method: \"PATCH\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n body: input,\n auth,\n });\n }\n\n /**\n * Full-replaces a product (`PUT /products/{productId}`). Returns the created\n * resource on 201 (upsert) and nothing on 204. `options.partial` sends\n * `?partial=true` for a merge-style replace. Default auth: service.\n */\n async replace(\n productId: string,\n input: ProductUpdateInput,\n options: ProductWriteOptions & { partial?: boolean } = {},\n auth: AuthContext = SERVICE,\n ): Promise<ProductCreated | void> {\n const query = {\n ...(options.partial === undefined ? {} : { partial: String(options.partial) }),\n ...(options.skipVariantGeneration === undefined ? {} : { skipVariantGeneration: String(options.skipVariantGeneration) }),\n ...(options.doIndex === undefined ? {} : { doIndex: String(options.doIndex) }),\n ...(options.skipRelatedItemsValidation === undefined ? {} : { skipRelatedItemsValidation: String(options.skipRelatedItemsValidation) }),\n };\n return this.ctx.http.request<ProductCreated | void>({\n method: \"PUT\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n body: input,\n auth,\n });\n }\n\n /**\n * Deletes a product (`DELETE /products/{productId}`). `options.force` deletes\n * even when the product is referenced. Default auth: service.\n */\n async delete(\n productId: string,\n options: { force?: boolean; doIndex?: boolean } = {},\n auth: AuthContext = SERVICE,\n ): Promise<void> {\n const query = {\n ...(options.force === undefined ? {} : { force: String(options.force) }),\n ...(options.doIndex === undefined ? {} : { doIndex: String(options.doIndex) }),\n };\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n auth,\n });\n }\n\n /**\n * Bulk-creates products (`POST /products/bulk`). Responds 207 Multi-Status:\n * partial failures do **not** throw — inspect each entry. Default auth: service.\n */\n async bulkCreate(\n input: ProductBulkCreateInput,\n options: ProductWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<ProductBulkResult[]> {\n const query = {\n ...(options.skipVariantGeneration === undefined ? {} : { skipVariantGeneration: String(options.skipVariantGeneration) }),\n ...(options.doIndex === undefined ? {} : { doIndex: String(options.doIndex) }),\n ...(options.skipRelatedItemsValidation === undefined ? {} : { skipRelatedItemsValidation: String(options.skipRelatedItemsValidation) }),\n };\n return this.ctx.http.request<ProductBulkResult[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/bulk`,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n body: input,\n auth,\n });\n }\n\n /**\n * Bulk-updates products (`PUT /products/bulk`). Responds 207 Multi-Status:\n * partial failures do **not** throw — inspect each entry. Default auth: service.\n */\n async bulkUpdate(\n input: ProductBulkUpdateInput,\n options: ProductWriteOptions = {},\n auth: AuthContext = SERVICE,\n ): Promise<ProductBulkResult[]> {\n const query = {\n ...(options.skipVariantGeneration === undefined ? {} : { skipVariantGeneration: String(options.skipVariantGeneration) }),\n ...(options.doIndex === undefined ? {} : { doIndex: String(options.doIndex) }),\n ...(options.skipRelatedItemsValidation === undefined ? {} : { skipRelatedItemsValidation: String(options.skipRelatedItemsValidation) }),\n };\n return this.ctx.http.request<ProductBulkResult[]>({\n method: \"PUT\",\n path: `/product/${this.ctx.tenant}/products/bulk`,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n body: input,\n auth,\n });\n }\n\n /**\n * Triggers a dynamic-variant recalculation for the given product ids\n * (`POST /products/recalculate`, 202). The result carries the created or\n * already-referenced `jobs` plus `skippedProductIds` — products whose root\n * already has a PENDING/PROCESSING job. Default auth: service.\n */\n async recalculate(\n input: ProductRecalculationInput,\n auth: AuthContext = SERVICE,\n ): Promise<ProductRecalculationResult> {\n return this.ctx.http.request<ProductRecalculationResult>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/recalculate`,\n body: input,\n auth,\n });\n }\n\n /** Lists dynamic-variant recalculation jobs, optionally filtered by status. Default auth: anonymous. */\n async listRecalculationJobs(\n params: { status?: ProductRecalculationJobStatus } = {},\n auth: AuthContext = ANON,\n ): Promise<ProductRecalculationJob[]> {\n return this.ctx.http.request<ProductRecalculationJob[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/recalculate/jobs`,\n ...(params.status === undefined ? {} : { query: { status: params.status } }),\n auth,\n });\n }\n\n /** Fetches one dynamic-variant recalculation job by id. Default auth: anonymous. */\n async getRecalculationJob(jobId: string, auth: AuthContext = ANON): Promise<ProductRecalculationJob> {\n return this.ctx.http.request<ProductRecalculationJob>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/recalculate/jobs/${jobId}`,\n auth,\n });\n }\n\n /**\n * Product templates (`/product-templates`). Reads default to anonymous,\n * writes to service auth.\n */\n readonly templates = {\n /** One page of product templates. Default auth: anonymous. */\n list: async (\n params: { pageNumber?: number; pageSize?: number; sort?: string; q?: string } = {},\n auth: AuthContext = ANON,\n ): Promise<ProductTemplate[]> =>\n this.ctx.http.request<ProductTemplate[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/product-templates`,\n query: {\n ...(params.pageNumber === undefined ? {} : { pageNumber: params.pageNumber }),\n ...(params.pageSize === undefined ? {} : { pageSize: params.pageSize }),\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n ...(params.q === undefined ? {} : { q: params.q }),\n },\n auth,\n }),\n\n /** Fetches one product template by id. Default auth: anonymous. */\n get: async (templateId: string, auth: AuthContext = ANON): Promise<ProductTemplate> =>\n this.ctx.http.request<ProductTemplate>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/product-templates/${templateId}`,\n auth,\n }),\n\n /** Creates a product template. Default auth: service. */\n create: async (\n input: ProductTemplateCreateInput,\n auth: AuthContext = SERVICE,\n ): Promise<ProductTemplateCreated> =>\n this.ctx.http.request<ProductTemplateCreated>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/product-templates`,\n body: input,\n auth,\n }),\n\n /** Full-replaces a product template (`PUT`). Default auth: service. */\n update: async (\n templateId: string,\n input: ProductTemplateUpdateInput,\n auth: AuthContext = SERVICE,\n ): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"PUT\",\n path: `/product/${this.ctx.tenant}/product-templates/${templateId}`,\n body: input,\n auth,\n });\n },\n\n /** Deletes a product template. Default auth: service. */\n delete: async (templateId: string, auth: AuthContext = SERVICE): Promise<void> => {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/product/${this.ctx.tenant}/product-templates/${templateId}`,\n auth,\n });\n },\n };\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -890,7 +890,7 @@ var HttpClient = class {
|
|
|
890
890
|
};
|
|
891
891
|
|
|
892
892
|
// package.json
|
|
893
|
-
var version = "2.
|
|
893
|
+
var version = "2.28.1";
|
|
894
894
|
|
|
895
895
|
// src/version.ts
|
|
896
896
|
var SDK_VERSION = version;
|
|
@@ -1320,9 +1320,28 @@ var ProductService = class {
|
|
|
1320
1320
|
* so a bare term (e.g. "in time") 400s with "No value for key …". This builds
|
|
1321
1321
|
* a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates
|
|
1322
1322
|
* to {@link search}.
|
|
1323
|
+
*
|
|
1324
|
+
* Safe for text a shopper typed: `( ) "` are **removed** rather than escaped,
|
|
1325
|
+
* because Emporix parses the filter's own structure before it looks at the
|
|
1326
|
+
* regex. `name:(~a \()` is rejected with «Missing closing parenthesis in value»
|
|
1327
|
+
* even though the paren is escaped, so a search box would 400 on an opening
|
|
1328
|
+
* bracket. Measured against a live tenant on 2026-08-03: of every regex
|
|
1329
|
+
* metacharacter only those three break; the rest survive escaping.
|
|
1330
|
+
*
|
|
1331
|
+
* A query consisting solely of those characters leaves nothing to search for and
|
|
1332
|
+
* returns an empty page without a request — `name:(~)` is a 400.
|
|
1323
1333
|
*/
|
|
1324
1334
|
async searchByName(query, params = {}, auth2 = ANON) {
|
|
1325
|
-
const
|
|
1335
|
+
const term = query.replace(/[()"]/g, " ").replace(/\s+/g, " ").trim();
|
|
1336
|
+
if (term === "") {
|
|
1337
|
+
return {
|
|
1338
|
+
items: [],
|
|
1339
|
+
pageNumber: params.pageNumber ?? 1,
|
|
1340
|
+
pageSize: params.pageSize ?? 50,
|
|
1341
|
+
hasNextPage: false
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
const escaped = term.replace(/[.*+?^${}|[\]\\]/g, "\\$&");
|
|
1326
1345
|
return this.search(`name:(~${escaped})`, params, auth2);
|
|
1327
1346
|
}
|
|
1328
1347
|
/**
|
|
@@ -6673,6 +6692,17 @@ var CurrencyService = class {
|
|
|
6673
6692
|
|
|
6674
6693
|
// src/services/shipping.ts
|
|
6675
6694
|
var SERVICE25 = { kind: "service" };
|
|
6695
|
+
function resolveZone(zones, country) {
|
|
6696
|
+
if (!zones || zones.length === 0) return void 0;
|
|
6697
|
+
const c = country.trim().toUpperCase();
|
|
6698
|
+
const byCountry = c ? zones.find((z) => (z.shipTo ?? []).some((s) => s.country?.toUpperCase() === c)) : void 0;
|
|
6699
|
+
return byCountry ?? zones.find((z) => z.default) ?? zones[0];
|
|
6700
|
+
}
|
|
6701
|
+
function pickFee(fees, cartTotal) {
|
|
6702
|
+
if (!fees || fees.length === 0) return void 0;
|
|
6703
|
+
const eligible = fees.filter((f) => (f.minOrderValue?.amount ?? 0) <= cartTotal).sort((a, b) => (b.minOrderValue?.amount ?? 0) - (a.minOrderValue?.amount ?? 0));
|
|
6704
|
+
return eligible[0] ?? fees[0];
|
|
6705
|
+
}
|
|
6676
6706
|
var ShippingService = class {
|
|
6677
6707
|
constructor(ctx) {
|
|
6678
6708
|
this.ctx = ctx;
|
|
@@ -8256,10 +8286,12 @@ exports.createEmporixClient = createEmporixClient;
|
|
|
8256
8286
|
exports.createNoopLogger = createNoopLogger;
|
|
8257
8287
|
exports.errorFromResponse = errorFromResponse;
|
|
8258
8288
|
exports.iterateAll = iterateAll;
|
|
8289
|
+
exports.pickFee = pickFee;
|
|
8259
8290
|
exports.productIdFromYrn = productIdFromYrn;
|
|
8260
8291
|
exports.redact = redact;
|
|
8261
8292
|
exports.resolveQuery = resolveQuery;
|
|
8262
8293
|
exports.resolveToken = resolveToken;
|
|
8294
|
+
exports.resolveZone = resolveZone;
|
|
8263
8295
|
exports.validateConfig = validateConfig;
|
|
8264
8296
|
//# sourceMappingURL=index.cjs.map
|
|
8265
8297
|
//# sourceMappingURL=index.cjs.map
|