@viu/emporix-sdk 2.33.5 → 2.35.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 +60 -0
- package/dist/index.cjs +83 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +207 -2
- package/dist/index.d.ts +207 -2
- package/dist/index.js +82 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# @viu/emporix-sdk
|
|
2
2
|
|
|
3
|
+
## 2.35.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#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
|
|
8
|
+
|
|
9
|
+
`client.customerAdmin` gains the four operations Emporix added to the Customer
|
|
10
|
+
Service: `getPasswordMigrationRetention`, `configurePasswordMigrationRetention`
|
|
11
|
+
and `deletePasswordMigrationRetention` for the retention window, plus
|
|
12
|
+
`importCustomers` for the bulk import.
|
|
13
|
+
|
|
14
|
+
Together they cover migrating customers off a legacy shop. Configure a retention
|
|
15
|
+
window, import customers carrying `legacyAuth`, and each legacy password hash is
|
|
16
|
+
replaced with an Emporix hash on that customer's first successful login. Without
|
|
17
|
+
an active config the import is rejected — the order matters.
|
|
18
|
+
|
|
19
|
+
`importCustomers` answers **207 Multi-Status**, so per-item failures arrive as
|
|
20
|
+
data with their own `code` rather than throwing. Inspect every entry.
|
|
21
|
+
|
|
22
|
+
All four need a service token with `customer.import_read` or
|
|
23
|
+
`customer.import_manage`, so there are no React hooks — see `docs/customer-admin.md`.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- [#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
|
|
28
|
+
|
|
29
|
+
Updated services: customer-service
|
|
30
|
+
|
|
31
|
+
## 2.34.0
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- [#269](https://github.com/viuteam/emporix-sdk/pull/269) [`1cc5094`](https://github.com/viuteam/emporix-sdk/commit/1cc5094f092529494c166fbf8e5a315adac127b2) Thanks [@amnael1](https://github.com/amnael1)! - Fix the JSON-Patch `op` enum for the Approval service. The upstream spec ships
|
|
36
|
+
`ADD`/`REMOVE`/`REPLACE`, which the live API rejects with 400; `ApprovalPatch['op']`
|
|
37
|
+
is now `'add' | 'remove' | 'replace'`. Callers that worked around the wrong type
|
|
38
|
+
with a cast can drop it. Measured against tenant `viu` on 2026-08-18.
|
|
39
|
+
|
|
40
|
+
- [#269](https://github.com/viuteam/emporix-sdk/pull/269) [`c2e9993`](https://github.com/viuteam/emporix-sdk/commit/c2e999351b0ca99ae96b8615957cb2d168c2ee34) Thanks [@amnael1](https://github.com/amnael1)! - Add `approvalStatusPatch(status, approverComment?)`, which builds the JSON-Patch for
|
|
41
|
+
an approval decision. It encodes two measured quirks: the op is lowercase, and the
|
|
42
|
+
approver comment needs `add` rather than `replace` — `replace` on the absent
|
|
43
|
+
`approverComment` field answers APPROVAL-400010 and, because PATCH is atomic, drops
|
|
44
|
+
the status change with it.
|
|
45
|
+
|
|
46
|
+
- [#269](https://github.com/viuteam/emporix-sdk/pull/269) [`071cb9c`](https://github.com/viuteam/emporix-sdk/commit/071cb9c6022c3dc4cd1f99f114c208fc057344f1) Thanks [@amnael1](https://github.com/amnael1)! - Add `productYrn(tenant, productId)`, the inverse of `productIdFromYrn` and the form
|
|
47
|
+
`carts.addItem` requires. Also notes in `productIdFromYrn` that approval resource
|
|
48
|
+
items carry a bare product id rather than a YRN, so callers need the `itemId` fallback.
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- [#269](https://github.com/viuteam/emporix-sdk/pull/269) [`ab8c607`](https://github.com/viuteam/emporix-sdk/commit/ab8c6078349738867877c3600f3ef52880c82439) Thanks [@amnael1](https://github.com/amnael1)! - Document measured Approval-service behaviour: `createApproval` consumes the cart
|
|
53
|
+
(404 from the Cart API, not restored by decline or withdrawal), `checkPermitted`
|
|
54
|
+
answers `true` for the approver as well as the requester, and the approver comment
|
|
55
|
+
needs `add`. Also corrects the `useCreateApproval` example, which showed the payload
|
|
56
|
+
nested under `resource` and omitted the mandatory `action`, `approver` and `details`.
|
|
57
|
+
|
|
58
|
+
- [#269](https://github.com/viuteam/emporix-sdk/pull/269) [`75bf3ef`](https://github.com/viuteam/emporix-sdk/commit/75bf3efae89dbcd19283dc9ac8f6cc609e72ee7b) Thanks [@amnael1](https://github.com/amnael1)! - Warn when `context` is passed at the top level of `EmporixConfig` instead of inside
|
|
59
|
+
`credentials.storefront`. It was silently dropped, after which `matchByContext`
|
|
60
|
+
returns an empty list with no error because the anonymous token carries no site,
|
|
61
|
+
currency or country. `logger: false` is honoured as a request for silence.
|
|
62
|
+
|
|
3
63
|
## 2.33.5
|
|
4
64
|
|
|
5
65
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -90,6 +90,17 @@ function errorFromResponse(status, message, body) {
|
|
|
90
90
|
// src/core/config.ts
|
|
91
91
|
var DEFAULT_HOST = "https://api.emporix.io";
|
|
92
92
|
var TENANT_RE = /^[a-z][a-z0-9]{2,15}$/;
|
|
93
|
+
function warnOnMisplacedContext(input) {
|
|
94
|
+
if (!("context" in input)) return;
|
|
95
|
+
const logger = input.logger;
|
|
96
|
+
if (logger === false) return;
|
|
97
|
+
const message = "EmporixConfig has no top-level `context` \u2014 it is being ignored. Move it into `credentials.storefront.context`, otherwise the anonymous token carries no site/currency/country and price matching returns an empty list without erroring.";
|
|
98
|
+
if (logger && typeof logger.warn === "function") {
|
|
99
|
+
logger.warn(message);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
console.warn(`[emporix] ${message}`);
|
|
103
|
+
}
|
|
93
104
|
function validateConfig(input) {
|
|
94
105
|
if (!TENANT_RE.test(input.tenant)) {
|
|
95
106
|
throw new Error(
|
|
@@ -99,6 +110,7 @@ function validateConfig(input) {
|
|
|
99
110
|
if (!input.credentials) {
|
|
100
111
|
throw new Error("credentials is required (provide at least one of backend/storefront/custom)");
|
|
101
112
|
}
|
|
113
|
+
warnOnMisplacedContext(input);
|
|
102
114
|
return {
|
|
103
115
|
tenant: input.tenant,
|
|
104
116
|
host: input.host ?? DEFAULT_HOST,
|
|
@@ -983,7 +995,7 @@ var HttpClient = class {
|
|
|
983
995
|
};
|
|
984
996
|
|
|
985
997
|
// package.json
|
|
986
|
-
var version = "2.
|
|
998
|
+
var version = "2.35.0";
|
|
987
999
|
|
|
988
1000
|
// src/version.ts
|
|
989
1001
|
var SDK_VERSION = version;
|
|
@@ -8378,6 +8390,9 @@ var CustomerAdminService = class {
|
|
|
8378
8390
|
customerPath(customerNumber) {
|
|
8379
8391
|
return `${this.base()}/${encodeURIComponent(customerNumber)}`;
|
|
8380
8392
|
}
|
|
8393
|
+
configPath() {
|
|
8394
|
+
return `/customer/${this.ctx.tenant}/config/password-migration-retention`;
|
|
8395
|
+
}
|
|
8381
8396
|
addressPath(customerNumber, addressId) {
|
|
8382
8397
|
return `${this.customerPath(customerNumber)}/addresses/${encodeURIComponent(addressId)}`;
|
|
8383
8398
|
}
|
|
@@ -8468,6 +8483,59 @@ var CustomerAdminService = class {
|
|
|
8468
8483
|
query: { tags: tags.join(",") }
|
|
8469
8484
|
});
|
|
8470
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
|
+
}
|
|
8471
8539
|
};
|
|
8472
8540
|
|
|
8473
8541
|
// src/services/approval.ts
|
|
@@ -8543,6 +8611,15 @@ var ApprovalService = class {
|
|
|
8543
8611
|
});
|
|
8544
8612
|
}
|
|
8545
8613
|
};
|
|
8614
|
+
function approvalStatusPatch(status, approverComment) {
|
|
8615
|
+
const comment = approverComment?.trim() ?? "";
|
|
8616
|
+
return [
|
|
8617
|
+
{ op: "replace", path: "/status", value: status },
|
|
8618
|
+
// `as const` on both fields: the generated type narrows `path` to an enum too, so
|
|
8619
|
+
// a widened `string` from the spread would not be assignable.
|
|
8620
|
+
...comment !== "" ? [{ op: "add", path: "/approverComment", value: comment }] : []
|
|
8621
|
+
];
|
|
8622
|
+
}
|
|
8546
8623
|
|
|
8547
8624
|
// src/client.ts
|
|
8548
8625
|
var EmporixClient = class {
|
|
@@ -8733,6 +8810,9 @@ function productIdFromYrn(yrn) {
|
|
|
8733
8810
|
const semi = yrn.lastIndexOf(";");
|
|
8734
8811
|
return semi >= 0 ? yrn.slice(semi + 1) : "";
|
|
8735
8812
|
}
|
|
8813
|
+
function productYrn(tenant, productId) {
|
|
8814
|
+
return `urn:yaas:hybris:product:product:${tenant};${productId}`;
|
|
8815
|
+
}
|
|
8736
8816
|
|
|
8737
8817
|
exports.AiService = AiService;
|
|
8738
8818
|
exports.ApprovalService = ApprovalService;
|
|
@@ -8800,6 +8880,7 @@ exports.TenantConfigService = TenantConfigService;
|
|
|
8800
8880
|
exports.UnitHandlingService = UnitHandlingService;
|
|
8801
8881
|
exports.VendorService = VendorService;
|
|
8802
8882
|
exports.WebhookService = WebhookService;
|
|
8883
|
+
exports.approvalStatusPatch = approvalStatusPatch;
|
|
8803
8884
|
exports.auth = auth;
|
|
8804
8885
|
exports.createConsoleLogger = createConsoleLogger;
|
|
8805
8886
|
exports.createCookieBackedStorage = createCookieBackedStorage;
|
|
@@ -8812,6 +8893,7 @@ exports.iterateAll = iterateAll;
|
|
|
8812
8893
|
exports.parseAnonymousSession = parseAnonymousSession;
|
|
8813
8894
|
exports.pickFee = pickFee;
|
|
8814
8895
|
exports.productIdFromYrn = productIdFromYrn;
|
|
8896
|
+
exports.productYrn = productYrn;
|
|
8815
8897
|
exports.redact = redact;
|
|
8816
8898
|
exports.resolveQuery = resolveQuery;
|
|
8817
8899
|
exports.resolveToken = resolveToken;
|