@viu/emporix-sdk 4.9.4 → 4.11.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 +35 -0
- package/README.md +2 -1
- 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/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-BJeomwxV.d.cts → context-BqSLYN2q.d.cts} +68 -1
- package/dist/{context-BJeomwxV.d.ts → context-BqSLYN2q.d.ts} +68 -1
- package/dist/{customer-groups-ZlnnZrX_.d.cts → customer-groups-B3jlWR4O.d.cts} +1 -1
- package/dist/{customer-groups-ByyBHCBH.d.ts → customer-groups-oJ9YcjDe.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 +499 -299
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +174 -28
- package/dist/index.d.ts +174 -28
- package/dist/index.js +498 -301
- package/dist/index.js.map +1 -1
- package/dist/locations.d.cts +1 -1
- package/dist/locations.d.ts +1 -1
- package/dist/media.d.cts +1 -1
- package/dist/media.d.ts +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.d.cts +1 -1
- package/dist/product.d.ts +1 -1
- package/dist/segment.d.cts +1 -1
- package/dist/segment.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -114,6 +114,17 @@ function validateConfig(input) {
|
|
|
114
114
|
throw new Error("credentials is required (provide at least one of backend/storefront/custom)");
|
|
115
115
|
}
|
|
116
116
|
warnOnMisplacedContext(input);
|
|
117
|
+
const proxy = input.proxy;
|
|
118
|
+
if (proxy) {
|
|
119
|
+
if (input.tokenProvider) {
|
|
120
|
+
throw new Error("proxy and tokenProvider are mutually exclusive: in proxy mode the SDK requests no tokens");
|
|
121
|
+
}
|
|
122
|
+
if (input.credentials.backend || input.credentials.custom) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
"credentials.backend and credentials.custom cannot be used in proxy mode: the proxy attaches the token, and service credentials never belong in a browser"
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
117
128
|
return {
|
|
118
129
|
tenant: input.tenant,
|
|
119
130
|
host: input.host ?? DEFAULT_HOST,
|
|
@@ -130,241 +141,15 @@ function validateConfig(input) {
|
|
|
130
141
|
},
|
|
131
142
|
logger: input.logger,
|
|
132
143
|
fetch: input.fetch,
|
|
133
|
-
contentLanguage: input.contentLanguage
|
|
144
|
+
contentLanguage: input.contentLanguage,
|
|
145
|
+
proxy: proxy ? {
|
|
146
|
+
headers: proxy.headers ?? {},
|
|
147
|
+
credentials: proxy.credentials ?? "same-origin",
|
|
148
|
+
onUnauthorized: proxy.onUnauthorized
|
|
149
|
+
} : void 0
|
|
134
150
|
};
|
|
135
151
|
}
|
|
136
152
|
|
|
137
|
-
// src/core/logger.ts
|
|
138
|
-
var LEVEL = {
|
|
139
|
-
trace: 10,
|
|
140
|
-
debug: 20,
|
|
141
|
-
info: 30,
|
|
142
|
-
warn: 40,
|
|
143
|
-
error: 50,
|
|
144
|
-
silent: 60
|
|
145
|
-
};
|
|
146
|
-
function isValidLevel(v) {
|
|
147
|
-
return v !== void 0 && v in LEVEL;
|
|
148
|
-
}
|
|
149
|
-
function readEnv(name) {
|
|
150
|
-
try {
|
|
151
|
-
return typeof process !== "undefined" && process.env ? process.env[name] : void 0;
|
|
152
|
-
} catch {
|
|
153
|
-
return void 0;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
var LevelResolver = class {
|
|
157
|
-
constructor(cfg, warn = () => {
|
|
158
|
-
}) {
|
|
159
|
-
this.warn = warn;
|
|
160
|
-
this.cfgLevel = cfg.level ?? "warn";
|
|
161
|
-
this.cfgServices = { ...cfg.services };
|
|
162
|
-
}
|
|
163
|
-
warn;
|
|
164
|
-
cfgLevel;
|
|
165
|
-
cfgServices;
|
|
166
|
-
forcedServices = {};
|
|
167
|
-
forcedGlobal;
|
|
168
|
-
warned = false;
|
|
169
|
-
envFor(svc) {
|
|
170
|
-
const raw = readEnv(`EMPORIX_LOG_LEVEL_${svc.toUpperCase()}`);
|
|
171
|
-
if (raw === void 0) return void 0;
|
|
172
|
-
if (isValidLevel(raw)) return raw;
|
|
173
|
-
if (!this.warned) {
|
|
174
|
-
this.warned = true;
|
|
175
|
-
this.warn(`Invalid EMPORIX_LOG_LEVEL_${svc.toUpperCase()}="${raw}" ignored`);
|
|
176
|
-
}
|
|
177
|
-
return void 0;
|
|
178
|
-
}
|
|
179
|
-
envGlobal() {
|
|
180
|
-
const raw = readEnv("EMPORIX_LOG_LEVEL");
|
|
181
|
-
if (raw === void 0) return void 0;
|
|
182
|
-
if (isValidLevel(raw)) return raw;
|
|
183
|
-
if (!this.warned) {
|
|
184
|
-
this.warned = true;
|
|
185
|
-
this.warn(`Invalid EMPORIX_LOG_LEVEL="${raw}" ignored`);
|
|
186
|
-
}
|
|
187
|
-
return void 0;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Effective level for a service. Forced overrides (from `set(..., force)`)
|
|
191
|
-
* take precedence over env vars; otherwise env > programmatic config.
|
|
192
|
-
*/
|
|
193
|
-
get(svc) {
|
|
194
|
-
return this.forcedServices[svc] ?? this.envFor(svc) ?? this.forcedGlobal ?? this.envGlobal() ?? this.cfgServices[svc] ?? this.cfgLevel ?? "warn";
|
|
195
|
-
}
|
|
196
|
-
/** Numeric effective level for a service. */
|
|
197
|
-
numericLevel(svc) {
|
|
198
|
-
return LEVEL[this.get(svc)];
|
|
199
|
-
}
|
|
200
|
-
/** True if `svc`'s effective level allows emitting at `at`. */
|
|
201
|
-
isAtLeast(svc, at) {
|
|
202
|
-
return this.numericLevel(svc) <= LEVEL[at];
|
|
203
|
-
}
|
|
204
|
-
/** Mutates programmatic level (global or one service). Env-set levels are sticky unless `force`. */
|
|
205
|
-
set(level, svc, force = false) {
|
|
206
|
-
if (svc) {
|
|
207
|
-
const envBound = readEnv(`EMPORIX_LOG_LEVEL_${svc.toUpperCase()}`) !== void 0;
|
|
208
|
-
if (envBound && !force) {
|
|
209
|
-
this.warn(`Level for "${svc}" is env-controlled; pass force to override`);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (force) this.forcedServices[svc] = level;
|
|
213
|
-
else this.cfgServices[svc] = level;
|
|
214
|
-
} else {
|
|
215
|
-
const envBound = readEnv("EMPORIX_LOG_LEVEL") !== void 0;
|
|
216
|
-
if (envBound && !force) {
|
|
217
|
-
this.warn("Global level is env-controlled; pass force to override");
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
if (force) this.forcedGlobal = level;
|
|
221
|
-
else this.cfgLevel = level;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
var DEFAULT_REDACT = /* @__PURE__ */ new Set([
|
|
226
|
-
"authorization",
|
|
227
|
-
"password",
|
|
228
|
-
"oldpassword",
|
|
229
|
-
"newpassword",
|
|
230
|
-
"clientsecret",
|
|
231
|
-
"secret",
|
|
232
|
-
"access_token",
|
|
233
|
-
"refresh_token",
|
|
234
|
-
"customertoken",
|
|
235
|
-
"saastoken",
|
|
236
|
-
"saas-token",
|
|
237
|
-
"bearertoken",
|
|
238
|
-
"apikey",
|
|
239
|
-
"token"
|
|
240
|
-
]);
|
|
241
|
-
function redact(value, extra = []) {
|
|
242
|
-
const keys = new Set(DEFAULT_REDACT);
|
|
243
|
-
for (const k of extra) keys.add(k.toLowerCase());
|
|
244
|
-
const walk = (v) => {
|
|
245
|
-
if (Array.isArray(v)) return v.map(walk);
|
|
246
|
-
if (v && typeof v === "object") {
|
|
247
|
-
const src = v;
|
|
248
|
-
if (typeof src.kind === "string" && "token" in src) return { kind: src.kind };
|
|
249
|
-
const out = {};
|
|
250
|
-
for (const [k, val] of Object.entries(src)) {
|
|
251
|
-
if (keys.has(k.toLowerCase())) {
|
|
252
|
-
out[k] = k.toLowerCase() === "authorization" && typeof val === "string" ? "Bearer ***redacted***" : "***redacted***";
|
|
253
|
-
} else {
|
|
254
|
-
out[k] = walk(val);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return out;
|
|
258
|
-
}
|
|
259
|
-
return v;
|
|
260
|
-
};
|
|
261
|
-
return walk(value);
|
|
262
|
-
}
|
|
263
|
-
var EMIT = {
|
|
264
|
-
trace: LEVEL.trace,
|
|
265
|
-
debug: LEVEL.debug,
|
|
266
|
-
info: LEVEL.info,
|
|
267
|
-
warn: LEVEL.warn,
|
|
268
|
-
error: LEVEL.error
|
|
269
|
-
};
|
|
270
|
-
var BaseLogger = class {
|
|
271
|
-
constructor(resolver, bindings, extraRedact) {
|
|
272
|
-
this.resolver = resolver;
|
|
273
|
-
this.bindings = bindings;
|
|
274
|
-
this.extraRedact = extraRedact;
|
|
275
|
-
}
|
|
276
|
-
resolver;
|
|
277
|
-
bindings;
|
|
278
|
-
extraRedact;
|
|
279
|
-
svc() {
|
|
280
|
-
return this.bindings.service ?? "http";
|
|
281
|
-
}
|
|
282
|
-
get level() {
|
|
283
|
-
return this.resolver.get(this.svc());
|
|
284
|
-
}
|
|
285
|
-
isLevelEnabled(level) {
|
|
286
|
-
return this.resolver.isAtLeast(this.svc(), level);
|
|
287
|
-
}
|
|
288
|
-
at(level, msg, fields) {
|
|
289
|
-
if (this.resolver.numericLevel(this.svc()) > EMIT[level]) return;
|
|
290
|
-
const merged = { ...this.bindings, ...fields ?? {} };
|
|
291
|
-
this.emit(level, msg, redact(merged, this.extraRedact));
|
|
292
|
-
}
|
|
293
|
-
trace(m, f) {
|
|
294
|
-
this.at("trace", m, f);
|
|
295
|
-
}
|
|
296
|
-
debug(m, f) {
|
|
297
|
-
this.at("debug", m, f);
|
|
298
|
-
}
|
|
299
|
-
info(m, f) {
|
|
300
|
-
this.at("info", m, f);
|
|
301
|
-
}
|
|
302
|
-
warn(m, f) {
|
|
303
|
-
this.at("warn", m, f);
|
|
304
|
-
}
|
|
305
|
-
error(m, f) {
|
|
306
|
-
this.at("error", m, f);
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
var ConsoleLogger = class _ConsoleLogger extends BaseLogger {
|
|
310
|
-
constructor(resolver, bindings, extra, sink, pretty) {
|
|
311
|
-
super(resolver, bindings, extra);
|
|
312
|
-
this.sink = sink;
|
|
313
|
-
this.pretty = pretty;
|
|
314
|
-
}
|
|
315
|
-
sink;
|
|
316
|
-
pretty;
|
|
317
|
-
emit(level, msg, fields) {
|
|
318
|
-
if (this.pretty) {
|
|
319
|
-
const fn = level === "error" ? this.sink.error : level === "warn" ? this.sink.warn : level === "info" ? this.sink.info : this.sink.log;
|
|
320
|
-
fn(`[${level}] ${msg}`, fields);
|
|
321
|
-
} else {
|
|
322
|
-
this.sink.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level, msg, ...fields }));
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
child(bindings) {
|
|
326
|
-
return new _ConsoleLogger(
|
|
327
|
-
this.resolver,
|
|
328
|
-
{ ...this.bindings, ...bindings },
|
|
329
|
-
this.extraRedact,
|
|
330
|
-
this.sink,
|
|
331
|
-
this.pretty
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
var NoopLogger = class {
|
|
336
|
-
level = "silent";
|
|
337
|
-
isLevelEnabled() {
|
|
338
|
-
return false;
|
|
339
|
-
}
|
|
340
|
-
trace() {
|
|
341
|
-
}
|
|
342
|
-
debug() {
|
|
343
|
-
}
|
|
344
|
-
info() {
|
|
345
|
-
}
|
|
346
|
-
warn() {
|
|
347
|
-
}
|
|
348
|
-
error() {
|
|
349
|
-
}
|
|
350
|
-
child() {
|
|
351
|
-
return this;
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
function createConsoleLogger(resolver, bindings = {}, opts = {}) {
|
|
355
|
-
const pretty = opts.pretty ?? readEnv("NODE_ENV") !== "production";
|
|
356
|
-
const sink = opts.sink ?? {
|
|
357
|
-
log: console.log,
|
|
358
|
-
info: console.info,
|
|
359
|
-
warn: console.warn,
|
|
360
|
-
error: console.error
|
|
361
|
-
};
|
|
362
|
-
return new ConsoleLogger(resolver, bindings, opts.redact ?? [], sink, pretty);
|
|
363
|
-
}
|
|
364
|
-
function createNoopLogger() {
|
|
365
|
-
return new NoopLogger();
|
|
366
|
-
}
|
|
367
|
-
|
|
368
153
|
// src/core/auth.ts
|
|
369
154
|
var auth = {
|
|
370
155
|
/** Service/custom credential set (default `backend`). */
|
|
@@ -833,46 +618,343 @@ function createLocalStorage(opts = {}) {
|
|
|
833
618
|
console.warn("[emporix] localStorage unavailable; falling back to in-memory storage");
|
|
834
619
|
return createMemoryStorage();
|
|
835
620
|
}
|
|
836
|
-
return fromWebStorage(store, opts);
|
|
837
|
-
}
|
|
838
|
-
var createLocalStorageStorage = createLocalStorage;
|
|
839
|
-
function createSessionStorage(opts = {}) {
|
|
840
|
-
const store = browser.sessionStorage;
|
|
841
|
-
if (store === void 0) {
|
|
842
|
-
console.warn("[emporix] sessionStorage unavailable; falling back to in-memory storage");
|
|
843
|
-
return createMemoryStorage();
|
|
621
|
+
return fromWebStorage(store, opts);
|
|
622
|
+
}
|
|
623
|
+
var createLocalStorageStorage = createLocalStorage;
|
|
624
|
+
function createSessionStorage(opts = {}) {
|
|
625
|
+
const store = browser.sessionStorage;
|
|
626
|
+
if (store === void 0) {
|
|
627
|
+
console.warn("[emporix] sessionStorage unavailable; falling back to in-memory storage");
|
|
628
|
+
return createMemoryStorage();
|
|
629
|
+
}
|
|
630
|
+
return fromWebStorage(store, opts);
|
|
631
|
+
}
|
|
632
|
+
function createCookieStorage(opts = {}) {
|
|
633
|
+
const sameSite = opts.sameSite ?? "lax";
|
|
634
|
+
const secure = opts.secure ?? browser.location?.protocol === "https:";
|
|
635
|
+
const doc = browser.document;
|
|
636
|
+
if (doc === void 0) {
|
|
637
|
+
console.warn("[emporix] document unavailable; cookie storage falling back to in-memory");
|
|
638
|
+
return createMemoryStorage();
|
|
639
|
+
}
|
|
640
|
+
const attrs = `path=/; SameSite=${sameSite}${secure ? "; Secure" : ""}`;
|
|
641
|
+
const all = createListenerSet();
|
|
642
|
+
const storage = createCookieBackedStorage(
|
|
643
|
+
{
|
|
644
|
+
get: (name) => {
|
|
645
|
+
for (const part of doc.cookie.split("; ")) {
|
|
646
|
+
const [k, ...v] = part.split("=");
|
|
647
|
+
if (k === name) return decodeURIComponent(v.join("=")) || null;
|
|
648
|
+
}
|
|
649
|
+
return null;
|
|
650
|
+
},
|
|
651
|
+
set: (name, value) => {
|
|
652
|
+
doc.cookie = value === null ? `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; ${attrs}` : `${name}=${encodeURIComponent(value)}; ${attrs}`;
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
...opts.name !== void 0 ? { tokenName: opts.name } : {},
|
|
657
|
+
notify: (key) => all.notify(key)
|
|
658
|
+
}
|
|
659
|
+
);
|
|
660
|
+
return { ...storage, subscribeAll: (l) => all.add(l) };
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/core/proxy.ts
|
|
664
|
+
var PROXY_CUSTOMER_TOKEN = "emporix-proxy-session";
|
|
665
|
+
function createProxyModeTokenProvider() {
|
|
666
|
+
const refuse = () => {
|
|
667
|
+
throw new EmporixAuthError(
|
|
668
|
+
"The client runs in proxy mode: the proxy attaches the token, so the SDK requests none"
|
|
669
|
+
);
|
|
670
|
+
};
|
|
671
|
+
return {
|
|
672
|
+
getToken: async () => refuse(),
|
|
673
|
+
getAnonymousToken: async () => refuse(),
|
|
674
|
+
refreshAnonymous: async () => refuse(),
|
|
675
|
+
setAnonymousContext: () => {
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
var TOKEN_KEYS = /* @__PURE__ */ new Set([
|
|
680
|
+
"customerToken",
|
|
681
|
+
"anonymousSession",
|
|
682
|
+
"refreshToken",
|
|
683
|
+
"saasToken"
|
|
684
|
+
]);
|
|
685
|
+
function createProxySessionStorage(base, authenticated) {
|
|
686
|
+
let current = authenticated;
|
|
687
|
+
const tokenListeners = createListenerSet();
|
|
688
|
+
const keyListeners = createListenerSet();
|
|
689
|
+
const token = () => current ? PROXY_CUSTOMER_TOKEN : null;
|
|
690
|
+
const drop = () => {
|
|
691
|
+
};
|
|
692
|
+
return {
|
|
693
|
+
getCustomerToken: token,
|
|
694
|
+
setCustomerToken: drop,
|
|
695
|
+
subscribe: (listener) => tokenListeners.add(listener),
|
|
696
|
+
getCartId: () => base.getCartId(),
|
|
697
|
+
setCartId: (id) => base.setCartId(id),
|
|
698
|
+
getAnonymousSession: () => null,
|
|
699
|
+
setAnonymousSession: drop,
|
|
700
|
+
getSiteCode: () => base.getSiteCode(),
|
|
701
|
+
setSiteCode: (code) => base.setSiteCode(code),
|
|
702
|
+
getLanguage: () => base.getLanguage(),
|
|
703
|
+
setLanguage: (language) => base.setLanguage(language),
|
|
704
|
+
getActiveLegalEntityId: () => base.getActiveLegalEntityId(),
|
|
705
|
+
setActiveLegalEntityId: (id) => base.setActiveLegalEntityId(id),
|
|
706
|
+
getRefreshToken: () => null,
|
|
707
|
+
setRefreshToken: drop,
|
|
708
|
+
getSaasToken: () => null,
|
|
709
|
+
setSaasToken: drop,
|
|
710
|
+
subscribeAll(listener) {
|
|
711
|
+
const own = keyListeners.add(listener);
|
|
712
|
+
const passed = base.subscribeAll?.((key) => {
|
|
713
|
+
if (!TOKEN_KEYS.has(key)) listener(key);
|
|
714
|
+
});
|
|
715
|
+
return () => {
|
|
716
|
+
own();
|
|
717
|
+
passed?.();
|
|
718
|
+
};
|
|
719
|
+
},
|
|
720
|
+
setProxyAuthenticated(next) {
|
|
721
|
+
if (next === current) return;
|
|
722
|
+
current = next;
|
|
723
|
+
tokenListeners.notify(token());
|
|
724
|
+
keyListeners.notify("customerToken");
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// src/core/logger.ts
|
|
730
|
+
var LEVEL = {
|
|
731
|
+
trace: 10,
|
|
732
|
+
debug: 20,
|
|
733
|
+
info: 30,
|
|
734
|
+
warn: 40,
|
|
735
|
+
error: 50,
|
|
736
|
+
silent: 60
|
|
737
|
+
};
|
|
738
|
+
function isValidLevel(v) {
|
|
739
|
+
return v !== void 0 && v in LEVEL;
|
|
740
|
+
}
|
|
741
|
+
function readEnv(name) {
|
|
742
|
+
try {
|
|
743
|
+
return typeof process !== "undefined" && process.env ? process.env[name] : void 0;
|
|
744
|
+
} catch {
|
|
745
|
+
return void 0;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
var LevelResolver = class {
|
|
749
|
+
constructor(cfg, warn = () => {
|
|
750
|
+
}) {
|
|
751
|
+
this.warn = warn;
|
|
752
|
+
this.cfgLevel = cfg.level ?? "warn";
|
|
753
|
+
this.cfgServices = { ...cfg.services };
|
|
754
|
+
}
|
|
755
|
+
warn;
|
|
756
|
+
cfgLevel;
|
|
757
|
+
cfgServices;
|
|
758
|
+
forcedServices = {};
|
|
759
|
+
forcedGlobal;
|
|
760
|
+
warned = false;
|
|
761
|
+
envFor(svc) {
|
|
762
|
+
const raw = readEnv(`EMPORIX_LOG_LEVEL_${svc.toUpperCase()}`);
|
|
763
|
+
if (raw === void 0) return void 0;
|
|
764
|
+
if (isValidLevel(raw)) return raw;
|
|
765
|
+
if (!this.warned) {
|
|
766
|
+
this.warned = true;
|
|
767
|
+
this.warn(`Invalid EMPORIX_LOG_LEVEL_${svc.toUpperCase()}="${raw}" ignored`);
|
|
768
|
+
}
|
|
769
|
+
return void 0;
|
|
770
|
+
}
|
|
771
|
+
envGlobal() {
|
|
772
|
+
const raw = readEnv("EMPORIX_LOG_LEVEL");
|
|
773
|
+
if (raw === void 0) return void 0;
|
|
774
|
+
if (isValidLevel(raw)) return raw;
|
|
775
|
+
if (!this.warned) {
|
|
776
|
+
this.warned = true;
|
|
777
|
+
this.warn(`Invalid EMPORIX_LOG_LEVEL="${raw}" ignored`);
|
|
778
|
+
}
|
|
779
|
+
return void 0;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Effective level for a service. Forced overrides (from `set(..., force)`)
|
|
783
|
+
* take precedence over env vars; otherwise env > programmatic config.
|
|
784
|
+
*/
|
|
785
|
+
get(svc) {
|
|
786
|
+
return this.forcedServices[svc] ?? this.envFor(svc) ?? this.forcedGlobal ?? this.envGlobal() ?? this.cfgServices[svc] ?? this.cfgLevel ?? "warn";
|
|
787
|
+
}
|
|
788
|
+
/** Numeric effective level for a service. */
|
|
789
|
+
numericLevel(svc) {
|
|
790
|
+
return LEVEL[this.get(svc)];
|
|
844
791
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
const sameSite = opts.sameSite ?? "lax";
|
|
849
|
-
const secure = opts.secure ?? browser.location?.protocol === "https:";
|
|
850
|
-
const doc = browser.document;
|
|
851
|
-
if (doc === void 0) {
|
|
852
|
-
console.warn("[emporix] document unavailable; cookie storage falling back to in-memory");
|
|
853
|
-
return createMemoryStorage();
|
|
792
|
+
/** True if `svc`'s effective level allows emitting at `at`. */
|
|
793
|
+
isAtLeast(svc, at) {
|
|
794
|
+
return this.numericLevel(svc) <= LEVEL[at];
|
|
854
795
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
for
|
|
861
|
-
|
|
862
|
-
|
|
796
|
+
/** Mutates programmatic level (global or one service). Env-set levels are sticky unless `force`. */
|
|
797
|
+
set(level, svc, force = false) {
|
|
798
|
+
if (svc) {
|
|
799
|
+
const envBound = readEnv(`EMPORIX_LOG_LEVEL_${svc.toUpperCase()}`) !== void 0;
|
|
800
|
+
if (envBound && !force) {
|
|
801
|
+
this.warn(`Level for "${svc}" is env-controlled; pass force to override`);
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
if (force) this.forcedServices[svc] = level;
|
|
805
|
+
else this.cfgServices[svc] = level;
|
|
806
|
+
} else {
|
|
807
|
+
const envBound = readEnv("EMPORIX_LOG_LEVEL") !== void 0;
|
|
808
|
+
if (envBound && !force) {
|
|
809
|
+
this.warn("Global level is env-controlled; pass force to override");
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
if (force) this.forcedGlobal = level;
|
|
813
|
+
else this.cfgLevel = level;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
var DEFAULT_REDACT = /* @__PURE__ */ new Set([
|
|
818
|
+
"authorization",
|
|
819
|
+
"password",
|
|
820
|
+
"oldpassword",
|
|
821
|
+
"newpassword",
|
|
822
|
+
"clientsecret",
|
|
823
|
+
"secret",
|
|
824
|
+
"access_token",
|
|
825
|
+
"refresh_token",
|
|
826
|
+
"customertoken",
|
|
827
|
+
"saastoken",
|
|
828
|
+
"saas-token",
|
|
829
|
+
"bearertoken",
|
|
830
|
+
"apikey",
|
|
831
|
+
"token"
|
|
832
|
+
]);
|
|
833
|
+
function redact(value, extra = []) {
|
|
834
|
+
const keys = new Set(DEFAULT_REDACT);
|
|
835
|
+
for (const k of extra) keys.add(k.toLowerCase());
|
|
836
|
+
const walk = (v) => {
|
|
837
|
+
if (Array.isArray(v)) return v.map(walk);
|
|
838
|
+
if (v && typeof v === "object") {
|
|
839
|
+
const src = v;
|
|
840
|
+
if (typeof src.kind === "string" && "token" in src) return { kind: src.kind };
|
|
841
|
+
const out = {};
|
|
842
|
+
for (const [k, val] of Object.entries(src)) {
|
|
843
|
+
if (keys.has(k.toLowerCase())) {
|
|
844
|
+
out[k] = k.toLowerCase() === "authorization" && typeof val === "string" ? "Bearer ***redacted***" : "***redacted***";
|
|
845
|
+
} else {
|
|
846
|
+
out[k] = walk(val);
|
|
863
847
|
}
|
|
864
|
-
return null;
|
|
865
|
-
},
|
|
866
|
-
set: (name, value) => {
|
|
867
|
-
doc.cookie = value === null ? `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; ${attrs}` : `${name}=${encodeURIComponent(value)}; ${attrs}`;
|
|
868
848
|
}
|
|
869
|
-
|
|
870
|
-
{
|
|
871
|
-
...opts.name !== void 0 ? { tokenName: opts.name } : {},
|
|
872
|
-
notify: (key) => all.notify(key)
|
|
849
|
+
return out;
|
|
873
850
|
}
|
|
874
|
-
|
|
875
|
-
|
|
851
|
+
return v;
|
|
852
|
+
};
|
|
853
|
+
return walk(value);
|
|
854
|
+
}
|
|
855
|
+
var EMIT = {
|
|
856
|
+
trace: LEVEL.trace,
|
|
857
|
+
debug: LEVEL.debug,
|
|
858
|
+
info: LEVEL.info,
|
|
859
|
+
warn: LEVEL.warn,
|
|
860
|
+
error: LEVEL.error
|
|
861
|
+
};
|
|
862
|
+
var BaseLogger = class {
|
|
863
|
+
constructor(resolver, bindings, extraRedact) {
|
|
864
|
+
this.resolver = resolver;
|
|
865
|
+
this.bindings = bindings;
|
|
866
|
+
this.extraRedact = extraRedact;
|
|
867
|
+
}
|
|
868
|
+
resolver;
|
|
869
|
+
bindings;
|
|
870
|
+
extraRedact;
|
|
871
|
+
svc() {
|
|
872
|
+
return this.bindings.service ?? "http";
|
|
873
|
+
}
|
|
874
|
+
get level() {
|
|
875
|
+
return this.resolver.get(this.svc());
|
|
876
|
+
}
|
|
877
|
+
isLevelEnabled(level) {
|
|
878
|
+
return this.resolver.isAtLeast(this.svc(), level);
|
|
879
|
+
}
|
|
880
|
+
at(level, msg, fields) {
|
|
881
|
+
if (this.resolver.numericLevel(this.svc()) > EMIT[level]) return;
|
|
882
|
+
const merged = { ...this.bindings, ...fields ?? {} };
|
|
883
|
+
this.emit(level, msg, redact(merged, this.extraRedact));
|
|
884
|
+
}
|
|
885
|
+
trace(m, f) {
|
|
886
|
+
this.at("trace", m, f);
|
|
887
|
+
}
|
|
888
|
+
debug(m, f) {
|
|
889
|
+
this.at("debug", m, f);
|
|
890
|
+
}
|
|
891
|
+
info(m, f) {
|
|
892
|
+
this.at("info", m, f);
|
|
893
|
+
}
|
|
894
|
+
warn(m, f) {
|
|
895
|
+
this.at("warn", m, f);
|
|
896
|
+
}
|
|
897
|
+
error(m, f) {
|
|
898
|
+
this.at("error", m, f);
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
var ConsoleLogger = class _ConsoleLogger extends BaseLogger {
|
|
902
|
+
constructor(resolver, bindings, extra, sink, pretty) {
|
|
903
|
+
super(resolver, bindings, extra);
|
|
904
|
+
this.sink = sink;
|
|
905
|
+
this.pretty = pretty;
|
|
906
|
+
}
|
|
907
|
+
sink;
|
|
908
|
+
pretty;
|
|
909
|
+
emit(level, msg, fields) {
|
|
910
|
+
if (this.pretty) {
|
|
911
|
+
const fn = level === "error" ? this.sink.error : level === "warn" ? this.sink.warn : level === "info" ? this.sink.info : this.sink.log;
|
|
912
|
+
fn(`[${level}] ${msg}`, fields);
|
|
913
|
+
} else {
|
|
914
|
+
this.sink.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level, msg, ...fields }));
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
child(bindings) {
|
|
918
|
+
return new _ConsoleLogger(
|
|
919
|
+
this.resolver,
|
|
920
|
+
{ ...this.bindings, ...bindings },
|
|
921
|
+
this.extraRedact,
|
|
922
|
+
this.sink,
|
|
923
|
+
this.pretty
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
var NoopLogger = class {
|
|
928
|
+
level = "silent";
|
|
929
|
+
isLevelEnabled() {
|
|
930
|
+
return false;
|
|
931
|
+
}
|
|
932
|
+
trace() {
|
|
933
|
+
}
|
|
934
|
+
debug() {
|
|
935
|
+
}
|
|
936
|
+
info() {
|
|
937
|
+
}
|
|
938
|
+
warn() {
|
|
939
|
+
}
|
|
940
|
+
error() {
|
|
941
|
+
}
|
|
942
|
+
child() {
|
|
943
|
+
return this;
|
|
944
|
+
}
|
|
945
|
+
};
|
|
946
|
+
function createConsoleLogger(resolver, bindings = {}, opts = {}) {
|
|
947
|
+
const pretty = opts.pretty ?? readEnv("NODE_ENV") !== "production";
|
|
948
|
+
const sink = opts.sink ?? {
|
|
949
|
+
log: console.log,
|
|
950
|
+
info: console.info,
|
|
951
|
+
warn: console.warn,
|
|
952
|
+
error: console.error
|
|
953
|
+
};
|
|
954
|
+
return new ConsoleLogger(resolver, bindings, opts.redact ?? [], sink, pretty);
|
|
955
|
+
}
|
|
956
|
+
function createNoopLogger() {
|
|
957
|
+
return new NoopLogger();
|
|
876
958
|
}
|
|
877
959
|
|
|
878
960
|
// src/core/query-keys.ts
|
|
@@ -986,20 +1068,72 @@ var HttpClient = class {
|
|
|
986
1068
|
sleep;
|
|
987
1069
|
/** Resolved request fetch. The arrow keeps `globalThis.fetch` correctly bound. */
|
|
988
1070
|
doFetch;
|
|
1071
|
+
/**
|
|
1072
|
+
* `null` in proxy mode, where no token is resolved at all — the provider is
|
|
1073
|
+
* never asked, so no token request can happen. A service context is refused
|
|
1074
|
+
* there rather than sent anonymously through the proxy.
|
|
1075
|
+
*/
|
|
1076
|
+
async tokenFor(o) {
|
|
1077
|
+
if (!this.opts.proxy) return resolveToken(o.auth, this.opts.provider);
|
|
1078
|
+
if (o.auth.kind === "service") {
|
|
1079
|
+
throw new EmporixAuthError(
|
|
1080
|
+
`${o.method} ${o.path}: auth.service() is not available in proxy mode \u2014 service tokens never belong in a browser. Make this call from your server.`
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1083
|
+
return null;
|
|
1084
|
+
}
|
|
1085
|
+
/** `host + path` plus query. A relative host (`/emporix`) resolves against the page origin. */
|
|
1086
|
+
urlFor(o) {
|
|
1087
|
+
const host = this.opts.host;
|
|
1088
|
+
let url;
|
|
1089
|
+
if (host.startsWith("/")) {
|
|
1090
|
+
const origin = globalThis.location?.origin;
|
|
1091
|
+
if (!origin) {
|
|
1092
|
+
throw new EmporixError(
|
|
1093
|
+
`host "${host}" is a path, which needs a page origin to resolve against, and globalThis.location is not available here. Use an absolute host on a server.`
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
url = new URL(host + o.path, origin);
|
|
1097
|
+
} else {
|
|
1098
|
+
url = new URL(host + o.path);
|
|
1099
|
+
}
|
|
1100
|
+
for (const [k, v] of Object.entries(o.query ?? {})) {
|
|
1101
|
+
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
1102
|
+
}
|
|
1103
|
+
return url;
|
|
1104
|
+
}
|
|
1105
|
+
/** Proxy mode: report the 401 before it is thrown. A throwing callback must not mask it. */
|
|
1106
|
+
reportUnauthorized(o) {
|
|
1107
|
+
try {
|
|
1108
|
+
this.opts.proxy?.onUnauthorized?.({ method: o.method, path: o.path });
|
|
1109
|
+
} catch {
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
989
1112
|
buildHeaders(o, token, isFormData) {
|
|
990
|
-
|
|
1113
|
+
const headers = {
|
|
991
1114
|
// Before `o.headers` on purpose: a caller may override the tenant for a
|
|
992
1115
|
// single request, the way `Accept-Language` and `Content-Language` can be
|
|
993
1116
|
// overridden. Only `Authorization` is non-negotiable.
|
|
994
1117
|
...this.opts.tenant !== void 0 ? { "Emporix-Tenant": this.opts.tenant } : {},
|
|
995
1118
|
...this.opts.requestContext?.language ? { "Accept-Language": this.opts.requestContext.language } : {},
|
|
996
1119
|
...this.opts.contentLanguage && o.body !== void 0 ? { "Content-Language": this.opts.contentLanguage } : {},
|
|
1120
|
+
...this.opts.proxy?.headers ?? {},
|
|
997
1121
|
...o.headers ?? {},
|
|
998
|
-
Authorization: `Bearer ${token}
|
|
1122
|
+
...token !== null ? { Authorization: `Bearer ${token}` } : {},
|
|
999
1123
|
// JSON bodies: set Content-Type. FormData bodies: let `fetch`
|
|
1000
1124
|
// emit `multipart/form-data; boundary=...` itself.
|
|
1001
1125
|
...o.body !== void 0 && !isFormData ? { "Content-Type": "application/json" } : {}
|
|
1002
1126
|
};
|
|
1127
|
+
if (token === null) {
|
|
1128
|
+
for (const k of Object.keys(headers)) {
|
|
1129
|
+
if (k.toLowerCase() === "authorization") delete headers[k];
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return headers;
|
|
1133
|
+
}
|
|
1134
|
+
/** `fetch`'s `credentials` — set only in proxy mode, where the session cookie must go along. */
|
|
1135
|
+
credentialsInit() {
|
|
1136
|
+
return this.opts.proxy ? { credentials: this.opts.proxy.credentials } : {};
|
|
1003
1137
|
}
|
|
1004
1138
|
/**
|
|
1005
1139
|
* Issues a request and returns the parsed body. Retries 5xx/429 on idempotent
|
|
@@ -1022,17 +1156,14 @@ var HttpClient = class {
|
|
|
1022
1156
|
async send(o) {
|
|
1023
1157
|
const requestId = `req-${++requestSeq}`;
|
|
1024
1158
|
const log = this.opts.logger.child({ requestId });
|
|
1025
|
-
const url =
|
|
1026
|
-
for (const [k, v] of Object.entries(o.query ?? {})) {
|
|
1027
|
-
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
1028
|
-
}
|
|
1159
|
+
const url = this.urlFor(o);
|
|
1029
1160
|
const sdkManaged = o.auth.kind === "service" || o.auth.kind === "anonymous";
|
|
1030
1161
|
const maxAttempts = this.opts.retry.maxAttempts;
|
|
1031
1162
|
let reauthed = false;
|
|
1032
1163
|
let customerToken = o.auth.kind === "customer" ? o.auth.token : void 0;
|
|
1033
1164
|
let customerReauthed = false;
|
|
1034
1165
|
for (let attempt = 1; ; attempt++) {
|
|
1035
|
-
const token = customerToken
|
|
1166
|
+
const token = !this.opts.proxy && customerToken !== void 0 ? customerToken : await this.tokenFor(o);
|
|
1036
1167
|
log.debug("http request", {
|
|
1037
1168
|
authKind: o.auth.kind,
|
|
1038
1169
|
method: o.method,
|
|
@@ -1056,7 +1187,8 @@ var HttpClient = class {
|
|
|
1056
1187
|
const init = {
|
|
1057
1188
|
method: o.method,
|
|
1058
1189
|
headers: this.buildHeaders(o, token, isFormData),
|
|
1059
|
-
signal: controller.signal
|
|
1190
|
+
signal: controller.signal,
|
|
1191
|
+
...this.credentialsInit()
|
|
1060
1192
|
};
|
|
1061
1193
|
if (o.body !== void 0) {
|
|
1062
1194
|
init.body = isFormData ? o.body : JSON.stringify(o.body);
|
|
@@ -1089,6 +1221,10 @@ var HttpClient = class {
|
|
|
1089
1221
|
return { data: parsed, headers: res.headers };
|
|
1090
1222
|
}
|
|
1091
1223
|
if (res.status === 401) {
|
|
1224
|
+
if (this.opts.proxy) {
|
|
1225
|
+
this.reportUnauthorized(o);
|
|
1226
|
+
throw errorFromResponse(res.status, `${o.method} ${o.path} \u2192 401`, parsed);
|
|
1227
|
+
}
|
|
1092
1228
|
if (sdkManaged && !reauthed) {
|
|
1093
1229
|
reauthed = true;
|
|
1094
1230
|
if (o.auth.kind === "service") {
|
|
@@ -1141,11 +1277,8 @@ var HttpClient = class {
|
|
|
1141
1277
|
async requestRaw(o, extra) {
|
|
1142
1278
|
const requestId = `req-${++requestSeq}`;
|
|
1143
1279
|
const log = this.opts.logger.child({ requestId });
|
|
1144
|
-
const url =
|
|
1145
|
-
|
|
1146
|
-
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
1147
|
-
}
|
|
1148
|
-
const token = await resolveToken(o.auth, this.opts.provider);
|
|
1280
|
+
const url = this.urlFor(o);
|
|
1281
|
+
const token = await this.tokenFor(o);
|
|
1149
1282
|
log.debug("http requestRaw", {
|
|
1150
1283
|
authKind: o.auth.kind,
|
|
1151
1284
|
method: o.method,
|
|
@@ -1162,13 +1295,15 @@ var HttpClient = class {
|
|
|
1162
1295
|
method: o.method,
|
|
1163
1296
|
headers: this.buildHeaders(o, token, isFormData),
|
|
1164
1297
|
signal: controller.signal,
|
|
1165
|
-
...extra?.redirect ? { redirect: extra.redirect } : {}
|
|
1298
|
+
...extra?.redirect ? { redirect: extra.redirect } : {},
|
|
1299
|
+
...this.credentialsInit()
|
|
1166
1300
|
};
|
|
1167
1301
|
if (o.body !== void 0) {
|
|
1168
1302
|
init.body = isFormData ? o.body : JSON.stringify(o.body);
|
|
1169
1303
|
}
|
|
1304
|
+
let res;
|
|
1170
1305
|
try {
|
|
1171
|
-
|
|
1306
|
+
res = await this.doFetch(url, init);
|
|
1172
1307
|
} catch (err) {
|
|
1173
1308
|
if (err.name === "AbortError") {
|
|
1174
1309
|
throw new EmporixTimeoutError(
|
|
@@ -1181,6 +1316,12 @@ var HttpClient = class {
|
|
|
1181
1316
|
} finally {
|
|
1182
1317
|
clearTimeout(timer);
|
|
1183
1318
|
}
|
|
1319
|
+
if (this.opts.proxy && res.status === 401) {
|
|
1320
|
+
this.reportUnauthorized(o);
|
|
1321
|
+
const text = await res.text().catch(() => "");
|
|
1322
|
+
throw errorFromResponse(401, `${o.method} ${o.path} \u2192 401`, text ? safeJson(text) : void 0);
|
|
1323
|
+
}
|
|
1324
|
+
return res;
|
|
1184
1325
|
}
|
|
1185
1326
|
/**
|
|
1186
1327
|
* Open a Server-Sent Events stream (`text/event-stream`) and yield parsed
|
|
@@ -1192,11 +1333,8 @@ var HttpClient = class {
|
|
|
1192
1333
|
*/
|
|
1193
1334
|
async *requestStream(o) {
|
|
1194
1335
|
const log = this.opts.logger.child({ requestId: `req-${++requestSeq}` });
|
|
1195
|
-
const url =
|
|
1196
|
-
|
|
1197
|
-
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
1198
|
-
}
|
|
1199
|
-
const token = await resolveToken(o.auth, this.opts.provider);
|
|
1336
|
+
const url = this.urlFor(o);
|
|
1337
|
+
const token = await this.tokenFor(o);
|
|
1200
1338
|
const controller = new AbortController();
|
|
1201
1339
|
const connectTimer = setTimeout(() => controller.abort(), this.opts.timeouts.connectMs);
|
|
1202
1340
|
const headers = this.buildHeaders(o, token, false);
|
|
@@ -1207,7 +1345,8 @@ var HttpClient = class {
|
|
|
1207
1345
|
method: o.method,
|
|
1208
1346
|
headers,
|
|
1209
1347
|
signal: controller.signal,
|
|
1210
|
-
...o.body !== void 0 ? { body: JSON.stringify(o.body) } : {}
|
|
1348
|
+
...o.body !== void 0 ? { body: JSON.stringify(o.body) } : {},
|
|
1349
|
+
...this.credentialsInit()
|
|
1211
1350
|
});
|
|
1212
1351
|
} catch (err) {
|
|
1213
1352
|
clearTimeout(connectTimer);
|
|
@@ -1220,6 +1359,7 @@ var HttpClient = class {
|
|
|
1220
1359
|
}
|
|
1221
1360
|
clearTimeout(connectTimer);
|
|
1222
1361
|
if (!res.ok) {
|
|
1362
|
+
if (this.opts.proxy && res.status === 401) this.reportUnauthorized(o);
|
|
1223
1363
|
const text = await res.text().catch(() => "");
|
|
1224
1364
|
throw errorFromResponse(
|
|
1225
1365
|
res.status,
|
|
@@ -1247,7 +1387,7 @@ var HttpClient = class {
|
|
|
1247
1387
|
};
|
|
1248
1388
|
|
|
1249
1389
|
// package.json
|
|
1250
|
-
var version = "4.
|
|
1390
|
+
var version = "4.11.0";
|
|
1251
1391
|
|
|
1252
1392
|
// src/version.ts
|
|
1253
1393
|
var SDK_VERSION = version;
|
|
@@ -1270,8 +1410,19 @@ function createCore(config) {
|
|
|
1270
1410
|
sdkVersion: SDK_VERSION,
|
|
1271
1411
|
tenant: cfg.tenant
|
|
1272
1412
|
});
|
|
1273
|
-
const tokenProvider = cfg.tokenProvider ?? new DefaultTokenProvider(cfg);
|
|
1413
|
+
const tokenProvider = cfg.proxy ? createProxyModeTokenProvider() : cfg.tokenProvider ?? new DefaultTokenProvider(cfg);
|
|
1274
1414
|
const customerRefresh = new CustomerRefreshRegistry();
|
|
1415
|
+
const unauthorized = createListenerSet();
|
|
1416
|
+
const proxy = cfg.proxy && {
|
|
1417
|
+
...cfg.proxy,
|
|
1418
|
+
onUnauthorized: (info) => {
|
|
1419
|
+
try {
|
|
1420
|
+
cfg.proxy?.onUnauthorized?.(info);
|
|
1421
|
+
} finally {
|
|
1422
|
+
unauthorized.notify(info);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1275
1426
|
const requestContext = {
|
|
1276
1427
|
language: cfg.credentials.storefront?.context?.language
|
|
1277
1428
|
};
|
|
@@ -1291,7 +1442,8 @@ function createCore(config) {
|
|
|
1291
1442
|
// exactOptionalPropertyTypes: `{ fetch: undefined }` is a type error
|
|
1292
1443
|
// against `fetch?: typeof globalThis.fetch`, so spread conditionally.
|
|
1293
1444
|
...cfg.fetch !== void 0 ? { fetch: cfg.fetch } : {},
|
|
1294
|
-
...cfg.contentLanguage !== void 0 ? { contentLanguage: cfg.contentLanguage } : {}
|
|
1445
|
+
...cfg.contentLanguage !== void 0 ? { contentLanguage: cfg.contentLanguage } : {},
|
|
1446
|
+
...proxy ? { proxy } : {}
|
|
1295
1447
|
})
|
|
1296
1448
|
});
|
|
1297
1449
|
return {
|
|
@@ -1316,6 +1468,9 @@ function createCore(config) {
|
|
|
1316
1468
|
},
|
|
1317
1469
|
setCustomerTokenRefresher(refresher) {
|
|
1318
1470
|
customerRefresh.set(refresher);
|
|
1471
|
+
},
|
|
1472
|
+
onUnauthorized(listener) {
|
|
1473
|
+
return unauthorized.add(listener);
|
|
1319
1474
|
}
|
|
1320
1475
|
};
|
|
1321
1476
|
}
|
|
@@ -8523,13 +8678,18 @@ var SearchService = class {
|
|
|
8523
8678
|
return `/search/${this.ctx.tenant}`;
|
|
8524
8679
|
}
|
|
8525
8680
|
/**
|
|
8526
|
-
* Search the documents of one custom schema type
|
|
8527
|
-
* `fields` travel as query parameters, not
|
|
8681
|
+
* Search the documents of one type — a custom schema type, `customer` or
|
|
8682
|
+
* `legal-entity`. Paging, `sort` and `fields` travel as query parameters, not
|
|
8683
|
+
* in the body.
|
|
8528
8684
|
*
|
|
8529
8685
|
* Filter and sort fields must be indexed on the index the search uses —
|
|
8530
|
-
* `exact`, or `text: true` for a `CONTAINS` filter — or the call answers
|
|
8531
|
-
* `
|
|
8532
|
-
*
|
|
8686
|
+
* `exact`, or `text: true` for a `CONTAINS` filter — or the call answers
|
|
8687
|
+
* `400`. A `TEXT` or `PHRASE` query may pick the field's `analyzer` or one of
|
|
8688
|
+
* its `additionalAnalyzers`. Conditions joined by `and` on fields of one
|
|
8689
|
+
* `itemFields` list must match the same list item. A saved-search call
|
|
8690
|
+
* (`{ searchQueryId, query }`) answers `404` when no saved search has that id
|
|
8691
|
+
* for `type`, and `502` means the Schema Service could not confirm that a
|
|
8692
|
+
* custom `type` is a custom entity.
|
|
8533
8693
|
*
|
|
8534
8694
|
* @example
|
|
8535
8695
|
* const hits = await client.search.search("VEHICLE", {
|
|
@@ -8554,7 +8714,7 @@ var SearchService = class {
|
|
|
8554
8714
|
page
|
|
8555
8715
|
);
|
|
8556
8716
|
}
|
|
8557
|
-
/** List saved searches of one
|
|
8717
|
+
/** List saved searches of one type (`opts.type`), or of every type. */
|
|
8558
8718
|
async listSavedSearches(opts = {}, auth2 = SERVICE29) {
|
|
8559
8719
|
const { query, page } = pageQuery(opts);
|
|
8560
8720
|
const t = opts.type;
|
|
@@ -8602,7 +8762,7 @@ var SearchService = class {
|
|
|
8602
8762
|
auth: auth2
|
|
8603
8763
|
});
|
|
8604
8764
|
}
|
|
8605
|
-
/** List search indexes of one
|
|
8765
|
+
/** List search indexes of one type (`opts.type`), or of every type. */
|
|
8606
8766
|
async listIndexes(opts = {}, auth2 = SERVICE29) {
|
|
8607
8767
|
const { query, page } = pageQuery(opts);
|
|
8608
8768
|
const t = opts.type;
|
|
@@ -8896,6 +9056,11 @@ var ImportService = class {
|
|
|
8896
9056
|
* streams. Read it back with {@link getRun}, or follow it with
|
|
8897
9057
|
* {@link streamRun}, before treating a resolved call as a started import.
|
|
8898
9058
|
*
|
|
9059
|
+
* A configuration that does not exist answers `404` (since 2026-11-06; it used
|
|
9060
|
+
* to be a `500`). A real run with nothing to import answers `400`: every stream
|
|
9061
|
+
* it starts from reads uploaded files, and none has ever had one. Upload a file
|
|
9062
|
+
* with {@link uploadStreamFile} first. A dry run is not refused for this.
|
|
9063
|
+
*
|
|
8899
9064
|
* Not retried on a 5xx: a POST that timed out may already have queued a run.
|
|
8900
9065
|
*
|
|
8901
9066
|
* @example
|
|
@@ -9146,7 +9311,7 @@ var ImportService = class {
|
|
|
9146
9311
|
* {@link streamRun} exactly as you would a triggered run. Like one, it comes
|
|
9147
9312
|
* back `QUEUED`, answers `409` while the configuration has a run `QUEUED`,
|
|
9148
9313
|
* `RUNNING` or `RESUMABLE`, runs the published mappings and can finish
|
|
9149
|
-
* `ABORTED`.
|
|
9314
|
+
* `ABORTED`. A run that does not exist answers `404`.
|
|
9150
9315
|
*
|
|
9151
9316
|
* Not retried on a 5xx, for the same reason {@link triggerRun} is not: a POST
|
|
9152
9317
|
* that timed out may already have queued the retry.
|
|
@@ -9257,6 +9422,29 @@ var ImportService = class {
|
|
|
9257
9422
|
auth: auth2
|
|
9258
9423
|
});
|
|
9259
9424
|
}
|
|
9425
|
+
/**
|
|
9426
|
+
* Put a `FAILED` file back at the end of the stream's queue, so the next run
|
|
9427
|
+
* reads the content the service already holds — no new upload. Use it after
|
|
9428
|
+
* fixing the cause of the failure, a mapping say. Resolves to the file,
|
|
9429
|
+
* `PENDING` again.
|
|
9430
|
+
*
|
|
9431
|
+
* Only a failed file can be queued again; `409` otherwise. A file imported with
|
|
9432
|
+
* some records failing is `PROCESSED`: retry those records with
|
|
9433
|
+
* {@link retryRun} instead. On a `SNAPSHOT` stream a failed file cannot be
|
|
9434
|
+
* queued again once a newer file arrived, since the older snapshot would be
|
|
9435
|
+
* imported over newer data — upload a corrected current file instead. `409`
|
|
9436
|
+
* also when the stored content is gone, and while the job has a run in flight.
|
|
9437
|
+
*
|
|
9438
|
+
* Not retried on a 5xx: if the first attempt went through, the file is no
|
|
9439
|
+
* longer `FAILED` and a repeat answers `409`.
|
|
9440
|
+
*/
|
|
9441
|
+
async requeueStreamFile(streamId, fileId, auth2 = SERVICE30) {
|
|
9442
|
+
return this.ctx.http.request({
|
|
9443
|
+
method: "POST",
|
|
9444
|
+
path: `${this.base()}/streams/${encodeURIComponent(streamId)}/files/${encodeURIComponent(fileId)}/requeue`,
|
|
9445
|
+
auth: auth2
|
|
9446
|
+
});
|
|
9447
|
+
}
|
|
9260
9448
|
};
|
|
9261
9449
|
|
|
9262
9450
|
// src/services/audit-log.ts
|
|
@@ -9989,6 +10177,15 @@ var EmporixClient = class {
|
|
|
9989
10177
|
setCustomerTokenRefresher(refresher) {
|
|
9990
10178
|
this.core.setCustomerTokenRefresher(refresher);
|
|
9991
10179
|
}
|
|
10180
|
+
/**
|
|
10181
|
+
* Proxy mode (`config.proxy`): subscribes to the 401s the proxy answers, next
|
|
10182
|
+
* to `proxy.onUnauthorized`. Returns the unsubscribe function. The React
|
|
10183
|
+
* `EmporixProvider` uses it for `onCustomerSessionExpired`. Never fires outside
|
|
10184
|
+
* proxy mode — there a 401 is answered by re-authenticating.
|
|
10185
|
+
*/
|
|
10186
|
+
onUnauthorized(listener) {
|
|
10187
|
+
return this.core.onUnauthorized(listener);
|
|
10188
|
+
}
|
|
9992
10189
|
};
|
|
9993
10190
|
|
|
9994
10191
|
// src/create-emporix-client.ts
|
|
@@ -10070,6 +10267,7 @@ exports.LevelResolver = LevelResolver;
|
|
|
10070
10267
|
exports.LocationsService = LocationsService;
|
|
10071
10268
|
exports.MediaService = MediaService;
|
|
10072
10269
|
exports.OrdersService = OrdersService;
|
|
10270
|
+
exports.PROXY_CUSTOMER_TOKEN = PROXY_CUSTOMER_TOKEN;
|
|
10073
10271
|
exports.PaymentGatewayService = PaymentGatewayService;
|
|
10074
10272
|
exports.PriceService = PriceService;
|
|
10075
10273
|
exports.ProductService = ProductService;
|
|
@@ -10104,6 +10302,8 @@ exports.createLocalStorage = createLocalStorage;
|
|
|
10104
10302
|
exports.createLocalStorageStorage = createLocalStorageStorage;
|
|
10105
10303
|
exports.createMemoryStorage = createMemoryStorage;
|
|
10106
10304
|
exports.createNoopLogger = createNoopLogger;
|
|
10305
|
+
exports.createProxyModeTokenProvider = createProxyModeTokenProvider;
|
|
10306
|
+
exports.createProxySessionStorage = createProxySessionStorage;
|
|
10107
10307
|
exports.createServerStorage = createServerStorage;
|
|
10108
10308
|
exports.createSessionStorage = createSessionStorage;
|
|
10109
10309
|
exports.emporixKey = emporixKey;
|