@viu/emporix-sdk-react 1.0.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 +519 -0
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/dist/chunk-D43CSHK3.js +410 -0
- package/dist/chunk-D43CSHK3.js.map +1 -0
- package/dist/chunk-FBQY2N7S.js +212 -0
- package/dist/chunk-FBQY2N7S.js.map +1 -0
- package/dist/chunk-N3VDSKCT.js +1128 -0
- package/dist/chunk-N3VDSKCT.js.map +1 -0
- package/dist/chunk-TIS4BKHK.js +25 -0
- package/dist/chunk-TIS4BKHK.js.map +1 -0
- package/dist/hooks.cjs +1212 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.cts +529 -0
- package/dist/hooks.d.ts +529 -0
- package/dist/hooks.js +5 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.cjs +1849 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +67 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/provider-BhvQWnnh.d.cts +133 -0
- package/dist/provider-fvcYdqqX.d.ts +133 -0
- package/dist/provider.cjs +480 -0
- package/dist/provider.cjs.map +1 -0
- package/dist/provider.d.cts +5 -0
- package/dist/provider.d.ts +5 -0
- package/dist/provider.js +4 -0
- package/dist/provider.js.map +1 -0
- package/dist/ssr.cjs +29 -0
- package/dist/ssr.cjs.map +1 -0
- package/dist/ssr.d.cts +23 -0
- package/dist/ssr.d.ts +23 -0
- package/dist/ssr.js +3 -0
- package/dist/ssr.js.map +1 -0
- package/dist/storage.cjs +218 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +65 -0
- package/dist/storage.d.ts +65 -0
- package/dist/storage.js +3 -0
- package/dist/storage.js.map +1 -0
- package/package.json +104 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1849 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var reactQuery = require('@tanstack/react-query');
|
|
5
|
+
var emporixSdk = require('@viu/emporix-sdk');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
// src/provider.tsx
|
|
9
|
+
|
|
10
|
+
// src/storage/local-storage.ts
|
|
11
|
+
var DEFAULT_TOKEN_KEY = "emporix.customerToken";
|
|
12
|
+
var CART_KEY = "emporix.cartId";
|
|
13
|
+
var ANON_KEY = "emporix.anonymousSession";
|
|
14
|
+
var SITE_KEY = "emporix.siteCode";
|
|
15
|
+
var ACTIVE_LE_KEY = "emporix.activeLegalEntityId";
|
|
16
|
+
var REFRESH_KEY = "emporix.refreshToken";
|
|
17
|
+
function createLocalStorageStorage(opts = {}) {
|
|
18
|
+
const tokenKey = opts.key ?? DEFAULT_TOKEN_KEY;
|
|
19
|
+
const available = typeof globalThis !== "undefined" && typeof globalThis.localStorage !== "undefined";
|
|
20
|
+
if (!available) {
|
|
21
|
+
console.warn("[emporix] localStorage unavailable; falling back to in-memory storage");
|
|
22
|
+
return createMemoryStorage();
|
|
23
|
+
}
|
|
24
|
+
const ls = globalThis.localStorage;
|
|
25
|
+
const tokenListeners = /* @__PURE__ */ new Set();
|
|
26
|
+
const all = createListenerSet();
|
|
27
|
+
return {
|
|
28
|
+
getCustomerToken: () => ls.getItem(tokenKey),
|
|
29
|
+
setCustomerToken: (t) => {
|
|
30
|
+
if (t === null) ls.removeItem(tokenKey);
|
|
31
|
+
else ls.setItem(tokenKey, t);
|
|
32
|
+
for (const l of tokenListeners) l(t);
|
|
33
|
+
all.notify("customerToken");
|
|
34
|
+
},
|
|
35
|
+
subscribe: (l) => {
|
|
36
|
+
tokenListeners.add(l);
|
|
37
|
+
return () => tokenListeners.delete(l);
|
|
38
|
+
},
|
|
39
|
+
getCartId: () => ls.getItem(CART_KEY),
|
|
40
|
+
setCartId: (id) => {
|
|
41
|
+
if (id === null) ls.removeItem(CART_KEY);
|
|
42
|
+
else ls.setItem(CART_KEY, id);
|
|
43
|
+
all.notify("cartId");
|
|
44
|
+
},
|
|
45
|
+
getAnonymousSession: () => parseAnonymousSession(ls.getItem(ANON_KEY)),
|
|
46
|
+
setAnonymousSession: (s) => {
|
|
47
|
+
if (s === null) ls.removeItem(ANON_KEY);
|
|
48
|
+
else ls.setItem(ANON_KEY, JSON.stringify({ refreshToken: s.refreshToken, sessionId: s.sessionId }));
|
|
49
|
+
all.notify("anonymousSession");
|
|
50
|
+
},
|
|
51
|
+
getSiteCode: () => ls.getItem(SITE_KEY),
|
|
52
|
+
setSiteCode: (code) => {
|
|
53
|
+
if (code === null) ls.removeItem(SITE_KEY);
|
|
54
|
+
else ls.setItem(SITE_KEY, code);
|
|
55
|
+
all.notify("siteCode");
|
|
56
|
+
},
|
|
57
|
+
getActiveLegalEntityId: () => ls.getItem(ACTIVE_LE_KEY),
|
|
58
|
+
setActiveLegalEntityId: (id) => {
|
|
59
|
+
if (id === null) ls.removeItem(ACTIVE_LE_KEY);
|
|
60
|
+
else ls.setItem(ACTIVE_LE_KEY, id);
|
|
61
|
+
all.notify("activeLegalEntityId");
|
|
62
|
+
},
|
|
63
|
+
getRefreshToken: () => ls.getItem(REFRESH_KEY),
|
|
64
|
+
setRefreshToken: (t) => {
|
|
65
|
+
if (t === null) ls.removeItem(REFRESH_KEY);
|
|
66
|
+
else ls.setItem(REFRESH_KEY, t);
|
|
67
|
+
all.notify("refreshToken");
|
|
68
|
+
},
|
|
69
|
+
subscribeAll: (l) => all.add(l)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/storage/cookie.ts
|
|
74
|
+
var DEFAULT_TOKEN_NAME = "emporix.customerToken";
|
|
75
|
+
var CART_NAME = "emporix.cartId";
|
|
76
|
+
var ANON_NAME = "emporix.anonymousSession";
|
|
77
|
+
var SITE_NAME = "emporix.siteCode";
|
|
78
|
+
var ACTIVE_LE_NAME = "emporix.activeLegalEntityId";
|
|
79
|
+
var REFRESH_NAME = "emporix.refreshToken";
|
|
80
|
+
function createCookieStorage(opts = {}) {
|
|
81
|
+
const tokenName = opts.name ?? DEFAULT_TOKEN_NAME;
|
|
82
|
+
const sameSite = opts.sameSite ?? "lax";
|
|
83
|
+
const secure = opts.secure ?? false;
|
|
84
|
+
if (typeof document === "undefined") {
|
|
85
|
+
console.warn("[emporix] document unavailable; cookie storage falling back to in-memory");
|
|
86
|
+
return createMemoryStorage();
|
|
87
|
+
}
|
|
88
|
+
const attrs = `path=/; SameSite=${sameSite}${secure ? "; Secure" : ""}`;
|
|
89
|
+
const readCookie = (name) => {
|
|
90
|
+
for (const part of document.cookie.split("; ")) {
|
|
91
|
+
const [k, ...v] = part.split("=");
|
|
92
|
+
if (k === name) return decodeURIComponent(v.join("=")) || null;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
};
|
|
96
|
+
const writeCookie = (name, value) => {
|
|
97
|
+
document.cookie = value === null ? `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; ${attrs}` : `${name}=${encodeURIComponent(value)}; ${attrs}`;
|
|
98
|
+
};
|
|
99
|
+
const all = createListenerSet();
|
|
100
|
+
return {
|
|
101
|
+
getCustomerToken: () => readCookie(tokenName),
|
|
102
|
+
setCustomerToken: (t) => {
|
|
103
|
+
writeCookie(tokenName, t);
|
|
104
|
+
all.notify("customerToken");
|
|
105
|
+
},
|
|
106
|
+
getCartId: () => readCookie(CART_NAME),
|
|
107
|
+
setCartId: (id) => {
|
|
108
|
+
writeCookie(CART_NAME, id);
|
|
109
|
+
all.notify("cartId");
|
|
110
|
+
},
|
|
111
|
+
getAnonymousSession: () => parseAnonymousSession(readCookie(ANON_NAME)),
|
|
112
|
+
setAnonymousSession: (s) => {
|
|
113
|
+
writeCookie(
|
|
114
|
+
ANON_NAME,
|
|
115
|
+
s === null ? null : JSON.stringify({ refreshToken: s.refreshToken, sessionId: s.sessionId })
|
|
116
|
+
);
|
|
117
|
+
all.notify("anonymousSession");
|
|
118
|
+
},
|
|
119
|
+
getSiteCode: () => readCookie(SITE_NAME),
|
|
120
|
+
setSiteCode: (code) => {
|
|
121
|
+
writeCookie(SITE_NAME, code);
|
|
122
|
+
all.notify("siteCode");
|
|
123
|
+
},
|
|
124
|
+
getActiveLegalEntityId: () => readCookie(ACTIVE_LE_NAME),
|
|
125
|
+
setActiveLegalEntityId: (id) => {
|
|
126
|
+
writeCookie(ACTIVE_LE_NAME, id);
|
|
127
|
+
all.notify("activeLegalEntityId");
|
|
128
|
+
},
|
|
129
|
+
getRefreshToken: () => readCookie(REFRESH_NAME),
|
|
130
|
+
setRefreshToken: (t) => {
|
|
131
|
+
writeCookie(REFRESH_NAME, t);
|
|
132
|
+
all.notify("refreshToken");
|
|
133
|
+
},
|
|
134
|
+
subscribeAll: (l) => all.add(l)
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/storage/index.ts
|
|
139
|
+
function createListenerSet() {
|
|
140
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
141
|
+
return {
|
|
142
|
+
add(l) {
|
|
143
|
+
listeners.add(l);
|
|
144
|
+
return () => listeners.delete(l);
|
|
145
|
+
},
|
|
146
|
+
notify(value) {
|
|
147
|
+
for (const l of listeners) {
|
|
148
|
+
try {
|
|
149
|
+
l(value);
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function parseAnonymousSession(raw) {
|
|
157
|
+
if (!raw) return null;
|
|
158
|
+
try {
|
|
159
|
+
const parsed = JSON.parse(raw);
|
|
160
|
+
if (typeof parsed.refreshToken === "string" && typeof parsed.sessionId === "string") {
|
|
161
|
+
return { refreshToken: parsed.refreshToken, sessionId: parsed.sessionId };
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
} catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/storage/memory.ts
|
|
170
|
+
function createMemoryStorage(opts = {}) {
|
|
171
|
+
let token = opts.initial ?? null;
|
|
172
|
+
let cartId = null;
|
|
173
|
+
let anon = null;
|
|
174
|
+
let siteCode = null;
|
|
175
|
+
let activeLegalEntityId = null;
|
|
176
|
+
let refreshToken = null;
|
|
177
|
+
const tokenListeners = /* @__PURE__ */ new Set();
|
|
178
|
+
const all = createListenerSet();
|
|
179
|
+
return {
|
|
180
|
+
getCustomerToken: () => token,
|
|
181
|
+
setCustomerToken: (t) => {
|
|
182
|
+
token = t;
|
|
183
|
+
for (const l of tokenListeners) l(token);
|
|
184
|
+
all.notify("customerToken");
|
|
185
|
+
},
|
|
186
|
+
subscribe: (l) => {
|
|
187
|
+
tokenListeners.add(l);
|
|
188
|
+
return () => tokenListeners.delete(l);
|
|
189
|
+
},
|
|
190
|
+
getCartId: () => cartId,
|
|
191
|
+
setCartId: (id) => {
|
|
192
|
+
cartId = id;
|
|
193
|
+
all.notify("cartId");
|
|
194
|
+
},
|
|
195
|
+
getAnonymousSession: () => anon,
|
|
196
|
+
setAnonymousSession: (s) => {
|
|
197
|
+
anon = s;
|
|
198
|
+
all.notify("anonymousSession");
|
|
199
|
+
},
|
|
200
|
+
getSiteCode: () => siteCode,
|
|
201
|
+
setSiteCode: (code) => {
|
|
202
|
+
siteCode = code;
|
|
203
|
+
all.notify("siteCode");
|
|
204
|
+
},
|
|
205
|
+
getActiveLegalEntityId: () => activeLegalEntityId,
|
|
206
|
+
setActiveLegalEntityId: (id) => {
|
|
207
|
+
activeLegalEntityId = id;
|
|
208
|
+
all.notify("activeLegalEntityId");
|
|
209
|
+
},
|
|
210
|
+
getRefreshToken: () => refreshToken,
|
|
211
|
+
setRefreshToken: (t) => {
|
|
212
|
+
refreshToken = t;
|
|
213
|
+
all.notify("refreshToken");
|
|
214
|
+
},
|
|
215
|
+
subscribeAll: (l) => all.add(l)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
var EmporixTelemetryContext = react.createContext(null);
|
|
219
|
+
function useEmporixTelemetry() {
|
|
220
|
+
const ctx = react.useContext(EmporixTelemetryContext);
|
|
221
|
+
if (!ctx) {
|
|
222
|
+
throw new Error("useEmporixTelemetry must be used within an EmporixProvider");
|
|
223
|
+
}
|
|
224
|
+
return ctx;
|
|
225
|
+
}
|
|
226
|
+
var NULL_CTX = {
|
|
227
|
+
activeCompany: null,
|
|
228
|
+
myCompanies: [],
|
|
229
|
+
mode: "b2c",
|
|
230
|
+
status: "idle",
|
|
231
|
+
error: null,
|
|
232
|
+
setActiveCompany: async () => {
|
|
233
|
+
throw new Error("CompanyContextProvider not mounted");
|
|
234
|
+
},
|
|
235
|
+
refetchMyCompanies: async () => {
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
var EmporixCompanyContext = react.createContext(NULL_CTX);
|
|
239
|
+
function useActiveCompany() {
|
|
240
|
+
return react.useContext(EmporixCompanyContext);
|
|
241
|
+
}
|
|
242
|
+
function CompanyContextProvider({
|
|
243
|
+
client,
|
|
244
|
+
storage,
|
|
245
|
+
initialActiveLegalEntityId,
|
|
246
|
+
children
|
|
247
|
+
}) {
|
|
248
|
+
const qc = reactQuery.useQueryClient();
|
|
249
|
+
const { emit } = useEmporixTelemetry();
|
|
250
|
+
const [myCompanies, setMyCompanies] = react.useState([]);
|
|
251
|
+
const [activeCompany, setActive] = react.useState(null);
|
|
252
|
+
const [status, setStatus] = react.useState("idle");
|
|
253
|
+
const [error, setError] = react.useState(null);
|
|
254
|
+
const activeRef = react.useRef(null);
|
|
255
|
+
activeRef.current = activeCompany;
|
|
256
|
+
const switchTo = react.useCallback(
|
|
257
|
+
async (target) => {
|
|
258
|
+
const start = Date.now();
|
|
259
|
+
const from = activeRef.current?.id ?? null;
|
|
260
|
+
const refreshToken = storage.getRefreshToken();
|
|
261
|
+
const token = storage.getCustomerToken();
|
|
262
|
+
if (!refreshToken || !token) {
|
|
263
|
+
setActive(target);
|
|
264
|
+
storage.setActiveLegalEntityId(target?.id ?? null);
|
|
265
|
+
} else {
|
|
266
|
+
const next = await client.customers.refresh({
|
|
267
|
+
refreshToken,
|
|
268
|
+
...target ? { legalEntityId: target.id } : {}
|
|
269
|
+
});
|
|
270
|
+
storage.setCustomerToken(next.customerToken);
|
|
271
|
+
if (next.refreshToken) storage.setRefreshToken(next.refreshToken);
|
|
272
|
+
storage.setCartId(null);
|
|
273
|
+
storage.setActiveLegalEntityId(target?.id ?? null);
|
|
274
|
+
setActive(target);
|
|
275
|
+
qc.invalidateQueries({
|
|
276
|
+
predicate: (q) => Array.isArray(q.queryKey) && q.queryKey.some(
|
|
277
|
+
(k) => k === "cart" || k === "companies" || k === "customer" || k === from || target !== null && k === target.id
|
|
278
|
+
)
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
emit({
|
|
282
|
+
type: "company:switched",
|
|
283
|
+
from,
|
|
284
|
+
to: target?.id ?? null,
|
|
285
|
+
durationMs: Date.now() - start
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
[client, storage, qc, emit]
|
|
289
|
+
);
|
|
290
|
+
const load = react.useCallback(async () => {
|
|
291
|
+
const token = storage.getCustomerToken();
|
|
292
|
+
if (!token) {
|
|
293
|
+
setMyCompanies([]);
|
|
294
|
+
setActive(null);
|
|
295
|
+
setStatus("idle");
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
setStatus("loading");
|
|
299
|
+
try {
|
|
300
|
+
const companies = await client.companies.listMine(emporixSdk.auth.customer(token));
|
|
301
|
+
setMyCompanies(companies);
|
|
302
|
+
const persisted = initialActiveLegalEntityId ?? storage.getActiveLegalEntityId();
|
|
303
|
+
const matched = persisted ? companies.find((c) => c.id === persisted) ?? null : null;
|
|
304
|
+
if (matched) {
|
|
305
|
+
setActive(matched);
|
|
306
|
+
if (storage.getActiveLegalEntityId() !== matched.id) {
|
|
307
|
+
storage.setActiveLegalEntityId(matched.id);
|
|
308
|
+
}
|
|
309
|
+
} else if (companies.length === 1) {
|
|
310
|
+
await switchTo(companies[0] ?? null);
|
|
311
|
+
} else {
|
|
312
|
+
setActive(null);
|
|
313
|
+
if (persisted && !matched) storage.setActiveLegalEntityId(null);
|
|
314
|
+
}
|
|
315
|
+
setStatus("idle");
|
|
316
|
+
} catch (e) {
|
|
317
|
+
setError(e);
|
|
318
|
+
setStatus("error");
|
|
319
|
+
}
|
|
320
|
+
}, [client, storage, initialActiveLegalEntityId, switchTo]);
|
|
321
|
+
react.useEffect(() => {
|
|
322
|
+
void load();
|
|
323
|
+
}, [load]);
|
|
324
|
+
react.useEffect(() => {
|
|
325
|
+
let prev = storage.getCustomerToken();
|
|
326
|
+
return storage.subscribe?.((next) => {
|
|
327
|
+
const becameAuth = !prev && next;
|
|
328
|
+
const becameUnauth = prev && !next;
|
|
329
|
+
prev = next;
|
|
330
|
+
if (becameAuth || becameUnauth) void load();
|
|
331
|
+
});
|
|
332
|
+
}, [storage, load]);
|
|
333
|
+
const setActiveCompany = react.useCallback(
|
|
334
|
+
async (legalEntityId) => {
|
|
335
|
+
setStatus("switching");
|
|
336
|
+
try {
|
|
337
|
+
if (legalEntityId === null) {
|
|
338
|
+
await switchTo(null);
|
|
339
|
+
} else {
|
|
340
|
+
const target = myCompanies.find((c) => c.id === legalEntityId) ?? null;
|
|
341
|
+
if (!target) throw new Error(`setActiveCompany: unknown legalEntityId ${legalEntityId}`);
|
|
342
|
+
await switchTo(target);
|
|
343
|
+
}
|
|
344
|
+
setStatus("idle");
|
|
345
|
+
} catch (e) {
|
|
346
|
+
setError(e);
|
|
347
|
+
setStatus("error");
|
|
348
|
+
throw e;
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
[myCompanies, switchTo]
|
|
352
|
+
);
|
|
353
|
+
const value = react.useMemo(() => {
|
|
354
|
+
const mode = activeCompany ? "b2b" : myCompanies.length > 1 ? "unresolved" : "b2c";
|
|
355
|
+
return {
|
|
356
|
+
activeCompany,
|
|
357
|
+
myCompanies,
|
|
358
|
+
mode,
|
|
359
|
+
status,
|
|
360
|
+
error,
|
|
361
|
+
setActiveCompany,
|
|
362
|
+
refetchMyCompanies: load
|
|
363
|
+
};
|
|
364
|
+
}, [activeCompany, myCompanies, status, error, setActiveCompany, load]);
|
|
365
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EmporixCompanyContext.Provider, { value, children });
|
|
366
|
+
}
|
|
367
|
+
var EmporixContext = react.createContext(null);
|
|
368
|
+
var EmporixSiteContext = react.createContext(null);
|
|
369
|
+
var DEFAULT_QUERY_OPTIONS = {
|
|
370
|
+
staleTime: 3e4,
|
|
371
|
+
refetchOnWindowFocus: false,
|
|
372
|
+
retry: 1
|
|
373
|
+
};
|
|
374
|
+
function EmporixProvider({
|
|
375
|
+
client,
|
|
376
|
+
queryClient,
|
|
377
|
+
storage,
|
|
378
|
+
initialCustomerToken,
|
|
379
|
+
initialSiteCode,
|
|
380
|
+
initialActiveLegalEntityId,
|
|
381
|
+
onTelemetry,
|
|
382
|
+
children
|
|
383
|
+
}) {
|
|
384
|
+
const value = react.useMemo(() => {
|
|
385
|
+
const s = storage ?? createMemoryStorage(
|
|
386
|
+
initialCustomerToken !== void 0 ? { initial: initialCustomerToken } : {}
|
|
387
|
+
);
|
|
388
|
+
if (initialCustomerToken && storage && storage.getCustomerToken() === null) {
|
|
389
|
+
storage.setCustomerToken(initialCustomerToken);
|
|
390
|
+
}
|
|
391
|
+
return { client, storage: s };
|
|
392
|
+
}, [client, storage, initialCustomerToken]);
|
|
393
|
+
const qc = react.useMemo(
|
|
394
|
+
() => queryClient ?? new reactQuery.QueryClient({ defaultOptions: { queries: DEFAULT_QUERY_OPTIONS } }),
|
|
395
|
+
[queryClient]
|
|
396
|
+
);
|
|
397
|
+
react.useState(() => {
|
|
398
|
+
client.tokenProvider.attachAnonymousStore?.({
|
|
399
|
+
read: () => value.storage.getAnonymousSession(),
|
|
400
|
+
write: (s) => value.storage.setAnonymousSession(s)
|
|
401
|
+
});
|
|
402
|
+
return null;
|
|
403
|
+
});
|
|
404
|
+
const safeEmit = react.useCallback(
|
|
405
|
+
(event) => {
|
|
406
|
+
if (!onTelemetry) return;
|
|
407
|
+
try {
|
|
408
|
+
onTelemetry(event);
|
|
409
|
+
} catch (err) {
|
|
410
|
+
console.error("[emporix] telemetry handler threw:", err);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
[onTelemetry]
|
|
414
|
+
);
|
|
415
|
+
const telemetryValue = react.useMemo(() => ({ emit: safeEmit }), [safeEmit]);
|
|
416
|
+
react.useEffect(() => {
|
|
417
|
+
if (!onTelemetry) return;
|
|
418
|
+
const startedAt = /* @__PURE__ */ new Map();
|
|
419
|
+
const unsubQuery = qc.getQueryCache().subscribe((event) => {
|
|
420
|
+
const key = event.query.queryKey;
|
|
421
|
+
if (!Array.isArray(key) || key[0] !== "emporix") return;
|
|
422
|
+
if (event.type === "updated") {
|
|
423
|
+
const action = event.action;
|
|
424
|
+
if (action.type === "fetch") {
|
|
425
|
+
const isRefetch = event.query.state.dataUpdateCount > 0;
|
|
426
|
+
if (isRefetch) {
|
|
427
|
+
safeEmit({
|
|
428
|
+
type: "query.refetch",
|
|
429
|
+
queryKey: key,
|
|
430
|
+
tenant: client.tenant,
|
|
431
|
+
reason: "invalidate"
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
startedAt.set(event.query.queryHash, Date.now());
|
|
435
|
+
} else if (action.type === "success") {
|
|
436
|
+
const start = startedAt.get(event.query.queryHash);
|
|
437
|
+
startedAt.delete(event.query.queryHash);
|
|
438
|
+
safeEmit({
|
|
439
|
+
type: "cache.miss",
|
|
440
|
+
queryKey: key,
|
|
441
|
+
tenant: client.tenant,
|
|
442
|
+
durationMs: start ? Date.now() - start : 0
|
|
443
|
+
});
|
|
444
|
+
} else if (action.type === "error") {
|
|
445
|
+
startedAt.delete(event.query.queryHash);
|
|
446
|
+
safeEmit({
|
|
447
|
+
type: "query.error",
|
|
448
|
+
queryKey: key,
|
|
449
|
+
tenant: client.tenant,
|
|
450
|
+
error: event.query.state.error
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
} else if (event.type === "observerResultsUpdated") {
|
|
454
|
+
const s = event.query.state;
|
|
455
|
+
if (s.status === "success" && s.fetchStatus === "idle" && s.dataUpdateCount > 0) {
|
|
456
|
+
safeEmit({ type: "cache.hit", queryKey: key, tenant: client.tenant });
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
const unsubMut = qc.getMutationCache().subscribe((event) => {
|
|
461
|
+
if (event.type !== "updated") return;
|
|
462
|
+
const m = event.mutation;
|
|
463
|
+
const dur = Date.now() - (m.state.submittedAt ?? Date.now());
|
|
464
|
+
const mk = m.options.mutationKey;
|
|
465
|
+
if (m.state.status === "success") {
|
|
466
|
+
safeEmit({
|
|
467
|
+
type: "mutation.success",
|
|
468
|
+
...mk ? { mutationKey: mk } : {},
|
|
469
|
+
tenant: client.tenant,
|
|
470
|
+
durationMs: dur
|
|
471
|
+
});
|
|
472
|
+
} else if (m.state.status === "error") {
|
|
473
|
+
safeEmit({
|
|
474
|
+
type: "mutation.error",
|
|
475
|
+
...mk ? { mutationKey: mk } : {},
|
|
476
|
+
tenant: client.tenant,
|
|
477
|
+
error: m.state.error,
|
|
478
|
+
durationMs: dur
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
const unsubAuth = client.tokenProvider.onRefresh?.(
|
|
483
|
+
(evt) => safeEmit({ type: "auth.refresh", ...evt, tenant: client.tenant })
|
|
484
|
+
);
|
|
485
|
+
const unsubStorage = value.storage.subscribeAll?.(
|
|
486
|
+
(key) => safeEmit({ type: "storage.write", key })
|
|
487
|
+
);
|
|
488
|
+
return () => {
|
|
489
|
+
unsubQuery();
|
|
490
|
+
unsubMut();
|
|
491
|
+
unsubAuth?.();
|
|
492
|
+
unsubStorage?.();
|
|
493
|
+
};
|
|
494
|
+
}, [qc, onTelemetry, client, value.storage, safeEmit]);
|
|
495
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EmporixContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(EmporixTelemetryContext.Provider, { value: telemetryValue, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: qc, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
496
|
+
SiteContextProvider,
|
|
497
|
+
{
|
|
498
|
+
client,
|
|
499
|
+
storage: value.storage,
|
|
500
|
+
...initialSiteCode !== void 0 ? { initialSiteCode } : {},
|
|
501
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
502
|
+
CompanyContextProvider,
|
|
503
|
+
{
|
|
504
|
+
client,
|
|
505
|
+
storage: value.storage,
|
|
506
|
+
...initialActiveLegalEntityId !== void 0 ? { initialActiveLegalEntityId } : {},
|
|
507
|
+
children
|
|
508
|
+
}
|
|
509
|
+
)
|
|
510
|
+
}
|
|
511
|
+
) }) }) });
|
|
512
|
+
}
|
|
513
|
+
function SiteContextProvider({
|
|
514
|
+
client,
|
|
515
|
+
storage,
|
|
516
|
+
initialSiteCode,
|
|
517
|
+
children
|
|
518
|
+
}) {
|
|
519
|
+
const qc = reactQuery.useQueryClient();
|
|
520
|
+
const [siteCode, setSiteCodeState] = react.useState(() => {
|
|
521
|
+
if (initialSiteCode !== void 0) return initialSiteCode;
|
|
522
|
+
const fromStorage = storage.getSiteCode();
|
|
523
|
+
if (fromStorage !== null) return fromStorage;
|
|
524
|
+
return client.config?.credentials?.storefront?.context?.siteCode ?? null;
|
|
525
|
+
});
|
|
526
|
+
const [currency, setCurrency] = react.useState(null);
|
|
527
|
+
const [targetLocation, setTargetLocation] = react.useState(null);
|
|
528
|
+
const [isSwitching, setIsSwitching] = react.useState(false);
|
|
529
|
+
const [switchError, setSwitchError] = react.useState(null);
|
|
530
|
+
react.useEffect(() => {
|
|
531
|
+
if (!siteCode || currency !== null) return;
|
|
532
|
+
let cancelled = false;
|
|
533
|
+
const token = storage.getCustomerToken();
|
|
534
|
+
const authCtx = token ? emporixSdk.auth.customer(token) : emporixSdk.auth.anonymous();
|
|
535
|
+
qc.fetchQuery({
|
|
536
|
+
queryKey: [
|
|
537
|
+
"emporix",
|
|
538
|
+
"site-by-code",
|
|
539
|
+
siteCode,
|
|
540
|
+
{ tenant: client.tenant, authKind: authCtx.kind }
|
|
541
|
+
],
|
|
542
|
+
queryFn: () => client.sites.get(siteCode, authCtx),
|
|
543
|
+
staleTime: 5 * 6e4
|
|
544
|
+
}).then((site) => {
|
|
545
|
+
if (cancelled) return;
|
|
546
|
+
setCurrency(site.currency);
|
|
547
|
+
setTargetLocation(site.homeBase?.address?.country ?? null);
|
|
548
|
+
}).catch(() => {
|
|
549
|
+
});
|
|
550
|
+
return () => {
|
|
551
|
+
cancelled = true;
|
|
552
|
+
};
|
|
553
|
+
}, [siteCode]);
|
|
554
|
+
const setSite = react.useCallback(
|
|
555
|
+
async (code) => {
|
|
556
|
+
storage.setSiteCode(code);
|
|
557
|
+
storage.setCartId(null);
|
|
558
|
+
setSiteCodeState(code);
|
|
559
|
+
setSwitchError(null);
|
|
560
|
+
void qc.invalidateQueries({ queryKey: ["emporix"] });
|
|
561
|
+
if (code === null) {
|
|
562
|
+
setCurrency(null);
|
|
563
|
+
setTargetLocation(null);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
setIsSwitching(true);
|
|
567
|
+
try {
|
|
568
|
+
const token = storage.getCustomerToken();
|
|
569
|
+
const authCtx = token ? emporixSdk.auth.customer(token) : emporixSdk.auth.anonymous();
|
|
570
|
+
const site = await qc.fetchQuery({
|
|
571
|
+
queryKey: [
|
|
572
|
+
"emporix",
|
|
573
|
+
"site-by-code",
|
|
574
|
+
code,
|
|
575
|
+
{ tenant: client.tenant, authKind: authCtx.kind }
|
|
576
|
+
],
|
|
577
|
+
queryFn: () => client.sites.get(code, authCtx),
|
|
578
|
+
staleTime: 5 * 6e4
|
|
579
|
+
});
|
|
580
|
+
const nextCurrency = site.currency;
|
|
581
|
+
const nextTarget = site.homeBase?.address?.country ?? null;
|
|
582
|
+
setCurrency(nextCurrency);
|
|
583
|
+
setTargetLocation(nextTarget);
|
|
584
|
+
await client.sessionContext.patch(
|
|
585
|
+
{
|
|
586
|
+
siteCode: code,
|
|
587
|
+
...nextCurrency ? { currency: nextCurrency } : {},
|
|
588
|
+
...nextTarget ? { targetLocation: nextTarget } : {}
|
|
589
|
+
},
|
|
590
|
+
authCtx
|
|
591
|
+
);
|
|
592
|
+
} catch (e) {
|
|
593
|
+
setSwitchError(e instanceof Error ? e : new Error(String(e)));
|
|
594
|
+
} finally {
|
|
595
|
+
setIsSwitching(false);
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
[client, storage, qc]
|
|
599
|
+
);
|
|
600
|
+
const value = react.useMemo(
|
|
601
|
+
() => ({
|
|
602
|
+
siteCode,
|
|
603
|
+
currency,
|
|
604
|
+
targetLocation,
|
|
605
|
+
setSite,
|
|
606
|
+
isSwitching,
|
|
607
|
+
switchError
|
|
608
|
+
}),
|
|
609
|
+
[siteCode, currency, targetLocation, setSite, isSwitching, switchError]
|
|
610
|
+
);
|
|
611
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EmporixSiteContext.Provider, { value, children });
|
|
612
|
+
}
|
|
613
|
+
function useEmporix() {
|
|
614
|
+
const ctx = react.useContext(EmporixContext);
|
|
615
|
+
if (!ctx) throw new Error("useEmporix must be used within an EmporixProvider");
|
|
616
|
+
return ctx;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// src/hooks/internal/bootstrap-cart.ts
|
|
620
|
+
async function bootstrapCart(opts) {
|
|
621
|
+
return opts.qc.fetchQuery({
|
|
622
|
+
queryKey: [
|
|
623
|
+
"emporix",
|
|
624
|
+
"cart-bootstrap",
|
|
625
|
+
{
|
|
626
|
+
tenant: opts.client.tenant,
|
|
627
|
+
// ctx.kind is the discriminator of AuthContext — same string as the
|
|
628
|
+
// legacy `authKind` param, derived directly so callers can't drift.
|
|
629
|
+
authKind: opts.ctx.kind,
|
|
630
|
+
siteCode: opts.siteCode,
|
|
631
|
+
...opts.type !== void 0 ? { type: opts.type } : {},
|
|
632
|
+
...opts.legalEntityId !== void 0 ? { legalEntityId: opts.legalEntityId } : {}
|
|
633
|
+
}
|
|
634
|
+
],
|
|
635
|
+
queryFn: () => opts.client.carts.getCurrent(opts.ctx, {
|
|
636
|
+
siteCode: opts.siteCode,
|
|
637
|
+
...opts.type !== void 0 ? { type: opts.type } : {},
|
|
638
|
+
...opts.legalEntityId !== void 0 ? { legalEntityId: opts.legalEntityId } : {},
|
|
639
|
+
create: true
|
|
640
|
+
}),
|
|
641
|
+
staleTime: Infinity
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// src/hooks/use-customer-session.ts
|
|
646
|
+
var EMPTY_SESSION = {
|
|
647
|
+
token: null,
|
|
648
|
+
refreshToken: null,
|
|
649
|
+
saasToken: null
|
|
650
|
+
};
|
|
651
|
+
function useCustomerSession() {
|
|
652
|
+
const { client, storage } = useEmporix();
|
|
653
|
+
const qc = reactQuery.useQueryClient();
|
|
654
|
+
const siteCtx = react.useContext(EmporixSiteContext);
|
|
655
|
+
const [session, setSession] = react.useState(() => ({
|
|
656
|
+
token: storage.getCustomerToken(),
|
|
657
|
+
refreshToken: null,
|
|
658
|
+
saasToken: null
|
|
659
|
+
}));
|
|
660
|
+
react.useEffect(() => {
|
|
661
|
+
return storage.subscribe?.((t) => setSession((s) => ({ ...s, token: t })));
|
|
662
|
+
}, [storage]);
|
|
663
|
+
const meQuery = reactQuery.useQuery({
|
|
664
|
+
queryKey: ["emporix", "customer", "me", { tenant: client.tenant, hasToken: session.token !== null }],
|
|
665
|
+
enabled: session.token !== null,
|
|
666
|
+
queryFn: () => client.customers.me(emporixSdk.auth.customer(session.token)),
|
|
667
|
+
// 30s — matches Balanced default. Lets honourPreferredSite's fetchQuery
|
|
668
|
+
// (with staleTime: Infinity) reuse the cache instead of refetching.
|
|
669
|
+
staleTime: 3e4
|
|
670
|
+
});
|
|
671
|
+
const login = react.useCallback(
|
|
672
|
+
async (input) => {
|
|
673
|
+
const result = await client.customers.login(input);
|
|
674
|
+
storage.setCustomerToken(result.customerToken);
|
|
675
|
+
storage.setRefreshToken(result.refreshToken || null);
|
|
676
|
+
setSession({
|
|
677
|
+
token: result.customerToken,
|
|
678
|
+
refreshToken: result.refreshToken || null,
|
|
679
|
+
saasToken: result.saasToken || null
|
|
680
|
+
});
|
|
681
|
+
await onboardCustomerCart({
|
|
682
|
+
qc,
|
|
683
|
+
client,
|
|
684
|
+
storage,
|
|
685
|
+
customerToken: result.customerToken
|
|
686
|
+
});
|
|
687
|
+
await honourPreferredSite({
|
|
688
|
+
qc,
|
|
689
|
+
client,
|
|
690
|
+
customerToken: result.customerToken,
|
|
691
|
+
siteCtx
|
|
692
|
+
});
|
|
693
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "customer"], refetchType: "none" });
|
|
694
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "cart"], refetchType: "none" });
|
|
695
|
+
},
|
|
696
|
+
[client, storage, qc, siteCtx]
|
|
697
|
+
);
|
|
698
|
+
const signup = react.useCallback(
|
|
699
|
+
async (input) => {
|
|
700
|
+
await client.customers.signup(input);
|
|
701
|
+
},
|
|
702
|
+
[client]
|
|
703
|
+
);
|
|
704
|
+
const applySession = react.useCallback(
|
|
705
|
+
async (incoming) => {
|
|
706
|
+
storage.setCustomerToken(incoming.customerToken);
|
|
707
|
+
storage.setRefreshToken(incoming.refreshToken || null);
|
|
708
|
+
setSession({
|
|
709
|
+
token: incoming.customerToken,
|
|
710
|
+
refreshToken: incoming.refreshToken || null,
|
|
711
|
+
saasToken: incoming.saasToken || null
|
|
712
|
+
});
|
|
713
|
+
await onboardCustomerCart({
|
|
714
|
+
qc,
|
|
715
|
+
client,
|
|
716
|
+
storage,
|
|
717
|
+
customerToken: incoming.customerToken
|
|
718
|
+
});
|
|
719
|
+
await honourPreferredSite({
|
|
720
|
+
qc,
|
|
721
|
+
client,
|
|
722
|
+
customerToken: incoming.customerToken,
|
|
723
|
+
siteCtx
|
|
724
|
+
});
|
|
725
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "customer"], refetchType: "none" });
|
|
726
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "cart"], refetchType: "none" });
|
|
727
|
+
},
|
|
728
|
+
[client, storage, qc, siteCtx]
|
|
729
|
+
);
|
|
730
|
+
const socialLogin = react.useCallback(
|
|
731
|
+
async (input) => {
|
|
732
|
+
await applySession(await client.customers.socialLogin(input));
|
|
733
|
+
},
|
|
734
|
+
[client, applySession]
|
|
735
|
+
);
|
|
736
|
+
const exchangeToken = react.useCallback(
|
|
737
|
+
async (input) => {
|
|
738
|
+
await applySession(await client.customers.exchangeToken(input));
|
|
739
|
+
},
|
|
740
|
+
[client, applySession]
|
|
741
|
+
);
|
|
742
|
+
const logout = react.useCallback(async () => {
|
|
743
|
+
if (session.token) {
|
|
744
|
+
try {
|
|
745
|
+
await client.customers.logout(emporixSdk.auth.customer(session.token));
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
storage.setCustomerToken(null);
|
|
750
|
+
storage.setRefreshToken(null);
|
|
751
|
+
storage.setActiveLegalEntityId(null);
|
|
752
|
+
setSession(EMPTY_SESSION);
|
|
753
|
+
qc.removeQueries({ queryKey: ["emporix", "customer"] });
|
|
754
|
+
qc.removeQueries({ queryKey: ["emporix", "cart"] });
|
|
755
|
+
}, [client, session.token, storage, qc]);
|
|
756
|
+
const refresh = react.useCallback(async () => {
|
|
757
|
+
await meQuery.refetch();
|
|
758
|
+
}, [meQuery]);
|
|
759
|
+
const refreshSession = react.useCallback(async () => {
|
|
760
|
+
if (!session.refreshToken) return;
|
|
761
|
+
const refreshed = await client.customers.refresh({
|
|
762
|
+
refreshToken: session.refreshToken,
|
|
763
|
+
...session.saasToken ? { saasToken: session.saasToken } : {}
|
|
764
|
+
});
|
|
765
|
+
storage.setCustomerToken(refreshed.customerToken);
|
|
766
|
+
if (refreshed.refreshToken) storage.setRefreshToken(refreshed.refreshToken);
|
|
767
|
+
setSession((s) => ({
|
|
768
|
+
token: refreshed.customerToken,
|
|
769
|
+
refreshToken: refreshed.refreshToken || s.refreshToken,
|
|
770
|
+
saasToken: refreshed.saasToken || s.saasToken
|
|
771
|
+
}));
|
|
772
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "customer"] });
|
|
773
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "cart"] });
|
|
774
|
+
}, [client, storage, qc, session.refreshToken, session.saasToken]);
|
|
775
|
+
return {
|
|
776
|
+
customerToken: session.token,
|
|
777
|
+
refreshToken: session.refreshToken,
|
|
778
|
+
customer: meQuery.data ?? null,
|
|
779
|
+
isAuthenticated: session.token !== null,
|
|
780
|
+
isLoading: meQuery.isLoading && session.token !== null,
|
|
781
|
+
login,
|
|
782
|
+
signup,
|
|
783
|
+
socialLogin,
|
|
784
|
+
exchangeToken,
|
|
785
|
+
logout,
|
|
786
|
+
refresh,
|
|
787
|
+
refreshSession
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
async function honourPreferredSite(opts) {
|
|
791
|
+
const { qc, client, customerToken, siteCtx } = opts;
|
|
792
|
+
if (!siteCtx) return;
|
|
793
|
+
try {
|
|
794
|
+
const me = await qc.fetchQuery({
|
|
795
|
+
queryKey: [
|
|
796
|
+
"emporix",
|
|
797
|
+
"customer",
|
|
798
|
+
"me",
|
|
799
|
+
{ tenant: client.tenant, hasToken: true }
|
|
800
|
+
],
|
|
801
|
+
queryFn: () => client.customers.me(emporixSdk.auth.customer(customerToken)),
|
|
802
|
+
// Reuse whatever meQuery already wrote (login flow runs meQuery in
|
|
803
|
+
// parallel). Without this, fetchQuery refetches if meQuery's data is
|
|
804
|
+
// already stale (default staleTime: 0 on meQuery).
|
|
805
|
+
staleTime: Infinity
|
|
806
|
+
});
|
|
807
|
+
const preferred = me.preferredSite;
|
|
808
|
+
if (preferred && siteCtx.siteCode !== preferred) {
|
|
809
|
+
await siteCtx.setSite(preferred);
|
|
810
|
+
}
|
|
811
|
+
} catch {
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
async function onboardCustomerCart(opts) {
|
|
815
|
+
const { qc, client, storage, customerToken } = opts;
|
|
816
|
+
const siteCode = client.config?.credentials?.storefront?.context?.siteCode;
|
|
817
|
+
if (!siteCode) return;
|
|
818
|
+
const ctx = emporixSdk.auth.customer(customerToken);
|
|
819
|
+
try {
|
|
820
|
+
const customerCart = await bootstrapCart({
|
|
821
|
+
qc,
|
|
822
|
+
client,
|
|
823
|
+
ctx,
|
|
824
|
+
siteCode
|
|
825
|
+
});
|
|
826
|
+
const customerCartId = customerCart?.id;
|
|
827
|
+
if (!customerCartId) return;
|
|
828
|
+
const anonCartId = storage.getCartId();
|
|
829
|
+
if (anonCartId && anonCartId !== customerCartId) {
|
|
830
|
+
await client.carts.merge(customerCartId, [anonCartId], ctx);
|
|
831
|
+
}
|
|
832
|
+
storage.setCartId(customerCartId);
|
|
833
|
+
} catch {
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function useReadAuth(override) {
|
|
837
|
+
const { storage } = useEmporix();
|
|
838
|
+
if (override) return { ctx: override };
|
|
839
|
+
const token = storage.getCustomerToken();
|
|
840
|
+
return token ? { ctx: emporixSdk.auth.customer(token) } : { ctx: emporixSdk.auth.anonymous() };
|
|
841
|
+
}
|
|
842
|
+
function useCustomerOnlyCtx() {
|
|
843
|
+
const { storage } = useEmporix();
|
|
844
|
+
const token = storage.getCustomerToken();
|
|
845
|
+
if (!token) {
|
|
846
|
+
throw new Error("Requires a logged-in customer (no token in storage)");
|
|
847
|
+
}
|
|
848
|
+
return emporixSdk.auth.customer(token);
|
|
849
|
+
}
|
|
850
|
+
function useReadSite() {
|
|
851
|
+
const ctx = react.useContext(EmporixSiteContext);
|
|
852
|
+
return { siteCode: ctx?.siteCode ?? null };
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// src/hooks/internal/query-keys.ts
|
|
856
|
+
function emporixKey(resource, args, context) {
|
|
857
|
+
const meta = {
|
|
858
|
+
tenant: context.tenant,
|
|
859
|
+
authKind: context.authKind
|
|
860
|
+
};
|
|
861
|
+
if (context.siteCode !== void 0) {
|
|
862
|
+
meta.siteCode = context.siteCode;
|
|
863
|
+
}
|
|
864
|
+
return ["emporix", resource, ...args, meta];
|
|
865
|
+
}
|
|
866
|
+
function useEmporixInfinite(opts) {
|
|
867
|
+
return reactQuery.useInfiniteQuery({
|
|
868
|
+
queryKey: opts.queryKey,
|
|
869
|
+
initialPageParam: 1,
|
|
870
|
+
queryFn: ({ pageParam }) => opts.fetchPage(pageParam),
|
|
871
|
+
getNextPageParam: (last) => last.hasNextPage ? last.pageNumber + 1 : void 0,
|
|
872
|
+
...opts.enabled !== void 0 ? { enabled: opts.enabled } : {},
|
|
873
|
+
...opts.staleTime !== void 0 ? { staleTime: opts.staleTime } : {}
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// src/hooks/use-products.ts
|
|
878
|
+
var PRODUCTS_STALE_TIME = 6e4;
|
|
879
|
+
function useProduct(productId, options = {}) {
|
|
880
|
+
const { client } = useEmporix();
|
|
881
|
+
const { ctx } = useReadAuth(options.auth);
|
|
882
|
+
const { siteCode } = useReadSite();
|
|
883
|
+
return reactQuery.useQuery({
|
|
884
|
+
queryKey: emporixKey("product", [productId], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
885
|
+
queryFn: () => client.products.get(productId, void 0, ctx),
|
|
886
|
+
staleTime: PRODUCTS_STALE_TIME
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
function useProducts(params = {}, options = {}) {
|
|
890
|
+
const { client } = useEmporix();
|
|
891
|
+
const { ctx } = useReadAuth(options.auth);
|
|
892
|
+
const { siteCode } = useReadSite();
|
|
893
|
+
return reactQuery.useQuery({
|
|
894
|
+
queryKey: emporixKey("products", [params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
895
|
+
queryFn: () => client.products.list(params, ctx),
|
|
896
|
+
staleTime: PRODUCTS_STALE_TIME
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
function useProductsInfinite(params = {}, options = {}) {
|
|
900
|
+
const { client } = useEmporix();
|
|
901
|
+
const { ctx } = useReadAuth(options.auth);
|
|
902
|
+
const { siteCode } = useReadSite();
|
|
903
|
+
return useEmporixInfinite({
|
|
904
|
+
queryKey: emporixKey("products-infinite", [params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
905
|
+
fetchPage: (pageNumber) => client.products.list(
|
|
906
|
+
params.pageSize !== void 0 ? { pageNumber, pageSize: params.pageSize } : { pageNumber },
|
|
907
|
+
ctx
|
|
908
|
+
),
|
|
909
|
+
staleTime: PRODUCTS_STALE_TIME
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
function useProductByCode(code, options = {}) {
|
|
913
|
+
const { client } = useEmporix();
|
|
914
|
+
const { ctx } = useReadAuth(options.auth);
|
|
915
|
+
const { siteCode } = useReadSite();
|
|
916
|
+
return reactQuery.useQuery({
|
|
917
|
+
queryKey: emporixKey("product-by-code", [code], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
918
|
+
enabled: typeof code === "string" && code !== "",
|
|
919
|
+
queryFn: () => client.products.getByCode(code, ctx),
|
|
920
|
+
staleTime: PRODUCTS_STALE_TIME
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
function useProductSearch(query, params = {}, options = {}) {
|
|
924
|
+
const { client } = useEmporix();
|
|
925
|
+
const { ctx } = useReadAuth(options.auth);
|
|
926
|
+
const { siteCode } = useReadSite();
|
|
927
|
+
return reactQuery.useQuery({
|
|
928
|
+
queryKey: emporixKey("product-search", [query, params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
929
|
+
enabled: typeof query === "string" && query.trim() !== "",
|
|
930
|
+
queryFn: () => client.products.search(query, params, ctx),
|
|
931
|
+
staleTime: PRODUCTS_STALE_TIME
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
var CATEGORIES_STALE_TIME = 5 * 6e4;
|
|
935
|
+
function useCategory(categoryId, options = {}) {
|
|
936
|
+
const { client } = useEmporix();
|
|
937
|
+
const { ctx } = useReadAuth(options.auth);
|
|
938
|
+
const { siteCode } = useReadSite();
|
|
939
|
+
return reactQuery.useQuery({
|
|
940
|
+
queryKey: emporixKey("category", [categoryId], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
941
|
+
queryFn: () => client.categories.get(categoryId, ctx),
|
|
942
|
+
staleTime: CATEGORIES_STALE_TIME
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
function useCategories(params = {}, options = {}) {
|
|
946
|
+
const { client } = useEmporix();
|
|
947
|
+
const { ctx } = useReadAuth(options.auth);
|
|
948
|
+
const { siteCode } = useReadSite();
|
|
949
|
+
return reactQuery.useQuery({
|
|
950
|
+
queryKey: emporixKey("categories", [params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
951
|
+
queryFn: () => client.categories.list(params, ctx),
|
|
952
|
+
staleTime: CATEGORIES_STALE_TIME
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
function useCategoriesInfinite(params = {}, options = {}) {
|
|
956
|
+
const { client } = useEmporix();
|
|
957
|
+
const { ctx } = useReadAuth(options.auth);
|
|
958
|
+
const { siteCode } = useReadSite();
|
|
959
|
+
return useEmporixInfinite({
|
|
960
|
+
queryKey: emporixKey("categories-infinite", [params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
961
|
+
fetchPage: (pageNumber) => client.categories.list(
|
|
962
|
+
params.pageSize !== void 0 ? { pageNumber, pageSize: params.pageSize } : { pageNumber },
|
|
963
|
+
ctx
|
|
964
|
+
),
|
|
965
|
+
staleTime: CATEGORIES_STALE_TIME
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
function useCategoryTree(rootId, options = {}) {
|
|
969
|
+
const { client } = useEmporix();
|
|
970
|
+
const { ctx } = useReadAuth(options.auth);
|
|
971
|
+
const { siteCode } = useReadSite();
|
|
972
|
+
return reactQuery.useQuery({
|
|
973
|
+
queryKey: emporixKey("category-tree", [rootId ?? null], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
974
|
+
queryFn: () => client.categories.tree(rootId, ctx),
|
|
975
|
+
staleTime: CATEGORIES_STALE_TIME
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
function useProductsInCategory(categoryId, params = {}, options = {}) {
|
|
979
|
+
const { client } = useEmporix();
|
|
980
|
+
const { ctx } = useReadAuth(options.auth);
|
|
981
|
+
const { siteCode } = useReadSite();
|
|
982
|
+
return reactQuery.useQuery({
|
|
983
|
+
queryKey: emporixKey("products-in-category", [categoryId, params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
984
|
+
enabled: typeof categoryId === "string" && categoryId !== "",
|
|
985
|
+
queryFn: () => client.categories.productsIn(categoryId, params, ctx),
|
|
986
|
+
staleTime: CATEGORIES_STALE_TIME
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
function useProductsInCategoryInfinite(categoryId, params = {}, options = {}) {
|
|
990
|
+
const { client } = useEmporix();
|
|
991
|
+
const { ctx } = useReadAuth(options.auth);
|
|
992
|
+
const { siteCode } = useReadSite();
|
|
993
|
+
return useEmporixInfinite({
|
|
994
|
+
queryKey: emporixKey("products-in-category-infinite", [categoryId, params], { tenant: client.tenant, authKind: ctx.kind, siteCode }),
|
|
995
|
+
enabled: typeof categoryId === "string" && categoryId !== "",
|
|
996
|
+
fetchPage: (pageNumber) => client.categories.productsIn(
|
|
997
|
+
categoryId,
|
|
998
|
+
params.pageSize !== void 0 ? { pageNumber, pageSize: params.pageSize } : { pageNumber },
|
|
999
|
+
ctx
|
|
1000
|
+
),
|
|
1001
|
+
staleTime: CATEGORIES_STALE_TIME
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
function useCart(cartId, options = {}) {
|
|
1005
|
+
const { client, storage } = useEmporix();
|
|
1006
|
+
const { ctx } = useReadAuth(options.auth);
|
|
1007
|
+
const { siteCode } = useReadSite();
|
|
1008
|
+
const { activeCompany } = useActiveCompany();
|
|
1009
|
+
const resolvedId = cartId ?? storage.getCartId() ?? void 0;
|
|
1010
|
+
return reactQuery.useQuery({
|
|
1011
|
+
queryKey: emporixKey(
|
|
1012
|
+
"cart",
|
|
1013
|
+
[resolvedId ?? null, activeCompany?.id ?? null],
|
|
1014
|
+
{ tenant: client.tenant, authKind: ctx.kind, siteCode }
|
|
1015
|
+
),
|
|
1016
|
+
enabled: resolvedId !== void 0,
|
|
1017
|
+
queryFn: () => client.carts.get(resolvedId, ctx)
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
function useCartMutations(cartId) {
|
|
1021
|
+
const { client, storage } = useEmporix();
|
|
1022
|
+
const qc = reactQuery.useQueryClient();
|
|
1023
|
+
const { ctx } = useReadAuth();
|
|
1024
|
+
const { siteCode } = useReadSite();
|
|
1025
|
+
const { activeCompany } = useActiveCompany();
|
|
1026
|
+
const resolveId = () => {
|
|
1027
|
+
const id = cartId ?? storage.getCartId();
|
|
1028
|
+
if (!id) {
|
|
1029
|
+
throw new emporixSdk.EmporixError(
|
|
1030
|
+
"useCartMutations: no cartId available \u2014 pass one explicitly or call useActiveCart({ create: true }) first"
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1033
|
+
return id;
|
|
1034
|
+
};
|
|
1035
|
+
const keyFor = (id) => emporixKey(
|
|
1036
|
+
"cart",
|
|
1037
|
+
[id, activeCompany?.id ?? null],
|
|
1038
|
+
{ tenant: client.tenant, authKind: ctx.kind, siteCode }
|
|
1039
|
+
);
|
|
1040
|
+
function make(run, optimistic) {
|
|
1041
|
+
return reactQuery.useMutation({
|
|
1042
|
+
mutationFn: async (vars) => run(resolveId(), vars),
|
|
1043
|
+
onMutate: async (vars) => {
|
|
1044
|
+
const id = resolveId();
|
|
1045
|
+
const key = keyFor(id);
|
|
1046
|
+
await qc.cancelQueries({ queryKey: key });
|
|
1047
|
+
const previous = qc.getQueryData(key);
|
|
1048
|
+
if (optimistic) qc.setQueryData(key, optimistic(previous, vars));
|
|
1049
|
+
return { previous, key };
|
|
1050
|
+
},
|
|
1051
|
+
onError: (_e, _v, c) => {
|
|
1052
|
+
if (c) qc.setQueryData(c.key, c.previous);
|
|
1053
|
+
},
|
|
1054
|
+
onSuccess: (cart, _v, c) => {
|
|
1055
|
+
if (c) qc.setQueryData(c.key, cart);
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
return {
|
|
1060
|
+
addItem: make(
|
|
1061
|
+
(id, v) => client.carts.addItem(id, v, ctx),
|
|
1062
|
+
(prev, v) => prev ? {
|
|
1063
|
+
...prev,
|
|
1064
|
+
// Optimistic placeholder; replaced by the real item on success.
|
|
1065
|
+
items: [
|
|
1066
|
+
...prev.items ?? [],
|
|
1067
|
+
{
|
|
1068
|
+
id: `optimistic-${v.product?.id ?? "item"}`,
|
|
1069
|
+
...v
|
|
1070
|
+
}
|
|
1071
|
+
]
|
|
1072
|
+
} : prev
|
|
1073
|
+
),
|
|
1074
|
+
updateItem: make((id, v) => client.carts.updateItem(id, v.itemId, v.patch, ctx)),
|
|
1075
|
+
removeItem: make(
|
|
1076
|
+
(id, v) => client.carts.removeItem(id, v.itemId, ctx),
|
|
1077
|
+
(prev, v) => prev ? { ...prev, items: (prev.items ?? []).filter((i) => i.id !== v.itemId) } : prev
|
|
1078
|
+
),
|
|
1079
|
+
clear: make(
|
|
1080
|
+
(id) => client.carts.clear(id, ctx),
|
|
1081
|
+
(prev) => prev ? { ...prev, items: [] } : prev
|
|
1082
|
+
),
|
|
1083
|
+
applyCoupon: make((id, v) => client.carts.applyCoupon(id, v.code, ctx)),
|
|
1084
|
+
removeCoupon: make((id, v) => client.carts.removeCoupon(id, v.code, ctx)),
|
|
1085
|
+
setShippingAddress: make((id, v) => client.carts.setShippingAddress(id, v, ctx)),
|
|
1086
|
+
setBillingAddress: make((id, v) => client.carts.setBillingAddress(id, v, ctx))
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
function useCreateCart() {
|
|
1090
|
+
const { client, storage } = useEmporix();
|
|
1091
|
+
const qc = reactQuery.useQueryClient();
|
|
1092
|
+
const { ctx } = useReadAuth();
|
|
1093
|
+
return reactQuery.useMutation({
|
|
1094
|
+
mutationFn: (input) => client.carts.create(input, ctx),
|
|
1095
|
+
onSuccess: async (cart) => {
|
|
1096
|
+
if (cart.cartId) storage.setCartId(cart.cartId);
|
|
1097
|
+
await qc.invalidateQueries({ queryKey: ["emporix", "cart"] });
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
function useActiveCart(opts) {
|
|
1102
|
+
const { client, storage } = useEmporix();
|
|
1103
|
+
const qc = reactQuery.useQueryClient();
|
|
1104
|
+
const { ctx } = useReadAuth(opts?.auth);
|
|
1105
|
+
const { siteCode: activeSite } = useReadSite();
|
|
1106
|
+
const { activeCompany } = useActiveCompany();
|
|
1107
|
+
const [cartId, setCartId] = react.useState(() => storage.getCartId());
|
|
1108
|
+
const effectiveLegalEntityId = opts?.legalEntityId ?? activeCompany?.id;
|
|
1109
|
+
react.useEffect(() => {
|
|
1110
|
+
if (cartId !== null) return;
|
|
1111
|
+
if (!opts?.create) return;
|
|
1112
|
+
const siteCode = activeSite ?? client.config?.credentials?.storefront?.context?.siteCode;
|
|
1113
|
+
if (!siteCode) return;
|
|
1114
|
+
let cancelled = false;
|
|
1115
|
+
bootstrapCart({
|
|
1116
|
+
qc,
|
|
1117
|
+
client,
|
|
1118
|
+
ctx,
|
|
1119
|
+
siteCode,
|
|
1120
|
+
...opts.type !== void 0 ? { type: opts.type } : {},
|
|
1121
|
+
...effectiveLegalEntityId !== void 0 ? { legalEntityId: effectiveLegalEntityId } : {}
|
|
1122
|
+
}).then((cart) => {
|
|
1123
|
+
if (cancelled) return;
|
|
1124
|
+
if (cart?.id) {
|
|
1125
|
+
storage.setCartId(cart.id);
|
|
1126
|
+
setCartId(cart.id);
|
|
1127
|
+
}
|
|
1128
|
+
}).catch(() => {
|
|
1129
|
+
});
|
|
1130
|
+
return () => {
|
|
1131
|
+
cancelled = true;
|
|
1132
|
+
};
|
|
1133
|
+
}, [cartId, opts?.create, opts?.type, effectiveLegalEntityId, ctx.kind, activeSite]);
|
|
1134
|
+
const inner = useCart(cartId ?? void 0, opts?.auth ? { auth: opts.auth } : {});
|
|
1135
|
+
const data = cartId === null ? null : inner.data;
|
|
1136
|
+
return { ...inner, data };
|
|
1137
|
+
}
|
|
1138
|
+
var PAYMENT_MODES_STALE_TIME = 10 * 6e4;
|
|
1139
|
+
function customerOnlyCtx(token) {
|
|
1140
|
+
if (!token) throw new Error("usePaymentModes requires a logged-in customer token");
|
|
1141
|
+
return emporixSdk.auth.customer(token);
|
|
1142
|
+
}
|
|
1143
|
+
function useCheckout() {
|
|
1144
|
+
const { client } = useEmporix();
|
|
1145
|
+
const { ctx } = useReadAuth();
|
|
1146
|
+
const { activeCompany } = useActiveCompany();
|
|
1147
|
+
const withLE = (input) => {
|
|
1148
|
+
if (!activeCompany?.id) return input;
|
|
1149
|
+
if ("legalEntityId" in input) return input;
|
|
1150
|
+
return { ...input, legalEntityId: activeCompany.id };
|
|
1151
|
+
};
|
|
1152
|
+
const placeOrder = reactQuery.useMutation({
|
|
1153
|
+
mutationFn: (v) => client.checkout.placeOrder(withLE(v.input), ctx, {
|
|
1154
|
+
...v.saasToken !== void 0 ? { saasToken: v.saasToken } : {},
|
|
1155
|
+
...v.siteCode !== void 0 ? { siteCode: v.siteCode } : {}
|
|
1156
|
+
})
|
|
1157
|
+
});
|
|
1158
|
+
const placeOrderFromQuote = reactQuery.useMutation({
|
|
1159
|
+
mutationFn: (v) => client.checkout.placeOrderFromQuote(withLE(v.input), ctx, {
|
|
1160
|
+
...v.saasToken !== void 0 ? { saasToken: v.saasToken } : {},
|
|
1161
|
+
...v.siteCode !== void 0 ? { siteCode: v.siteCode } : {}
|
|
1162
|
+
})
|
|
1163
|
+
});
|
|
1164
|
+
return { placeOrder, placeOrderFromQuote };
|
|
1165
|
+
}
|
|
1166
|
+
function usePaymentModes(options = {}) {
|
|
1167
|
+
const { client, storage } = useEmporix();
|
|
1168
|
+
const token = storage.getCustomerToken();
|
|
1169
|
+
const { siteCode } = useReadSite();
|
|
1170
|
+
const { activeCompany } = useActiveCompany();
|
|
1171
|
+
return reactQuery.useQuery({
|
|
1172
|
+
queryKey: emporixKey(
|
|
1173
|
+
"payment-modes",
|
|
1174
|
+
[activeCompany?.id ?? null],
|
|
1175
|
+
{ tenant: client.tenant, authKind: "customer", siteCode }
|
|
1176
|
+
),
|
|
1177
|
+
enabled: (options.enabled ?? true) && token !== null,
|
|
1178
|
+
queryFn: () => client.payments.listPaymentModes(customerOnlyCtx(token)),
|
|
1179
|
+
staleTime: PAYMENT_MODES_STALE_TIME
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
var PRICES_STALE_TIME = 6e4;
|
|
1183
|
+
function useMatchPrices(input, options = {}) {
|
|
1184
|
+
const { client } = useEmporix();
|
|
1185
|
+
const { siteCode } = useReadSite();
|
|
1186
|
+
const ctx = options.customerToken ? emporixSdk.auth.customer(options.customerToken) : emporixSdk.auth.anonymous();
|
|
1187
|
+
return reactQuery.useQuery({
|
|
1188
|
+
queryKey: [
|
|
1189
|
+
"emporix",
|
|
1190
|
+
"match-prices",
|
|
1191
|
+
{ tenant: client.tenant, input, anon: !options.customerToken, siteCode }
|
|
1192
|
+
],
|
|
1193
|
+
enabled: (options.enabled ?? true) && (input.items?.length ?? 0) > 0,
|
|
1194
|
+
queryFn: () => client.prices.matchByContext(input, ctx),
|
|
1195
|
+
staleTime: PRICES_STALE_TIME
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// src/hooks/use-product-media.ts
|
|
1200
|
+
function useProductMedia(productId) {
|
|
1201
|
+
const q = useProduct(productId);
|
|
1202
|
+
const data = q.data?.productMedia;
|
|
1203
|
+
return { data, isLoading: q.isLoading, error: q.error };
|
|
1204
|
+
}
|
|
1205
|
+
var SEGMENTS_STALE_TIME = 5 * 6e4;
|
|
1206
|
+
function customerCtx(token) {
|
|
1207
|
+
if (!token) throw new Error("requires a customer token in storage");
|
|
1208
|
+
return emporixSdk.auth.customer(token);
|
|
1209
|
+
}
|
|
1210
|
+
function useMySegments(query = {}) {
|
|
1211
|
+
const { client, storage } = useEmporix();
|
|
1212
|
+
const token = storage.getCustomerToken();
|
|
1213
|
+
const { siteCode } = useReadSite();
|
|
1214
|
+
return reactQuery.useQuery({
|
|
1215
|
+
queryKey: ["emporix", "segment", "list", { tenant: client.tenant, query, siteCode }],
|
|
1216
|
+
enabled: token !== null,
|
|
1217
|
+
queryFn: () => client.segments.list(query, customerCtx(token)),
|
|
1218
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
function useMySegmentItems(query = {}) {
|
|
1222
|
+
const { client, storage } = useEmporix();
|
|
1223
|
+
const token = storage.getCustomerToken();
|
|
1224
|
+
const { siteCode } = useReadSite();
|
|
1225
|
+
return reactQuery.useQuery({
|
|
1226
|
+
queryKey: ["emporix", "segment", "items", { tenant: client.tenant, query, siteCode }],
|
|
1227
|
+
enabled: token !== null,
|
|
1228
|
+
queryFn: () => client.segments.listItems(query, customerCtx(token)),
|
|
1229
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
function useMySegmentCategoryTree(query = {}) {
|
|
1233
|
+
const { client, storage } = useEmporix();
|
|
1234
|
+
const token = storage.getCustomerToken();
|
|
1235
|
+
const { siteCode } = useReadSite();
|
|
1236
|
+
return reactQuery.useQuery({
|
|
1237
|
+
queryKey: ["emporix", "segment", "categoryTree", { tenant: client.tenant, query, siteCode }],
|
|
1238
|
+
enabled: token !== null,
|
|
1239
|
+
queryFn: () => client.segments.getCategoryTree(query, customerCtx(token)),
|
|
1240
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
function useMySegmentProducts(query = {}) {
|
|
1244
|
+
const { client, storage } = useEmporix();
|
|
1245
|
+
const token = storage.getCustomerToken();
|
|
1246
|
+
const { siteCode } = useReadSite();
|
|
1247
|
+
return reactQuery.useQuery({
|
|
1248
|
+
queryKey: ["emporix", "segment", "myProducts", { tenant: client.tenant, query, siteCode }],
|
|
1249
|
+
enabled: token !== null,
|
|
1250
|
+
queryFn: () => client.segments.listMyProducts(query, customerCtx(token)),
|
|
1251
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
function useMySegmentProductsInfinite(query = {}) {
|
|
1255
|
+
const { client, storage } = useEmporix();
|
|
1256
|
+
const token = storage.getCustomerToken();
|
|
1257
|
+
const { siteCode } = useReadSite();
|
|
1258
|
+
return useEmporixInfinite({
|
|
1259
|
+
queryKey: [
|
|
1260
|
+
"emporix",
|
|
1261
|
+
"segment",
|
|
1262
|
+
"myProductsInfinite",
|
|
1263
|
+
{ tenant: client.tenant, query, siteCode }
|
|
1264
|
+
],
|
|
1265
|
+
enabled: token !== null,
|
|
1266
|
+
fetchPage: (pageNumber) => client.segments.listMyProducts(
|
|
1267
|
+
{ ...query, pageNumber, pageSize: query.pageSize ?? 20 },
|
|
1268
|
+
customerCtx(token)
|
|
1269
|
+
),
|
|
1270
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
function useMySegmentCategories(query = {}) {
|
|
1274
|
+
const { client, storage } = useEmporix();
|
|
1275
|
+
const token = storage.getCustomerToken();
|
|
1276
|
+
const { siteCode } = useReadSite();
|
|
1277
|
+
return reactQuery.useQuery({
|
|
1278
|
+
queryKey: ["emporix", "segment", "myCategories", { tenant: client.tenant, query, siteCode }],
|
|
1279
|
+
enabled: token !== null,
|
|
1280
|
+
queryFn: () => client.segments.listMyCategories(query, customerCtx(token)),
|
|
1281
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
function useMySegmentCategoriesInfinite(query = {}) {
|
|
1285
|
+
const { client, storage } = useEmporix();
|
|
1286
|
+
const token = storage.getCustomerToken();
|
|
1287
|
+
const { siteCode } = useReadSite();
|
|
1288
|
+
return useEmporixInfinite({
|
|
1289
|
+
queryKey: [
|
|
1290
|
+
"emporix",
|
|
1291
|
+
"segment",
|
|
1292
|
+
"myCategoriesInfinite",
|
|
1293
|
+
{ tenant: client.tenant, query, siteCode }
|
|
1294
|
+
],
|
|
1295
|
+
enabled: token !== null,
|
|
1296
|
+
fetchPage: (pageNumber) => client.segments.listMyCategories(
|
|
1297
|
+
{ ...query, pageNumber, pageSize: query.pageSize ?? 20 },
|
|
1298
|
+
customerCtx(token)
|
|
1299
|
+
),
|
|
1300
|
+
staleTime: SEGMENTS_STALE_TIME
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
function useUpdateCustomer() {
|
|
1304
|
+
const { client } = useEmporix();
|
|
1305
|
+
const ctx = useCustomerOnlyCtx();
|
|
1306
|
+
const qc = reactQuery.useQueryClient();
|
|
1307
|
+
return reactQuery.useMutation({
|
|
1308
|
+
mutationFn: (patch) => client.customers.update(patch, ctx),
|
|
1309
|
+
onSuccess: () => {
|
|
1310
|
+
void qc.invalidateQueries({ queryKey: ["emporix", "customer", "me"] });
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
function useChangePassword() {
|
|
1315
|
+
const { client } = useEmporix();
|
|
1316
|
+
const ctx = useCustomerOnlyCtx();
|
|
1317
|
+
return reactQuery.useMutation({
|
|
1318
|
+
mutationFn: (input) => client.customers.changePassword(input, ctx)
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
var ADDRESSES_KEY = ["emporix", "customer", "addresses"];
|
|
1322
|
+
function useCustomerAddresses(options = {}) {
|
|
1323
|
+
const { client, storage } = useEmporix();
|
|
1324
|
+
const token = storage.getCustomerToken();
|
|
1325
|
+
const { activeCompany } = useActiveCompany();
|
|
1326
|
+
const ctx = options.auth ?? (token ? emporixSdk.auth.customer(token) : null);
|
|
1327
|
+
return reactQuery.useQuery({
|
|
1328
|
+
queryKey: [
|
|
1329
|
+
...ADDRESSES_KEY,
|
|
1330
|
+
{ tenant: client.tenant, hasToken: token !== null, legalEntityId: activeCompany?.id ?? null }
|
|
1331
|
+
],
|
|
1332
|
+
enabled: ctx !== null,
|
|
1333
|
+
queryFn: () => client.customers.addresses.list(ctx)
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
function useAddressMutations() {
|
|
1337
|
+
const { client } = useEmporix();
|
|
1338
|
+
const ctx = useCustomerOnlyCtx();
|
|
1339
|
+
const qc = reactQuery.useQueryClient();
|
|
1340
|
+
const invalidate = () => {
|
|
1341
|
+
void qc.invalidateQueries({ queryKey: ADDRESSES_KEY });
|
|
1342
|
+
};
|
|
1343
|
+
return {
|
|
1344
|
+
add: reactQuery.useMutation({
|
|
1345
|
+
mutationFn: (input) => client.customers.addresses.add(input, ctx),
|
|
1346
|
+
onSuccess: invalidate
|
|
1347
|
+
}),
|
|
1348
|
+
update: reactQuery.useMutation({
|
|
1349
|
+
mutationFn: ({ id, patch }) => client.customers.addresses.update(id, patch, ctx),
|
|
1350
|
+
onSuccess: invalidate
|
|
1351
|
+
}),
|
|
1352
|
+
remove: reactQuery.useMutation({
|
|
1353
|
+
mutationFn: ({ id }) => client.customers.addresses.remove(id, ctx),
|
|
1354
|
+
onSuccess: invalidate
|
|
1355
|
+
})
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
function usePasswordReset() {
|
|
1359
|
+
const { client } = useEmporix();
|
|
1360
|
+
const anonCtx = emporixSdk.auth.anonymous();
|
|
1361
|
+
return {
|
|
1362
|
+
request: reactQuery.useMutation({
|
|
1363
|
+
mutationFn: (input) => client.customers.requestPasswordReset(input, anonCtx)
|
|
1364
|
+
}),
|
|
1365
|
+
confirm: reactQuery.useMutation({
|
|
1366
|
+
mutationFn: (input) => client.customers.confirmPasswordReset(input, anonCtx)
|
|
1367
|
+
})
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
var SITES_STALE_TIME = 10 * 6e4;
|
|
1371
|
+
function useSites(options = {}) {
|
|
1372
|
+
const { client } = useEmporix();
|
|
1373
|
+
const { ctx } = useReadAuth(options.auth);
|
|
1374
|
+
return reactQuery.useQuery({
|
|
1375
|
+
queryKey: emporixKey("sites", [], { tenant: client.tenant, authKind: ctx.kind }),
|
|
1376
|
+
queryFn: () => client.sites.list(ctx),
|
|
1377
|
+
staleTime: SITES_STALE_TIME
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
function useDefaultSite(options = {}) {
|
|
1381
|
+
const { client } = useEmporix();
|
|
1382
|
+
const { ctx } = useReadAuth(options.auth);
|
|
1383
|
+
return reactQuery.useQuery({
|
|
1384
|
+
queryKey: emporixKey("site-default", [], { tenant: client.tenant, authKind: ctx.kind }),
|
|
1385
|
+
queryFn: () => client.sites.current(ctx),
|
|
1386
|
+
staleTime: SITES_STALE_TIME
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
function useSiteContext() {
|
|
1390
|
+
const ctx = react.useContext(EmporixSiteContext);
|
|
1391
|
+
if (!ctx) {
|
|
1392
|
+
throw new Error("useSiteContext must be used within an EmporixProvider");
|
|
1393
|
+
}
|
|
1394
|
+
return ctx;
|
|
1395
|
+
}
|
|
1396
|
+
function useMyCompanies() {
|
|
1397
|
+
const { client, storage } = useEmporix();
|
|
1398
|
+
const token = storage.getCustomerToken();
|
|
1399
|
+
return reactQuery.useQuery({
|
|
1400
|
+
queryKey: emporixKey("companies", ["mine"], {
|
|
1401
|
+
tenant: client.tenant,
|
|
1402
|
+
authKind: token ? "customer" : "anonymous"
|
|
1403
|
+
}),
|
|
1404
|
+
enabled: token !== null,
|
|
1405
|
+
queryFn: () => client.companies.listMine(emporixSdk.auth.customer(token))
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
function useCompany(legalEntityId) {
|
|
1409
|
+
const { client, storage } = useEmporix();
|
|
1410
|
+
const token = storage.getCustomerToken();
|
|
1411
|
+
return reactQuery.useQuery({
|
|
1412
|
+
queryKey: emporixKey("companies", [legalEntityId ?? null], {
|
|
1413
|
+
tenant: client.tenant,
|
|
1414
|
+
authKind: token ? "customer" : "anonymous"
|
|
1415
|
+
}),
|
|
1416
|
+
enabled: token !== null && legalEntityId !== void 0,
|
|
1417
|
+
queryFn: () => client.companies.get(legalEntityId, emporixSdk.auth.customer(token))
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1420
|
+
function useCompanyContacts(legalEntityId) {
|
|
1421
|
+
const { client, storage } = useEmporix();
|
|
1422
|
+
const token = storage.getCustomerToken();
|
|
1423
|
+
return reactQuery.useQuery({
|
|
1424
|
+
queryKey: emporixKey("companies", ["contacts", legalEntityId ?? null], {
|
|
1425
|
+
tenant: client.tenant,
|
|
1426
|
+
authKind: token ? "customer" : "anonymous"
|
|
1427
|
+
}),
|
|
1428
|
+
enabled: token !== null && legalEntityId !== void 0,
|
|
1429
|
+
queryFn: () => client.contacts.listForCompany(legalEntityId, emporixSdk.auth.customer(token))
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
function useCompanyLocations(legalEntityId) {
|
|
1433
|
+
const { client, storage } = useEmporix();
|
|
1434
|
+
const token = storage.getCustomerToken();
|
|
1435
|
+
return reactQuery.useQuery({
|
|
1436
|
+
queryKey: emporixKey("companies", ["locations", legalEntityId ?? null], {
|
|
1437
|
+
tenant: client.tenant,
|
|
1438
|
+
authKind: token ? "customer" : "anonymous"
|
|
1439
|
+
}),
|
|
1440
|
+
enabled: token !== null && legalEntityId !== void 0,
|
|
1441
|
+
queryFn: () => client.locations.listForCompany(legalEntityId, emporixSdk.auth.customer(token))
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
function useCompanyGroups(legalEntityId) {
|
|
1445
|
+
const { client, storage } = useEmporix();
|
|
1446
|
+
const token = storage.getCustomerToken();
|
|
1447
|
+
return reactQuery.useQuery({
|
|
1448
|
+
queryKey: emporixKey("companies", ["groups", legalEntityId ?? null], {
|
|
1449
|
+
tenant: client.tenant,
|
|
1450
|
+
authKind: token ? "customer" : "anonymous"
|
|
1451
|
+
}),
|
|
1452
|
+
enabled: token !== null && legalEntityId !== void 0,
|
|
1453
|
+
queryFn: () => client.customerGroups.listForCompany(legalEntityId, emporixSdk.auth.customer(token))
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
function useCustomerAuthResolver() {
|
|
1457
|
+
const { storage } = useEmporix();
|
|
1458
|
+
return () => {
|
|
1459
|
+
const token = storage.getCustomerToken();
|
|
1460
|
+
if (!token) throw new Error("Mutation requires a logged-in customer token");
|
|
1461
|
+
return emporixSdk.auth.customer(token);
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
function useCreateCompany() {
|
|
1465
|
+
const { client } = useEmporix();
|
|
1466
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1467
|
+
const qc = reactQuery.useQueryClient();
|
|
1468
|
+
return reactQuery.useMutation({
|
|
1469
|
+
mutationFn: (input) => client.companies.create(input, resolveAuth()),
|
|
1470
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: ["emporix", "companies", "mine"] })
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
function useUpdateCompany() {
|
|
1474
|
+
const { client } = useEmporix();
|
|
1475
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1476
|
+
const qc = reactQuery.useQueryClient();
|
|
1477
|
+
return reactQuery.useMutation({
|
|
1478
|
+
mutationFn: ({ id, patch }) => client.companies.update(id, patch, resolveAuth()),
|
|
1479
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: ["emporix", "companies"] })
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
function useDeleteCompany() {
|
|
1483
|
+
const { client } = useEmporix();
|
|
1484
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1485
|
+
const qc = reactQuery.useQueryClient();
|
|
1486
|
+
return reactQuery.useMutation({
|
|
1487
|
+
mutationFn: (id) => client.companies.delete(id, resolveAuth()),
|
|
1488
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: ["emporix", "companies"] })
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1491
|
+
function useAssignContact() {
|
|
1492
|
+
const { client } = useEmporix();
|
|
1493
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1494
|
+
const qc = reactQuery.useQueryClient();
|
|
1495
|
+
return reactQuery.useMutation({
|
|
1496
|
+
mutationFn: (input) => client.contacts.assign(input, resolveAuth()),
|
|
1497
|
+
onSuccess: () => qc.invalidateQueries({ predicate: (q) => q.queryKey.includes("contacts") })
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
function useUpdateContactAssignment() {
|
|
1501
|
+
const { client } = useEmporix();
|
|
1502
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1503
|
+
const qc = reactQuery.useQueryClient();
|
|
1504
|
+
return reactQuery.useMutation({
|
|
1505
|
+
mutationFn: ({ id, patch }) => client.contacts.update(id, patch, resolveAuth()),
|
|
1506
|
+
onSuccess: () => qc.invalidateQueries({ predicate: (q) => q.queryKey.includes("contacts") })
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
function useUnassignContact() {
|
|
1510
|
+
const { client } = useEmporix();
|
|
1511
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1512
|
+
const qc = reactQuery.useQueryClient();
|
|
1513
|
+
return reactQuery.useMutation({
|
|
1514
|
+
mutationFn: (id) => client.contacts.unassign(id, resolveAuth()),
|
|
1515
|
+
onSuccess: () => qc.invalidateQueries({ predicate: (q) => q.queryKey.includes("contacts") })
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
function useCreateLocation() {
|
|
1519
|
+
const { client } = useEmporix();
|
|
1520
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1521
|
+
const qc = reactQuery.useQueryClient();
|
|
1522
|
+
return reactQuery.useMutation({
|
|
1523
|
+
mutationFn: (input) => client.locations.create(input, resolveAuth()),
|
|
1524
|
+
onSuccess: () => qc.invalidateQueries({ predicate: (q) => q.queryKey.includes("locations") })
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
function useUpdateLocation() {
|
|
1528
|
+
const { client } = useEmporix();
|
|
1529
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1530
|
+
const qc = reactQuery.useQueryClient();
|
|
1531
|
+
return reactQuery.useMutation({
|
|
1532
|
+
mutationFn: ({ id, patch }) => client.locations.update(id, patch, resolveAuth()),
|
|
1533
|
+
onSuccess: () => qc.invalidateQueries({ predicate: (q) => q.queryKey.includes("locations") })
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
function useDeleteLocation() {
|
|
1537
|
+
const { client } = useEmporix();
|
|
1538
|
+
const resolveAuth = useCustomerAuthResolver();
|
|
1539
|
+
const qc = reactQuery.useQueryClient();
|
|
1540
|
+
return reactQuery.useMutation({
|
|
1541
|
+
mutationFn: (id) => client.locations.delete(id, resolveAuth()),
|
|
1542
|
+
onSuccess: () => qc.invalidateQueries({ predicate: (q) => q.queryKey.includes("locations") })
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
function useCompanySwitcher() {
|
|
1546
|
+
const ctx = useActiveCompany();
|
|
1547
|
+
const switchFn = react.useCallback(
|
|
1548
|
+
(legalEntityId) => ctx.setActiveCompany(legalEntityId),
|
|
1549
|
+
[ctx]
|
|
1550
|
+
);
|
|
1551
|
+
const clearFn = react.useCallback(() => ctx.setActiveCompany(null), [ctx]);
|
|
1552
|
+
return {
|
|
1553
|
+
companies: ctx.myCompanies,
|
|
1554
|
+
active: ctx.activeCompany,
|
|
1555
|
+
status: ctx.status,
|
|
1556
|
+
switch: switchFn,
|
|
1557
|
+
clear: clearFn
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
function useMyOrders(options = {}) {
|
|
1561
|
+
const { client, storage } = useEmporix();
|
|
1562
|
+
const { activeCompany } = useActiveCompany();
|
|
1563
|
+
const { siteCode } = useReadSite();
|
|
1564
|
+
const token = storage.getCustomerToken();
|
|
1565
|
+
const effectiveLE = options.legalEntityId === null ? void 0 : options.legalEntityId ?? activeCompany?.id;
|
|
1566
|
+
return reactQuery.useQuery({
|
|
1567
|
+
queryKey: emporixKey(
|
|
1568
|
+
"orders",
|
|
1569
|
+
["mine", effectiveLE ?? null, options.status ?? null, options.pageNumber ?? 1, options.pageSize ?? null],
|
|
1570
|
+
{ tenant: client.tenant, authKind: token ? "customer" : "anonymous", siteCode }
|
|
1571
|
+
),
|
|
1572
|
+
enabled: token !== null,
|
|
1573
|
+
queryFn: () => client.orders.listMine(emporixSdk.auth.customer(token), {
|
|
1574
|
+
...options.pageNumber !== void 0 ? { pageNumber: options.pageNumber } : {},
|
|
1575
|
+
...options.pageSize !== void 0 ? { pageSize: options.pageSize } : {},
|
|
1576
|
+
...options.status !== void 0 ? { status: options.status } : {},
|
|
1577
|
+
...effectiveLE !== void 0 ? { legalEntityId: effectiveLE } : {},
|
|
1578
|
+
...siteCode ? { siteCode } : {},
|
|
1579
|
+
...options.saasToken !== void 0 ? { saasToken: options.saasToken } : {}
|
|
1580
|
+
})
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
function useMyOrdersInfinite(options = {}) {
|
|
1584
|
+
const { client, storage } = useEmporix();
|
|
1585
|
+
const { activeCompany } = useActiveCompany();
|
|
1586
|
+
const { siteCode } = useReadSite();
|
|
1587
|
+
const token = storage.getCustomerToken();
|
|
1588
|
+
const effectiveLE = options.legalEntityId === null ? void 0 : options.legalEntityId ?? activeCompany?.id;
|
|
1589
|
+
return useEmporixInfinite({
|
|
1590
|
+
queryKey: emporixKey(
|
|
1591
|
+
"orders",
|
|
1592
|
+
["mine-infinite", effectiveLE ?? null, options.status ?? null, options.pageSize ?? null],
|
|
1593
|
+
{ tenant: client.tenant, authKind: token ? "customer" : "anonymous", siteCode }
|
|
1594
|
+
),
|
|
1595
|
+
enabled: token !== null,
|
|
1596
|
+
fetchPage: (pageNumber) => client.orders.listMine(emporixSdk.auth.customer(token), {
|
|
1597
|
+
pageNumber,
|
|
1598
|
+
...options.pageSize !== void 0 ? { pageSize: options.pageSize } : {},
|
|
1599
|
+
...options.status !== void 0 ? { status: options.status } : {},
|
|
1600
|
+
...effectiveLE !== void 0 ? { legalEntityId: effectiveLE } : {},
|
|
1601
|
+
...siteCode ? { siteCode } : {},
|
|
1602
|
+
...options.saasToken !== void 0 ? { saasToken: options.saasToken } : {}
|
|
1603
|
+
})
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
function useOrder(orderId, options = {}) {
|
|
1607
|
+
const { client, storage } = useEmporix();
|
|
1608
|
+
const token = storage.getCustomerToken();
|
|
1609
|
+
return reactQuery.useQuery({
|
|
1610
|
+
queryKey: emporixKey("orders", [orderId ?? null], {
|
|
1611
|
+
tenant: client.tenant,
|
|
1612
|
+
authKind: token ? "customer" : "anonymous"
|
|
1613
|
+
}),
|
|
1614
|
+
enabled: token !== null && orderId !== void 0,
|
|
1615
|
+
queryFn: () => client.orders.get(
|
|
1616
|
+
orderId,
|
|
1617
|
+
emporixSdk.auth.customer(token),
|
|
1618
|
+
options.saasToken ? { saasToken: options.saasToken } : {}
|
|
1619
|
+
)
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1622
|
+
function useCancelOrder() {
|
|
1623
|
+
const { client, storage } = useEmporix();
|
|
1624
|
+
const qc = reactQuery.useQueryClient();
|
|
1625
|
+
return reactQuery.useMutation({
|
|
1626
|
+
mutationKey: ["emporix", "orders", "cancel"],
|
|
1627
|
+
mutationFn: async (input) => {
|
|
1628
|
+
const token = storage.getCustomerToken();
|
|
1629
|
+
if (!token) throw new Error("useCancelOrder: requires a logged-in customer");
|
|
1630
|
+
const { orderId, saasToken } = typeof input === "string" ? { orderId: input, saasToken: void 0 } : input;
|
|
1631
|
+
await client.orders.cancel(
|
|
1632
|
+
orderId,
|
|
1633
|
+
emporixSdk.auth.customer(token),
|
|
1634
|
+
saasToken ? { saasToken } : {}
|
|
1635
|
+
);
|
|
1636
|
+
},
|
|
1637
|
+
onSuccess: () => qc.invalidateQueries({
|
|
1638
|
+
predicate: (q) => Array.isArray(q.queryKey) && q.queryKey[1] === "orders"
|
|
1639
|
+
})
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
function useOrderTransition() {
|
|
1643
|
+
const { client, storage } = useEmporix();
|
|
1644
|
+
const qc = reactQuery.useQueryClient();
|
|
1645
|
+
return reactQuery.useMutation({
|
|
1646
|
+
mutationKey: ["emporix", "orders", "transition"],
|
|
1647
|
+
mutationFn: async ({ orderId, status, comment, saasToken }) => {
|
|
1648
|
+
const token = storage.getCustomerToken();
|
|
1649
|
+
if (!token) throw new Error("useOrderTransition: requires a logged-in customer");
|
|
1650
|
+
await client.orders.transition(
|
|
1651
|
+
orderId,
|
|
1652
|
+
status,
|
|
1653
|
+
emporixSdk.auth.customer(token),
|
|
1654
|
+
{
|
|
1655
|
+
...comment !== void 0 ? { comment } : {},
|
|
1656
|
+
...saasToken !== void 0 ? { saasToken } : {}
|
|
1657
|
+
}
|
|
1658
|
+
);
|
|
1659
|
+
},
|
|
1660
|
+
onSuccess: () => qc.invalidateQueries({
|
|
1661
|
+
predicate: (q) => Array.isArray(q.queryKey) && q.queryKey[1] === "orders"
|
|
1662
|
+
})
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
function useReorder() {
|
|
1666
|
+
const { client, storage } = useEmporix();
|
|
1667
|
+
const qc = reactQuery.useQueryClient();
|
|
1668
|
+
return reactQuery.useMutation({
|
|
1669
|
+
mutationKey: ["emporix", "orders", "reorder"],
|
|
1670
|
+
mutationFn: async ({ orderId, saasToken }) => {
|
|
1671
|
+
const token = storage.getCustomerToken();
|
|
1672
|
+
if (!token) throw new Error("useReorder: requires a logged-in customer");
|
|
1673
|
+
const ctx = emporixSdk.auth.customer(token);
|
|
1674
|
+
const order = await qc.fetchQuery({
|
|
1675
|
+
queryKey: emporixKey("orders", [orderId], { tenant: client.tenant, authKind: ctx.kind }),
|
|
1676
|
+
queryFn: () => client.orders.get(orderId, ctx, saasToken ? { saasToken } : {})
|
|
1677
|
+
});
|
|
1678
|
+
const cartId = storage.getCartId();
|
|
1679
|
+
if (!cartId) throw new Error("useReorder: no active cart id in storage");
|
|
1680
|
+
if (order.items.length === 0) return { added: 0, errors: [] };
|
|
1681
|
+
const batchBody = order.items.map((item) => ({
|
|
1682
|
+
product: { id: item.productId },
|
|
1683
|
+
quantity: item.quantity
|
|
1684
|
+
}));
|
|
1685
|
+
const res = await client.carts.addItemsBatch(cartId, batchBody, ctx);
|
|
1686
|
+
let added = 0;
|
|
1687
|
+
const errors = [];
|
|
1688
|
+
for (const entry of res) {
|
|
1689
|
+
if (entry.status >= 200 && entry.status < 300) {
|
|
1690
|
+
added += 1;
|
|
1691
|
+
} else {
|
|
1692
|
+
errors.push(
|
|
1693
|
+
new Error(
|
|
1694
|
+
`addItemsBatch entry ${entry.index ?? "?"}: status=${entry.status}${entry.errorMessage ? " " + entry.errorMessage : ""}`
|
|
1695
|
+
)
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
return { added, errors };
|
|
1700
|
+
},
|
|
1701
|
+
onSuccess: () => {
|
|
1702
|
+
qc.invalidateQueries({ predicate: (q) => Array.isArray(q.queryKey) && q.queryKey[1] === "cart" });
|
|
1703
|
+
}
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
function useSalesOrder(orderId, authCtx) {
|
|
1707
|
+
const { client } = useEmporix();
|
|
1708
|
+
return reactQuery.useQuery({
|
|
1709
|
+
queryKey: emporixKey("salesorders", [orderId ?? null], {
|
|
1710
|
+
tenant: client.tenant,
|
|
1711
|
+
authKind: authCtx?.kind ?? "anonymous"
|
|
1712
|
+
}),
|
|
1713
|
+
enabled: orderId !== void 0 && authCtx !== void 0,
|
|
1714
|
+
queryFn: () => client.salesOrders.get(orderId, authCtx)
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
function useUpdateSalesOrder() {
|
|
1718
|
+
const { client } = useEmporix();
|
|
1719
|
+
const qc = reactQuery.useQueryClient();
|
|
1720
|
+
return reactQuery.useMutation({
|
|
1721
|
+
mutationKey: ["emporix", "salesorders", "update"],
|
|
1722
|
+
mutationFn: async ({ orderId, patch, auth: auth23, recalculate }) => {
|
|
1723
|
+
if (!auth23) throw new Error("useUpdateSalesOrder: requires an auth context");
|
|
1724
|
+
return client.salesOrders.update(
|
|
1725
|
+
orderId,
|
|
1726
|
+
patch,
|
|
1727
|
+
auth23,
|
|
1728
|
+
recalculate !== void 0 ? { recalculate } : {}
|
|
1729
|
+
);
|
|
1730
|
+
},
|
|
1731
|
+
onSuccess: (_data, vars) => {
|
|
1732
|
+
qc.invalidateQueries({
|
|
1733
|
+
predicate: (q) => Array.isArray(q.queryKey) && (q.queryKey[1] === "salesorders" || q.queryKey[1] === "orders" && q.queryKey[2] === vars.orderId)
|
|
1734
|
+
});
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
var EmporixErrorBoundary = class extends react.Component {
|
|
1739
|
+
state = { error: null };
|
|
1740
|
+
static getDerivedStateFromError(error) {
|
|
1741
|
+
return { error };
|
|
1742
|
+
}
|
|
1743
|
+
componentDidCatch(error, info) {
|
|
1744
|
+
this.props.onError?.(error, info);
|
|
1745
|
+
}
|
|
1746
|
+
render() {
|
|
1747
|
+
if (this.state.error) return this.props.fallback;
|
|
1748
|
+
return this.props.children;
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1751
|
+
function useEmporixErrorHandler(handlers) {
|
|
1752
|
+
return (error) => {
|
|
1753
|
+
if (error instanceof emporixSdk.EmporixAuthError) handlers.onAuthError?.(error);
|
|
1754
|
+
else if (error instanceof emporixSdk.EmporixError) handlers.onError?.(error);
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
async function prefetchProduct(qc, client, productId, authCtx = emporixSdk.auth.anonymous()) {
|
|
1758
|
+
await qc.prefetchQuery({
|
|
1759
|
+
queryKey: ["emporix", "product", productId, { tenant: client.tenant, authKind: authCtx.kind }],
|
|
1760
|
+
queryFn: () => client.products.get(productId, void 0, authCtx)
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
async function prefetchCart(qc, client, cartId, authCtx) {
|
|
1764
|
+
await qc.prefetchQuery({
|
|
1765
|
+
queryKey: ["emporix", "cart", cartId, { tenant: client.tenant, authKind: authCtx.kind }],
|
|
1766
|
+
queryFn: () => client.carts.get(cartId, authCtx)
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
async function prefetchOrder(qc, client, orderId, authCtx, opts = {}) {
|
|
1770
|
+
await qc.prefetchQuery({
|
|
1771
|
+
queryKey: ["emporix", "orders", orderId, { tenant: client.tenant, authKind: authCtx.kind }],
|
|
1772
|
+
queryFn: () => client.orders.get(orderId, authCtx, opts.saasToken ? { saasToken: opts.saasToken } : {})
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
exports.CompanyContextProvider = CompanyContextProvider;
|
|
1777
|
+
exports.EmporixCompanyContext = EmporixCompanyContext;
|
|
1778
|
+
exports.EmporixErrorBoundary = EmporixErrorBoundary;
|
|
1779
|
+
exports.EmporixProvider = EmporixProvider;
|
|
1780
|
+
exports.createCookieStorage = createCookieStorage;
|
|
1781
|
+
exports.createLocalStorageStorage = createLocalStorageStorage;
|
|
1782
|
+
exports.createMemoryStorage = createMemoryStorage;
|
|
1783
|
+
exports.prefetchCart = prefetchCart;
|
|
1784
|
+
exports.prefetchOrder = prefetchOrder;
|
|
1785
|
+
exports.prefetchProduct = prefetchProduct;
|
|
1786
|
+
exports.useActiveCart = useActiveCart;
|
|
1787
|
+
exports.useActiveCompany = useActiveCompany;
|
|
1788
|
+
exports.useAddressMutations = useAddressMutations;
|
|
1789
|
+
exports.useAssignContact = useAssignContact;
|
|
1790
|
+
exports.useCancelOrder = useCancelOrder;
|
|
1791
|
+
exports.useCart = useCart;
|
|
1792
|
+
exports.useCartMutations = useCartMutations;
|
|
1793
|
+
exports.useCategories = useCategories;
|
|
1794
|
+
exports.useCategoriesInfinite = useCategoriesInfinite;
|
|
1795
|
+
exports.useCategory = useCategory;
|
|
1796
|
+
exports.useCategoryTree = useCategoryTree;
|
|
1797
|
+
exports.useChangePassword = useChangePassword;
|
|
1798
|
+
exports.useCheckout = useCheckout;
|
|
1799
|
+
exports.useCompany = useCompany;
|
|
1800
|
+
exports.useCompanyContacts = useCompanyContacts;
|
|
1801
|
+
exports.useCompanyGroups = useCompanyGroups;
|
|
1802
|
+
exports.useCompanyLocations = useCompanyLocations;
|
|
1803
|
+
exports.useCompanySwitcher = useCompanySwitcher;
|
|
1804
|
+
exports.useCreateCart = useCreateCart;
|
|
1805
|
+
exports.useCreateCompany = useCreateCompany;
|
|
1806
|
+
exports.useCreateLocation = useCreateLocation;
|
|
1807
|
+
exports.useCustomerAddresses = useCustomerAddresses;
|
|
1808
|
+
exports.useCustomerSession = useCustomerSession;
|
|
1809
|
+
exports.useDefaultSite = useDefaultSite;
|
|
1810
|
+
exports.useDeleteCompany = useDeleteCompany;
|
|
1811
|
+
exports.useDeleteLocation = useDeleteLocation;
|
|
1812
|
+
exports.useEmporix = useEmporix;
|
|
1813
|
+
exports.useEmporixErrorHandler = useEmporixErrorHandler;
|
|
1814
|
+
exports.useEmporixTelemetry = useEmporixTelemetry;
|
|
1815
|
+
exports.useMatchPrices = useMatchPrices;
|
|
1816
|
+
exports.useMyCompanies = useMyCompanies;
|
|
1817
|
+
exports.useMyOrders = useMyOrders;
|
|
1818
|
+
exports.useMyOrdersInfinite = useMyOrdersInfinite;
|
|
1819
|
+
exports.useMySegmentCategories = useMySegmentCategories;
|
|
1820
|
+
exports.useMySegmentCategoriesInfinite = useMySegmentCategoriesInfinite;
|
|
1821
|
+
exports.useMySegmentCategoryTree = useMySegmentCategoryTree;
|
|
1822
|
+
exports.useMySegmentItems = useMySegmentItems;
|
|
1823
|
+
exports.useMySegmentProducts = useMySegmentProducts;
|
|
1824
|
+
exports.useMySegmentProductsInfinite = useMySegmentProductsInfinite;
|
|
1825
|
+
exports.useMySegments = useMySegments;
|
|
1826
|
+
exports.useOrder = useOrder;
|
|
1827
|
+
exports.useOrderTransition = useOrderTransition;
|
|
1828
|
+
exports.usePasswordReset = usePasswordReset;
|
|
1829
|
+
exports.usePaymentModes = usePaymentModes;
|
|
1830
|
+
exports.useProduct = useProduct;
|
|
1831
|
+
exports.useProductByCode = useProductByCode;
|
|
1832
|
+
exports.useProductMedia = useProductMedia;
|
|
1833
|
+
exports.useProductSearch = useProductSearch;
|
|
1834
|
+
exports.useProducts = useProducts;
|
|
1835
|
+
exports.useProductsInCategory = useProductsInCategory;
|
|
1836
|
+
exports.useProductsInCategoryInfinite = useProductsInCategoryInfinite;
|
|
1837
|
+
exports.useProductsInfinite = useProductsInfinite;
|
|
1838
|
+
exports.useReorder = useReorder;
|
|
1839
|
+
exports.useSalesOrder = useSalesOrder;
|
|
1840
|
+
exports.useSiteContext = useSiteContext;
|
|
1841
|
+
exports.useSites = useSites;
|
|
1842
|
+
exports.useUnassignContact = useUnassignContact;
|
|
1843
|
+
exports.useUpdateCompany = useUpdateCompany;
|
|
1844
|
+
exports.useUpdateContactAssignment = useUpdateContactAssignment;
|
|
1845
|
+
exports.useUpdateCustomer = useUpdateCustomer;
|
|
1846
|
+
exports.useUpdateLocation = useUpdateLocation;
|
|
1847
|
+
exports.useUpdateSalesOrder = useUpdateSalesOrder;
|
|
1848
|
+
//# sourceMappingURL=index.cjs.map
|
|
1849
|
+
//# sourceMappingURL=index.cjs.map
|