@ahoo-wang/fetcher-cosec 3.13.15 → 3.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -1,929 +1,273 @@
1
- import { DEFAULT_INTERCEPTOR_ORDER_STEP as I, FetcherError as y, URL_RESOLVE_INTERCEPTOR_ORDER as m, ResultExtractors as v } from "@ahoo-wang/fetcher";
2
- import { nanoid as b } from "nanoid";
3
- import { KeyStorage as p, typedIdentitySerializer as N } from "@ahoo-wang/fetcher-storage";
4
- import { BroadcastTypedEventBus as R, SerialTypedEventBus as T } from "@ahoo-wang/fetcher-eventbus";
5
- const a = class a {
1
+ import { DEFAULT_INTERCEPTOR_ORDER_STEP as e, FetcherError as t, ResultExtractors as n, URL_RESOLVE_INTERCEPTOR_ORDER as r } from "@ahoo-wang/fetcher";
2
+ import { nanoid as i } from "nanoid";
3
+ import { KeyStorage as a, typedIdentitySerializer as o } from "@ahoo-wang/fetcher-storage";
4
+ import { BroadcastTypedEventBus as s, SerialTypedEventBus as c } from "@ahoo-wang/fetcher-eventbus";
5
+ //#region src/types.ts
6
+ var l = class {
7
+ static {
8
+ this.DEVICE_ID = "CoSec-Device-Id";
9
+ }
10
+ static {
11
+ this.APP_ID = "CoSec-App-Id";
12
+ }
13
+ static {
14
+ this.SPACE_ID = "CoSec-Space-Id";
15
+ }
16
+ static {
17
+ this.AUTHORIZATION = "Authorization";
18
+ }
19
+ static {
20
+ this.REQUEST_ID = "CoSec-Request-Id";
21
+ }
22
+ }, u = class {
23
+ static {
24
+ this.UNAUTHORIZED = 401;
25
+ }
26
+ static {
27
+ this.FORBIDDEN = 403;
28
+ }
29
+ }, d = {
30
+ ALLOW: {
31
+ authorized: !0,
32
+ reason: "Allow"
33
+ },
34
+ EXPLICIT_DENY: {
35
+ authorized: !1,
36
+ reason: "Explicit Deny"
37
+ },
38
+ IMPLICIT_DENY: {
39
+ authorized: !1,
40
+ reason: "Implicit Deny"
41
+ },
42
+ TOKEN_EXPIRED: {
43
+ authorized: !1,
44
+ reason: "Token Expired"
45
+ },
46
+ TOO_MANY_REQUESTS: {
47
+ authorized: !1,
48
+ reason: "Too Many Requests"
49
+ }
50
+ }, f = class {
51
+ generateId() {
52
+ return i();
53
+ }
54
+ }, p = new f(), m = { resolveSpaceId: () => null }, h = "cosec-space-id", g = class extends a {
55
+ constructor({ key: e = h, eventBus: t = new s({ delegate: new c(h) }), ...n } = {}) {
56
+ super({
57
+ key: e,
58
+ eventBus: t,
59
+ ...n,
60
+ serializer: o()
61
+ });
62
+ }
63
+ }, _ = class {
64
+ constructor(e) {
65
+ this.options = e;
66
+ }
67
+ resolveSpaceId(e) {
68
+ return this.options.spacedResourcePredicate.test(e) ? this.options.spaceIdStorage.get() : null;
69
+ }
70
+ }, v = "CoSecRequestInterceptor", y = -(2 ** 53 - 1) + e, b = "Ignore-Refresh-Token", x = class {
71
+ constructor({ appId: e, deviceIdStorage: t, spaceIdProvider: n }) {
72
+ this.name = v, this.order = y, this.appId = e, this.deviceIdStorage = t, this.spaceIdProvider = n ?? m;
73
+ }
74
+ async intercept(e) {
75
+ let t = p.generateId(), n = this.deviceIdStorage.getOrCreate(), r = this.spaceIdProvider.resolveSpaceId(e), i = e.ensureRequestHeaders();
76
+ i[l.APP_ID] = this.appId, i[l.DEVICE_ID] = n, i[l.REQUEST_ID] = t, r && (i[l.SPACE_ID] = r);
77
+ }
78
+ }, S = "AuthorizationRequestInterceptor", C = y + e, w = class {
79
+ constructor(e) {
80
+ this.options = e, this.name = S, this.order = C;
81
+ }
82
+ async intercept(e) {
83
+ let t = this.options.tokenManager.currentToken, n = e.ensureRequestHeaders();
84
+ !t || n[l.AUTHORIZATION] || (!e.attributes.has("Ignore-Refresh-Token") && t.isRefreshNeeded && t.isRefreshable && await this.options.tokenManager.refresh(), t = this.options.tokenManager.currentToken, t && (n[l.AUTHORIZATION] = `Bearer ${t.access.token}`));
85
+ }
86
+ }, T = "AuthorizationResponseInterceptor", E = -(2 ** 53 - 1) + 1e3, D = class {
87
+ constructor(e) {
88
+ this.options = e, this.name = T, this.order = E;
89
+ }
90
+ async intercept(e) {
91
+ let t = e.response;
92
+ if (t && t.status === u.UNAUTHORIZED && this.options.tokenManager.isRefreshable) try {
93
+ await this.options.tokenManager.refresh(), await e.fetcher.interceptors.exchange(e);
94
+ } catch (e) {
95
+ throw this.options.tokenManager.tokenStorage.remove(), e;
96
+ }
97
+ }
98
+ }, O = "cosec-device-id", k = class extends a {
99
+ constructor({ key: e = O, eventBus: t = new s({ delegate: new c(O) }), ...n } = {}) {
100
+ super({
101
+ key: e,
102
+ eventBus: t,
103
+ ...n,
104
+ serializer: o()
105
+ });
106
+ }
107
+ generateDeviceId() {
108
+ return p.generateId();
109
+ }
110
+ getOrCreate() {
111
+ let e = this.get();
112
+ return e || (e = this.generateDeviceId(), this.set(e)), e;
113
+ }
114
+ }, A = "ForbiddenErrorInterceptor", j = 0, M = class {
115
+ constructor(e) {
116
+ this.options = e, this.name = A, this.order = 0;
117
+ }
118
+ async intercept(e) {
119
+ e.response?.status === u.FORBIDDEN && await this.options.onForbidden(e);
120
+ }
121
+ }, N = class e extends t {
122
+ constructor(t, n) {
123
+ super("Refresh token failed.", n), this.token = t, this.name = "RefreshTokenError", Object.setPrototypeOf(this, e.prototype);
124
+ }
125
+ }, P = class {
126
+ constructor(e, t) {
127
+ this.tokenStorage = e, this.tokenRefresher = t;
128
+ }
129
+ get currentToken() {
130
+ return this.tokenStorage.get();
131
+ }
132
+ async refresh() {
133
+ let e = this.currentToken;
134
+ if (!e) throw Error("No token found");
135
+ return this.refreshInProgress ||= this.tokenRefresher.refresh(e.token).then((e) => {
136
+ this.tokenStorage.setCompositeToken(e);
137
+ }).catch((t) => {
138
+ throw this.tokenStorage.remove(), new N(e, t);
139
+ }).finally(() => {
140
+ this.refreshInProgress = void 0;
141
+ }), this.refreshInProgress;
142
+ }
143
+ get isRefreshNeeded() {
144
+ return this.currentToken ? this.currentToken.isRefreshNeeded : !1;
145
+ }
146
+ get isRefreshable() {
147
+ return this.currentToken ? this.currentToken.isRefreshable : !1;
148
+ }
149
+ }, F = "tenantId", I = "ownerId", L = "ResourceAttributionRequestInterceptor", R = r - e, z = class {
150
+ constructor({ tenantId: e = F, ownerId: t = I, tokenStorage: n }) {
151
+ this.name = L, this.order = R, this.tenantIdPathKey = e, this.ownerIdPathKey = t, this.tokenStorage = n;
152
+ }
153
+ intercept(e) {
154
+ let t = this.tokenStorage.get();
155
+ if (!t) return;
156
+ let n = t.access.payload;
157
+ if (!n || !n.tenantId && !n.sub) return;
158
+ let r = e.fetcher.urlBuilder.urlTemplateResolver.extractPathParams(e.request.url), i = this.tenantIdPathKey, a = e.ensureRequestUrlParams().path, o = n.tenantId;
159
+ o && r.includes(i) && !a[i] && (a[i] = o);
160
+ let s = this.ownerIdPathKey, c = n.sub;
161
+ c && r.includes(s) && !a[s] && (a[s] = c);
162
+ }
6
163
  };
7
- a.DEVICE_ID = "CoSec-Device-Id", a.APP_ID = "CoSec-App-Id", a.SPACE_ID = "CoSec-Space-Id", a.AUTHORIZATION = "Authorization", a.REQUEST_ID = "CoSec-Request-Id";
8
- let i = a;
9
- const u = class u {
10
- };
11
- u.UNAUTHORIZED = 401, u.FORBIDDEN = 403;
12
- let h = u;
13
- const he = {
14
- ALLOW: { authorized: !0, reason: "Allow" },
15
- EXPLICIT_DENY: { authorized: !1, reason: "Explicit Deny" },
16
- IMPLICIT_DENY: { authorized: !1, reason: "Implicit Deny" },
17
- TOKEN_EXPIRED: { authorized: !1, reason: "Token Expired" },
18
- TOO_MANY_REQUESTS: { authorized: !1, reason: "Too Many Requests" }
19
- };
20
- class z {
21
- /**
22
- * Generate a unique request ID.
23
- *
24
- * @returns A unique request ID
25
- */
26
- generateId() {
27
- return b();
28
- }
29
- }
30
- const P = new z(), k = {
31
- resolveSpaceId: () => null
32
- }, O = "cosec-space-id";
33
- class ue extends p {
34
- /**
35
- * Creates a new SpaceIdStorage instance.
36
- *
37
- * @param options - Optional configuration options for the storage
38
- * @param options.key - The storage key (defaults to DEFAULT_COSEC_SPACE_ID_KEY)
39
- * @param options.eventBus - Custom event bus for cross-tab communication
40
- * @param options.storage - Custom storage implementation (defaults to localStorage)
41
- * @param options.serializer - Custom serializer (defaults to identity serializer)
42
- * @param options.defaultValue - Default value when no space ID is stored
43
- *
44
- * @throws Error if the underlying storage is unavailable
45
- *
46
- * @example
47
- * ```typescript
48
- * // Default configuration
49
- * const storage = new SpaceIdStorage();
50
- *
51
- * // With custom options
52
- * const storage = new SpaceIdStorage({
53
- * key: 'custom-space-key',
54
- * storage: sessionStorage,
55
- * defaultValue: 'default-space'
56
- * });
57
- * ```
58
- */
59
- constructor({
60
- key: e = O,
61
- eventBus: t = new R({
62
- delegate: new T(O)
63
- }),
64
- ...r
65
- } = {}) {
66
- super({ key: e, eventBus: t, ...r, serializer: N() });
67
- }
68
- }
69
- class de {
70
- /**
71
- * Creates a new DefaultSpaceIdProvider instance.
72
- *
73
- * @param options - The configuration options containing the predicate and storage
74
- * @param options.spacedResourcePredicate - Determines which requests require space scoping
75
- * @param options.spaceIdStorage - Provides access to the persisted space identifier
76
- *
77
- * @example
78
- * ```typescript
79
- * const provider = new DefaultSpaceIdProvider({
80
- * spacedResourcePredicate: {
81
- * test: (exchange) => exchange.request.url.includes('/api/')
82
- * },
83
- * spaceIdStorage: new SpaceIdStorage()
84
- * });
85
- * ```
86
- */
87
- constructor(e) {
88
- this.options = e;
89
- }
90
- /**
91
- * Resolves the space identifier for a given fetch exchange.
92
- *
93
- * This method first checks if the request requires space scoping by
94
- * evaluating the predicate. If the predicate returns true, it retrieves
95
- * the space ID from storage. Otherwise, it returns null.
96
- *
97
- * @param exchange - The fetch exchange containing the HTTP request details
98
- * @returns The space identifier if the request requires scoping and one exists,
99
- * otherwise null
100
- *
101
- * @example
102
- * ```typescript
103
- * const provider = new DefaultSpaceIdProvider({
104
- * spacedResourcePredicate: {
105
- * test: (exchange) => exchange.request.url.includes('/spaced/')
106
- * },
107
- * spaceIdStorage: new SpaceIdStorage()
108
- * });
109
- *
110
- * // For a request to /api/spaces/workspace-alpha/resources
111
- * const exchange = createMockExchange({ url: '/api/spaces/workspace-alpha/resources' });
112
- * const spaceId = provider.resolveSpaceId(exchange); // Returns stored space ID
113
- *
114
- * // For a request to /api/public/resources
115
- * const publicExchange = createMockExchange({ url: '/api/public/resources' });
116
- * const noSpace = provider.resolveSpaceId(publicExchange); // Returns null
117
- * ```
118
- */
119
- resolveSpaceId(e) {
120
- return this.options.spacedResourcePredicate.test(e) ? this.options.spaceIdStorage.get() : null;
121
- }
122
- }
123
- const M = "CoSecRequestInterceptor", A = Number.MIN_SAFE_INTEGER + I, D = "Ignore-Refresh-Token";
124
- class q {
125
- /**
126
- * Creates a new CoSecRequestInterceptor instance.
127
- *
128
- * @param options - The CoSec configuration options
129
- * @param options.appId - The application identifier for CoSec authentication
130
- * @param options.deviceIdStorage - Storage for device identifier management
131
- * @param options.spaceIdProvider - Optional provider for space identification
132
- *
133
- * @throws Error if appId is empty or not provided
134
- * @throws Error if deviceIdStorage is not provided
135
- *
136
- * @example
137
- * ```typescript
138
- * // Basic instantiation
139
- * const interceptor = new CoSecRequestInterceptor({
140
- * appId: 'my-web-app',
141
- * deviceIdStorage: new DeviceIdStorage()
142
- * });
143
- *
144
- * // With custom device ID storage
145
- * const customStorage = new DeviceIdStorage({
146
- * key: 'custom-device-key',
147
- * storage: sessionStorage
148
- * });
149
- * const interceptorWithCustom = new CoSecRequestInterceptor({
150
- * appId: 'my-web-app',
151
- * deviceIdStorage: customStorage
152
- * });
153
- *
154
- * // With space support
155
- * const spaceStorage = new SpaceIdStorage();
156
- * const spaceProvider = new DefaultSpaceIdProvider({
157
- * spacedResourcePredicate: { test: (e) => true },
158
- * spaceIdStorage: spaceStorage
159
- * });
160
- * const interceptorWithSpace = new CoSecRequestInterceptor({
161
- * appId: 'my-web-app',
162
- * deviceIdStorage,
163
- * spaceIdProvider: spaceProvider
164
- * });
165
- * ```
166
- */
167
- constructor({
168
- appId: e,
169
- deviceIdStorage: t,
170
- spaceIdProvider: r
171
- }) {
172
- this.name = M, this.order = A, this.appId = e, this.deviceIdStorage = t, this.spaceIdProvider = r ?? k;
173
- }
174
- /**
175
- * Intercepts outgoing requests to add CoSec authentication headers.
176
- *
177
- * This method is called by the Fetcher interceptor chain for each request.
178
- * It enriches the request with security headers before the HTTP request is made.
179
- *
180
- * **Header Injection Process:**
181
- * 1. Generates a unique request ID using the idGenerator
182
- * 2. Retrieves or creates a device ID from deviceIdStorage
183
- * 3. Resolves space ID from spaceIdProvider (if applicable)
184
- * 4. Adds all headers to the request
185
- *
186
- * @param exchange - The fetch exchange containing the request to process
187
- *
188
- * @remarks
189
- * **Header Values:**
190
- * - `CoSec-App-Id`: Always set to the configured appId
191
- * - `CoSec-Device-Id`: Retrieved from storage or newly generated
192
- * - `CoSec-Request-Id`: Unique per request (not persisted)
193
- * - `CoSec-Space-Id`: Set only if spaceIdProvider returns a value
194
- *
195
- * **Error Handling:**
196
- * - If deviceIdStorage.getOrCreate() throws, the error propagates
197
- * - If spaceIdProvider.resolveSpaceId() throws, the error propagates
198
- * - If ensureRequestHeaders() fails, the error propagates
199
- *
200
- * **Thread Safety:**
201
- * - The idGenerator is safe for concurrent use
202
- * - deviceIdStorage handles concurrent access internally
203
- * - Each request gets a unique request ID
204
- *
205
- * @example
206
- * ```typescript
207
- * // The interceptor is called automatically by Fetcher
208
- * const fetcher = new Fetcher()
209
- * .addInterceptor(new CoSecRequestInterceptor({
210
- * appId: 'my-app',
211
- * deviceIdStorage: new DeviceIdStorage()
212
- * }));
213
- *
214
- * // This request will have CoSec headers added
215
- * const response = await fetcher.get('/api/data');
216
- * ```
217
- *
218
- * @example
219
- * ```typescript
220
- * // Headers added to outgoing request:
221
- * // GET /api/users HTTP/1.1
222
- * // Host: api.example.com
223
- * // CoSec-App-Id: my-app
224
- * // CoSec-Device-Id: abc123xyz789
225
- * // CoSec-Request-Id: req_abc123def456
226
- * // CoSec-Space-Id: workspace-alpha (if space resolved)
227
- * ```
228
- */
229
- async intercept(e) {
230
- const t = P.generateId(), r = this.deviceIdStorage.getOrCreate(), o = this.spaceIdProvider.resolveSpaceId(e), n = e.ensureRequestHeaders();
231
- n[i.APP_ID] = this.appId, n[i.DEVICE_ID] = r, n[i.REQUEST_ID] = t, o && (n[i.SPACE_ID] = o);
232
- }
233
- }
234
- const F = "AuthorizationRequestInterceptor", K = A + I;
235
- class B {
236
- /**
237
- * Creates an AuthorizationRequestInterceptor instance.
238
- *
239
- * @param options - Configuration options containing the token manager
240
- */
241
- constructor(e) {
242
- this.options = e, this.name = F, this.order = K;
243
- }
244
- /**
245
- * Intercepts the request exchange to add authorization headers.
246
- *
247
- * This method performs the following operations:
248
- * 1. Checks if a token exists and if Authorization header is already set
249
- * 2. Refreshes the token if needed, possible, and not explicitly ignored
250
- * 3. Adds the Authorization header with Bearer token if a token is available
251
- *
252
- * @param exchange - The fetch exchange containing request information
253
- * @returns Promise that resolves when the interception is complete
254
- */
255
- async intercept(e) {
256
- let t = this.options.tokenManager.currentToken;
257
- const r = e.ensureRequestHeaders();
258
- !t || r[i.AUTHORIZATION] || (!e.attributes.has(D) && t.isRefreshNeeded && t.isRefreshable && await this.options.tokenManager.refresh(), t = this.options.tokenManager.currentToken, t && (r[i.AUTHORIZATION] = `Bearer ${t.access.token}`));
259
- }
260
- }
261
- const H = "AuthorizationResponseInterceptor", Z = Number.MIN_SAFE_INTEGER + 1e3;
262
- class x {
263
- /**
264
- * Creates a new AuthorizationResponseInterceptor instance.
265
- * @param options - The CoSec configuration options including token storage and refresher
266
- */
267
- constructor(e) {
268
- this.options = e, this.name = H, this.order = Z;
269
- }
270
- /**
271
- * Intercepts the response and handles unauthorized responses by refreshing tokens.
272
- * @param exchange - The fetch exchange containing request and response information
273
- */
274
- async intercept(e) {
275
- const t = e.response;
276
- if (t && t.status === h.UNAUTHORIZED && this.options.tokenManager.isRefreshable)
277
- try {
278
- await this.options.tokenManager.refresh(), await e.fetcher.interceptors.exchange(e);
279
- } catch (r) {
280
- throw this.options.tokenManager.tokenStorage.remove(), r;
281
- }
282
- }
283
- }
284
- const _ = "cosec-device-id";
285
- class J extends p {
286
- constructor({
287
- key: e = _,
288
- eventBus: t = new R({
289
- delegate: new T(_)
290
- }),
291
- ...r
292
- } = {}) {
293
- super({ key: e, eventBus: t, ...r, serializer: N() });
294
- }
295
- /**
296
- * Generate a new device ID.
297
- *
298
- * @returns A newly generated device ID
299
- */
300
- generateDeviceId() {
301
- return P.generateId();
302
- }
303
- /**
304
- * Get or create a device ID.
305
- *
306
- * @returns The existing device ID if available, otherwise a newly generated one
307
- */
308
- getOrCreate() {
309
- let e = this.get();
310
- return e || (e = this.generateDeviceId(), this.set(e)), e;
311
- }
312
- }
313
- const L = "ForbiddenErrorInterceptor", Q = 0;
314
- class Y {
315
- /**
316
- * Creates a new ForbiddenErrorInterceptor instance.
317
- *
318
- * @param options - Configuration options containing the callback to handle forbidden responses.
319
- * Must include the `onForbidden` callback function.
320
- *
321
- * @throws Will throw an error if options are not provided or if `onForbidden` callback is missing.
322
- *
323
- * @example
324
- * ```typescript
325
- * const interceptor = new ForbiddenErrorInterceptor({
326
- * onForbidden: async (exchange) => {
327
- * // Handle forbidden access
328
- * }
329
- * });
330
- * ```
331
- */
332
- constructor(e) {
333
- this.options = e, this.name = L, this.order = Q;
334
- }
335
- /**
336
- * Intercepts fetch exchanges to detect and handle forbidden (403) responses.
337
- *
338
- * This method examines the response status code and invokes the configured `onForbidden`
339
- * callback when a 403 Forbidden response is detected. The method is asynchronous to
340
- * allow the callback to perform async operations like API calls, redirects, or UI updates.
341
- *
342
- * The interceptor only acts on responses with status code 403. Other error codes are
343
- * ignored and passed through to other error interceptors in the chain.
344
- *
345
- * @param exchange - The fetch exchange containing request, response, and error information
346
- * to be inspected for forbidden status codes. The exchange object provides
347
- * access to the original request, response details, and any error information.
348
- * @returns Promise that resolves when the forbidden error handling is complete.
349
- * Returns void - the method does not modify the exchange or return values.
350
- *
351
- * @remarks
352
- * - Only responds to HTTP 403 status codes
353
- * - Does not retry requests or modify responses
354
- * - Allows async operations in the callback
355
- * - Does not throw exceptions - delegates all error handling to the callback
356
- * - Safe to use with other error interceptors
357
- *
358
- * @example
359
- * ```typescript
360
- * // The intercept method is called automatically by the fetcher
361
- * // No manual invocation needed - this is for documentation purposes
362
- * const interceptor = new ForbiddenErrorInterceptor({
363
- * onForbidden: async (exchange) => {
364
- * // exchange.response.status === 403
365
- * // exchange.request contains original request details
366
- * await handleForbiddenAccess(exchange);
367
- * }
368
- * });
369
- * ```
370
- */
371
- async intercept(e) {
372
- e.response?.status === h.FORBIDDEN && await this.options.onForbidden(e);
373
- }
374
- }
375
- class d extends y {
376
- constructor(e, t) {
377
- super("Refresh token failed.", t), this.token = e, this.name = "RefreshTokenError", Object.setPrototypeOf(this, d.prototype);
378
- }
379
- }
380
- class j {
381
- /**
382
- * Creates a new JwtTokenManager instance
383
- * @param tokenStorage The storage used to persist tokens
384
- * @param tokenRefresher The refresher used to refresh expired tokens
385
- */
386
- constructor(e, t) {
387
- this.tokenStorage = e, this.tokenRefresher = t;
388
- }
389
- /**
390
- * Gets the current JWT composite token from storage
391
- * @returns The current token or null if none exists
392
- */
393
- get currentToken() {
394
- return this.tokenStorage.get();
395
- }
396
- /**
397
- * Refreshes the JWT token
398
- * @returns Promise that resolves when refresh is complete
399
- * @throws Error if no token is found or refresh fails
400
- */
401
- async refresh() {
402
- const e = this.currentToken;
403
- if (!e)
404
- throw new Error("No token found");
405
- return this.refreshInProgress ? this.refreshInProgress : (this.refreshInProgress = this.tokenRefresher.refresh(e.token).then((t) => {
406
- this.tokenStorage.setCompositeToken(t);
407
- }).catch((t) => {
408
- throw this.tokenStorage.remove(), new d(e, t);
409
- }).finally(() => {
410
- this.refreshInProgress = void 0;
411
- }), this.refreshInProgress);
412
- }
413
- /**
414
- * Indicates if the current token needs to be refreshed
415
- * @returns true if the access token is expired and needs refresh, false otherwise
416
- */
417
- get isRefreshNeeded() {
418
- return this.currentToken ? this.currentToken.isRefreshNeeded : !1;
419
- }
420
- /**
421
- * Indicates if the current token can be refreshed
422
- * @returns true if the refresh token is still valid, false otherwise
423
- */
424
- get isRefreshable() {
425
- return this.currentToken ? this.currentToken.isRefreshable : !1;
426
- }
427
- }
428
- const G = "tenantId", V = "ownerId", W = "ResourceAttributionRequestInterceptor", X = m - I;
429
- class $ {
430
- /**
431
- * Creates a new ResourceAttributionRequestInterceptor
432
- * @param options - Configuration options for resource attribution including tenantId, ownerId and tokenStorage
433
- */
434
- constructor({
435
- tenantId: e = G,
436
- ownerId: t = V,
437
- tokenStorage: r
438
- }) {
439
- this.name = W, this.order = X, this.tenantIdPathKey = e, this.ownerIdPathKey = t, this.tokenStorage = r;
440
- }
441
- /**
442
- * Intercepts outgoing requests and automatically adds tenant and owner ID path parameters
443
- * if they are defined in the URL template but not provided in the request.
444
- * @param exchange - The fetch exchange containing the request information
445
- */
446
- intercept(e) {
447
- const t = this.tokenStorage.get();
448
- if (!t)
449
- return;
450
- const r = t.access.payload;
451
- if (!r || !r.tenantId && !r.sub)
452
- return;
453
- const o = e.fetcher.urlBuilder.urlTemplateResolver.extractPathParams(
454
- e.request.url
455
- ), n = this.tenantIdPathKey, c = e.ensureRequestUrlParams().path, l = r.tenantId;
456
- l && o.includes(n) && !c[n] && (c[n] = l);
457
- const E = this.ownerIdPathKey, f = r.sub;
458
- f && o.includes(E) && !c[E] && (c[E] = f);
459
- }
460
- }
461
- function w(s) {
462
- try {
463
- if (typeof s != "string")
464
- return null;
465
- const e = s.split(".");
466
- if (e.length !== 3)
467
- return null;
468
- const r = e[1].replace(/-/g, "+").replace(/_/g, "/"), o = r.padEnd(
469
- r.length + (4 - r.length % 4) % 4,
470
- "="
471
- ), n = decodeURIComponent(
472
- atob(o).split("").map(function(c) {
473
- return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
474
- }).join("")
475
- );
476
- return JSON.parse(n);
477
- } catch (e) {
478
- return console.error("Failed to parse JWT token", e), null;
479
- }
480
- }
481
- function ee(s, e = 0) {
482
- const t = typeof s == "string" ? w(s) : s;
483
- if (!t)
484
- return !0;
485
- const r = t.exp;
486
- return r ? Date.now() / 1e3 > r - e : !1;
487
- }
488
- class g {
489
- /**
490
- * Creates a new JwtToken instance.
491
- *
492
- * Parses the JWT token string to extract the payload and stores the early period
493
- * for expiration checks.
494
- *
495
- * @param token The raw JWT token string to parse
496
- * @param earlyPeriod The early expiration period in milliseconds (default: 0).
497
- * Tokens are considered expired this many milliseconds before their actual expiration time.
498
- *
499
- * @throws Will not throw but payload will be null if token parsing fails
500
- */
501
- constructor(e, t = 0) {
502
- this.token = e, this.earlyPeriod = t, this.payload = w(e);
503
- }
504
- /**
505
- * Checks if the token is expired.
506
- *
507
- * Considers both the token's expiration time and the early period.
508
- * Returns true if the payload is null (parsing failed) or if the token is expired.
509
- *
510
- * @returns true if the token is expired or invalid, false otherwise
511
- */
512
- get isExpired() {
513
- return this.payload ? ee(this.payload, this.earlyPeriod) : !0;
514
- }
515
- }
516
- class U {
517
- /**
518
- * Creates a new JwtCompositeToken instance.
519
- *
520
- * Initializes both access and refresh token instances with the provided early period.
521
- *
522
- * @param token The composite token containing access and refresh token strings
523
- * @param earlyPeriod The early expiration period in milliseconds (default: 0)
524
- */
525
- constructor(e, t = 0) {
526
- this.token = e, this.earlyPeriod = t, this.access = new g(e.accessToken, t), this.refresh = new g(e.refreshToken, t);
527
- }
528
- /**
529
- * Checks if the access token needs to be refreshed.
530
- *
531
- * @returns true if the access token is expired, false otherwise
532
- */
533
- get isRefreshNeeded() {
534
- return this.access.isExpired;
535
- }
536
- /**
537
- * Checks if the refresh token is still valid and can be used to refresh the access token.
538
- *
539
- * @returns true if the refresh token is not expired, false otherwise
540
- */
541
- get isRefreshable() {
542
- return !this.refresh.isExpired;
543
- }
544
- /**
545
- * Checks if the user is currently authenticated (access token is valid).
546
- *
547
- * @returns true if the access token is not expired, false otherwise
548
- */
549
- get authenticated() {
550
- return !this.access.isExpired;
551
- }
552
- }
553
- class C {
554
- /**
555
- * Creates a new JwtCompositeTokenSerializer instance.
556
- *
557
- * @param earlyPeriod The early expiration period in milliseconds to use for deserialized tokens (default: 0)
558
- */
559
- constructor(e = 0) {
560
- this.earlyPeriod = e;
561
- }
562
- /**
563
- * Deserializes a JSON string to a JwtCompositeToken.
564
- *
565
- * Parses the JSON string and creates a new JwtCompositeToken instance with the stored tokens.
566
- *
567
- * @param value The JSON string representation of a composite token
568
- * @returns A JwtCompositeToken instance
569
- * @throws SyntaxError if the JSON string is invalid
570
- * @throws Error if the parsed object doesn't match the expected CompositeToken structure
571
- */
572
- deserialize(e) {
573
- const t = JSON.parse(e);
574
- return new U(t, this.earlyPeriod);
575
- }
576
- /**
577
- * Serializes a JwtCompositeToken to a JSON string.
578
- *
579
- * Converts the composite token to a JSON string for storage.
580
- *
581
- * @param value The JwtCompositeToken to serialize
582
- * @returns A JSON string representation of the composite token
583
- */
584
- serialize(e) {
585
- return JSON.stringify(e.token);
586
- }
587
- }
588
- const Ee = new C(), S = "cosec-token";
589
- class te extends p {
590
- /**
591
- * Creates a new TokenStorage instance.
592
- * @param options - Configuration options for the token storage.
593
- * @param options.key - The storage key for tokens. Defaults to DEFAULT_COSEC_TOKEN_KEY.
594
- * @param options.eventBus - Event bus for token change notifications. Defaults to a BroadcastTypedEventBus with SerialTypedEventBus delegate.
595
- * @param options.earlyPeriod - Early period for token refresh in milliseconds. Defaults to 0.
596
- * @param reset - Additional options passed to KeyStorage.
597
- */
598
- constructor({
599
- key: e = S,
600
- eventBus: t = new R({
601
- delegate: new T(S)
602
- }),
603
- earlyPeriod: r = 0,
604
- ...o
605
- } = {}) {
606
- super({
607
- key: e,
608
- eventBus: t,
609
- ...o,
610
- serializer: new C(r)
611
- }), this.earlyPeriod = r;
612
- }
613
- /**
614
- * Sets a composite token in storage.
615
- * Converts the composite token to a JwtCompositeToken and stores it.
616
- * @deprecated Use signIn() instead for better semantic clarity.
617
- * @param compositeToken - The composite token containing access and refresh tokens.
618
- */
619
- setCompositeToken(e) {
620
- this.signIn(e);
621
- }
622
- /**
623
- * Signs in by storing the composite token.
624
- * @param compositeToken - The composite token to store for authentication.
625
- */
626
- signIn(e) {
627
- this.set(new U(e, this.earlyPeriod));
628
- }
629
- /**
630
- * Signs out by removing the stored token.
631
- * Clears the token from storage.
632
- */
633
- signOut() {
634
- this.remove();
635
- }
636
- /**
637
- * Checks if the user is authenticated.
638
- * @returns true if a valid token is present and authenticated, false otherwise.
639
- */
640
- get authenticated() {
641
- return this.get()?.authenticated === !0;
642
- }
643
- /**
644
- * Gets the current user's JWT payload.
645
- * @returns The JWT payload of the current user if authenticated, null otherwise.
646
- */
647
- get currentUser() {
648
- return this.authenticated ? this.get()?.access.payload ?? null : null;
649
- }
650
- }
651
- const re = "UnauthorizedErrorInterceptor", se = 0;
652
- class oe {
653
- /**
654
- * Creates a new UnauthorizedErrorInterceptor instance.
655
- *
656
- * @param options - Configuration options containing the callback to handle unauthorized responses
657
- */
658
- constructor(e) {
659
- this.options = e, this.name = re, this.order = se;
660
- }
661
- /**
662
- * Intercepts fetch exchanges to detect and handle unauthorized (401) responses
663
- * and RefreshTokenError exceptions.
664
- *
665
- * This method checks if the response status is 401 (Unauthorized) or if the exchange
666
- * contains an error of type `RefreshTokenError`. If either condition is met, it invokes
667
- * the configured `onUnauthorized` callback with the exchange details. The method
668
- * does not return a value or throw exceptions - all error handling is delegated
669
- * to the callback function.
670
- *
671
- * @param exchange - The fetch exchange containing request, response, and error information
672
- * to be inspected for unauthorized status codes or refresh token errors
673
- * @returns {void} This method does not return a value
674
- *
675
- * @example
676
- * ```typescript
677
- * const interceptor = new UnauthorizedErrorInterceptor({
678
- * onUnauthorized: (exchange) => {
679
- * // Custom logic here
680
- * }
681
- * });
682
- * ```
683
- */
684
- async intercept(e) {
685
- (e.response?.status === h.UNAUTHORIZED || e.error instanceof d) && await this.options.onUnauthorized(e);
686
- }
687
- }
688
- class Ie {
689
- /**
690
- * Creates a new CoSecConfigurer instance with the provided configuration.
691
- *
692
- * The constructor performs dependency initialization:
693
- * - Creates or wraps tokenStorage and deviceIdStorage with defaults
694
- * - Initializes spaceIdProvider (defaults to NoneSpaceIdProvider)
695
- * - Conditionally creates tokenManager only if tokenRefresher is provided
696
- *
697
- * @param config - CoSec configuration object containing all settings
698
- *
699
- * @throws Error if appId is not provided
700
- * @throws Error if provided dependencies are invalid
701
- *
702
- * @example
703
- * ```typescript
704
- * // Full configuration
705
- * const configurer = new CoSecConfigurer({
706
- * appId: 'my-app',
707
- * tokenStorage: customTokenStorage,
708
- * deviceIdStorage: customDeviceStorage,
709
- * tokenRefresher: myRefresher,
710
- * spaceIdProvider: mySpaceProvider,
711
- * onUnauthorized: handle401,
712
- * onForbidden: handle403
713
- * });
714
- *
715
- * // Minimal configuration
716
- * const configurer = new CoSecConfigurer({
717
- * appId: 'my-app'
718
- * });
719
- *
720
- * // Custom storage with default refresh
721
- * const configurer = new CoSecConfigurer({
722
- * appId: 'my-app',
723
- * tokenStorage: encryptedStorage,
724
- * deviceIdStorage: customDeviceStorage
725
- * });
726
- * ```
727
- */
728
- constructor(e) {
729
- this.config = e, this.tokenStorage = e.tokenStorage ?? new te(), this.deviceIdStorage = e.deviceIdStorage ?? new J(), this.spaceIdProvider = e.spaceIdProvider ?? k, e.tokenRefresher && (this.tokenManager = new j(
730
- this.tokenStorage,
731
- e.tokenRefresher
732
- ));
733
- }
734
- /**
735
- * Applies CoSec interceptors to the specified Fetcher instance.
736
- *
737
- * This method registers all configured interceptors with the Fetcher's
738
- * interceptor chain. The registration is conditional based on the config:
739
- *
740
- * **Always Registered (Headers & Attribution):**
741
- * - CoSecRequestInterceptor: Injects security headers
742
- * - ResourceAttributionRequestInterceptor: Adds tenant attribution parameters
743
- *
744
- * **Conditional Registration (Authentication):**
745
- * - AuthorizationRequestInterceptor: Adds Bearer token [requires tokenRefresher]
746
- * - AuthorizationResponseInterceptor: Handles 401 refresh [requires tokenRefresher]
747
- *
748
- * **Conditional Registration (Error Handling):**
749
- * - UnauthorizedErrorInterceptor: Custom 401 handling [requires onUnauthorized]
750
- * - ForbiddenErrorInterceptor: Custom 403 handling [requires onForbidden]
751
- *
752
- * @param fetcher - The Fetcher instance to configure with CoSec interceptors
753
- *
754
- * @throws Error if fetcher is null or undefined
755
- *
756
- * @example
757
- * ```typescript
758
- * const fetcher = new Fetcher({ baseUrl: 'https://api.example.com' });
759
- *
760
- * const configurer = new CoSecConfigurer({
761
- * appId: 'my-app',
762
- * tokenRefresher: myRefresher,
763
- * onUnauthorized: () => redirectToLogin(),
764
- * onForbidden: () => showError()
765
- * });
766
- *
767
- * configurer.applyTo(fetcher);
768
- *
769
- * // Now fetcher has all CoSec interceptors configured
770
- * const data = await fetcher.get('/api/data');
771
- * ```
772
- *
773
- * @example
774
- * ```typescript
775
- * // Applying to multiple fetchers
776
- * const apiFetcher = new Fetcher({ baseUrl: 'https://api.example.com' });
777
- * const adminFetcher = new Fetcher({ baseUrl: 'https://admin.example.com' });
778
- *
779
- * const configurer = new CoSecConfigurer({
780
- * appId: 'my-app',
781
- * tokenRefresher: myRefresher,
782
- * onForbidden: showAccessDenied
783
- * });
784
- *
785
- * // Apply same configuration to multiple fetchers
786
- * configurer.applyTo(apiFetcher);
787
- * configurer.applyTo(adminFetcher);
788
- * ```
789
- */
790
- applyTo(e) {
791
- e.interceptors.request.use(
792
- new q({
793
- appId: this.config.appId,
794
- deviceIdStorage: this.deviceIdStorage,
795
- spaceIdProvider: this.spaceIdProvider
796
- })
797
- ), e.interceptors.request.use(
798
- new $({
799
- tokenStorage: this.tokenStorage
800
- })
801
- ), this.tokenManager && (e.interceptors.request.use(
802
- new B({
803
- tokenManager: this.tokenManager
804
- })
805
- ), e.interceptors.response.use(
806
- new x({
807
- tokenManager: this.tokenManager
808
- })
809
- )), this.config.onUnauthorized && e.interceptors.error.use(
810
- new oe({
811
- onUnauthorized: this.config.onUnauthorized
812
- })
813
- ), this.config.onForbidden && e.interceptors.error.use(
814
- new Y({
815
- onForbidden: this.config.onForbidden
816
- })
817
- );
818
- }
164
+ //#endregion
165
+ //#region src/jwts.ts
166
+ function B(e) {
167
+ try {
168
+ if (typeof e != "string") return null;
169
+ let t = e.split(".");
170
+ if (t.length !== 3) return null;
171
+ let n = t[1].replace(/-/g, "+").replace(/_/g, "/"), r = n.padEnd(n.length + (4 - n.length % 4) % 4, "="), i = decodeURIComponent(atob(r).split("").map(function(e) {
172
+ return "%" + ("00" + e.charCodeAt(0).toString(16)).slice(-2);
173
+ }).join(""));
174
+ return JSON.parse(i);
175
+ } catch (e) {
176
+ return console.error("Failed to parse JWT token", e), null;
177
+ }
819
178
  }
820
- class pe {
821
- /**
822
- * Creates a new instance of CoSecTokenRefresher.
823
- *
824
- * @param {CoSecTokenRefresherOptions} options - The configuration options for the token refresher.
825
- * @param {Fetcher} options.fetcher - The HTTP client instance used for making refresh requests.
826
- * @param {string} options.endpoint - The URL endpoint for token refresh operations.
827
- *
828
- * @example
829
- * ```typescript
830
- * const refresher = new CoSecTokenRefresher({
831
- * fetcher: myFetcherInstance,
832
- * endpoint: '/api/v1/auth/refresh'
833
- * });
834
- * ```
835
- */
836
- constructor(e) {
837
- this.options = e;
838
- }
839
- /**
840
- * Refreshes the given composite token by sending a POST request to the configured endpoint.
841
- *
842
- * This method sends the current token pair to the refresh endpoint and expects
843
- * a new CompositeToken in response.
844
- *
845
- * **CRITICAL**: The request includes a special
846
- * attribute `attributes: new Map([[IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY, true]])`
847
- * to prevent infinite loops. Without this attribute, the request interceptor
848
- * may attempt to refresh the token again, causing a recursive loop.
849
- *
850
- * @param {CompositeToken} token - The composite token to refresh, containing both access and refresh tokens.
851
- * @returns {Promise<CompositeToken>} A promise that resolves to a new CompositeToken with refreshed tokens.
852
- * @throws {Error} Throws an error if the HTTP request fails, the server returns an error status, or the response cannot be parsed as JSON.
853
- * @throws {NetworkError} Throws a network error if there are connectivity issues.
854
- * @throws {AuthenticationError} Throws an authentication error if the refresh token is invalid or expired.
855
- *
856
- * @example
857
- * ```typescript
858
- * const refresher = new CoSecTokenRefresher({ fetcher, endpoint: '/auth/refresh' });
859
- * const token = { accessToken: 'expired-token', refreshToken: 'valid-refresh-token' };
860
- *
861
- * try {
862
- * const newToken = await refresher.refresh(token);
863
- * console.log('Refreshed access token:', newToken.accessToken);
864
- * } catch (error) {
865
- * console.error('Token refresh failed:', error.message);
866
- * }
867
- * ```
868
- *
869
- * @warning **Important**: Always include the `IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY` attribute
870
- * in refresh requests to avoid infinite loops caused by recursive token refresh attempts.
871
- */
872
- refresh(e) {
873
- return this.options.fetcher.post(
874
- this.options.endpoint,
875
- {
876
- body: e
877
- },
878
- {
879
- resultExtractor: v.Json,
880
- attributes: /* @__PURE__ */ new Map([[D, !0]])
881
- }
882
- );
883
- }
179
+ function V(e, t = 0) {
180
+ let n = typeof e == "string" ? B(e) : e;
181
+ if (!n) return !0;
182
+ let r = n.exp;
183
+ return r ? Date.now() / 1e3 > r - t : !1;
884
184
  }
885
- export {
886
- F as AUTHORIZATION_REQUEST_INTERCEPTOR_NAME,
887
- K as AUTHORIZATION_REQUEST_INTERCEPTOR_ORDER,
888
- H as AUTHORIZATION_RESPONSE_INTERCEPTOR_NAME,
889
- Z as AUTHORIZATION_RESPONSE_INTERCEPTOR_ORDER,
890
- B as AuthorizationRequestInterceptor,
891
- x as AuthorizationResponseInterceptor,
892
- he as AuthorizeResults,
893
- M as COSEC_REQUEST_INTERCEPTOR_NAME,
894
- A as COSEC_REQUEST_INTERCEPTOR_ORDER,
895
- Ie as CoSecConfigurer,
896
- i as CoSecHeaders,
897
- q as CoSecRequestInterceptor,
898
- pe as CoSecTokenRefresher,
899
- _ as DEFAULT_COSEC_DEVICE_ID_KEY,
900
- O as DEFAULT_COSEC_SPACE_ID_KEY,
901
- S as DEFAULT_COSEC_TOKEN_KEY,
902
- de as DefaultSpaceIdProvider,
903
- J as DeviceIdStorage,
904
- L as FORBIDDEN_ERROR_INTERCEPTOR_NAME,
905
- Q as FORBIDDEN_ERROR_INTERCEPTOR_ORDER,
906
- Y as ForbiddenErrorInterceptor,
907
- D as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY,
908
- U as JwtCompositeToken,
909
- C as JwtCompositeTokenSerializer,
910
- g as JwtToken,
911
- j as JwtTokenManager,
912
- z as NanoIdGenerator,
913
- k as NoneSpaceIdProvider,
914
- W as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_NAME,
915
- X as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_ORDER,
916
- d as RefreshTokenError,
917
- $ as ResourceAttributionRequestInterceptor,
918
- h as ResponseCodes,
919
- ue as SpaceIdStorage,
920
- te as TokenStorage,
921
- re as UNAUTHORIZED_ERROR_INTERCEPTOR_NAME,
922
- se as UNAUTHORIZED_ERROR_INTERCEPTOR_ORDER,
923
- oe as UnauthorizedErrorInterceptor,
924
- P as idGenerator,
925
- ee as isTokenExpired,
926
- Ee as jwtCompositeTokenSerializer,
927
- w as parseJwtPayload
185
+ //#endregion
186
+ //#region src/jwtToken.ts
187
+ var H = class {
188
+ constructor(e, t = 0) {
189
+ this.token = e, this.earlyPeriod = t, this.payload = B(e);
190
+ }
191
+ get isExpired() {
192
+ return this.payload ? V(this.payload, this.earlyPeriod) : !0;
193
+ }
194
+ }, U = class {
195
+ constructor(e, t = 0) {
196
+ this.token = e, this.earlyPeriod = t, this.access = new H(e.accessToken, t), this.refresh = new H(e.refreshToken, t);
197
+ }
198
+ get isRefreshNeeded() {
199
+ return this.access.isExpired;
200
+ }
201
+ get isRefreshable() {
202
+ return !this.refresh.isExpired;
203
+ }
204
+ get authenticated() {
205
+ return !this.access.isExpired;
206
+ }
207
+ }, W = class {
208
+ constructor(e = 0) {
209
+ this.earlyPeriod = e;
210
+ }
211
+ deserialize(e) {
212
+ return new U(JSON.parse(e), this.earlyPeriod);
213
+ }
214
+ serialize(e) {
215
+ return JSON.stringify(e.token);
216
+ }
217
+ }, G = new W(), K = "cosec-token", q = class extends a {
218
+ constructor({ key: e = K, eventBus: t = new s({ delegate: new c(K) }), earlyPeriod: n = 0, ...r } = {}) {
219
+ super({
220
+ key: e,
221
+ eventBus: t,
222
+ ...r,
223
+ serializer: new W(n)
224
+ }), this.earlyPeriod = n;
225
+ }
226
+ setCompositeToken(e) {
227
+ this.signIn(e);
228
+ }
229
+ signIn(e) {
230
+ this.set(new U(e, this.earlyPeriod));
231
+ }
232
+ signOut() {
233
+ this.remove();
234
+ }
235
+ get authenticated() {
236
+ return this.get()?.authenticated === !0;
237
+ }
238
+ get currentUser() {
239
+ return this.authenticated ? this.get()?.access.payload ?? null : null;
240
+ }
241
+ }, J = "UnauthorizedErrorInterceptor", Y = 0, X = class {
242
+ constructor(e) {
243
+ this.options = e, this.name = J, this.order = 0;
244
+ }
245
+ async intercept(e) {
246
+ (e.response?.status === u.UNAUTHORIZED || e.error instanceof N) && await this.options.onUnauthorized(e);
247
+ }
248
+ }, Z = class {
249
+ constructor(e) {
250
+ this.config = e, this.tokenStorage = e.tokenStorage ?? new q(), this.deviceIdStorage = e.deviceIdStorage ?? new k(), this.spaceIdProvider = e.spaceIdProvider ?? m, e.tokenRefresher && (this.tokenManager = new P(this.tokenStorage, e.tokenRefresher));
251
+ }
252
+ applyTo(e) {
253
+ e.interceptors.request.use(new x({
254
+ appId: this.config.appId,
255
+ deviceIdStorage: this.deviceIdStorage,
256
+ spaceIdProvider: this.spaceIdProvider
257
+ })), e.interceptors.request.use(new z({ tokenStorage: this.tokenStorage })), this.tokenManager && (e.interceptors.request.use(new w({ tokenManager: this.tokenManager })), e.interceptors.response.use(new D({ tokenManager: this.tokenManager }))), this.config.onUnauthorized && e.interceptors.error.use(new X({ onUnauthorized: this.config.onUnauthorized })), this.config.onForbidden && e.interceptors.error.use(new M({ onForbidden: this.config.onForbidden }));
258
+ }
259
+ }, Q = class {
260
+ constructor(e) {
261
+ this.options = e;
262
+ }
263
+ refresh(e) {
264
+ return this.options.fetcher.post(this.options.endpoint, { body: e }, {
265
+ resultExtractor: n.Json,
266
+ attributes: new Map([[b, !0]])
267
+ });
268
+ }
928
269
  };
929
- //# sourceMappingURL=index.es.js.map
270
+ //#endregion
271
+ export { S as AUTHORIZATION_REQUEST_INTERCEPTOR_NAME, C as AUTHORIZATION_REQUEST_INTERCEPTOR_ORDER, T as AUTHORIZATION_RESPONSE_INTERCEPTOR_NAME, E as AUTHORIZATION_RESPONSE_INTERCEPTOR_ORDER, w as AuthorizationRequestInterceptor, D as AuthorizationResponseInterceptor, d as AuthorizeResults, v as COSEC_REQUEST_INTERCEPTOR_NAME, y as COSEC_REQUEST_INTERCEPTOR_ORDER, Z as CoSecConfigurer, l as CoSecHeaders, x as CoSecRequestInterceptor, Q as CoSecTokenRefresher, O as DEFAULT_COSEC_DEVICE_ID_KEY, h as DEFAULT_COSEC_SPACE_ID_KEY, K as DEFAULT_COSEC_TOKEN_KEY, _ as DefaultSpaceIdProvider, k as DeviceIdStorage, A as FORBIDDEN_ERROR_INTERCEPTOR_NAME, j as FORBIDDEN_ERROR_INTERCEPTOR_ORDER, M as ForbiddenErrorInterceptor, b as IGNORE_REFRESH_TOKEN_ATTRIBUTE_KEY, U as JwtCompositeToken, W as JwtCompositeTokenSerializer, H as JwtToken, P as JwtTokenManager, f as NanoIdGenerator, m as NoneSpaceIdProvider, L as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_NAME, R as RESOURCE_ATTRIBUTION_REQUEST_INTERCEPTOR_ORDER, N as RefreshTokenError, z as ResourceAttributionRequestInterceptor, u as ResponseCodes, g as SpaceIdStorage, q as TokenStorage, J as UNAUTHORIZED_ERROR_INTERCEPTOR_NAME, Y as UNAUTHORIZED_ERROR_INTERCEPTOR_ORDER, X as UnauthorizedErrorInterceptor, p as idGenerator, V as isTokenExpired, G as jwtCompositeTokenSerializer, B as parseJwtPayload };
272
+
273
+ //# sourceMappingURL=index.es.js.map