@viu/emporix-sdk 3.5.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +148 -0
- package/README.md +2 -2
- package/dist/availability.d.cts +1 -1
- package/dist/availability.d.ts +1 -1
- package/dist/cart.d.cts +1 -1
- package/dist/cart.d.ts +1 -1
- package/dist/category.d.cts +1 -1
- package/dist/category.d.ts +1 -1
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/{chunk-JQWUGGRV.js → chunk-2SHTDVOC.js} +22 -2
- package/dist/chunk-2SHTDVOC.js.map +1 -0
- package/dist/{chunk-TI56QENX.js → chunk-CSYXGTOH.js} +31 -2
- package/dist/chunk-CSYXGTOH.js.map +1 -0
- package/dist/{chunk-3G5KROEC.js → chunk-XJJDCK2Z.js} +80 -3
- package/dist/chunk-XJJDCK2Z.js.map +1 -0
- package/dist/companies.d.cts +1 -1
- package/dist/companies.d.ts +1 -1
- package/dist/contacts.d.cts +1 -1
- package/dist/contacts.d.ts +1 -1
- package/dist/{context-CZdtWgQO.d.cts → context-5lt8Q0MT.d.cts} +1 -1
- package/dist/{context-CZdtWgQO.d.ts → context-5lt8Q0MT.d.ts} +1 -1
- package/dist/{customer-groups-OEnqHFsX.d.cts → customer-groups-8cgS8S5d.d.cts} +1 -1
- package/dist/{customer-groups-DhrOoC8M.d.ts → customer-groups-DizW_a-w.d.ts} +1 -1
- package/dist/customer-groups.d.cts +2 -2
- package/dist/customer-groups.d.ts +2 -2
- package/dist/customer.d.cts +1 -1
- package/dist/customer.d.ts +1 -1
- package/dist/index.cjs +272 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +333 -591
- package/dist/index.d.ts +333 -591
- package/dist/index.js +152 -137
- package/dist/index.js.map +1 -1
- package/dist/locations.d.cts +1 -1
- package/dist/locations.d.ts +1 -1
- package/dist/media.cjs +29 -0
- package/dist/media.cjs.map +1 -1
- package/dist/media.d.cts +45 -3
- package/dist/media.d.ts +45 -3
- package/dist/media.js +1 -1
- package/dist/orders.d.cts +1 -1
- package/dist/orders.d.ts +1 -1
- package/dist/payment.d.cts +1 -1
- package/dist/payment.d.ts +1 -1
- package/dist/price.d.cts +1 -1
- package/dist/price.d.ts +1 -1
- package/dist/product.cjs +20 -0
- package/dist/product.cjs.map +1 -1
- package/dist/product.d.cts +24 -2
- package/dist/product.d.ts +24 -2
- package/dist/product.js +1 -1
- package/dist/segment.cjs +78 -1
- package/dist/segment.cjs.map +1 -1
- package/dist/segment.d.cts +90 -3
- package/dist/segment.d.ts +90 -3
- package/dist/segment.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-3G5KROEC.js.map +0 -1
- package/dist/chunk-JQWUGGRV.js.map +0 -1
- package/dist/chunk-TI56QENX.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,153 @@
|
|
|
1
1
|
# @viu/emporix-sdk
|
|
2
2
|
|
|
3
|
+
## 4.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#346](https://github.com/viuteam/emporix-sdk/pull/346) [`f2a70d4`](https://github.com/viuteam/emporix-sdk/commit/f2a70d41709369082cf183cf7db159031c0f549e) Thanks [@amnael1](https://github.com/amnael1)! - feat(sdk): send the chat session from `chat` and `chatAsync` — options second, auth third
|
|
8
|
+
|
|
9
|
+
**Breaking: `client.ai.chat(input, auth)` and `client.ai.chatAsync(input, auth)`
|
|
10
|
+
are now `(input, opts, auth)`**, the order `chatStream` already used.
|
|
11
|
+
`opts.sessionId` is sent as the `session-id` header.
|
|
12
|
+
|
|
13
|
+
Until now only `chatStream` could send that header, so a synchronous or
|
|
14
|
+
asynchronous chat could neither continue a conversation (continuity needs the
|
|
15
|
+
header plus `enabledMemory` on the agent) nor use an attachment, which the
|
|
16
|
+
service resolves inside the session its upload or reuse returned. The chat body
|
|
17
|
+
has no `sessionId` field; the header is the only way.
|
|
18
|
+
|
|
19
|
+
**Migrating:** `chat(input)` and `chatAsync(input)` are unchanged. A call that
|
|
20
|
+
passes an auth context second becomes `chat(input, {}, auth)`. Passing it second
|
|
21
|
+
now **throws** (`pass the auth context third`) instead of being read as options
|
|
22
|
+
— which in plain JavaScript would have run the call on the default service token
|
|
23
|
+
without a word. `chatStream` refuses the same mistake.
|
|
24
|
+
|
|
25
|
+
`ChatOptions` is the new shared options type; `ChatStreamOptions` remains as a
|
|
26
|
+
deprecated alias of it.
|
|
27
|
+
|
|
28
|
+
- [#340](https://github.com/viuteam/emporix-sdk/pull/340) [`3977a77`](https://github.com/viuteam/emporix-sdk/commit/3977a7767e0dc82fe1f6d70a21d76ac8da7a82e7) Thanks [@amnael1](https://github.com/amnael1)! - feat(sdk): remove the Pick-Pack service — upstream End of Life
|
|
29
|
+
|
|
30
|
+
**Breaking: `client.pickPack` and every Pick-Pack type are gone.**
|
|
31
|
+
|
|
32
|
+
Emporix retired the Pick-Pack Service. It was deprecated on 2026-05-25 with
|
|
33
|
+
removal announced for 2026-08-24, and on 2026-09-16 all twelve endpoints and the
|
|
34
|
+
API reference were taken down — see "Pick-pack Service - removal of deprecated
|
|
35
|
+
endpoints" in the [Emporix changelog](https://developer.emporix.io/changelog)
|
|
36
|
+
and [emporix/api-references#497](https://github.com/emporix/api-references/pull/497).
|
|
37
|
+
The service's `@deprecated` marker in this SDK already announced the removal.
|
|
38
|
+
|
|
39
|
+
Nothing here could keep working: every `/pick-pack/{tenant}/…` operation —
|
|
40
|
+
orders, order cycles, assignees, packaging, packing events and recalculation
|
|
41
|
+
jobs — no longer exists. Keeping `client.pickPack` would have shipped a facade
|
|
42
|
+
that only ever answers 404 while looking like a working API, which is worse than
|
|
43
|
+
removing it.
|
|
44
|
+
|
|
45
|
+
Removed: the `pickPack` client property; `PickPackService` and its twelve
|
|
46
|
+
methods (`listOrders`, `getOrder`, `updateOrder`, `finishOrder`,
|
|
47
|
+
`listOrderCycles`, `addAssignee`, `removeAssignee`, `updatePackaging`,
|
|
48
|
+
`createEvent`, `listEvents`, `triggerRecalculation`, `getRecalculationJob`); the
|
|
49
|
+
types `PickOrder`, `PickOrderList`, `OrderStatusChange`, `PackagingProductsChange`,
|
|
50
|
+
`Assignee`, `OrderEntryEventCreate`, `PackingEvent`, `PackingEventList`,
|
|
51
|
+
`OrderCycleList`, `RecalculationJobInput`, `RecalculationJob`, `PickPackAck` and
|
|
52
|
+
`RecalculationJobCreated`; the generated types, the vendored spec, the
|
|
53
|
+
`"pick-pack"` logger channel and `docs/pick-pack.md`.
|
|
54
|
+
|
|
55
|
+
**If you used it:** there is no replacement in the Emporix API.
|
|
56
|
+
|
|
57
|
+
This also unblocks the `Emporix API Sync` workflow, which has failed on every run
|
|
58
|
+
since 2026-09-17 — `fetch-specs` requests each vendored spec and throws on a
|
|
59
|
+
non-200, so the 404 on `orders/pick-pack/api-reference/api.yml` stopped the whole
|
|
60
|
+
sync after 33 successful fetches and left the remaining nine unrequested. That fail-fast is deliberate and stays, as it
|
|
61
|
+
did for the SEPA Export removal in 3.0.0: a silently skipped spec would
|
|
62
|
+
regenerate types without a service and nobody would notice.
|
|
63
|
+
|
|
64
|
+
### Minor Changes
|
|
65
|
+
|
|
66
|
+
- [#341](https://github.com/viuteam/emporix-sdk/pull/341) [`aa9f411`](https://github.com/viuteam/emporix-sdk/commit/aa9f411308e775efc8f4e17f089fe6316caaeb36) Thanks [@amnael1](https://github.com/amnael1)! - feat(sdk): sync with the 2026-09-14 … 2026-09-25 Emporix changes — segment IAM groups, import run diagnostics, attachment reuse
|
|
67
|
+
|
|
68
|
+
Nine new endpoints are wrapped; every vendored spec that changed is back at full
|
|
69
|
+
coverage (customer-segment 36/36, import-service 24/24).
|
|
70
|
+
|
|
71
|
+
**Customer segments.** `client.segments.listMine()` calls the new
|
|
72
|
+
`GET /segments/me`: the customer's active segments, assigned directly and
|
|
73
|
+
inherited through their IAM groups — including groups bound to the customer's
|
|
74
|
+
current legal entity, so the result can change when a B2B customer switches
|
|
75
|
+
company. `client.segments.groups.{list, search, get, assign, remove}` manage the
|
|
76
|
+
new IAM group assignments (service token by default). Only groups with
|
|
77
|
+
`userType: "CUSTOMER"` can be assigned, and `assign` resolves to nothing because
|
|
78
|
+
the upsert's `201`/`204` carry no body.
|
|
79
|
+
|
|
80
|
+
**Import service.** `client.imports.getStreamOrder(configId)` returns the
|
|
81
|
+
computed run order (stream names) and each stream's prerequisites.
|
|
82
|
+
`client.imports.listRunDiagnostics(runId, { kind, streamId, limit })` and
|
|
83
|
+
`downloadRunDiagnosticsCsv(...)` return the rows behind a run's `duplicateKeys`
|
|
84
|
+
and `unresolvedParents` counters — a capped sample, not the full set.
|
|
85
|
+
`triggerRun` accepts `streamIds` to run a subset (ids, not names).
|
|
86
|
+
|
|
87
|
+
**AI attachment reuse.** `client.ai.reuseAttachment` now resolves to the
|
|
88
|
+
attachment `{ id, sessionId }` instead of `undefined`, and `opts.sessionId` is
|
|
89
|
+
optional: since 2026-09-25 the service answers `200` with a body and opens a new
|
|
90
|
+
session when the `session-id` header is absent. Existing calls keep compiling.
|
|
91
|
+
|
|
92
|
+
Type changes that follow upstream without a new method: `ImportStream` loses
|
|
93
|
+
`targetDeleteSubscriptionEnabled` and `onTargetReappear` and gains
|
|
94
|
+
`deleteConfig` (the Import Service is preview, which the SDK documents as
|
|
95
|
+
allowed to change without a major); AI logs gain `promptTokens` /
|
|
96
|
+
`completionTokens`; `handOff` on agent responses is deprecated.
|
|
97
|
+
|
|
98
|
+
Not exposed yet: the cursor pagination Emporix added to AI logs and jobs — those
|
|
99
|
+
facades return arrays, so the cursor headers are dropped.
|
|
100
|
+
|
|
101
|
+
`docs/ai.md` also stops showing `chat({ …, sessionId } as never)` for an
|
|
102
|
+
attachment chat. The chat body has no `sessionId`; the session travels as the
|
|
103
|
+
`session-id` header, which only `chatStream` can send today.
|
|
104
|
+
|
|
105
|
+
### Patch Changes
|
|
106
|
+
|
|
107
|
+
- [#345](https://github.com/viuteam/emporix-sdk/pull/345) [`4e706dd`](https://github.com/viuteam/emporix-sdk/commit/4e706ddad0dedb17ea17f1d9b1a7d2ec65d1a02c) Thanks [@viu-release-bot](https://github.com/apps/viu-release-bot)! - chore(sdk): sync generated types with upstream Emporix API specs
|
|
108
|
+
|
|
109
|
+
Updated services: ai-service,import-service
|
|
110
|
+
|
|
111
|
+
## 3.6.0
|
|
112
|
+
|
|
113
|
+
### Minor Changes
|
|
114
|
+
|
|
115
|
+
- [#335](https://github.com/viuteam/emporix-sdk/pull/335) [`a2e1e96`](https://github.com/viuteam/emporix-sdk/commit/a2e1e96e706265176b37b8355cd6a6213588e8ef) Thanks [@amnael1](https://github.com/amnael1)! - feat(sdk): add media.patch and ai.reuseAttachment, and document the product mixin merge
|
|
116
|
+
|
|
117
|
+
Two endpoints Emporix changed on 2026-09-10, plus one undocumented contract that
|
|
118
|
+
turned up in the same sync.
|
|
119
|
+
|
|
120
|
+
- `client.media.patch(assetId, ops)` — the new `PATCH /media/{tenant}/assets/{assetId}`,
|
|
121
|
+
an RFC-6902 op-array (`add`/`remove`/`replace`), resolving on `204`. This is the
|
|
122
|
+
only way to change a `BLOB` asset's metadata **without re-uploading the file**:
|
|
123
|
+
`update(assetId, { kind: "blob", … })` always replaces the bytes. Append to an
|
|
124
|
+
array with a path ending in `/-` — `{ op: "add", path: "/refIds/-", value }`
|
|
125
|
+
keeps the existing entries, while `/refIds` without the suffix replaces them
|
|
126
|
+
all. `type` and `access` stay immutable, and a stale `metadata.version` still
|
|
127
|
+
gets a `409`.
|
|
128
|
+
- `client.ai.reuseAttachment(agentId, attachmentId, { sessionId })` — the
|
|
129
|
+
attachments endpoint now takes either a file or the id of an attachment already
|
|
130
|
+
in the session, and **exactly one of the two**; both or neither is a `400`. A
|
|
131
|
+
separate method rather than an overload, because the two branches disagree on
|
|
132
|
+
more than the input: the upload answers `201` with `{ id, sessionId }` while the
|
|
133
|
+
reuse answers `204` and returns nothing, and `session-id` is optional on the
|
|
134
|
+
upload but required on the reuse — the attachment id is resolved inside that
|
|
135
|
+
session, so omitting it cannot succeed.
|
|
136
|
+
|
|
137
|
+
`AGENT` joined the media reference types (`RefId.type`), which links a `PRIVATE`
|
|
138
|
+
asset to an AI agent. Nothing was needed for it — `AssetRefId` aliases the
|
|
139
|
+
generated type, so it arrived with the sync.
|
|
140
|
+
|
|
141
|
+
**The product service also drifted, with no schema change and no changelog entry
|
|
142
|
+
upstream**, and what it added is worth knowing because it is easy to get
|
|
143
|
+
backwards: `products.update` (`PATCH`) **merges** mixins. An omitted mixin name
|
|
144
|
+
stays on the product, sent fields merge recursively, and `null` stores `null`
|
|
145
|
+
instead of deleting. There is therefore no way to delete a mixin through `PATCH`
|
|
146
|
+
— that needs `products.replace` with `partial: false` and a complete document
|
|
147
|
+
that omits the mixin from both `mixins` and `metadata.mixins`. And despite the
|
|
148
|
+
verb, product `PATCH` is **not** a JSON-Patch endpoint; an op-array is rejected.
|
|
149
|
+
Both are now in the JSDoc of the two methods.
|
|
150
|
+
|
|
3
151
|
## 3.5.0
|
|
4
152
|
|
|
5
153
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ property on the `EmporixClient` instance:
|
|
|
63
63
|
| --- | --- |
|
|
64
64
|
| Catalog | `products`, `categories`, `prices`, `brands`, `labels`, `catalogs` |
|
|
65
65
|
| Cart & checkout | `carts`, `checkout`, `payments`, `coupons`, `taxes`, `shipping`, `fees` |
|
|
66
|
-
| Orders & fulfilment | `orders`, `salesOrders`, `quotes`, `invoices`, `returns`, `
|
|
66
|
+
| Orders & fulfilment | `orders`, `salesOrders`, `quotes`, `invoices`, `returns`, `availability`, `indexing` |
|
|
67
67
|
| Customers & B2B | `customers`, `customerAdmin`, `companies`, `contacts`, `locations`, `customerGroups`, `approvals`, `rewardPoints`, `segments`, `iam` |
|
|
68
68
|
| Platform & config | `sites`, `sessionContext`, `tenantConfig`, `clientConfig`, `media`, `schemas`, `webhooks`, `sequentialIds`, `units`, `countries`, `currencies`, `vendors`, `shoppingLists`, `cloudFunctions`, `ai`, `ragIndexer`, `imports`, `auditLogs` |
|
|
69
69
|
|
|
@@ -190,7 +190,7 @@ services: `./customer`, `./product`, `./category`, `./cart`, `./checkout`,
|
|
|
190
190
|
`./payment`, `./price`, `./media`, `./segment`, `./companies`, `./contacts`,
|
|
191
191
|
`./locations`, `./customer-groups`, `./orders`, `./availability`. All other
|
|
192
192
|
services (Tax, Coupon, RewardPoints, Shipping, Returns, Catalog, Vendor,
|
|
193
|
-
|
|
193
|
+
CustomerAdmin, Approval, …) are reached from the package root.
|
|
194
194
|
|
|
195
195
|
## Changelog
|
|
196
196
|
|
package/dist/availability.d.cts
CHANGED
package/dist/availability.d.ts
CHANGED
package/dist/cart.d.cts
CHANGED
package/dist/cart.d.ts
CHANGED
package/dist/category.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-
|
|
1
|
+
import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-5lt8Q0MT.cjs';
|
|
2
2
|
import { a as QueryFor } from './query-mLQs2WFr.cjs';
|
|
3
3
|
import { Product } from './product.cjs';
|
|
4
4
|
|
package/dist/category.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-
|
|
1
|
+
import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-5lt8Q0MT.js';
|
|
2
2
|
import { a as QueryFor } from './query-mLQs2WFr.js';
|
|
3
3
|
import { Product } from './product.js';
|
|
4
4
|
|
package/dist/checkout.d.cts
CHANGED
package/dist/checkout.d.ts
CHANGED
|
@@ -224,6 +224,20 @@ var ProductService = class {
|
|
|
224
224
|
/**
|
|
225
225
|
* Partially updates a product (`PATCH /products/{productId}`). Default auth:
|
|
226
226
|
* service. Use {@link replace} for a full replace (PUT).
|
|
227
|
+
*
|
|
228
|
+
* Omitted fields stay as they are. **Mixins merge rather than replace**, and
|
|
229
|
+
* the corollary catches people out: there is no way to delete a mixin here.
|
|
230
|
+
* - a mixin name you omit stays on the product;
|
|
231
|
+
* - fields you send inside a mixin are merged recursively, and fields you
|
|
232
|
+
* omit inside that mixin keep their values;
|
|
233
|
+
* - `null` does **not** delete a mixin — it stores `null` as its value.
|
|
234
|
+
*
|
|
235
|
+
* To actually remove one, read the product and send it back through
|
|
236
|
+
* {@link replace} with `partial: false`, leaving the mixin out of both
|
|
237
|
+
* `mixins` and `metadata.mixins`.
|
|
238
|
+
*
|
|
239
|
+
* Despite the HTTP verb this is **not** a JSON-Patch endpoint: an op-array of
|
|
240
|
+
* `{ op, path, value }` is rejected. Send a partial product document.
|
|
227
241
|
*/
|
|
228
242
|
async update(productId, input, options = {}, auth = SERVICE) {
|
|
229
243
|
const query = {
|
|
@@ -243,6 +257,12 @@ var ProductService = class {
|
|
|
243
257
|
* Full-replaces a product (`PUT /products/{productId}`). Returns the created
|
|
244
258
|
* resource on 201 (upsert) and nothing on 204. `options.partial` sends
|
|
245
259
|
* `?partial=true` for a merge-style replace. Default auth: service.
|
|
260
|
+
*
|
|
261
|
+
* With `partial: false` (the default) the body must be the **complete**
|
|
262
|
+
* product document, and any mixin name missing from it is removed — which is
|
|
263
|
+
* what makes this the only way to delete a mixin, since {@link update} merges
|
|
264
|
+
* them. The flip side is that a body you did not build from a fresh read will
|
|
265
|
+
* silently drop mixins.
|
|
246
266
|
*/
|
|
247
267
|
async replace(productId, input, options = {}, auth = SERVICE) {
|
|
248
268
|
const query = {
|
|
@@ -393,5 +413,5 @@ var ProductService = class {
|
|
|
393
413
|
};
|
|
394
414
|
|
|
395
415
|
export { ProductService };
|
|
396
|
-
//# sourceMappingURL=chunk-
|
|
397
|
-
//# sourceMappingURL=chunk-
|
|
416
|
+
//# sourceMappingURL=chunk-2SHTDVOC.js.map
|
|
417
|
+
//# sourceMappingURL=chunk-2SHTDVOC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/product.ts"],"names":[],"mappings":"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","file":"chunk-2SHTDVOC.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport { requestPage } from \"../core/paged\";\nimport type { AuthContext } from \"../core/auth\";\nimport { resolveQuery, type QueryFor } from \"../core/query\";\nimport type {\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; totalCount?: boolean } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n return requestPage<Product>(\n this.ctx.http,\n {\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { pageNumber, pageSize },\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\n }\n\n /** Async-iterates every 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; totalCount?: boolean } = {},\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 return requestPage<Product>(\n this.ctx.http,\n {\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q, pageNumber, pageSize },\n auth,\n },\n {\n pageNumber,\n pageSize,\n ...(params.totalCount === undefined ? {} : { totalCount: params.totalCount }),\n },\n );\n }\n\n /**\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 // Makes no request of its own — `totalCount` is here purely so it can be\n // forwarded to `search`, which is where the header actually gets sent.\n params: { pageNumber?: number; pageSize?: number; totalCount?: boolean } = {},\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 * Omitted fields stay as they are. **Mixins merge rather than replace**, and\n * the corollary catches people out: there is no way to delete a mixin here.\n * - a mixin name you omit stays on the product;\n * - fields you send inside a mixin are merged recursively, and fields you\n * omit inside that mixin keep their values;\n * - `null` does **not** delete a mixin — it stores `null` as its value.\n *\n * To actually remove one, read the product and send it back through\n * {@link replace} with `partial: false`, leaving the mixin out of both\n * `mixins` and `metadata.mixins`.\n *\n * Despite the HTTP verb this is **not** a JSON-Patch endpoint: an op-array of\n * `{ op, path, value }` is rejected. Send a partial product document.\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 * With `partial: false` (the default) the body must be the **complete**\n * product document, and any mixin name missing from it is removed — which is\n * what makes this the only way to delete a mixin, since {@link update} merges\n * them. The flip side is that a body you did not build from a fresh read will\n * silently drop mixins.\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"]}
|
|
@@ -99,6 +99,35 @@ var MediaService = class {
|
|
|
99
99
|
body: input.body
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Partially update an asset with an RFC-6902 JSON-Patch op-array
|
|
104
|
+
* (`PATCH /assets/{id}`, HTTP 204 — nothing is returned).
|
|
105
|
+
*
|
|
106
|
+
* This is the way to change one field without resending the whole asset, and
|
|
107
|
+
* the only way to touch a `BLOB` asset's metadata **without re-uploading the
|
|
108
|
+
* file** — {@link update} in `blob` mode always replaces the bytes.
|
|
109
|
+
*
|
|
110
|
+
* Append to an array with a path ending in `/-`, which preserves the existing
|
|
111
|
+
* entries:
|
|
112
|
+
*
|
|
113
|
+
* ```ts
|
|
114
|
+
* await client.media.patch(assetId, [
|
|
115
|
+
* { op: "add", path: "/refIds/-", value: { id: "product1", type: "PRODUCT" } },
|
|
116
|
+
* ]);
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* `type` and `access` are immutable here too, as with {@link update}. Only
|
|
120
|
+
* `add`, `remove` and `replace` are accepted, and optimistic locking still
|
|
121
|
+
* applies — a stale `metadata.version` gets a 409.
|
|
122
|
+
*/
|
|
123
|
+
async patch(assetId, ops, auth = SERVICE) {
|
|
124
|
+
await this.ctx.http.request({
|
|
125
|
+
method: "PATCH",
|
|
126
|
+
path: `${this.base()}/${encodeURIComponent(assetId)}`,
|
|
127
|
+
auth,
|
|
128
|
+
body: ops
|
|
129
|
+
});
|
|
130
|
+
}
|
|
102
131
|
/** Remove an asset. */
|
|
103
132
|
async remove(assetId, auth = SERVICE) {
|
|
104
133
|
await this.ctx.http.request({
|
|
@@ -245,5 +274,5 @@ var MediaService = class {
|
|
|
245
274
|
var _internalMedia = { isProductRef };
|
|
246
275
|
|
|
247
276
|
export { MediaService, _internalMedia };
|
|
248
|
-
//# sourceMappingURL=chunk-
|
|
249
|
-
//# sourceMappingURL=chunk-
|
|
277
|
+
//# sourceMappingURL=chunk-CSYXGTOH.js.map
|
|
278
|
+
//# sourceMappingURL=chunk-CSYXGTOH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/media.ts"],"names":["text"],"mappings":"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","file":"chunk-CSYXGTOH.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { requestPage } from \"../core/paged\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixError, errorFromResponse } from \"../core/errors\";\nimport type {\n AssetCreateBlob,\n AssetCreateLink,\n AssetUpdateBlob,\n AssetUpdateLink,\n GetAsset,\n PatchOperation,\n RefId,\n} from \"../generated/media\";\n\n/** Generated media types (caller sends the exact wire shape). */\nexport type AssetCreateBlobInput = AssetCreateBlob;\nexport type AssetCreateLinkInput = AssetCreateLink;\nexport type AssetUpdateBlobInput = AssetUpdateBlob;\nexport type AssetUpdateLinkInput = AssetUpdateLink;\nexport type AssetUpdateInput = AssetUpdateBlob | AssetUpdateLink;\nexport type Asset = GetAsset;\nexport type AssetRefId = RefId;\n/** Partial-update body (`PATCH /assets/{id}`) — an RFC-6902 JSON-Patch op-array. */\nexport type AssetPatch = PatchOperation[];\n\n/**\n * Filter / pagination options for {@link MediaService.list}. The explicit\n * fields are typed for autocomplete; the index signature stays open so\n * Emporix `q`-syntax filters like `\"refIds.id\"` can be passed verbatim.\n */\nexport interface ListAssetsQuery {\n pageNumber?: number;\n pageSize?: number;\n /** Emporix sort syntax, e.g. `\"name,metadata.createdAt:desc\"`. */\n sort?: string;\n /** Emporix `q`-syntax filter, e.g. `\"name:hero\"`. */\n q?: string;\n /**\n * Ask for `X-Total-Count`. An SDK-side flag, not an Emporix query parameter:\n * it becomes a request header.\n */\n totalCount?: boolean;\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Result of {@link MediaService.download}. The endpoint's behaviour depends\n * on the asset's `access`:\n * - `PUBLIC` assets respond with a 30x redirect whose `Location` header\n * carries the externally-cacheable storage URL — useful when the\n * storefront wants to send the user there directly.\n * - `PRIVATE` assets respond with the raw bytes (plus an `ETag` header\n * for caching). The asset is delivered through Cloudinary behind the\n * server-side service token, never publicly addressable.\n */\nexport type DownloadResult =\n | { kind: \"redirect\"; url: string }\n | {\n kind: \"bytes\";\n data: ArrayBuffer;\n etag?: string;\n contentType?: string;\n };\n\nconst SERVICE: AuthContext = { kind: \"service\" };\n\nfunction isProductRef(r: AssetRefId, productId: string): boolean {\n return r.type === \"PRODUCT\" && r.id === productId;\n}\n\n/**\n * Media assets (BLOB/LINK). All endpoints require a backend-only scope\n * (`media.asset_manage` / `media.asset_read`) — default auth: service.\n */\nexport class MediaService {\n static readonly channel = \"media\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/media/${this.ctx.tenant}/assets`;\n }\n\n /** Create an asset. BLOB uploads via multipart; LINK via JSON. */\n async create(\n input:\n | { kind: \"blob\"; file: Blob; body: AssetCreateBlobInput }\n | { kind: \"link\"; body: AssetCreateLinkInput },\n auth: AuthContext = SERVICE,\n ): Promise<{ id: string }> {\n if (input.kind === \"blob\") {\n const fd = new FormData();\n fd.set(\"file\", input.file);\n fd.set(\"body\", JSON.stringify(input.body));\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: fd,\n });\n }\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input.body,\n });\n }\n\n /**\n * List assets, wrapped in the shared {@link PaginatedItems} envelope so\n * callers can iterate over pages consistently with the rest of the SDK.\n * `hasNextPage` is the standard SDK heuristic: `true` when the returned\n * page is full (`items.length === requested pageSize`). Pagination\n * defaults match Emporix's server defaults (`pageNumber: 1`,\n * `pageSize: 60`) so an empty `query` produces stable expectations.\n */\n async list(\n query: ListAssetsQuery = {},\n auth: AuthContext = SERVICE,\n ): Promise<PaginatedItems<Asset>> {\n const pageNumber = query.pageNumber ?? 1;\n const pageSize = query.pageSize ?? 60;\n // Destructured out because the rest of `query` is spread into the query\n // string: `totalCount` is an SDK-side flag that becomes a request header,\n // and would otherwise ride along as a stray `?totalCount=true`.\n const { totalCount, ...rest } = query;\n return requestPage<Asset>(\n this.ctx.http,\n {\n method: \"GET\",\n path: this.base(),\n auth,\n query: { ...rest, pageNumber, pageSize },\n },\n { pageNumber, pageSize, ...(totalCount === undefined ? {} : { totalCount }) },\n );\n }\n\n /** Fetch an asset by id. */\n async get(assetId: string, auth: AuthContext = SERVICE): Promise<Asset> {\n return this.ctx.http.request<Asset>({\n method: \"GET\",\n path: `${this.base()}/${assetId}`,\n auth,\n });\n }\n\n /**\n * Update an asset. The input is a discriminated union mirroring\n * {@link create}:\n * - `{ kind: \"json\", body }` — metadata-only patch (BLOB or LINK).\n * Sends `application/json`. Used for `refIds`, `details`, `metadata`,\n * or `url` changes.\n * - `{ kind: \"blob\", file, body }` — replaces the BLOB file content\n * (max 10MB) AND patches metadata in the same request. Sends\n * `multipart/form-data`.\n *\n * `type` and `access` are immutable per Emporix — they must match the\n * existing asset's values. Optimistic-locking is via `body.metadata.version`;\n * the server returns 409 Conflict on a stale version.\n */\n async update(\n assetId: string,\n input:\n | { kind: \"json\"; body: AssetUpdateInput }\n | { kind: \"blob\"; file: Blob; body: AssetUpdateBlobInput },\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n if (input.kind === \"blob\") {\n const fd = new FormData();\n fd.set(\"file\", input.file);\n fd.set(\"body\", JSON.stringify(input.body));\n return this.ctx.http.request<Asset>({\n method: \"PUT\",\n path: `${this.base()}/${assetId}`,\n auth,\n body: fd,\n });\n }\n return this.ctx.http.request<Asset>({\n method: \"PUT\",\n path: `${this.base()}/${assetId}`,\n auth,\n body: input.body,\n });\n }\n\n /**\n * Partially update an asset with an RFC-6902 JSON-Patch op-array\n * (`PATCH /assets/{id}`, HTTP 204 — nothing is returned).\n *\n * This is the way to change one field without resending the whole asset, and\n * the only way to touch a `BLOB` asset's metadata **without re-uploading the\n * file** — {@link update} in `blob` mode always replaces the bytes.\n *\n * Append to an array with a path ending in `/-`, which preserves the existing\n * entries:\n *\n * ```ts\n * await client.media.patch(assetId, [\n * { op: \"add\", path: \"/refIds/-\", value: { id: \"product1\", type: \"PRODUCT\" } },\n * ]);\n * ```\n *\n * `type` and `access` are immutable here too, as with {@link update}. Only\n * `add`, `remove` and `replace` are accepted, and optimistic locking still\n * applies — a stale `metadata.version` gets a 409.\n */\n async patch(assetId: string, ops: AssetPatch, auth: AuthContext = SERVICE): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"PATCH\",\n path: `${this.base()}/${encodeURIComponent(assetId)}`,\n auth,\n body: ops,\n });\n }\n\n /** Remove an asset. */\n async remove(assetId: string, auth: AuthContext = SERVICE): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${assetId}`,\n auth,\n });\n }\n\n /**\n * Download an asset by id. Returns a discriminated union:\n * - `{ kind: \"redirect\", url }` for `PUBLIC` assets (server-side 30x with\n * the storage URL in `Location`).\n * - `{ kind: \"bytes\", data }` for `PRIVATE` assets (server-side 200 with\n * the asset bytes; `etag` + `contentType` headers are exposed for\n * caching). When the server reports `text/plain` Content-Type (the\n * OpenAPI-documented format), the SDK decodes the base64 stream into\n * an `ArrayBuffer` transparently; binary Content-Types are passed\n * through verbatim.\n *\n * Implementation note: uses `redirect: \"manual\"` so the redirect-location\n * is observable. In Node.js this works; in a browser the redirect Location\n * is intentionally hidden by fetch — there, `PUBLIC` downloads will\n * surface as an opaque-redirect and the SDK throws. Browser code should\n * use the asset's `url` field from `get()` for `LINK` assets, or the\n * direct storage URL for `PUBLIC` `BLOB` assets (typically delivered via\n * an `<img>` tag rather than `download()`).\n */\n async download(\n assetId: string,\n auth: AuthContext = SERVICE,\n ): Promise<DownloadResult> {\n const path = `${this.base()}/${assetId}/download`;\n const res = await this.ctx.http.requestRaw(\n { method: \"GET\", path, auth },\n { redirect: \"manual\" },\n );\n\n // PUBLIC: server-side redirect — capture Location.\n if (res.status >= 300 && res.status < 400) {\n const url = res.headers.get(\"location\");\n if (!url) {\n throw new EmporixError(\n `media.download: ${res.status} response without a Location header`,\n res.status,\n );\n }\n return { kind: \"redirect\", url };\n }\n\n // PRIVATE: bytes.\n if (res.ok) {\n const etag = res.headers.get(\"etag\") ?? undefined;\n const contentType = res.headers.get(\"content-type\") ?? undefined;\n let data: ArrayBuffer;\n if (contentType?.startsWith(\"text/plain\")) {\n // Per OpenAPI spec the server returns the byte stream as a\n // base64-encoded text/plain body. Decode once into raw bytes\n // so callers always see an ArrayBuffer.\n const text = await res.text();\n const bin = atob(text);\n const arr = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i);\n data = arr.buffer;\n } else {\n data = await res.arrayBuffer();\n }\n return {\n kind: \"bytes\",\n data,\n ...(etag !== undefined ? { etag } : {}),\n ...(contentType !== undefined ? { contentType } : {}),\n };\n }\n\n // Error: surface via the standard EmporixError hierarchy.\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n throw errorFromResponse(res.status, `GET ${path} → ${res.status}`, parsed);\n }\n\n /** Multipart upload sugar: builds `AssetCreateBlob` from input. */\n async uploadFile(\n input: {\n file: Blob;\n productId?: string;\n filename?: string;\n mimeType?: string;\n access?: \"PUBLIC\" | \"PRIVATE\";\n },\n auth: AuthContext = SERVICE,\n ): Promise<{ id: string }> {\n const body: AssetCreateBlobInput = {\n type: \"BLOB\",\n access: input.access ?? \"PUBLIC\",\n ...(input.productId\n ? { refIds: [{ type: \"PRODUCT\", id: input.productId }] }\n : {}),\n ...(input.filename || input.mimeType\n ? {\n details: {\n ...(input.filename ? { filename: input.filename } : {}),\n ...(input.mimeType ? { mimeType: input.mimeType } : {}),\n },\n }\n : {}),\n };\n return this.create({ kind: \"blob\", file: input.file, body }, auth);\n }\n\n /**\n * Replace the file content of an existing BLOB asset. Sugar over\n * {@link update} with `kind: \"blob\"`. `access` is required because the\n * field is immutable and the server validates that the patch matches.\n * Pass `version` from `asset.metadata.version` if you want optimistic\n * locking (recommended when concurrent writers are possible).\n */\n async replaceFile(\n assetId: string,\n input: {\n file: Blob;\n access: \"PUBLIC\" | \"PRIVATE\";\n filename?: string;\n mimeType?: string;\n version?: number;\n },\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n const body: AssetUpdateBlobInput = {\n type: \"BLOB\",\n access: input.access,\n ...(input.filename || input.mimeType\n ? {\n details: {\n ...(input.filename ? { filename: input.filename } : {}),\n ...(input.mimeType ? { mimeType: input.mimeType } : {}),\n },\n }\n : {}),\n ...(input.version !== undefined\n ? { metadata: { version: input.version } }\n : {}),\n };\n return this.update(assetId, { kind: \"blob\", file: input.file, body }, auth);\n }\n\n /** External-URL sugar: builds `AssetCreateLink`. */\n async link(\n input: { url: string; productId?: string; access?: \"PUBLIC\" | \"PRIVATE\" },\n auth: AuthContext = SERVICE,\n ): Promise<{ id: string }> {\n const body: AssetCreateLinkInput = {\n type: \"LINK\",\n access: input.access ?? \"PUBLIC\",\n url: input.url,\n ...(input.productId\n ? { refIds: [{ type: \"PRODUCT\", id: input.productId }] }\n : {}),\n };\n return this.create({ kind: \"link\", body }, auth);\n }\n\n /** Idempotently add a PRODUCT refId to an asset. */\n async attachToProduct(\n assetId: string,\n productId: string,\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n const a = await this.get(assetId, auth);\n const refIds: AssetRefId[] = a.refIds ?? [];\n if (refIds.some((r) => isProductRef(r, productId))) return a;\n const next: AssetRefId[] = [...refIds, { type: \"PRODUCT\", id: productId }];\n // Preserve the asset's type discriminator so the update body satisfies\n // the AssetUpdateBlob | AssetUpdateLink union.\n const patch = { type: a.type, refIds: next } as unknown as AssetUpdateInput;\n return this.update(assetId, { kind: \"json\", body: patch }, auth);\n }\n\n /** Remove a PRODUCT refId from an asset (no-op if absent). */\n async detachFromProduct(\n assetId: string,\n productId: string,\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n const a = await this.get(assetId, auth);\n const refIds: AssetRefId[] = a.refIds ?? [];\n const next = refIds.filter((r) => !isProductRef(r, productId));\n if (next.length === refIds.length) return a;\n const patch = { type: a.type, refIds: next } as unknown as AssetUpdateInput;\n return this.update(assetId, { kind: \"json\", body: patch }, auth);\n }\n\n /** Convenience: list assets attached to a product (server-side filter). */\n async listForProduct(\n productId: string,\n auth: AuthContext = SERVICE,\n ): Promise<PaginatedItems<Asset>> {\n return this.list({ \"refIds.id\": productId }, auth);\n }\n}\n\n// Re-export so consumers can `import { isProductRef } from \"@viu/emporix-sdk/media\"`?\n// Internal helper — kept module-private; convenience methods in Task 4 use it.\nexport const _internalMedia = { isProductRef };\n"]}
|
|
@@ -19,7 +19,12 @@ var SegmentService = class {
|
|
|
19
19
|
base() {
|
|
20
20
|
return `/customer-segment/${this.ctx.tenant}/segments`;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Lists segments via the generic `GET /segments` (with `segment_read_own`).
|
|
24
|
+
* Its documentation does not say whether segments inherited through IAM
|
|
25
|
+
* groups are included — for "which segments is this customer in", use
|
|
26
|
+
* {@link listMine}, which is documented to include them.
|
|
27
|
+
*/
|
|
23
28
|
async list(query = {}, auth) {
|
|
24
29
|
const q = {};
|
|
25
30
|
setIfDefined(q, "q", query.q);
|
|
@@ -32,6 +37,26 @@ var SegmentService = class {
|
|
|
32
37
|
...Object.keys(q).length ? { query: q } : {}
|
|
33
38
|
});
|
|
34
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* The authenticated customer's **active** segments (`GET /segments/me`,
|
|
42
|
+
* `segment_read_own`): assigned directly, and inherited through the
|
|
43
|
+
* customer's IAM groups — groups not bound to a legal entity, plus groups
|
|
44
|
+
* bound to the customer's *current* legal entity. Switching the active company
|
|
45
|
+
* can therefore change the result.
|
|
46
|
+
*/
|
|
47
|
+
async listMine(query = {}, auth) {
|
|
48
|
+
const q = {};
|
|
49
|
+
setIfDefined(q, "q", query.q);
|
|
50
|
+
setIfDefined(q, "pageNumber", query.pageNumber);
|
|
51
|
+
setIfDefined(q, "pageSize", query.pageSize);
|
|
52
|
+
setIfDefined(q, "sort", query.sort);
|
|
53
|
+
return this.ctx.http.request({
|
|
54
|
+
method: "GET",
|
|
55
|
+
path: `${this.base()}/me`,
|
|
56
|
+
auth: requireCustomer(auth),
|
|
57
|
+
...Object.keys(q).length ? { query: q } : {}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
35
60
|
/** Fetches a single segment by id. */
|
|
36
61
|
async get(segmentId, auth) {
|
|
37
62
|
return this.ctx.http.request({
|
|
@@ -283,6 +308,58 @@ var SegmentService = class {
|
|
|
283
308
|
body
|
|
284
309
|
})
|
|
285
310
|
};
|
|
311
|
+
/**
|
|
312
|
+
* IAM group→segment assignments (`segment_read` / `segment_manage`). Customers
|
|
313
|
+
* inherit a segment through their groups, on top of direct assignment — see
|
|
314
|
+
* {@link listMine}. Only groups with `userType: "CUSTOMER"` can be assigned;
|
|
315
|
+
* anything else is a `400`. Default auth: service.
|
|
316
|
+
*/
|
|
317
|
+
groups = {
|
|
318
|
+
list: async (segmentId, query = {}, authCtx = SERVICE) => {
|
|
319
|
+
const q = {};
|
|
320
|
+
setIfDefined(q, "q", query.q);
|
|
321
|
+
setIfDefined(q, "pageNumber", query.pageNumber);
|
|
322
|
+
setIfDefined(q, "pageSize", query.pageSize);
|
|
323
|
+
setIfDefined(q, "sort", query.sort);
|
|
324
|
+
return this.ctx.http.request({
|
|
325
|
+
method: "GET",
|
|
326
|
+
path: `${this.base()}/${encodeURIComponent(segmentId)}/groups`,
|
|
327
|
+
auth: authCtx,
|
|
328
|
+
...Object.keys(q).length ? { query: q } : {}
|
|
329
|
+
});
|
|
330
|
+
},
|
|
331
|
+
search: async (segmentId, query, authCtx = SERVICE) => this.ctx.http.request({
|
|
332
|
+
method: "POST",
|
|
333
|
+
path: `${this.base()}/${encodeURIComponent(segmentId)}/groups/search`,
|
|
334
|
+
auth: authCtx,
|
|
335
|
+
body: query
|
|
336
|
+
}),
|
|
337
|
+
get: async (segmentId, groupId, authCtx = SERVICE) => this.ctx.http.request({
|
|
338
|
+
method: "GET",
|
|
339
|
+
path: `${this.base()}/${encodeURIComponent(segmentId)}/groups/${encodeURIComponent(groupId)}`,
|
|
340
|
+
auth: authCtx
|
|
341
|
+
}),
|
|
342
|
+
/**
|
|
343
|
+
* Upsert: `201` when the assignment is created, `204` when it is updated —
|
|
344
|
+
* **neither returns a body**, so this resolves to nothing. Fetch it with
|
|
345
|
+
* {@link get} if you need the stored assignment.
|
|
346
|
+
*/
|
|
347
|
+
assign: async (segmentId, groupId, input = {}, authCtx = SERVICE) => {
|
|
348
|
+
await this.ctx.http.request({
|
|
349
|
+
method: "PUT",
|
|
350
|
+
path: `${this.base()}/${encodeURIComponent(segmentId)}/groups/${encodeURIComponent(groupId)}`,
|
|
351
|
+
auth: authCtx,
|
|
352
|
+
body: input
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
remove: async (segmentId, groupId, authCtx = SERVICE) => {
|
|
356
|
+
await this.ctx.http.request({
|
|
357
|
+
method: "DELETE",
|
|
358
|
+
path: `${this.base()}/${encodeURIComponent(segmentId)}/groups/${encodeURIComponent(groupId)}`,
|
|
359
|
+
auth: authCtx
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
};
|
|
286
363
|
/** Item→segment assignments (`type` = PRODUCT | CATEGORY). Default auth: service. */
|
|
287
364
|
items = {
|
|
288
365
|
search: async (segmentId, query, authCtx = SERVICE) => this.ctx.http.request({
|
|
@@ -325,5 +402,5 @@ var SegmentService = class {
|
|
|
325
402
|
};
|
|
326
403
|
|
|
327
404
|
export { SegmentService };
|
|
328
|
-
//# sourceMappingURL=chunk-
|
|
329
|
-
//# sourceMappingURL=chunk-
|
|
405
|
+
//# sourceMappingURL=chunk-XJJDCK2Z.js.map
|
|
406
|
+
//# sourceMappingURL=chunk-XJJDCK2Z.js.map
|