@viu/emporix-sdk 2.14.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/availability.cjs +1 -0
- package/dist/availability.cjs.map +1 -1
- package/dist/availability.d.cts +1 -0
- package/dist/availability.d.ts +1 -0
- package/dist/availability.js +1 -1
- package/dist/cart.cjs +1 -0
- package/dist/cart.cjs.map +1 -1
- package/dist/cart.d.cts +1 -0
- package/dist/cart.d.ts +1 -0
- package/dist/cart.js +1 -1
- package/dist/category.cjs +1 -0
- package/dist/category.cjs.map +1 -1
- package/dist/category.d.cts +1 -0
- package/dist/category.d.ts +1 -0
- package/dist/category.js +1 -1
- package/dist/checkout.cjs +1 -0
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +1 -0
- package/dist/checkout.d.ts +1 -0
- package/dist/checkout.js +1 -1
- package/dist/{chunk-LGOC5XOI.js → chunk-3BTPX7IJ.js} +3 -2
- package/dist/chunk-3BTPX7IJ.js.map +1 -0
- package/dist/{chunk-MIUVJEGR.js → chunk-5VTBLBXJ.js} +3 -2
- package/dist/chunk-5VTBLBXJ.js.map +1 -0
- package/dist/{chunk-WW3H7VJ5.js → chunk-62PCCHZ2.js} +4 -2
- package/dist/chunk-62PCCHZ2.js.map +1 -0
- package/dist/{chunk-BDFOD7W3.js → chunk-A3LYJUD4.js} +3 -2
- package/dist/chunk-A3LYJUD4.js.map +1 -0
- package/dist/{chunk-MM6JF3Z7.js → chunk-BNX3JULF.js} +3 -2
- package/dist/chunk-BNX3JULF.js.map +1 -0
- package/dist/{chunk-LGLFJL3S.js → chunk-DUVIIWFG.js} +3 -2
- package/dist/chunk-DUVIIWFG.js.map +1 -0
- package/dist/{chunk-HAEVK6IS.js → chunk-EAWGUZHS.js} +3 -2
- package/dist/chunk-EAWGUZHS.js.map +1 -0
- package/dist/{chunk-WWCCB22A.js → chunk-GIZS4BY3.js} +3 -2
- package/dist/chunk-GIZS4BY3.js.map +1 -0
- package/dist/{chunk-BPVMQFO4.js → chunk-K3VQLW3P.js} +3 -2
- package/dist/chunk-K3VQLW3P.js.map +1 -0
- package/dist/{chunk-CR2JRH7T.js → chunk-NE7MIZPR.js} +4 -2
- package/dist/chunk-NE7MIZPR.js.map +1 -0
- package/dist/{chunk-UOBOFCFU.js → chunk-NEXUWPHW.js} +3 -2
- package/dist/chunk-NEXUWPHW.js.map +1 -0
- package/dist/{chunk-FU5WQALW.js → chunk-OTG2S2L4.js} +3 -2
- package/dist/chunk-OTG2S2L4.js.map +1 -0
- package/dist/{chunk-P3UHYMDH.js → chunk-PAT4CS36.js} +3 -2
- package/dist/chunk-PAT4CS36.js.map +1 -0
- package/dist/chunk-PYLWZZC4.js +280 -0
- package/dist/chunk-PYLWZZC4.js.map +1 -0
- package/dist/{chunk-XG2TKFY5.js → chunk-RYQVMR26.js} +3 -2
- package/dist/chunk-RYQVMR26.js.map +1 -0
- package/dist/companies.cjs +1 -0
- package/dist/companies.cjs.map +1 -1
- package/dist/companies.d.cts +1 -0
- package/dist/companies.d.ts +1 -0
- package/dist/companies.js +1 -1
- package/dist/contacts.cjs +1 -0
- package/dist/contacts.cjs.map +1 -1
- package/dist/contacts.d.cts +1 -0
- package/dist/contacts.d.ts +1 -0
- package/dist/contacts.js +1 -1
- package/dist/customer-groups.cjs +1 -0
- package/dist/customer-groups.cjs.map +1 -1
- package/dist/customer-groups.d.cts +1 -0
- package/dist/customer-groups.d.ts +1 -0
- package/dist/customer-groups.js +1 -1
- package/dist/customer.cjs +1 -0
- package/dist/customer.cjs.map +1 -1
- package/dist/customer.d.cts +1 -0
- package/dist/customer.d.ts +1 -0
- package/dist/customer.js +1 -1
- package/dist/index.cjs +219 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -4
- package/dist/index.d.ts +76 -4
- package/dist/index.js +210 -377
- package/dist/index.js.map +1 -1
- package/dist/locations.cjs +1 -0
- package/dist/locations.cjs.map +1 -1
- package/dist/locations.d.cts +1 -0
- package/dist/locations.d.ts +1 -0
- package/dist/locations.js +1 -1
- package/dist/media.cjs +1 -0
- package/dist/media.cjs.map +1 -1
- package/dist/media.d.cts +1 -0
- package/dist/media.d.ts +1 -0
- package/dist/media.js +1 -1
- package/dist/orders.cjs +2 -0
- package/dist/orders.cjs.map +1 -1
- package/dist/orders.d.cts +2 -0
- package/dist/orders.d.ts +2 -0
- package/dist/orders.js +1 -1
- package/dist/payment.cjs +25 -7
- package/dist/payment.cjs.map +1 -1
- package/dist/payment.d.cts +8 -3
- package/dist/payment.d.ts +8 -3
- package/dist/payment.js +1 -1
- package/dist/price.cjs +1 -0
- package/dist/price.cjs.map +1 -1
- package/dist/price.d.cts +1 -0
- package/dist/price.d.ts +1 -0
- package/dist/price.js +1 -1
- package/dist/product.cjs +1 -0
- package/dist/product.cjs.map +1 -1
- package/dist/product.d.cts +1 -0
- package/dist/product.d.ts +1 -0
- package/dist/product.js +1 -1
- package/dist/segment.cjs +2 -0
- package/dist/segment.cjs.map +1 -1
- package/dist/segment.d.cts +2 -0
- package/dist/segment.d.ts +2 -0
- package/dist/segment.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-BDFOD7W3.js.map +0 -1
- package/dist/chunk-BPVMQFO4.js.map +0 -1
- package/dist/chunk-CR2JRH7T.js.map +0 -1
- package/dist/chunk-EINAVCV2.js +0 -30
- package/dist/chunk-EINAVCV2.js.map +0 -1
- package/dist/chunk-FU5WQALW.js.map +0 -1
- package/dist/chunk-HAEVK6IS.js.map +0 -1
- package/dist/chunk-LGLFJL3S.js.map +0 -1
- package/dist/chunk-LGOC5XOI.js.map +0 -1
- package/dist/chunk-MIUVJEGR.js.map +0 -1
- package/dist/chunk-MM6JF3Z7.js.map +0 -1
- package/dist/chunk-P3UHYMDH.js.map +0 -1
- package/dist/chunk-UOBOFCFU.js.map +0 -1
- package/dist/chunk-WW3H7VJ5.js.map +0 -1
- package/dist/chunk-WWCCB22A.js.map +0 -1
- package/dist/chunk-XG2TKFY5.js.map +0 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { requireCustomer } from './chunk-3BDDYX3V.js';
|
|
2
|
+
import { EmporixAuthError, EmporixTimeoutError, EmporixNetworkError } from './chunk-UWGGF4MC.js';
|
|
3
|
+
|
|
4
|
+
// src/core/auth.ts
|
|
5
|
+
var auth = {
|
|
6
|
+
/** Service/custom credential set (default `backend`). */
|
|
7
|
+
service: (credentials) => credentials === void 0 ? { kind: "service" } : { kind: "service", credentials },
|
|
8
|
+
/** Cached anonymous storefront token. */
|
|
9
|
+
anonymous: () => ({ kind: "anonymous" }),
|
|
10
|
+
/** Caller-owned customer bearer token. */
|
|
11
|
+
customer: (token) => ({ kind: "customer", token }),
|
|
12
|
+
/** Exact token, no transformation (SSO / token-exchange). */
|
|
13
|
+
raw: (token) => ({ kind: "raw", token })
|
|
14
|
+
};
|
|
15
|
+
async function resolveToken(ctx, provider) {
|
|
16
|
+
switch (ctx.kind) {
|
|
17
|
+
case "service":
|
|
18
|
+
return provider.getToken(ctx.credentials ?? "backend");
|
|
19
|
+
case "anonymous":
|
|
20
|
+
return (await provider.getAnonymousToken()).accessToken;
|
|
21
|
+
case "customer":
|
|
22
|
+
case "raw":
|
|
23
|
+
return ctx.token;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
var CustomerRefreshRegistry = class {
|
|
27
|
+
refresher = null;
|
|
28
|
+
inflight = null;
|
|
29
|
+
set(refresher) {
|
|
30
|
+
this.refresher = refresher;
|
|
31
|
+
}
|
|
32
|
+
get enabled() {
|
|
33
|
+
return this.refresher !== null;
|
|
34
|
+
}
|
|
35
|
+
/** Concurrent callers share one in-flight refresh. */
|
|
36
|
+
refresh(expiredToken) {
|
|
37
|
+
if (!this.refresher) return Promise.resolve(null);
|
|
38
|
+
if (this.inflight) return this.inflight;
|
|
39
|
+
const p = Promise.resolve(this.refresher.refresh(expiredToken)).finally(() => {
|
|
40
|
+
this.inflight = null;
|
|
41
|
+
});
|
|
42
|
+
this.inflight = p;
|
|
43
|
+
return p;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var DefaultTokenProvider = class {
|
|
47
|
+
constructor(cfg) {
|
|
48
|
+
this.cfg = cfg;
|
|
49
|
+
}
|
|
50
|
+
cfg;
|
|
51
|
+
serviceCache = /* @__PURE__ */ new Map();
|
|
52
|
+
serviceLocks = /* @__PURE__ */ new Map();
|
|
53
|
+
anon;
|
|
54
|
+
anonLock;
|
|
55
|
+
anonStore;
|
|
56
|
+
contextOverride;
|
|
57
|
+
refreshListeners = /* @__PURE__ */ new Set();
|
|
58
|
+
onRefresh(listener) {
|
|
59
|
+
this.refreshListeners.add(listener);
|
|
60
|
+
return () => {
|
|
61
|
+
this.refreshListeners.delete(listener);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
notifyRefresh(kind, success) {
|
|
65
|
+
for (const l of this.refreshListeners) {
|
|
66
|
+
try {
|
|
67
|
+
l({ kind, success });
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
attachAnonymousStore(store) {
|
|
73
|
+
this.anonStore = store;
|
|
74
|
+
if (!this.anon) {
|
|
75
|
+
const persisted = store.read();
|
|
76
|
+
if (persisted) {
|
|
77
|
+
this.anon = {
|
|
78
|
+
accessToken: "",
|
|
79
|
+
refreshToken: persisted.refreshToken,
|
|
80
|
+
sessionId: persisted.sessionId,
|
|
81
|
+
expiresIn: 0,
|
|
82
|
+
expiresAt: 0
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
creds(set) {
|
|
88
|
+
if (set === "backend") {
|
|
89
|
+
const b = this.cfg.credentials.backend;
|
|
90
|
+
if (!b?.clientId || !b.secret) {
|
|
91
|
+
throw new EmporixAuthError(
|
|
92
|
+
"A 'service' AuthContext was used but credentials.backend is not configured"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return b;
|
|
96
|
+
}
|
|
97
|
+
const c = this.cfg.credentials.custom?.[set];
|
|
98
|
+
if (!c) throw new Error(`Unknown credential set "${set}"`);
|
|
99
|
+
return c;
|
|
100
|
+
}
|
|
101
|
+
fresh(e) {
|
|
102
|
+
if (!e) return false;
|
|
103
|
+
const now = Date.now();
|
|
104
|
+
if (now - e.obtainedAt >= this.cfg.cache.maxLifetimeSeconds * 1e3) return false;
|
|
105
|
+
return now < e.expiresAt;
|
|
106
|
+
}
|
|
107
|
+
async getToken(set) {
|
|
108
|
+
this.creds(set);
|
|
109
|
+
const cached = this.serviceCache.get(set);
|
|
110
|
+
if (this.fresh(cached)) return cached.token;
|
|
111
|
+
const inflight = this.serviceLocks.get(set);
|
|
112
|
+
if (inflight) return inflight;
|
|
113
|
+
const p = this.requestServiceToken(set).finally(() => this.serviceLocks.delete(set));
|
|
114
|
+
this.serviceLocks.set(set, p);
|
|
115
|
+
return p;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* fetch with the configured read timeout. Token endpoints sit in front of
|
|
119
|
+
* single-flight locks — one hung call would otherwise block every request
|
|
120
|
+
* on this credential set forever.
|
|
121
|
+
*/
|
|
122
|
+
async boundedFetch(url, init = {}) {
|
|
123
|
+
const ms = this.cfg.timeouts?.readMs ?? 6e4;
|
|
124
|
+
const controller = new AbortController();
|
|
125
|
+
const timer = setTimeout(() => controller.abort(), ms);
|
|
126
|
+
try {
|
|
127
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (err.name === "AbortError") {
|
|
130
|
+
throw new EmporixTimeoutError(`token request timed out after ${ms}ms`);
|
|
131
|
+
}
|
|
132
|
+
throw new EmporixNetworkError(`token request network failure: ${err.message}`);
|
|
133
|
+
} finally {
|
|
134
|
+
clearTimeout(timer);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async requestServiceToken(set) {
|
|
138
|
+
const c = this.creds(set);
|
|
139
|
+
const body = new URLSearchParams({
|
|
140
|
+
grant_type: "client_credentials",
|
|
141
|
+
client_id: c.clientId,
|
|
142
|
+
client_secret: c.secret
|
|
143
|
+
});
|
|
144
|
+
if (c.scope) body.set("scope", c.scope);
|
|
145
|
+
const res = await this.boundedFetch(`${this.cfg.host}/oauth/token`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
148
|
+
body
|
|
149
|
+
});
|
|
150
|
+
const json = await res.json().catch(() => ({}));
|
|
151
|
+
if (!res.ok) {
|
|
152
|
+
throw new EmporixAuthError(`Token request failed for "${set}"`, res.status, json);
|
|
153
|
+
}
|
|
154
|
+
const obtainedAt = Date.now();
|
|
155
|
+
const ttl = Number(json.expires_in ?? 3600);
|
|
156
|
+
this.serviceCache.set(set, {
|
|
157
|
+
token: json.access_token,
|
|
158
|
+
obtainedAt,
|
|
159
|
+
expiresAt: obtainedAt + (ttl - this.cfg.cache.expirationBufferSeconds) * 1e3
|
|
160
|
+
});
|
|
161
|
+
return this.serviceCache.get(set).token;
|
|
162
|
+
}
|
|
163
|
+
invalidate(set) {
|
|
164
|
+
this.serviceCache.delete(set);
|
|
165
|
+
}
|
|
166
|
+
anonFresh() {
|
|
167
|
+
return !!this.anon && Date.now() < this.anon.expiresAt;
|
|
168
|
+
}
|
|
169
|
+
async getAnonymousToken() {
|
|
170
|
+
if (this.anonFresh()) return this.stripExpiry(this.anon);
|
|
171
|
+
if (this.anonLock) return this.anonLock;
|
|
172
|
+
const canRefresh = !!this.anon?.refreshToken;
|
|
173
|
+
const obtain = canRefresh ? this.fetchAnonymous("refresh").catch(() => this.fetchAnonymous("login")) : this.fetchAnonymous("login");
|
|
174
|
+
const p = obtain.finally(() => {
|
|
175
|
+
this.anonLock = void 0;
|
|
176
|
+
});
|
|
177
|
+
this.anonLock = p;
|
|
178
|
+
return p;
|
|
179
|
+
}
|
|
180
|
+
/** Refreshes the anonymous session, preserving its sessionId. */
|
|
181
|
+
async refreshAnonymous() {
|
|
182
|
+
if (!this.anon) return this.getAnonymousToken();
|
|
183
|
+
return this.fetchAnonymous("refresh");
|
|
184
|
+
}
|
|
185
|
+
invalidateAnonymous() {
|
|
186
|
+
this.anon = void 0;
|
|
187
|
+
this.anonStore?.write(null);
|
|
188
|
+
}
|
|
189
|
+
setAnonymousContext(ctx) {
|
|
190
|
+
const base = this.contextOverride ?? this.cfg.credentials.storefront?.context ?? {};
|
|
191
|
+
this.contextOverride = { ...base, ...ctx };
|
|
192
|
+
this.invalidateAnonymous();
|
|
193
|
+
}
|
|
194
|
+
/** Force a stale access token while keeping the refresh token + sessionId. */
|
|
195
|
+
expireAnonymous() {
|
|
196
|
+
if (this.anon) this.anon = { ...this.anon, expiresAt: 0 };
|
|
197
|
+
}
|
|
198
|
+
stripExpiry(s) {
|
|
199
|
+
const { expiresAt: _expiresAt, ...rest } = s;
|
|
200
|
+
return rest;
|
|
201
|
+
}
|
|
202
|
+
async fetchAnonymous(mode) {
|
|
203
|
+
const sf = this.cfg.credentials.storefront;
|
|
204
|
+
if (!sf?.clientId) {
|
|
205
|
+
throw new Error("credentials.storefront.clientId is required for anonymous tokens");
|
|
206
|
+
}
|
|
207
|
+
const url = new URL(`${this.cfg.host}/customerlogin/auth/anonymous/${mode}`);
|
|
208
|
+
url.searchParams.set("tenant", this.cfg.tenant);
|
|
209
|
+
url.searchParams.set("client_id", sf.clientId);
|
|
210
|
+
const c = this.contextOverride ?? sf.context;
|
|
211
|
+
if (c?.currency) url.searchParams.set("currency", c.currency);
|
|
212
|
+
if (c?.siteCode) url.searchParams.set("siteCode", c.siteCode);
|
|
213
|
+
if (c?.targetLocation) url.searchParams.set("targetLocation", c.targetLocation);
|
|
214
|
+
if (mode === "refresh" && this.anon) {
|
|
215
|
+
url.searchParams.set("refresh_token", this.anon.refreshToken);
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
const res = await this.boundedFetch(url, { method: "GET" });
|
|
219
|
+
const json = await res.json().catch(() => ({}));
|
|
220
|
+
if (!res.ok) {
|
|
221
|
+
this.notifyRefresh("anonymous", false);
|
|
222
|
+
throw new EmporixAuthError(`Anonymous token ${mode} failed`, res.status, json);
|
|
223
|
+
}
|
|
224
|
+
const obtainedAt = Date.now();
|
|
225
|
+
this.anon = {
|
|
226
|
+
accessToken: json.access_token,
|
|
227
|
+
refreshToken: json.refresh_token,
|
|
228
|
+
sessionId: json.sessionId,
|
|
229
|
+
expiresIn: json.expires_in,
|
|
230
|
+
expiresAt: obtainedAt + (json.expires_in - this.cfg.cache.expirationBufferSeconds) * 1e3
|
|
231
|
+
};
|
|
232
|
+
this.anonStore?.write({
|
|
233
|
+
refreshToken: this.anon.refreshToken,
|
|
234
|
+
sessionId: this.anon.sessionId
|
|
235
|
+
});
|
|
236
|
+
this.notifyRefresh("anonymous", true);
|
|
237
|
+
return this.stripExpiry(this.anon);
|
|
238
|
+
} catch (err) {
|
|
239
|
+
if (!(err instanceof EmporixAuthError)) {
|
|
240
|
+
this.notifyRefresh("anonymous", false);
|
|
241
|
+
}
|
|
242
|
+
throw err;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// src/services/payment.ts
|
|
248
|
+
var ANON = auth.anonymous();
|
|
249
|
+
var PaymentGatewayService = class {
|
|
250
|
+
constructor(ctx) {
|
|
251
|
+
this.ctx = ctx;
|
|
252
|
+
}
|
|
253
|
+
ctx;
|
|
254
|
+
static channel = "payment";
|
|
255
|
+
/**
|
|
256
|
+
* Lists configured frontend payment modes. The endpoint requires a bearer
|
|
257
|
+
* token but no customer scope ("No scope required"), so it defaults to an
|
|
258
|
+
* anonymous context and works for guests and logged-in customers alike.
|
|
259
|
+
*/
|
|
260
|
+
async listPaymentModes(authCtx = ANON) {
|
|
261
|
+
return this.ctx.http.request({
|
|
262
|
+
method: "GET",
|
|
263
|
+
path: `/payment-gateway/${this.ctx.tenant}/paymentmodes/frontend`,
|
|
264
|
+
auth: authCtx
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/** Authorizes a post-checkout (deferred) payment for an existing order. */
|
|
268
|
+
async authorize(input, authCtx) {
|
|
269
|
+
return this.ctx.http.request({
|
|
270
|
+
method: "POST",
|
|
271
|
+
path: `/payment-gateway/${this.ctx.tenant}/payment/frontend/authorize`,
|
|
272
|
+
auth: requireCustomer(authCtx),
|
|
273
|
+
body: input
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export { CustomerRefreshRegistry, DefaultTokenProvider, PaymentGatewayService, auth, resolveToken };
|
|
279
|
+
//# sourceMappingURL=chunk-PYLWZZC4.js.map
|
|
280
|
+
//# sourceMappingURL=chunk-PYLWZZC4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/auth.ts","../src/services/payment.ts"],"names":[],"mappings":"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","file":"chunk-PYLWZZC4.js","sourcesContent":["import type { ResolvedConfig, ServiceCredentials } from \"./config\";\nimport { EmporixAuthError, EmporixTimeoutError, EmporixNetworkError } from \"./errors\";\n\n/** Which token a call should use. */\nexport type AuthKind = \"service\" | \"customer\" | \"anonymous\" | \"raw\";\n\n/** Caller-supplied, per-call auth selector. Never stored on the client. */\nexport type AuthContext =\n | { kind: \"service\"; credentials?: string }\n | { kind: \"anonymous\" }\n | { kind: \"customer\"; token: string }\n | { kind: \"raw\"; token: string };\n\n/**\n * Supplies a fresh customer token when a `customer`-kind request 401s. The host\n * (e.g. EmporixProvider) implements this; the SDK never refreshes the\n * caller-owned customer token unless a refresher is registered.\n */\nexport interface CustomerTokenRefresher {\n /**\n * Called on a `customer`-kind 401. Receives the token that just failed;\n * returns a fresh customer token to retry with, or `null` to give up (the\n * 401 then propagates as EmporixAuthError).\n */\n refresh(expiredToken: string): Promise<string | null>;\n}\n\n/** An obtained anonymous storefront session. */\nexport interface AnonymousSession {\n accessToken: string;\n refreshToken: string;\n sessionId: string;\n expiresIn: number;\n}\n\n/**\n * Persistence callback for anonymous sessions. `read` is called once on the\n * first need for an anonymous token to bootstrap a possibly-existing session;\n * `write` is called after every successful login or refresh. `write(null)`\n * means the SDK is invalidating the stored session.\n */\nexport interface AnonymousSessionStore {\n read(): { refreshToken: string; sessionId: string } | null;\n write(session: { refreshToken: string; sessionId: string } | null): void;\n}\n\n/** Supplies SDK-managed tokens (service/custom + anonymous). May be user-injected. */\nexport interface TokenProvider {\n /** Service/custom client-credentials token for the named credential set. */\n getToken(credentialSet: string): Promise<string>;\n /** Cached anonymous storefront session (preserves sessionId across refreshes). */\n getAnonymousToken(): Promise<AnonymousSession>;\n /** Refresh the anonymous session, preserving sessionId. */\n refreshAnonymous?(): Promise<AnonymousSession>;\n /** Invalidate a cached SDK-managed token so the next call re-auths. */\n invalidate?(credentialSet: string): void;\n /** Invalidate the cached anonymous session entirely (next call re-logs in). */\n invalidateAnonymous?(): void;\n /**\n * Mark the anonymous access token stale but keep the refresh token, so the\n * next {@link getAnonymousToken} refreshes (preserving sessionId) rather\n * than starting a brand-new session.\n */\n expireAnonymous?(): void;\n /**\n * Install a persistence adapter for the anonymous session. The host (e.g.\n * `EmporixProvider`) calls this at construction so the SDK can bootstrap\n * an existing session and persist refreshes. Idempotent: a later call\n * replaces the previous adapter.\n */\n attachAnonymousStore?(store: AnonymousSessionStore): void;\n /**\n * Override the storefront context (currency/site/country) used for the next\n * anonymous login, then invalidate the current anonymous session so it\n * re-mints with the new context. No-op for providers without anon support.\n */\n setAnonymousContext?(ctx: {\n currency?: string;\n siteCode?: string;\n targetLocation?: string;\n }): void;\n /**\n * Subscribe to token-refresh events. Optional — implementations may no-op.\n * Returns an unsubscribe function. `DefaultTokenProvider` emits for the\n * anonymous-login / anonymous-refresh paths.\n */\n onRefresh?(\n listener: (event: { kind: \"anonymous\" | \"customer\"; success: boolean }) => void,\n ): () => void;\n}\n\n/** Tiny constructors for {@link AuthContext}. */\nexport const auth = {\n /** Service/custom credential set (default `backend`). */\n service: (credentials?: string): AuthContext =>\n credentials === undefined ? { kind: \"service\" } : { kind: \"service\", credentials },\n /** Cached anonymous storefront token. */\n anonymous: (): AuthContext => ({ kind: \"anonymous\" }),\n /** Caller-owned customer bearer token. */\n customer: (token: string): AuthContext => ({ kind: \"customer\", token }),\n /** Exact token, no transformation (SSO / token-exchange). */\n raw: (token: string): AuthContext => ({ kind: \"raw\", token }),\n};\n\n/** Resolves an {@link AuthContext} to a concrete bearer token. */\nexport async function resolveToken(ctx: AuthContext, provider: TokenProvider): Promise<string> {\n switch (ctx.kind) {\n case \"service\":\n return provider.getToken(ctx.credentials ?? \"backend\");\n case \"anonymous\":\n return (await provider.getAnonymousToken()).accessToken;\n case \"customer\":\n case \"raw\":\n return ctx.token;\n }\n}\n\n/**\n * Late-bindable, single-flight holder for an optional\n * {@link CustomerTokenRefresher}. Single-flight is required because Emporix\n * rotates the refresh token on each refresh — concurrent refreshes would\n * invalidate each other. Off (returns `null`) until a refresher is set.\n */\nexport class CustomerRefreshRegistry {\n private refresher: CustomerTokenRefresher | null = null;\n private inflight: Promise<string | null> | null = null;\n\n set(refresher: CustomerTokenRefresher | null): void {\n this.refresher = refresher;\n }\n\n get enabled(): boolean {\n return this.refresher !== null;\n }\n\n /** Concurrent callers share one in-flight refresh. */\n refresh(expiredToken: string): Promise<string | null> {\n if (!this.refresher) return Promise.resolve(null);\n if (this.inflight) return this.inflight;\n const p = Promise.resolve(this.refresher.refresh(expiredToken)).finally(() => {\n this.inflight = null;\n });\n this.inflight = p;\n return p;\n }\n}\n\ninterface CacheEntry {\n token: string;\n expiresAt: number;\n obtainedAt: number;\n}\n\n/** SDK-owned token provider: client-credentials service tokens + anonymous session. */\nexport class DefaultTokenProvider implements TokenProvider {\n private readonly serviceCache = new Map<string, CacheEntry>();\n private readonly serviceLocks = new Map<string, Promise<string>>();\n private anon: (AnonymousSession & { expiresAt: number }) | undefined;\n private anonLock: Promise<AnonymousSession> | undefined;\n private anonStore?: AnonymousSessionStore;\n private contextOverride:\n | { currency?: string; siteCode?: string; targetLocation?: string }\n | undefined;\n private readonly refreshListeners = new Set<\n (event: { kind: \"anonymous\" | \"customer\"; success: boolean }) => void\n >();\n\n constructor(private readonly cfg: ResolvedConfig) {}\n\n onRefresh(\n listener: (event: { kind: \"anonymous\" | \"customer\"; success: boolean }) => void,\n ): () => void {\n this.refreshListeners.add(listener);\n return () => {\n this.refreshListeners.delete(listener);\n };\n }\n\n private notifyRefresh(kind: \"anonymous\" | \"customer\", success: boolean): void {\n for (const l of this.refreshListeners) {\n try {\n l({ kind, success });\n } catch {\n // Never let a telemetry listener break the auth path.\n }\n }\n }\n\n attachAnonymousStore(store: AnonymousSessionStore): void {\n this.anonStore = store;\n // Bootstrap `this.anon` from the store if we don't have it yet. The seeded\n // session has expiresAt = 0 so the next getAnonymousToken triggers a refresh\n // (which preserves sessionId) instead of a fresh login.\n if (!this.anon) {\n const persisted = store.read();\n if (persisted) {\n this.anon = {\n accessToken: \"\",\n refreshToken: persisted.refreshToken,\n sessionId: persisted.sessionId,\n expiresIn: 0,\n expiresAt: 0,\n };\n }\n }\n }\n\n private creds(set: string): ServiceCredentials {\n if (set === \"backend\") {\n const b = this.cfg.credentials.backend;\n if (!b?.clientId || !b.secret) {\n throw new EmporixAuthError(\n \"A 'service' AuthContext was used but credentials.backend is not configured\",\n );\n }\n return b;\n }\n const c = this.cfg.credentials.custom?.[set];\n if (!c) throw new Error(`Unknown credential set \"${set}\"`);\n return c;\n }\n\n private fresh(e: CacheEntry | undefined): boolean {\n if (!e) return false;\n const now = Date.now();\n if (now - e.obtainedAt >= this.cfg.cache.maxLifetimeSeconds * 1000) return false;\n return now < e.expiresAt;\n }\n\n async getToken(set: string): Promise<string> {\n // Surface an unknown credential set before entering the cache/lock path.\n this.creds(set);\n const cached = this.serviceCache.get(set);\n if (this.fresh(cached)) return cached!.token;\n const inflight = this.serviceLocks.get(set);\n if (inflight) return inflight;\n const p = this.requestServiceToken(set).finally(() => this.serviceLocks.delete(set));\n this.serviceLocks.set(set, p);\n return p;\n }\n\n /**\n * fetch with the configured read timeout. Token endpoints sit in front of\n * single-flight locks — one hung call would otherwise block every request\n * on this credential set forever.\n */\n private async boundedFetch(url: string | URL, init: RequestInit = {}): Promise<Response> {\n const ms = this.cfg.timeouts?.readMs ?? 60_000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), ms);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n throw new EmporixTimeoutError(`token request timed out after ${ms}ms`);\n }\n throw new EmporixNetworkError(`token request network failure: ${(err as Error).message}`);\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async requestServiceToken(set: string): Promise<string> {\n const c = this.creds(set);\n const body = new URLSearchParams({\n grant_type: \"client_credentials\",\n client_id: c.clientId,\n client_secret: c.secret,\n });\n if (c.scope) body.set(\"scope\", c.scope);\n const res = await this.boundedFetch(`${this.cfg.host}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body,\n });\n const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n throw new EmporixAuthError(`Token request failed for \"${set}\"`, res.status, json);\n }\n const obtainedAt = Date.now();\n const ttl = Number((json.expires_in as number | undefined) ?? 3600);\n this.serviceCache.set(set, {\n token: json.access_token as string,\n obtainedAt,\n expiresAt: obtainedAt + (ttl - this.cfg.cache.expirationBufferSeconds) * 1000,\n });\n return this.serviceCache.get(set)!.token;\n }\n\n invalidate(set: string): void {\n this.serviceCache.delete(set);\n }\n\n private anonFresh(): boolean {\n return !!this.anon && Date.now() < this.anon.expiresAt;\n }\n\n async getAnonymousToken(): Promise<AnonymousSession> {\n if (this.anonFresh()) return this.stripExpiry(this.anon!);\n if (this.anonLock) return this.anonLock;\n // Token expired but a refresh token survives → refresh to keep the same\n // sessionId; only fall back to a brand-new login if the refresh fails.\n const canRefresh = !!this.anon?.refreshToken;\n const obtain = canRefresh\n ? this.fetchAnonymous(\"refresh\").catch(() => this.fetchAnonymous(\"login\"))\n : this.fetchAnonymous(\"login\");\n const p = obtain.finally(() => {\n this.anonLock = undefined;\n });\n this.anonLock = p;\n return p;\n }\n\n /** Refreshes the anonymous session, preserving its sessionId. */\n async refreshAnonymous(): Promise<AnonymousSession> {\n if (!this.anon) return this.getAnonymousToken();\n return this.fetchAnonymous(\"refresh\");\n }\n\n invalidateAnonymous(): void {\n this.anon = undefined;\n this.anonStore?.write(null);\n }\n\n setAnonymousContext(ctx: {\n currency?: string;\n siteCode?: string;\n targetLocation?: string;\n }): void {\n const base = this.contextOverride ?? this.cfg.credentials.storefront?.context ?? {};\n this.contextOverride = { ...base, ...ctx };\n this.invalidateAnonymous();\n }\n\n /** Force a stale access token while keeping the refresh token + sessionId. */\n expireAnonymous(): void {\n if (this.anon) this.anon = { ...this.anon, expiresAt: 0 };\n }\n\n private stripExpiry(s: AnonymousSession & { expiresAt: number }): AnonymousSession {\n const { expiresAt: _expiresAt, ...rest } = s;\n return rest;\n }\n\n private async fetchAnonymous(mode: \"login\" | \"refresh\"): Promise<AnonymousSession> {\n const sf = this.cfg.credentials.storefront;\n if (!sf?.clientId) {\n throw new Error(\"credentials.storefront.clientId is required for anonymous tokens\");\n }\n const url = new URL(`${this.cfg.host}/customerlogin/auth/anonymous/${mode}`);\n url.searchParams.set(\"tenant\", this.cfg.tenant);\n url.searchParams.set(\"client_id\", sf.clientId);\n // Context is the runtime override (set via setAnonymousContext) if present,\n // else the config-fixed context.\n const c = this.contextOverride ?? sf.context;\n if (c?.currency) url.searchParams.set(\"currency\", c.currency);\n if (c?.siteCode) url.searchParams.set(\"siteCode\", c.siteCode);\n if (c?.targetLocation) url.searchParams.set(\"targetLocation\", c.targetLocation);\n if (mode === \"refresh\" && this.anon) {\n url.searchParams.set(\"refresh_token\", this.anon.refreshToken);\n }\n try {\n const res = await this.boundedFetch(url, { method: \"GET\" });\n const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n this.notifyRefresh(\"anonymous\", false);\n throw new EmporixAuthError(`Anonymous token ${mode} failed`, res.status, json);\n }\n const obtainedAt = Date.now();\n this.anon = {\n accessToken: json.access_token as string,\n refreshToken: json.refresh_token as string,\n sessionId: json.sessionId as string,\n expiresIn: json.expires_in as number,\n expiresAt:\n obtainedAt +\n ((json.expires_in as number) - this.cfg.cache.expirationBufferSeconds) * 1000,\n };\n this.anonStore?.write({\n refreshToken: this.anon.refreshToken,\n sessionId: this.anon.sessionId,\n });\n this.notifyRefresh(\"anonymous\", true);\n return this.stripExpiry(this.anon);\n } catch (err) {\n // Re-throw EmporixAuthError as-is; for non-Emporix errors (network), also notify.\n if (!(err instanceof EmporixAuthError)) {\n this.notifyRefresh(\"anonymous\", false);\n }\n throw err;\n }\n }\n}\n// Customer-token refreshes happen via client.customers.refresh() and don't\n// route through this TokenProvider — only the anonymous flow notifies.\n// React-side useCustomerSession.refresh emits its own telemetry event in a\n// follow-up if needed.\n","import type { ClientContext } from \"../core/context\";\nimport { auth, type AuthContext } from \"../core/auth\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type {\n PaymentModeFrontendResponse,\n AuthorizePaymentRequest,\n} from \"../generated/payment\";\n\nconst ANON: AuthContext = auth.anonymous();\n\n/** A frontend payment mode (generated). */\nexport type PaymentMode = PaymentModeFrontendResponse;\n\n/** Post-checkout authorize request (generated; caller sends the exact wire shape). */\nexport type AuthorizePaymentInput = AuthorizePaymentRequest;\n\n/** Post-checkout authorize result. */\nexport interface AuthorizePaymentResult {\n successful: boolean;\n paymentTransactionId?: string;\n authorizationToken?: string;\n requiresExternalPayment?: boolean;\n externalPaymentRedirectURL?: string;\n externalPaymentHttpMethod?: string;\n [k: string]: unknown;\n}\n\n/** Payment-Gateway: list frontend payment modes, authorize deferred payments. */\nexport class PaymentGatewayService {\n static readonly channel = \"payment\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Lists configured frontend payment modes. The endpoint requires a bearer\n * token but no customer scope (\"No scope required\"), so it defaults to an\n * anonymous context and works for guests and logged-in customers alike.\n */\n async listPaymentModes(authCtx: AuthContext = ANON): Promise<PaymentMode[]> {\n return this.ctx.http.request<PaymentMode[]>({\n method: \"GET\",\n path: `/payment-gateway/${this.ctx.tenant}/paymentmodes/frontend`,\n auth: authCtx,\n });\n }\n\n /** Authorizes a post-checkout (deferred) payment for an existing order. */\n async authorize(\n input: AuthorizePaymentInput,\n authCtx?: AuthContext,\n ): Promise<AuthorizePaymentResult> {\n return this.ctx.http.request<AuthorizePaymentResult>({\n method: \"POST\",\n path: `/payment-gateway/${this.ctx.tenant}/payment/frontend/authorize`,\n auth: requireCustomer(authCtx),\n body: input,\n });\n }\n}\n"]}
|
|
@@ -16,6 +16,7 @@ var CheckoutService = class {
|
|
|
16
16
|
this.ctx = ctx;
|
|
17
17
|
}
|
|
18
18
|
ctx;
|
|
19
|
+
static channel = "checkout";
|
|
19
20
|
headers(opts, guest) {
|
|
20
21
|
if (guest || !opts.saasToken) return void 0;
|
|
21
22
|
return { "saas-token": opts.saasToken };
|
|
@@ -53,5 +54,5 @@ var CheckoutService = class {
|
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
export { CheckoutService };
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-RYQVMR26.js.map
|
|
58
|
+
//# sourceMappingURL=chunk-RYQVMR26.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/checkout.ts"],"names":[],"mappings":";;;AA2BA,SAAS,QAAQ,QAAA,EAA6C;AAC5D,EAAA,OAAO,UAAU,KAAA,KAAU,IAAA;AAC7B;AAEA,SAAS,WAAA,CAAY,MAA+B,KAAA,EAA6B;AAC/E,EAAA,IAAI,SAAS,IAAA,CAAK,IAAA,KAAS,cAAc,IAAA,CAAK,IAAA,KAAS,QAAQ,OAAO,IAAA;AACtE,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,aAAa,OAAO,IAAA;AACvD,EAAA,MAAM,IAAI,gBAAA;AAAA,IACR;AAAA,GACF;AACF;AAGO,IAAM,kBAAN,MAAsB;AAAA,EAE3B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,UAAA;AAAA,EAGlB,OAAA,CAAQ,MAAuB,KAAA,EAAoD;AACzF,IAAA,IAAI,KAAA,IAAS,CAAC,IAAA,CAAK,SAAA,EAAW,OAAO,MAAA;AACrC,IAAA,OAAO,EAAE,YAAA,EAAc,IAAA,CAAK,SAAA,EAAU;AAAA,EACxC;AAAA,EAEQ,MAAM,IAAA,EAA2D;AACvE,IAAA,OAAO,KAAK,QAAA,GAAW,EAAE,QAAA,EAAU,IAAA,CAAK,UAAS,GAAI,MAAA;AAAA,EACvD;AAAA;AAAA,EAGA,MAAM,UAAA,CACJ,KAAA,EACA,IAAA,EACA,IAAA,GAAwB,EAAC,EACA;AACzB,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA;AACpC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAM,KAAK,CAAA;AACxC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,CAAA;AAAA,MAClC,IAAA,EAAM,WAAA,CAAY,IAAA,EAAM,KAAK,CAAA;AAAA,MAC7B,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,MACzB,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,MAC7B,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,mBAAA,CACJ,KAAA,EACA,IAAA,EACA,IAAA,GAAwB,EAAC,EACA;AACzB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAM,KAAK,CAAA;AACxC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,gBAAA,CAAA;AAAA,MAClC,IAAA,EAAM,WAAA,CAAY,IAAA,EAAM,KAAK,CAAA;AAAA,MAC7B,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,MACzB,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,MAC7B,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF","file":"chunk-RYQVMR26.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixAuthError } from \"../core/errors\";\nimport type {\n ResponseCheckout,\n RequestCheckout,\n RequestFromQuoteCheckout,\n CustomerJson,\n} from \"../generated/checkout\";\n\n/** `requestCheckout` body (cart-based, generated). */\nexport type CheckoutInput = RequestCheckout;\n\n/** `requestFromQuoteCheckout` body (quote-based, generated). */\nexport type QuoteCheckoutInput = RequestFromQuoteCheckout;\n\n/** `responseCheckout` — the full generated checkout response. */\nexport type CheckoutResult = ResponseCheckout;\n\n/** Options for a checkout call. */\nexport interface CheckoutOptions {\n /** Customer `saasToken` from `customers.login()` — required for logged-in checkout. */\n saasToken?: string;\n /** Site code (`?siteCode=`). */\n siteCode?: string;\n}\n\nfunction isGuest(customer: CustomerJson | undefined): boolean {\n return customer?.guest === true;\n}\n\nfunction resolveAuth(auth: AuthContext | undefined, guest: boolean): AuthContext {\n if (auth && (auth.kind === \"customer\" || auth.kind === \"raw\")) return auth;\n if (guest && auth && auth.kind === \"anonymous\") return auth;\n throw new EmporixAuthError(\n \"checkout requires a customer/raw AuthContext (or anonymous for a guest checkout)\",\n );\n}\n\n/** Triggers Emporix checkout (atomic: validate → order → payment → close cart). */\nexport class CheckoutService {\n static readonly channel = \"checkout\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n private headers(opts: CheckoutOptions, guest: boolean): Record<string, string> | undefined {\n if (guest || !opts.saasToken) return undefined;\n return { \"saas-token\": opts.saasToken };\n }\n\n private query(opts: CheckoutOptions): Record<string, string> | undefined {\n return opts.siteCode ? { siteCode: opts.siteCode } : undefined;\n }\n\n /** Checkout from a cart. Requires customer/raw auth (or anonymous for guest). */\n async placeOrder(\n input: CheckoutInput,\n auth?: AuthContext,\n opts: CheckoutOptions = {},\n ): Promise<CheckoutResult> {\n const guest = isGuest(input.customer);\n const headers = this.headers(opts, guest);\n const query = this.query(opts);\n return this.ctx.http.request<CheckoutResult>({\n method: \"POST\",\n path: `/checkout/${this.ctx.tenant}/checkouts/order`,\n auth: resolveAuth(auth, guest),\n ...(query ? { query } : {}),\n ...(headers ? { headers } : {}),\n body: input,\n });\n }\n\n /** Checkout from a quote. */\n async placeOrderFromQuote(\n input: QuoteCheckoutInput,\n auth?: AuthContext,\n opts: CheckoutOptions = {},\n ): Promise<CheckoutResult> {\n const headers = this.headers(opts, false);\n const query = this.query(opts);\n return this.ctx.http.request<CheckoutResult>({\n method: \"POST\",\n path: `/checkout/${this.ctx.tenant}/checkouts/order`,\n auth: resolveAuth(auth, false),\n ...(query ? { query } : {}),\n ...(headers ? { headers } : {}),\n body: input,\n });\n }\n}\n"]}
|
package/dist/companies.cjs
CHANGED
package/dist/companies.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/companies.ts"],"names":[],"mappings":";;;AAgBO,IAAM,mBAAN,MAAuB;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/services/companies.ts"],"names":[],"mappings":";;;AAgBO,IAAM,mBAAN,MAAuB;AAAA,EAE5B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,qBAAA;AAAA,EAGlB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,eAAA,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,SAAS,IAAA,EAA2C;AACxD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAuB;AAAA,MAC1C,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,GAAA,CAAI,aAAA,EAAuB,IAAA,EAAyC;AACxE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAqB;AAAA,MACxC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,aAAa,CAAA,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,KAAA,EAA0B,IAAA,EAA4C;AACjF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,aAAA,EACA,KAAA,EACA,IAAA,EACsB;AACtB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAqB;AAAA,MACxC,MAAA,EAAQ,OAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,aAAa,CAAA,CAAA;AAAA,MACrC,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,aAAA,EAAuB,IAAA,EAAkC;AACpE,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,aAAa,CAAA,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"companies.cjs","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n LegalEntity,\n LegalEntityCreate,\n LegalEntityUpdate,\n} from \"../generated/customer-management\";\n\n/**\n * Storefront-customer access to Legal Entities.\n *\n * `listMine`/`get` require `customermanagement.legalentity_read_own` on the\n * customer token. `create`/`update`/`delete` require the corresponding\n * `_manage` scopes — typically only granted to Admin-group customers; a 403\n * surfaces as `EmporixInsufficientScopeError`.\n */\nexport class CompaniesService {\n static readonly channel = \"customer-management\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/customer-management/${this.ctx.tenant}/legal-entities`;\n }\n\n /** Lists the legal entities the calling customer is assigned to. */\n async listMine(auth: AuthContext): Promise<LegalEntity[]> {\n return this.ctx.http.request<LegalEntity[]>({\n method: \"GET\",\n path: this.base(),\n auth,\n });\n }\n\n /** Fetches a single legal entity by id. */\n async get(legalEntityId: string, auth: AuthContext): Promise<LegalEntity> {\n return this.ctx.http.request<LegalEntity>({\n method: \"GET\",\n path: `${this.base()}/${legalEntityId}`,\n auth,\n });\n }\n\n /** Creates a legal entity. Requires `customermanagement.legalentity_manage`. */\n async create(input: LegalEntityCreate, auth: AuthContext): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input,\n });\n }\n\n /**\n * Patches a legal entity. The endpoint is a PATCH, so the body is a partial\n * of the generated `LegalEntityUpdate` (full-replace) shape.\n */\n async update(\n legalEntityId: string,\n patch: Partial<LegalEntityUpdate>,\n auth: AuthContext,\n ): Promise<LegalEntity> {\n return this.ctx.http.request<LegalEntity>({\n method: \"PATCH\",\n path: `${this.base()}/${legalEntityId}`,\n auth,\n body: patch,\n });\n }\n\n /** Deletes a legal entity (async cascade on the server). */\n async delete(legalEntityId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${legalEntityId}`,\n auth,\n });\n }\n}\n"]}
|
package/dist/companies.d.cts
CHANGED
|
@@ -12,6 +12,7 @@ export { A as AccountLimit, d as CustomerGroup, g as LegalInfo } from './types.g
|
|
|
12
12
|
*/
|
|
13
13
|
declare class CompaniesService {
|
|
14
14
|
private readonly ctx;
|
|
15
|
+
static readonly channel: "customer-management";
|
|
15
16
|
constructor(ctx: ClientContext);
|
|
16
17
|
private base;
|
|
17
18
|
/** Lists the legal entities the calling customer is assigned to. */
|
package/dist/companies.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { A as AccountLimit, d as CustomerGroup, g as LegalInfo } from './types.g
|
|
|
12
12
|
*/
|
|
13
13
|
declare class CompaniesService {
|
|
14
14
|
private readonly ctx;
|
|
15
|
+
static readonly channel: "customer-management";
|
|
15
16
|
constructor(ctx: ClientContext);
|
|
16
17
|
private base;
|
|
17
18
|
/** Lists the legal entities the calling customer is assigned to. */
|
package/dist/companies.js
CHANGED
package/dist/contacts.cjs
CHANGED
package/dist/contacts.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/contacts.ts"],"names":[],"mappings":";;;AAeO,IAAM,kBAAN,MAAsB;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/services/contacts.ts"],"names":[],"mappings":";;;AAeO,IAAM,kBAAN,MAAsB;AAAA,EAE3B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,qBAAA;AAAA,EAGlB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,oBAAA,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,cAAA,CAAe,aAAA,EAAuB,IAAA,EAAiD;AAC3F,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA6B;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,KAAA,EAAO,EAAE,aAAA,EAAc;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,KAAA,EAAgC,IAAA,EAA4C;AACvF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,mBAAA,EACA,KAAA,EACA,IAAA,EAC4B;AAC5B,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA2B;AAAA,MAC9C,MAAA,EAAQ,OAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,mBAAmB,CAAA,CAAA;AAAA,MAC3C,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,QAAA,CAAS,mBAAA,EAA6B,IAAA,EAAkC;AAC5E,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,mBAAmB,CAAA,CAAA;AAAA,MAC3C;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"contacts.cjs","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n ContactAssignment,\n ContactAssignmentCreate,\n ContactAssignmentUpdate,\n} from \"../generated/customer-management\";\n\n/**\n * Manages contact assignments linking customers to legal entities.\n *\n * `listForCompany` requires `customermanagement.contactassignment_read`;\n * `assign`/`update`/`unassign` require `_manage`. The query param\n * `legalEntityId` scopes the list to one company.\n */\nexport class ContactsService {\n static readonly channel = \"customer-management\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/customer-management/${this.ctx.tenant}/contact-assignments`;\n }\n\n /** Lists contact assignments for one legal entity. */\n async listForCompany(legalEntityId: string, auth: AuthContext): Promise<ContactAssignment[]> {\n return this.ctx.http.request<ContactAssignment[]>({\n method: \"GET\",\n path: this.base(),\n query: { legalEntityId },\n auth,\n });\n }\n\n /** Creates a contact assignment. */\n async assign(input: ContactAssignmentCreate, auth: AuthContext): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input,\n });\n }\n\n /**\n * Patches a contact assignment. PATCH endpoint, so the body is a partial of\n * the generated `ContactAssignmentUpdate` shape.\n */\n async update(\n contactAssignmentId: string,\n patch: Partial<ContactAssignmentUpdate>,\n auth: AuthContext,\n ): Promise<ContactAssignment> {\n return this.ctx.http.request<ContactAssignment>({\n method: \"PATCH\",\n path: `${this.base()}/${contactAssignmentId}`,\n auth,\n body: patch,\n });\n }\n\n /** Deletes a contact assignment. */\n async unassign(contactAssignmentId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${contactAssignmentId}`,\n auth,\n });\n }\n}\n"]}
|
package/dist/contacts.d.cts
CHANGED
|
@@ -10,6 +10,7 @@ import { C as ContactAssignment, a as ContactAssignmentCreate, b as ContactAssig
|
|
|
10
10
|
*/
|
|
11
11
|
declare class ContactsService {
|
|
12
12
|
private readonly ctx;
|
|
13
|
+
static readonly channel: "customer-management";
|
|
13
14
|
constructor(ctx: ClientContext);
|
|
14
15
|
private base;
|
|
15
16
|
/** Lists contact assignments for one legal entity. */
|
package/dist/contacts.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { C as ContactAssignment, a as ContactAssignmentCreate, b as ContactAssig
|
|
|
10
10
|
*/
|
|
11
11
|
declare class ContactsService {
|
|
12
12
|
private readonly ctx;
|
|
13
|
+
static readonly channel: "customer-management";
|
|
13
14
|
constructor(ctx: ClientContext);
|
|
14
15
|
private base;
|
|
15
16
|
/** Lists contact assignments for one legal entity. */
|
package/dist/contacts.js
CHANGED
package/dist/customer-groups.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/customer-groups.ts"],"names":[],"mappings":";;;AAeO,IAAM,wBAAN,MAA4B;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/services/customer-groups.ts"],"names":[],"mappings":";;;AAeO,IAAM,wBAAN,MAA4B;AAAA,EAEjC,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAD7B,OAAgB,OAAA,GAAU,KAAA;AAAA,EAGlB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,OAAA,CAAA;AAAA,EAChC;AAAA;AAAA,EAGA,MAAM,cAAA,CAAe,aAAA,EAAuB,IAAA,EAAmD;AAC7F,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA+B;AAAA,MAClD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,KAAA,EAAO,EAAE,mBAAA,EAAqB,aAAA,EAAc;AAAA,MAC5C;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAA,CACJ,OAAA,EACA,MAAA,EACA,IAAA,EACyB;AACzB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,MAAA,CAAA;AAAA,MAC/B,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,YAAA,CAAa,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAkC;AACpF,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA,EAAM,GAAG,IAAA,CAAK,IAAA,EAAM,CAAA,CAAA,EAAI,OAAO,UAAU,MAAM,CAAA,CAAA;AAAA,MAC/C;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"customer-groups.cjs","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n GroupsQueryDocument,\n AssignmentCreateRequest,\n} from \"../generated/iam\";\n\n/**\n * Access to IAM customer groups for a legal entity.\n *\n * `listForCompany` requires `iam.group_read`; the member mutations\n * (`addMember`/`removeMember`) require `iam.group_manage` — typically only\n * granted to Admin-group customers; a 403 surfaces as\n * `EmporixInsufficientScopeError`.\n */\nexport class CustomerGroupsService {\n static readonly channel = \"iam\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/iam/${this.ctx.tenant}/groups`;\n }\n\n /** Lists customer groups belonging to one legal entity. */\n async listForCompany(legalEntityId: string, auth: AuthContext): Promise<GroupsQueryDocument[]> {\n return this.ctx.http.request<GroupsQueryDocument[]>({\n method: \"GET\",\n path: this.base(),\n query: { \"b2b.legalEntityId\": legalEntityId },\n auth,\n });\n }\n\n /** Adds a user (customer or employee) to a group. */\n async addMember(\n groupId: string,\n member: AssignmentCreateRequest,\n auth: AuthContext,\n ): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: `${this.base()}/${groupId}/users`,\n auth,\n body: member,\n });\n }\n\n /** Removes a user from a group. */\n async removeMember(groupId: string, userId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${groupId}/users/${userId}`,\n auth,\n });\n }\n}\n"]}
|
package/dist/customer-groups.js
CHANGED
package/dist/customer.cjs
CHANGED
|
@@ -68,6 +68,7 @@ var CustomerService = class {
|
|
|
68
68
|
this.ctx = ctx;
|
|
69
69
|
}
|
|
70
70
|
ctx;
|
|
71
|
+
static channel = "customer";
|
|
71
72
|
/** Obtains an anonymous storefront session (accessToken + sessionId + refreshToken). */
|
|
72
73
|
async anonymous() {
|
|
73
74
|
return this.ctx.tokenProvider.getAnonymousToken();
|