@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/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-XEJPH6UN.js';
8
- export { PaymentGatewayService } from './chunk-XEJPH6UN.js';
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 { EmporixAuthError, EmporixTimeoutError, EmporixNetworkError, errorFromResponse, EmporixNotFoundError, EmporixError } from './chunk-UWGGF4MC.js';
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.15.0";
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, CustomerRefreshRegistry, DEFAULT_HOST, DefaultTokenProvider, EmporixClient, FeeService, HttpClient, IndexingService, LEVEL, LabelService, LevelResolver, PickPackService, RagIndexerService, ReturnsService, RewardPointsService, SchemaService, SepaExportService, SequentialIdService, SessionContextService, ShippingService, ShoppingListService, SiteService, TaxService, TenantConfigService, UnitHandlingService, VendorService, WebhookService, auth, createConsoleLogger, createCore, createEmporixClient, createNoopLogger, productIdFromYrn, redact, resolveToken, validateConfig };
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