@viu/emporix-sdk 2.34.0 → 2.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,103 @@
1
1
  # @viu/emporix-sdk
2
2
 
3
+ ## 2.36.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#278](https://github.com/viuteam/emporix-sdk/pull/278) [`9cb8b15`](https://github.com/viuteam/emporix-sdk/commit/9cb8b15d14a122e5a69a36a4c1d4cce7c1308c3f) Thanks [@viu-release-bot](https://github.com/apps/viu-release-bot)! - chore(sdk): sync generated types with upstream Emporix API specs
8
+
9
+ Updated services: ai-service
10
+
11
+ Raised from `patch` to `minor` by hand: this sync reshapes the MCP server model
12
+ rather than extending it, and a patch would not announce that.
13
+
14
+ **`McpServerResponse` is now a union.** Emporix split the single managed-MCP-server
15
+ shape into a custom and a dynamic variant:
16
+
17
+ ```ts
18
+ // before
19
+ type McpServerResponse = BaseMcpServer & { … }
20
+ // after
21
+ type McpServerResponse = CustomMcpServerResponse | DynamicMcpServerResponse
22
+ ```
23
+
24
+ `McpServerRequest` splits the same way. Since `client.ai.mcpServers` is typed
25
+ `AgenticCrudResource<McpServer, McpServerInput>` and `McpServer` aliases
26
+ `McpServerResponse`, code that reads fields off a returned MCP server now has to
27
+ narrow first. Nothing inside the SDK does, which is why the build stays green — the
28
+ break lands in consumer code.
29
+
30
+ Also in this sync:
31
+ - `McpServerType` gains `'dynamic'` (was `'custom' | 'predefined'`).
32
+ - `BaseMcpServer` and `CustomAgentMcpServerResponse` are gone, replaced by
33
+ `BaseManagedMcpServer` and `AgentMcpServerResponse`.
34
+ - `AgentMcpServersResponse` changes element type to `Array<AgentMcpServerResponse>`.
35
+ - Eight new types describe MCP tool invocation: `McpToolRequest`/`Response`,
36
+ `McpToolConfigRequest`/`Response`, `McpToolInvocationRequest`/`Response`,
37
+ `McpToolInvocationMethod` and `McpToolInvocationArgsLocation`.
38
+
39
+ No facade change: all 57 ai-service operations were already wrapped, and none of
40
+ the removed type names appear outside the generated file.
41
+
42
+ ### Patch Changes
43
+
44
+ - [#277](https://github.com/viuteam/emporix-sdk/pull/277) [`f2b5def`](https://github.com/viuteam/emporix-sdk/commit/f2b5def1f125725602ca461f3cdd6b6cb485795c) Thanks [@amnael1](https://github.com/amnael1)! - docs: correct three stale claims in the SDK README, add the missing mixins LICENSE
45
+
46
+ Checked every verifiable claim in the sdk, react and mixins READMEs against the
47
+ code. The react one was clean. Three things in the SDK README were wrong:
48
+ - **`credentials.backend` was marked «(required)»**. It is not: `validateConfig`
49
+ requires only that the `credentials` object exists, so `credentials: {}` is a
50
+ legal credential-free client — which is exactly what `examples/md-module` does,
51
+ where the Managed Dashboard host owns the token. The table now marks
52
+ `credentials` itself as required and explains the empty case.
53
+ - **`customerGroups` was described as «read-only for now»**. It has `addMember`
54
+ and `removeMember`, and the React README already documented the
55
+ `useAddGroupMember` / `useRemoveGroupMember` hooks for them — the two READMEs
56
+ contradicted each other.
57
+ - **`availability` was described as a read-only service** naming two of its nine
58
+ methods. It has three reads defaulting to `anonymous` and six writes
59
+ (`create`, `update`, `delete`, `bulkCreate`, `bulkUpdate`, `bulkDelete`)
60
+ defaulting to `service`.
61
+
62
+ The documented tenant pattern was also the one from the error message
63
+ (`^[a-z][a-z0-9]+$`) rather than the one the code applies
64
+ (`^[a-z][a-z0-9]{2,15}$`); the prose «3–16 chars» was already right.
65
+
66
+ **`@viu/emporix-mixins` was shipping without a LICENSE file.** Its `files` array
67
+ has listed `LICENSE` since the changelog-links change, and `package.json`
68
+ declares `"license": "MIT"`, but the file itself never existed — so the published
69
+ tarball carried no license text. Added, identical to the other three packages.
70
+ Its README also gains the CI/npm badges and the Authors and License sections the
71
+ others have.
72
+
73
+ ## 2.35.0
74
+
75
+ ### Minor Changes
76
+
77
+ - [#273](https://github.com/viuteam/emporix-sdk/pull/273) [`23406dc`](https://github.com/viuteam/emporix-sdk/commit/23406dc3b99bde255c3c01157f3ee6093bbc490a) Thanks [@amnael1](https://github.com/amnael1)! - feat(sdk): expose the customer password-migration endpoints
78
+
79
+ `client.customerAdmin` gains the four operations Emporix added to the Customer
80
+ Service: `getPasswordMigrationRetention`, `configurePasswordMigrationRetention`
81
+ and `deletePasswordMigrationRetention` for the retention window, plus
82
+ `importCustomers` for the bulk import.
83
+
84
+ Together they cover migrating customers off a legacy shop. Configure a retention
85
+ window, import customers carrying `legacyAuth`, and each legacy password hash is
86
+ replaced with an Emporix hash on that customer's first successful login. Without
87
+ an active config the import is rejected — the order matters.
88
+
89
+ `importCustomers` answers **207 Multi-Status**, so per-item failures arrive as
90
+ data with their own `code` rather than throwing. Inspect every entry.
91
+
92
+ All four need a service token with `customer.import_read` or
93
+ `customer.import_manage`, so there are no React hooks — see `docs/customer-admin.md`.
94
+
95
+ ### Patch Changes
96
+
97
+ - [#272](https://github.com/viuteam/emporix-sdk/pull/272) [`87552e7`](https://github.com/viuteam/emporix-sdk/commit/87552e72d5e2de7d1523c3664c49d3cd2f643214) Thanks [@viu-release-bot](https://github.com/apps/viu-release-bot)! - chore(sdk): sync generated types with upstream Emporix API specs
98
+
99
+ Updated services: customer-service
100
+
3
101
  ## 2.34.0
4
102
 
5
103
  ### Minor Changes
package/README.md CHANGED
@@ -93,8 +93,9 @@ See [`../../docs/mixin-search.md`](../../docs/mixin-search.md) for the capabilit
93
93
 
94
94
  | Option | Default | Notes |
95
95
  | --- | --- | --- |
96
- | `tenant` (required) | — | lowercase, 3–16 chars, `^[a-z][a-z0-9]+$` |
97
- | `credentials.backend` (required) | — | `{ clientId, secret, scope? }` — service token |
96
+ | `tenant` (required) | — | lowercase, 3–16 chars, `^[a-z][a-z0-9]{2,15}$` |
97
+ | `credentials` (required) | — | the object itself is required; which sets it holds is up to you |
98
+ | `credentials.backend` | — | `{ clientId, secret, scope? }` — service token |
98
99
  | `credentials.storefront` | — | `{ clientId }` — anonymous token (no secret) |
99
100
  | `credentials.custom` | — | `Record<name, { clientId, secret, scope? }>` |
100
101
  | `host` | `https://api.emporix.io` | |
@@ -104,6 +105,13 @@ See [`../../docs/mixin-search.md`](../../docs/mixin-search.md) for the capabilit
104
105
  | `logger` | console @ `warn` | `false`, a `Logger`, or `{ level, services, pretty, redact }` |
105
106
  | `tokenProvider` | built-in | inject for SSO/token-exchange |
106
107
 
108
+ `credentials: {}` is legal: a client that never mints its own token, for when the
109
+ token comes from outside. The Managed Dashboard module in
110
+ [`examples/md-module`](../../examples/md-module) is built exactly that way — the
111
+ host hands it a customer token and the SDK only passes it through. Pass
112
+ `credentials.backend` when you need a `service` AuthContext, `storefront` for
113
+ anonymous browsing, both when you need both.
114
+
107
115
  ## AuthContext per method
108
116
 
109
117
  `auth.service(name?)`, `auth.anonymous()`, `auth.customer(token)`,
@@ -141,8 +149,9 @@ header, guest checkout and deferred payment are covered in
141
149
  ## B2B
142
150
 
143
151
  `sdk.companies` (legal entities), `sdk.contacts` (contact assignments),
144
- `sdk.locations` (HQ/warehouse/office), `sdk.customerGroups` (IAM groups,
145
- read-only for now). Switching company scope is a customer-token rescope via
152
+ `sdk.locations` (HQ/warehouse/office), `sdk.customerGroups` (IAM groups —
153
+ `listForCompany` plus `addMember` / `removeMember`). Switching company scope is
154
+ a customer-token rescope via
146
155
  `sdk.customers.refresh({ refreshToken, legalEntityId })`. Mutations that the
147
156
  customer's role lacks scope for surface as `EmporixInsufficientScopeError`
148
157
  (extends `EmporixForbiddenError`, carries `requiredScope`). See
@@ -162,11 +171,16 @@ the Media service directly. See [`../../docs/media.md`](../../docs/media.md).
162
171
 
163
172
  ## Availability
164
173
 
165
- `sdk.availability` reads site-aware product availability: `get(productId, siteCode)`
166
- for one product and `getMany(productIds, siteCode)` for a batch (single
167
- `POST .../search` request, result in input order). The opt-in
174
+ `sdk.availability` covers site-aware product availability in both directions.
175
+
176
+ **Reads** (default `anonymous`): `get(productId, siteCode)` for one product,
177
+ `getMany(productIds, siteCode)` for a batch (single `POST .../search` request,
178
+ result in input order), and `listForSite(siteCode)`. The opt-in
168
179
  `defaultAvailableOnNotFound` returns `{ available: true }` for products without a
169
- stock record. There is no restock-date field. See [`../../docs/availability.md`](../../docs/availability.md).
180
+ stock record. There is no restock-date field.
181
+
182
+ **Writes** (default `service`, so server-only): `create`, `update`, `delete`, plus
183
+ `bulkCreate` / `bulkUpdate` / `bulkDelete`. See [`../../docs/availability.md`](../../docs/availability.md).
170
184
 
171
185
  ## Subpath exports
172
186
 
package/dist/index.cjs CHANGED
@@ -995,7 +995,7 @@ var HttpClient = class {
995
995
  };
996
996
 
997
997
  // package.json
998
- var version = "2.34.0";
998
+ var version = "2.36.0";
999
999
 
1000
1000
  // src/version.ts
1001
1001
  var SDK_VERSION = version;
@@ -8390,6 +8390,9 @@ var CustomerAdminService = class {
8390
8390
  customerPath(customerNumber) {
8391
8391
  return `${this.base()}/${encodeURIComponent(customerNumber)}`;
8392
8392
  }
8393
+ configPath() {
8394
+ return `/customer/${this.ctx.tenant}/config/password-migration-retention`;
8395
+ }
8393
8396
  addressPath(customerNumber, addressId) {
8394
8397
  return `${this.customerPath(customerNumber)}/addresses/${encodeURIComponent(addressId)}`;
8395
8398
  }
@@ -8480,6 +8483,59 @@ var CustomerAdminService = class {
8480
8483
  query: { tags: tags.join(",") }
8481
8484
  });
8482
8485
  }
8486
+ // --- Password-migration retention ---
8487
+ /**
8488
+ * Retrieves the tenant's password-migration retention config. Requires the
8489
+ * `customer.import_read` scope. An unconfigured tenant answers with an empty
8490
+ * object rather than a 404.
8491
+ */
8492
+ async getPasswordMigrationRetention(auth2 = SERVICE35) {
8493
+ return this.ctx.http.request({
8494
+ method: "GET",
8495
+ path: this.configPath(),
8496
+ auth: auth2
8497
+ });
8498
+ }
8499
+ /**
8500
+ * Creates or updates the retention config (`POST`). Requires the
8501
+ * `customer.import_manage` scope. **Call this before importing customers with
8502
+ * `legacyAuth`** — that import is rejected without an active config. Re-POST with
8503
+ * an earlier `retentionEndDate` to shorten a running window.
8504
+ */
8505
+ async configurePasswordMigrationRetention(input, auth2 = SERVICE35) {
8506
+ return this.ctx.http.request({
8507
+ method: "POST",
8508
+ path: this.configPath(),
8509
+ auth: auth2,
8510
+ body: input
8511
+ });
8512
+ }
8513
+ /**
8514
+ * Removes the retention config. Requires the `customer.import_manage` scope.
8515
+ * Intended for after the migration window: when the window ends, unmigrated
8516
+ * accounts need a password reset and their legacy credentials are cleared.
8517
+ */
8518
+ async deletePasswordMigrationRetention(auth2 = SERVICE35) {
8519
+ await this.ctx.http.request({ method: "DELETE", path: this.configPath(), auth: auth2 });
8520
+ }
8521
+ // --- Bulk import ---
8522
+ /**
8523
+ * Bulk-imports customers (`POST /customers/import`). Requires the
8524
+ * `customer.import_manage` scope.
8525
+ *
8526
+ * Responds **207 Multi-Status**: per-item failures do **not** throw — inspect each
8527
+ * entry's `code`. Each item must carry exactly one of `account.passwordHash` or
8528
+ * `account.legacyAuth`, and importing `legacyAuth` requires an active retention
8529
+ * config (see `configurePasswordMigrationRetention`).
8530
+ */
8531
+ async importCustomers(input, auth2 = SERVICE35) {
8532
+ return this.ctx.http.request({
8533
+ method: "POST",
8534
+ path: `${this.base()}/import`,
8535
+ auth: auth2,
8536
+ body: input
8537
+ });
8538
+ }
8483
8539
  };
8484
8540
 
8485
8541
  // src/services/approval.ts