@viu/emporix-sdk 2.15.0 → 2.16.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 +9 -0
- package/dist/chunk-PYLWZZC4.js +280 -0
- package/dist/chunk-PYLWZZC4.js.map +1 -0
- package/dist/index.cjs +23 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -248
- package/dist/index.js.map +1 -1
- package/dist/payment.cjs +24 -7
- package/dist/payment.cjs.map +1 -1
- package/dist/payment.d.cts +7 -3
- package/dist/payment.d.ts +7 -3
- package/dist/payment.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-XEJPH6UN.js +0 -31
- package/dist/chunk-XEJPH6UN.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import { MediaService } from './chunk-OTG2S2L4.js';
|
|
|
4
4
|
export { MediaService } from './chunk-OTG2S2L4.js';
|
|
5
5
|
import { OrdersService, SalesOrdersService } from './chunk-62PCCHZ2.js';
|
|
6
6
|
export { OrdersService, SalesOrdersService } from './chunk-62PCCHZ2.js';
|
|
7
|
-
import { PaymentGatewayService } from './chunk-
|
|
8
|
-
export { PaymentGatewayService } from './chunk-
|
|
7
|
+
import { auth, resolveToken, DefaultTokenProvider, CustomerRefreshRegistry, PaymentGatewayService } from './chunk-PYLWZZC4.js';
|
|
8
|
+
export { CustomerRefreshRegistry, DefaultTokenProvider, PaymentGatewayService, auth, resolveToken } from './chunk-PYLWZZC4.js';
|
|
9
9
|
import { PriceService } from './chunk-A3LYJUD4.js';
|
|
10
10
|
export { PriceService } from './chunk-A3LYJUD4.js';
|
|
11
11
|
import { ProductService } from './chunk-5VTBLBXJ.js';
|
|
@@ -30,7 +30,7 @@ export { CustomerGroupsService } from './chunk-3BTPX7IJ.js';
|
|
|
30
30
|
import { CustomerService } from './chunk-NEXUWPHW.js';
|
|
31
31
|
export { CustomerService } from './chunk-NEXUWPHW.js';
|
|
32
32
|
import './chunk-3BDDYX3V.js';
|
|
33
|
-
import {
|
|
33
|
+
import { EmporixTimeoutError, EmporixNetworkError, errorFromResponse, EmporixNotFoundError, EmporixError } from './chunk-UWGGF4MC.js';
|
|
34
34
|
export { EmporixAuthError, EmporixError, EmporixForbiddenError, EmporixInsufficientScopeError, EmporixNetworkError, EmporixNotFoundError, EmporixServerError, EmporixTimeoutError, EmporixValidationError, errorFromResponse } from './chunk-UWGGF4MC.js';
|
|
35
35
|
|
|
36
36
|
// src/core/config.ts
|
|
@@ -294,249 +294,6 @@ function createNoopLogger() {
|
|
|
294
294
|
return new NoopLogger();
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
-
// src/core/auth.ts
|
|
298
|
-
var auth = {
|
|
299
|
-
/** Service/custom credential set (default `backend`). */
|
|
300
|
-
service: (credentials) => credentials === void 0 ? { kind: "service" } : { kind: "service", credentials },
|
|
301
|
-
/** Cached anonymous storefront token. */
|
|
302
|
-
anonymous: () => ({ kind: "anonymous" }),
|
|
303
|
-
/** Caller-owned customer bearer token. */
|
|
304
|
-
customer: (token) => ({ kind: "customer", token }),
|
|
305
|
-
/** Exact token, no transformation (SSO / token-exchange). */
|
|
306
|
-
raw: (token) => ({ kind: "raw", token })
|
|
307
|
-
};
|
|
308
|
-
async function resolveToken(ctx, provider) {
|
|
309
|
-
switch (ctx.kind) {
|
|
310
|
-
case "service":
|
|
311
|
-
return provider.getToken(ctx.credentials ?? "backend");
|
|
312
|
-
case "anonymous":
|
|
313
|
-
return (await provider.getAnonymousToken()).accessToken;
|
|
314
|
-
case "customer":
|
|
315
|
-
case "raw":
|
|
316
|
-
return ctx.token;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
var CustomerRefreshRegistry = class {
|
|
320
|
-
refresher = null;
|
|
321
|
-
inflight = null;
|
|
322
|
-
set(refresher) {
|
|
323
|
-
this.refresher = refresher;
|
|
324
|
-
}
|
|
325
|
-
get enabled() {
|
|
326
|
-
return this.refresher !== null;
|
|
327
|
-
}
|
|
328
|
-
/** Concurrent callers share one in-flight refresh. */
|
|
329
|
-
refresh(expiredToken) {
|
|
330
|
-
if (!this.refresher) return Promise.resolve(null);
|
|
331
|
-
if (this.inflight) return this.inflight;
|
|
332
|
-
const p = Promise.resolve(this.refresher.refresh(expiredToken)).finally(() => {
|
|
333
|
-
this.inflight = null;
|
|
334
|
-
});
|
|
335
|
-
this.inflight = p;
|
|
336
|
-
return p;
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
var DefaultTokenProvider = class {
|
|
340
|
-
constructor(cfg) {
|
|
341
|
-
this.cfg = cfg;
|
|
342
|
-
}
|
|
343
|
-
cfg;
|
|
344
|
-
serviceCache = /* @__PURE__ */ new Map();
|
|
345
|
-
serviceLocks = /* @__PURE__ */ new Map();
|
|
346
|
-
anon;
|
|
347
|
-
anonLock;
|
|
348
|
-
anonStore;
|
|
349
|
-
contextOverride;
|
|
350
|
-
refreshListeners = /* @__PURE__ */ new Set();
|
|
351
|
-
onRefresh(listener) {
|
|
352
|
-
this.refreshListeners.add(listener);
|
|
353
|
-
return () => {
|
|
354
|
-
this.refreshListeners.delete(listener);
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
notifyRefresh(kind, success) {
|
|
358
|
-
for (const l of this.refreshListeners) {
|
|
359
|
-
try {
|
|
360
|
-
l({ kind, success });
|
|
361
|
-
} catch {
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
attachAnonymousStore(store) {
|
|
366
|
-
this.anonStore = store;
|
|
367
|
-
if (!this.anon) {
|
|
368
|
-
const persisted = store.read();
|
|
369
|
-
if (persisted) {
|
|
370
|
-
this.anon = {
|
|
371
|
-
accessToken: "",
|
|
372
|
-
refreshToken: persisted.refreshToken,
|
|
373
|
-
sessionId: persisted.sessionId,
|
|
374
|
-
expiresIn: 0,
|
|
375
|
-
expiresAt: 0
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
creds(set) {
|
|
381
|
-
if (set === "backend") {
|
|
382
|
-
const b = this.cfg.credentials.backend;
|
|
383
|
-
if (!b?.clientId || !b.secret) {
|
|
384
|
-
throw new EmporixAuthError(
|
|
385
|
-
"A 'service' AuthContext was used but credentials.backend is not configured"
|
|
386
|
-
);
|
|
387
|
-
}
|
|
388
|
-
return b;
|
|
389
|
-
}
|
|
390
|
-
const c = this.cfg.credentials.custom?.[set];
|
|
391
|
-
if (!c) throw new Error(`Unknown credential set "${set}"`);
|
|
392
|
-
return c;
|
|
393
|
-
}
|
|
394
|
-
fresh(e) {
|
|
395
|
-
if (!e) return false;
|
|
396
|
-
const now = Date.now();
|
|
397
|
-
if (now - e.obtainedAt >= this.cfg.cache.maxLifetimeSeconds * 1e3) return false;
|
|
398
|
-
return now < e.expiresAt;
|
|
399
|
-
}
|
|
400
|
-
async getToken(set) {
|
|
401
|
-
this.creds(set);
|
|
402
|
-
const cached = this.serviceCache.get(set);
|
|
403
|
-
if (this.fresh(cached)) return cached.token;
|
|
404
|
-
const inflight = this.serviceLocks.get(set);
|
|
405
|
-
if (inflight) return inflight;
|
|
406
|
-
const p = this.requestServiceToken(set).finally(() => this.serviceLocks.delete(set));
|
|
407
|
-
this.serviceLocks.set(set, p);
|
|
408
|
-
return p;
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* fetch with the configured read timeout. Token endpoints sit in front of
|
|
412
|
-
* single-flight locks — one hung call would otherwise block every request
|
|
413
|
-
* on this credential set forever.
|
|
414
|
-
*/
|
|
415
|
-
async boundedFetch(url, init = {}) {
|
|
416
|
-
const ms = this.cfg.timeouts?.readMs ?? 6e4;
|
|
417
|
-
const controller = new AbortController();
|
|
418
|
-
const timer = setTimeout(() => controller.abort(), ms);
|
|
419
|
-
try {
|
|
420
|
-
return await fetch(url, { ...init, signal: controller.signal });
|
|
421
|
-
} catch (err) {
|
|
422
|
-
if (err.name === "AbortError") {
|
|
423
|
-
throw new EmporixTimeoutError(`token request timed out after ${ms}ms`);
|
|
424
|
-
}
|
|
425
|
-
throw new EmporixNetworkError(`token request network failure: ${err.message}`);
|
|
426
|
-
} finally {
|
|
427
|
-
clearTimeout(timer);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
async requestServiceToken(set) {
|
|
431
|
-
const c = this.creds(set);
|
|
432
|
-
const body = new URLSearchParams({
|
|
433
|
-
grant_type: "client_credentials",
|
|
434
|
-
client_id: c.clientId,
|
|
435
|
-
client_secret: c.secret
|
|
436
|
-
});
|
|
437
|
-
if (c.scope) body.set("scope", c.scope);
|
|
438
|
-
const res = await this.boundedFetch(`${this.cfg.host}/oauth/token`, {
|
|
439
|
-
method: "POST",
|
|
440
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
441
|
-
body
|
|
442
|
-
});
|
|
443
|
-
const json = await res.json().catch(() => ({}));
|
|
444
|
-
if (!res.ok) {
|
|
445
|
-
throw new EmporixAuthError(`Token request failed for "${set}"`, res.status, json);
|
|
446
|
-
}
|
|
447
|
-
const obtainedAt = Date.now();
|
|
448
|
-
const ttl = Number(json.expires_in ?? 3600);
|
|
449
|
-
this.serviceCache.set(set, {
|
|
450
|
-
token: json.access_token,
|
|
451
|
-
obtainedAt,
|
|
452
|
-
expiresAt: obtainedAt + (ttl - this.cfg.cache.expirationBufferSeconds) * 1e3
|
|
453
|
-
});
|
|
454
|
-
return this.serviceCache.get(set).token;
|
|
455
|
-
}
|
|
456
|
-
invalidate(set) {
|
|
457
|
-
this.serviceCache.delete(set);
|
|
458
|
-
}
|
|
459
|
-
anonFresh() {
|
|
460
|
-
return !!this.anon && Date.now() < this.anon.expiresAt;
|
|
461
|
-
}
|
|
462
|
-
async getAnonymousToken() {
|
|
463
|
-
if (this.anonFresh()) return this.stripExpiry(this.anon);
|
|
464
|
-
if (this.anonLock) return this.anonLock;
|
|
465
|
-
const canRefresh = !!this.anon?.refreshToken;
|
|
466
|
-
const obtain = canRefresh ? this.fetchAnonymous("refresh").catch(() => this.fetchAnonymous("login")) : this.fetchAnonymous("login");
|
|
467
|
-
const p = obtain.finally(() => {
|
|
468
|
-
this.anonLock = void 0;
|
|
469
|
-
});
|
|
470
|
-
this.anonLock = p;
|
|
471
|
-
return p;
|
|
472
|
-
}
|
|
473
|
-
/** Refreshes the anonymous session, preserving its sessionId. */
|
|
474
|
-
async refreshAnonymous() {
|
|
475
|
-
if (!this.anon) return this.getAnonymousToken();
|
|
476
|
-
return this.fetchAnonymous("refresh");
|
|
477
|
-
}
|
|
478
|
-
invalidateAnonymous() {
|
|
479
|
-
this.anon = void 0;
|
|
480
|
-
this.anonStore?.write(null);
|
|
481
|
-
}
|
|
482
|
-
setAnonymousContext(ctx) {
|
|
483
|
-
const base = this.contextOverride ?? this.cfg.credentials.storefront?.context ?? {};
|
|
484
|
-
this.contextOverride = { ...base, ...ctx };
|
|
485
|
-
this.invalidateAnonymous();
|
|
486
|
-
}
|
|
487
|
-
/** Force a stale access token while keeping the refresh token + sessionId. */
|
|
488
|
-
expireAnonymous() {
|
|
489
|
-
if (this.anon) this.anon = { ...this.anon, expiresAt: 0 };
|
|
490
|
-
}
|
|
491
|
-
stripExpiry(s) {
|
|
492
|
-
const { expiresAt: _expiresAt, ...rest } = s;
|
|
493
|
-
return rest;
|
|
494
|
-
}
|
|
495
|
-
async fetchAnonymous(mode) {
|
|
496
|
-
const sf = this.cfg.credentials.storefront;
|
|
497
|
-
if (!sf?.clientId) {
|
|
498
|
-
throw new Error("credentials.storefront.clientId is required for anonymous tokens");
|
|
499
|
-
}
|
|
500
|
-
const url = new URL(`${this.cfg.host}/customerlogin/auth/anonymous/${mode}`);
|
|
501
|
-
url.searchParams.set("tenant", this.cfg.tenant);
|
|
502
|
-
url.searchParams.set("client_id", sf.clientId);
|
|
503
|
-
const c = this.contextOverride ?? sf.context;
|
|
504
|
-
if (c?.currency) url.searchParams.set("currency", c.currency);
|
|
505
|
-
if (c?.siteCode) url.searchParams.set("siteCode", c.siteCode);
|
|
506
|
-
if (c?.targetLocation) url.searchParams.set("targetLocation", c.targetLocation);
|
|
507
|
-
if (mode === "refresh" && this.anon) {
|
|
508
|
-
url.searchParams.set("refresh_token", this.anon.refreshToken);
|
|
509
|
-
}
|
|
510
|
-
try {
|
|
511
|
-
const res = await this.boundedFetch(url, { method: "GET" });
|
|
512
|
-
const json = await res.json().catch(() => ({}));
|
|
513
|
-
if (!res.ok) {
|
|
514
|
-
this.notifyRefresh("anonymous", false);
|
|
515
|
-
throw new EmporixAuthError(`Anonymous token ${mode} failed`, res.status, json);
|
|
516
|
-
}
|
|
517
|
-
const obtainedAt = Date.now();
|
|
518
|
-
this.anon = {
|
|
519
|
-
accessToken: json.access_token,
|
|
520
|
-
refreshToken: json.refresh_token,
|
|
521
|
-
sessionId: json.sessionId,
|
|
522
|
-
expiresIn: json.expires_in,
|
|
523
|
-
expiresAt: obtainedAt + (json.expires_in - this.cfg.cache.expirationBufferSeconds) * 1e3
|
|
524
|
-
};
|
|
525
|
-
this.anonStore?.write({
|
|
526
|
-
refreshToken: this.anon.refreshToken,
|
|
527
|
-
sessionId: this.anon.sessionId
|
|
528
|
-
});
|
|
529
|
-
this.notifyRefresh("anonymous", true);
|
|
530
|
-
return this.stripExpiry(this.anon);
|
|
531
|
-
} catch (err) {
|
|
532
|
-
if (!(err instanceof EmporixAuthError)) {
|
|
533
|
-
this.notifyRefresh("anonymous", false);
|
|
534
|
-
}
|
|
535
|
-
throw err;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
};
|
|
539
|
-
|
|
540
297
|
// src/core/http.ts
|
|
541
298
|
var requestSeq = 0;
|
|
542
299
|
function safeJson(text) {
|
|
@@ -729,7 +486,7 @@ var HttpClient = class {
|
|
|
729
486
|
};
|
|
730
487
|
|
|
731
488
|
// package.json
|
|
732
|
-
var version = "2.
|
|
489
|
+
var version = "2.16.0";
|
|
733
490
|
|
|
734
491
|
// src/version.ts
|
|
735
492
|
var SDK_VERSION = version;
|
|
@@ -3813,6 +3570,6 @@ function productIdFromYrn(yrn) {
|
|
|
3813
3570
|
return semi >= 0 ? yrn.slice(semi + 1) : "";
|
|
3814
3571
|
}
|
|
3815
3572
|
|
|
3816
|
-
export { AiService, ApprovalService, BrandService, CatalogService, ClientConfigService, CloudFunctionsService, CountryService, CouponService, CurrencyService, CustomerAdminService,
|
|
3573
|
+
export { AiService, ApprovalService, BrandService, CatalogService, ClientConfigService, CloudFunctionsService, CountryService, CouponService, CurrencyService, CustomerAdminService, DEFAULT_HOST, EmporixClient, FeeService, HttpClient, IndexingService, LEVEL, LabelService, LevelResolver, PickPackService, RagIndexerService, ReturnsService, RewardPointsService, SchemaService, SepaExportService, SequentialIdService, SessionContextService, ShippingService, ShoppingListService, SiteService, TaxService, TenantConfigService, UnitHandlingService, VendorService, WebhookService, createConsoleLogger, createCore, createEmporixClient, createNoopLogger, productIdFromYrn, redact, validateConfig };
|
|
3817
3574
|
//# sourceMappingURL=index.js.map
|
|
3818
3575
|
//# sourceMappingURL=index.js.map
|