@23blocks/angular 14.4.0 β†’ 14.5.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/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## 14.5.1 (2026-03-14)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **@23blocks/angular:** start lifecycle on OAuth login methods ([6af5acd](https://github.com/23blocks-OS/frontend-sdk/commit/6af5acd))
6
+ - **@23blocks/angular:** fix lifecycle stop-before-signOut and token storage race ([e009c86](https://github.com/23blocks-OS/frontend-sdk/commit/e009c86))
7
+
8
+ ### πŸ“– Documentation
9
+
10
+ - update llms.txt and JSDoc for token lifecycle across all packages ([74d8319](https://github.com/23blocks-OS/frontend-sdk/commit/74d8319))
11
+
12
+ ### ❀️ Thank You
13
+
14
+ - Claude Opus 4.6
15
+ - Juan Pelaez
16
+
17
+ ## 14.5.0 (2026-03-14)
18
+
19
+ ### πŸš€ Features
20
+
21
+ - **@23blocks/angular:** integrate token lifecycle with AuthenticationService ([df3c6c3](https://github.com/23blocks-OS/frontend-sdk/commit/df3c6c3))
22
+
23
+ ### ❀️ Thank You
24
+
25
+ - Claude Opus 4.6
26
+ - Juan Pelaez
27
+
1
28
  ## 14.4.0 (2026-03-09)
2
29
 
3
30
  ### πŸš€ Features
@@ -1,8 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, makeEnvironmentProviders, Optional, Inject, Injectable } from '@angular/core';
3
3
  import { createHttpTransport } from '@23blocks/transport-http';
4
- import { from, tap } from 'rxjs';
4
+ import { BlockErrorException } from '@23blocks/contracts';
5
5
  import { createAuthenticationBlock } from '@23blocks/block-authentication';
6
+ import { from, tap } from 'rxjs';
6
7
  import { createSearchBlock } from '@23blocks/block-search';
7
8
  import { createProductsBlock } from '@23blocks/block-products';
8
9
  import { createCrmBlock } from '@23blocks/block-crm';
@@ -148,6 +149,10 @@ const WALLET_CONFIG = new InjectionToken('23blocks.wallet.config');
148
149
  */
149
150
  const RAG_CONFIG = new InjectionToken('23blocks.rag.config');
150
151
 
152
+ /**
153
+ * Injection token for the token lifecycle manager
154
+ */
155
+ const TOKEN_LIFECYCLE = new InjectionToken('23blocks.token-lifecycle');
151
156
  /**
152
157
  * Injection token for the token manager (internal use)
153
158
  */
@@ -287,6 +292,220 @@ function createTransportWithAuth(baseUrl, config, tokenManager) {
287
292
  },
288
293
  });
289
294
  }
295
+ // ─────────────────────────────────────────────────────────────────────────────
296
+ // Token Lifecycle Helpers
297
+ // CANONICAL SOURCE: packages/sdk/src/lib/token-lifecycle.ts
298
+ // These are inlined here to avoid adding @23blocks/sdk as a dependency
299
+ // (which would change ng-packagr and consumer dependency requirements).
300
+ // When fixing bugs, update all three copies: sdk, react, angular.
301
+ // ─────────────────────────────────────────────────────────────────────────────
302
+ function decodeJwtExp(token) {
303
+ try {
304
+ const parts = token.split('.');
305
+ if (parts.length !== 3)
306
+ return null;
307
+ let payload = parts[1].replace(/-/g, '+').replace(/_/g, '/');
308
+ const pad = payload.length % 4;
309
+ if (pad)
310
+ payload += '='.repeat(4 - pad);
311
+ let decoded;
312
+ if (typeof atob === 'function') {
313
+ decoded = atob(payload);
314
+ }
315
+ else if (typeof Buffer !== 'undefined') {
316
+ decoded = Buffer.from(payload, 'base64').toString('utf-8');
317
+ }
318
+ else {
319
+ return null;
320
+ }
321
+ const parsed = JSON.parse(decoded);
322
+ return typeof parsed.exp === 'number' ? parsed.exp : null;
323
+ }
324
+ catch {
325
+ return null;
326
+ }
327
+ }
328
+ function isBrowserEnv() {
329
+ try {
330
+ return typeof window !== 'undefined'
331
+ && typeof window.localStorage !== 'undefined'
332
+ && typeof window.localStorage.getItem === 'function';
333
+ }
334
+ catch {
335
+ return false;
336
+ }
337
+ }
338
+ function createLifecycleManager(tokenManager, refreshFn, config = {}) {
339
+ const { refreshBufferSeconds = 120, enableVisibilityRefresh = true, enableProactiveRefresh = true, } = config;
340
+ const listeners = new Set();
341
+ let refreshTimer = null;
342
+ let refreshPromise = null;
343
+ let visibilityHandler = null;
344
+ let destroyed = false;
345
+ let running = false;
346
+ function notify(event) {
347
+ listeners.forEach((l) => { try {
348
+ l(event);
349
+ }
350
+ catch { } });
351
+ }
352
+ function clearTimer() {
353
+ if (refreshTimer !== null) {
354
+ clearTimeout(refreshTimer);
355
+ refreshTimer = null;
356
+ }
357
+ }
358
+ function scheduleRefresh() {
359
+ if (!enableProactiveRefresh || destroyed || !running)
360
+ return;
361
+ clearTimer();
362
+ const accessToken = tokenManager.getAccessToken();
363
+ if (!accessToken)
364
+ return;
365
+ const exp = decodeJwtExp(accessToken);
366
+ if (!exp)
367
+ return;
368
+ const refreshInSeconds = (exp - Math.floor(Date.now() / 1000)) - refreshBufferSeconds;
369
+ if (refreshInSeconds <= 0) {
370
+ refreshNow().catch(() => { });
371
+ return;
372
+ }
373
+ refreshTimer = setTimeout(() => {
374
+ if (!destroyed && running)
375
+ refreshNow().catch(() => { });
376
+ }, refreshInSeconds * 1000);
377
+ }
378
+ function handleVisibilityChange() {
379
+ if (destroyed || !running || typeof document === 'undefined')
380
+ return;
381
+ if (document.visibilityState === 'visible') {
382
+ const accessToken = tokenManager.getAccessToken();
383
+ if (!accessToken)
384
+ return;
385
+ const exp = decodeJwtExp(accessToken);
386
+ if (!exp) {
387
+ refreshNow().catch(() => { });
388
+ return;
389
+ }
390
+ const secondsUntilExpiry = exp - Math.floor(Date.now() / 1000);
391
+ if (secondsUntilExpiry <= refreshBufferSeconds) {
392
+ refreshNow().catch(() => { });
393
+ }
394
+ else {
395
+ scheduleRefresh();
396
+ }
397
+ }
398
+ }
399
+ async function refreshNow() {
400
+ if (destroyed)
401
+ throw new Error('[23blocks] Lifecycle destroyed');
402
+ if (refreshPromise)
403
+ return refreshPromise;
404
+ refreshPromise = (async () => {
405
+ try {
406
+ const rt = tokenManager.getRefreshToken();
407
+ if (!rt)
408
+ throw new Error('No refresh token');
409
+ const result = await refreshFn(rt);
410
+ // Guard: don't store tokens if lifecycle was stopped/destroyed during the async call
411
+ if (!running || destroyed)
412
+ return result.accessToken;
413
+ tokenManager.setTokens(result.accessToken, result.refreshToken);
414
+ scheduleRefresh();
415
+ notify('TOKEN_REFRESHED');
416
+ return result.accessToken;
417
+ }
418
+ catch (error) {
419
+ clearTimer();
420
+ tokenManager.clearTokens();
421
+ running = false;
422
+ notify('SESSION_EXPIRED');
423
+ throw error;
424
+ }
425
+ finally {
426
+ refreshPromise = null;
427
+ }
428
+ })();
429
+ return refreshPromise;
430
+ }
431
+ return {
432
+ start() {
433
+ if (destroyed)
434
+ return;
435
+ running = true;
436
+ scheduleRefresh();
437
+ if (enableVisibilityRefresh && isBrowserEnv() && !visibilityHandler && typeof document !== 'undefined') {
438
+ visibilityHandler = handleVisibilityChange;
439
+ document.addEventListener('visibilitychange', visibilityHandler);
440
+ }
441
+ notify('SIGNED_IN');
442
+ },
443
+ stop() {
444
+ running = false;
445
+ clearTimer();
446
+ refreshPromise = null;
447
+ notify('SIGNED_OUT');
448
+ },
449
+ onAuthStateChanged(listener) {
450
+ listeners.add(listener);
451
+ return () => { listeners.delete(listener); };
452
+ },
453
+ refreshNow,
454
+ destroy() {
455
+ destroyed = true;
456
+ running = false;
457
+ clearTimer();
458
+ refreshPromise = null;
459
+ if (visibilityHandler && typeof document !== 'undefined') {
460
+ document.removeEventListener('visibilitychange', visibilityHandler);
461
+ visibilityHandler = null;
462
+ }
463
+ listeners.clear();
464
+ },
465
+ };
466
+ }
467
+ function createRetryTransport(baseTransport, getLifecycle) {
468
+ async function withRetry(fn) {
469
+ try {
470
+ return await fn();
471
+ }
472
+ catch (error) {
473
+ if (error instanceof BlockErrorException && error.status === 401) {
474
+ const lc = getLifecycle();
475
+ if (lc) {
476
+ try {
477
+ await lc.refreshNow();
478
+ return await fn();
479
+ }
480
+ catch {
481
+ throw error;
482
+ }
483
+ }
484
+ }
485
+ throw error;
486
+ }
487
+ }
488
+ return {
489
+ get(path, options) {
490
+ return withRetry(() => baseTransport.get(path, options));
491
+ },
492
+ post(path, body, options) {
493
+ return withRetry(() => baseTransport.post(path, body, options));
494
+ },
495
+ patch(path, body, options) {
496
+ return withRetry(() => baseTransport.patch(path, body, options));
497
+ },
498
+ put(path, body, options) {
499
+ return withRetry(() => baseTransport.put(path, body, options));
500
+ },
501
+ delete(path, options) {
502
+ return withRetry(() => baseTransport.delete(path, options));
503
+ },
504
+ };
505
+ }
506
+ // ─────────────────────────────────────────────────────────────────────────────
507
+ // Providers
508
+ // ─────────────────────────────────────────────────────────────────────────────
290
509
  /**
291
510
  * Provide 23blocks services with simplified configuration.
292
511
  *
@@ -335,15 +554,20 @@ function createTransportWithAuth(baseUrl, config, tokenManager) {
335
554
  function provideBlocks23(config) {
336
555
  // Block config for all services
337
556
  const blockConfig = { apiKey: config.apiKey, tenantId: config.tenantId };
557
+ const lifecycleEnabled = config.authMode !== 'cookie' && config.tokenLifecycle !== false;
338
558
  // Helper to create transport provider for a service URL
339
559
  const createTransportProvider = (token, url) => ({
340
560
  provide: token,
341
- useFactory: (tokenManager) => {
561
+ useFactory: (tokenManager, lifecycle) => {
342
562
  if (!url)
343
563
  return null;
344
- return createTransportWithAuth(url, config, tokenManager);
564
+ const base = createTransportWithAuth(url, config, tokenManager);
565
+ if (lifecycleEnabled && lifecycle) {
566
+ return createRetryTransport(base, () => lifecycle);
567
+ }
568
+ return base;
345
569
  },
346
- deps: [TOKEN_MANAGER],
570
+ deps: [TOKEN_MANAGER, TOKEN_LIFECYCLE],
347
571
  });
348
572
  const providers = [
349
573
  // Store config for injection
@@ -356,7 +580,34 @@ function provideBlocks23(config) {
356
580
  return createTokenManager(config.apiKey, storage, config.tenantId);
357
581
  },
358
582
  },
359
- // Per-service transport factories (null if URL not configured)
583
+ // Token lifecycle manager - uses a dedicated refresh transport (avoids circular retry)
584
+ {
585
+ provide: TOKEN_LIFECYCLE,
586
+ useFactory: (tokenManager) => {
587
+ if (!lifecycleEnabled || !config.urls.authentication)
588
+ return null;
589
+ // Dedicated transport for refresh calls β€” NOT wrapped with retry
590
+ const refreshTransport = createTransportWithAuth(config.urls.authentication, config, tokenManager);
591
+ const authBlock = createAuthenticationBlock(refreshTransport, blockConfig);
592
+ const refreshFn = async (refreshToken) => {
593
+ const response = await authBlock.auth.refreshToken({ refreshToken });
594
+ return {
595
+ accessToken: response.accessToken,
596
+ refreshToken: response.refreshToken,
597
+ expiresIn: response.expiresIn,
598
+ };
599
+ };
600
+ const lcConfig = typeof config.tokenLifecycle === 'object' ? config.tokenLifecycle : {};
601
+ const lc = createLifecycleManager(tokenManager, refreshFn, lcConfig);
602
+ // Auto-start if tokens exist (page reload)
603
+ if (tokenManager.getAccessToken() && tokenManager.getRefreshToken()) {
604
+ lc.start();
605
+ }
606
+ return lc;
607
+ },
608
+ deps: [TOKEN_MANAGER],
609
+ },
610
+ // Per-service transport factories (null if URL not configured, wrapped with retry if lifecycle enabled)
360
611
  createTransportProvider(AUTHENTICATION_TRANSPORT, config.urls.authentication),
361
612
  createTransportProvider(SEARCH_TRANSPORT, config.urls.search),
362
613
  createTransportProvider(PRODUCTS_TRANSPORT, config.urls.products),
@@ -448,15 +699,20 @@ function provideBlocks23(config) {
448
699
  function getBlocks23Providers(config) {
449
700
  // Block config for all services
450
701
  const blockConfig = { apiKey: config.apiKey, tenantId: config.tenantId };
702
+ const lifecycleEnabled = config.authMode !== 'cookie' && config.tokenLifecycle !== false;
451
703
  // Helper to create transport provider for a service URL
452
704
  const createTransportProvider = (token, url) => ({
453
705
  provide: token,
454
- useFactory: (tokenManager) => {
706
+ useFactory: (tokenManager, lifecycle) => {
455
707
  if (!url)
456
708
  return null;
457
- return createTransportWithAuth(url, config, tokenManager);
709
+ const base = createTransportWithAuth(url, config, tokenManager);
710
+ if (lifecycleEnabled && lifecycle) {
711
+ return createRetryTransport(base, () => lifecycle);
712
+ }
713
+ return base;
458
714
  },
459
- deps: [TOKEN_MANAGER],
715
+ deps: [TOKEN_MANAGER, TOKEN_LIFECYCLE],
460
716
  });
461
717
  return [
462
718
  // Store config for injection
@@ -469,7 +725,28 @@ function getBlocks23Providers(config) {
469
725
  return createTokenManager(config.apiKey, storage, config.tenantId);
470
726
  },
471
727
  },
472
- // Per-service transport factories (null if URL not configured)
728
+ // Token lifecycle manager
729
+ {
730
+ provide: TOKEN_LIFECYCLE,
731
+ useFactory: (tokenManager) => {
732
+ if (!lifecycleEnabled || !config.urls.authentication)
733
+ return null;
734
+ const refreshTransport = createTransportWithAuth(config.urls.authentication, config, tokenManager);
735
+ const authBlock = createAuthenticationBlock(refreshTransport, blockConfig);
736
+ const refreshFn = async (refreshToken) => {
737
+ const response = await authBlock.auth.refreshToken({ refreshToken });
738
+ return { accessToken: response.accessToken, refreshToken: response.refreshToken, expiresIn: response.expiresIn };
739
+ };
740
+ const lcConfig = typeof config.tokenLifecycle === 'object' ? config.tokenLifecycle : {};
741
+ const lc = createLifecycleManager(tokenManager, refreshFn, lcConfig);
742
+ if (tokenManager.getAccessToken() && tokenManager.getRefreshToken()) {
743
+ lc.start();
744
+ }
745
+ return lc;
746
+ },
747
+ deps: [TOKEN_MANAGER],
748
+ },
749
+ // Per-service transport factories (null if URL not configured, wrapped with retry if lifecycle enabled)
473
750
  createTransportProvider(AUTHENTICATION_TRANSPORT, config.urls.authentication),
474
751
  createTransportProvider(SEARCH_TRANSPORT, config.urls.search),
475
752
  createTransportProvider(PRODUCTS_TRANSPORT, config.urls.products),
@@ -729,11 +1006,13 @@ class AuthenticationService {
729
1006
  block;
730
1007
  tokenManager;
731
1008
  simpleConfig;
732
- constructor(serviceTransport, legacyTransport, config, tokenManager, simpleConfig) {
1009
+ lifecycle;
1010
+ constructor(serviceTransport, legacyTransport, config, tokenManager, simpleConfig, lifecycle) {
733
1011
  const transport = serviceTransport ?? legacyTransport;
734
1012
  this.block = transport ? createAuthenticationBlock(transport, config) : null;
735
1013
  this.tokenManager = tokenManager;
736
1014
  this.simpleConfig = simpleConfig;
1015
+ this.lifecycle = lifecycle;
737
1016
  }
738
1017
  ensureConfigured() {
739
1018
  if (!this.block) {
@@ -768,7 +1047,11 @@ class AuthenticationService {
768
1047
  * ```
769
1048
  */
770
1049
  signIn(request) {
771
- return from(this.ensureConfigured().auth.signIn(request)).pipe(tap((response) => this.storeTokens(response)));
1050
+ return from(this.ensureConfigured().auth.signIn(request)).pipe(tap((response) => {
1051
+ this.storeTokens(response);
1052
+ if (response.accessToken)
1053
+ this.lifecycle?.start();
1054
+ }));
772
1055
  }
773
1056
  /**
774
1057
  * Sign up a new user.
@@ -784,6 +1067,7 @@ class AuthenticationService {
784
1067
  return from(this.ensureConfigured().auth.signUp(request)).pipe(tap((response) => {
785
1068
  if (this.isTokenMode && this.tokenManager && response.accessToken) {
786
1069
  this.tokenManager.setTokens(response.accessToken);
1070
+ this.lifecycle?.start();
787
1071
  }
788
1072
  }));
789
1073
  }
@@ -794,6 +1078,8 @@ class AuthenticationService {
794
1078
  * @returns Observable that completes on successful sign-out
795
1079
  */
796
1080
  signOut() {
1081
+ // Stop lifecycle BEFORE the API call to prevent refresh during signOut
1082
+ this.lifecycle?.stop();
797
1083
  return from(this.ensureConfigured().auth.signOut()).pipe(tap(() => {
798
1084
  if (this.isTokenMode && this.tokenManager) {
799
1085
  this.tokenManager.clearTokens();
@@ -819,7 +1105,11 @@ class AuthenticationService {
819
1105
  * @returns Observable emitting SignInResponse with `user`, `accessToken`, optional `refreshToken`
820
1106
  */
821
1107
  verifyMagicLink(request) {
822
- return from(this.ensureConfigured().auth.verifyMagicLink(request)).pipe(tap((response) => this.storeTokens(response)));
1108
+ return from(this.ensureConfigured().auth.verifyMagicLink(request)).pipe(tap((response) => {
1109
+ this.storeTokens(response);
1110
+ if (response.accessToken)
1111
+ this.lifecycle?.start();
1112
+ }));
823
1113
  }
824
1114
  /**
825
1115
  * Accept an invitation and create the user's account.
@@ -830,7 +1120,11 @@ class AuthenticationService {
830
1120
  * optional `refreshToken`
831
1121
  */
832
1122
  acceptInvitation(request) {
833
- return from(this.ensureConfigured().auth.acceptInvitation(request)).pipe(tap((response) => this.storeTokens(response)));
1123
+ return from(this.ensureConfigured().auth.acceptInvitation(request)).pipe(tap((response) => {
1124
+ this.storeTokens(response);
1125
+ if (response.accessToken)
1126
+ this.lifecycle?.start();
1127
+ }));
834
1128
  }
835
1129
  /**
836
1130
  * Sign in via Facebook OAuth.
@@ -840,7 +1134,11 @@ class AuthenticationService {
840
1134
  * @returns Observable emitting SignInResponse with `user` and tokens
841
1135
  */
842
1136
  facebookLogin(request) {
843
- return from(this.ensureConfigured().oauth.facebookLogin(request)).pipe(tap((response) => this.storeTokens(response)));
1137
+ return from(this.ensureConfigured().oauth.facebookLogin(request)).pipe(tap((response) => {
1138
+ this.storeTokens(response);
1139
+ if (response.accessToken)
1140
+ this.lifecycle?.start();
1141
+ }));
844
1142
  }
845
1143
  /**
846
1144
  * Sign in via Google OAuth.
@@ -850,7 +1148,11 @@ class AuthenticationService {
850
1148
  * @returns Observable emitting SignInResponse with `user` and tokens
851
1149
  */
852
1150
  googleLogin(request) {
853
- return from(this.ensureConfigured().oauth.googleLogin(request)).pipe(tap((response) => this.storeTokens(response)));
1151
+ return from(this.ensureConfigured().oauth.googleLogin(request)).pipe(tap((response) => {
1152
+ this.storeTokens(response);
1153
+ if (response.accessToken)
1154
+ this.lifecycle?.start();
1155
+ }));
854
1156
  }
855
1157
  /**
856
1158
  * Sign in via tenant-specific login (white-label authentication).
@@ -860,7 +1162,11 @@ class AuthenticationService {
860
1162
  * @returns Observable emitting SignInResponse with `user` and tokens
861
1163
  */
862
1164
  tenantLogin(request) {
863
- return from(this.ensureConfigured().oauth.tenantLogin(request)).pipe(tap((response) => this.storeTokens(response)));
1165
+ return from(this.ensureConfigured().oauth.tenantLogin(request)).pipe(tap((response) => {
1166
+ this.storeTokens(response);
1167
+ if (response.accessToken)
1168
+ this.lifecycle?.start();
1169
+ }));
864
1170
  }
865
1171
  /**
866
1172
  * Request a 6-digit OTP code for password reset (mobile flow).
@@ -935,6 +1241,28 @@ class AuthenticationService {
935
1241
  return !!this.tokenManager.getAccessToken();
936
1242
  }
937
1243
  // ─────────────────────────────────────────────────────────────────────────────
1244
+ // Token Lifecycle
1245
+ // ─────────────────────────────────────────────────────────────────────────────
1246
+ /**
1247
+ * Subscribe to auth state changes (token refreshed, session expired, etc.).
1248
+ * Returns an unsubscribe function.
1249
+ * Only active when tokenLifecycle is enabled.
1250
+ */
1251
+ onAuthStateChanged(listener) {
1252
+ return this.lifecycle?.onAuthStateChanged(listener) ?? (() => { });
1253
+ }
1254
+ /**
1255
+ * Force an immediate token refresh.
1256
+ * Returns the new access token. Throws if lifecycle is unavailable or refresh fails.
1257
+ */
1258
+ refreshSession() {
1259
+ if (!this.lifecycle) {
1260
+ return Promise.reject(new Error('[23blocks] Token lifecycle is not available. ' +
1261
+ 'Ensure authMode is "token" and tokenLifecycle is not disabled.'));
1262
+ }
1263
+ return this.lifecycle.refreshNow();
1264
+ }
1265
+ // ─────────────────────────────────────────────────────────────────────────────
938
1266
  // Delegated sub-services (Promise-based, auto-sync with block API)
939
1267
  // ─────────────────────────────────────────────────────────────────────────────
940
1268
  /** Core auth operations (signIn, signUp, signOut, password reset link+OTP, magic links, invitations). Promise-based. */
@@ -999,7 +1327,7 @@ class AuthenticationService {
999
1327
  get oidc() { return this.ensureConfigured().oidc; }
1000
1328
  /** Direct access to the underlying AuthenticationBlock instance */
1001
1329
  get authenticationBlock() { return this.ensureConfigured(); }
1002
- static Ι΅fac = i0.Ι΅Ι΅ngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AuthenticationService, deps: [{ token: AUTHENTICATION_TRANSPORT, optional: true }, { token: TRANSPORT, optional: true }, { token: AUTHENTICATION_CONFIG }, { token: TOKEN_MANAGER, optional: true }, { token: SIMPLE_CONFIG, optional: true }], target: i0.Ι΅Ι΅FactoryTarget.Injectable });
1330
+ static Ι΅fac = i0.Ι΅Ι΅ngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AuthenticationService, deps: [{ token: AUTHENTICATION_TRANSPORT, optional: true }, { token: TRANSPORT, optional: true }, { token: AUTHENTICATION_CONFIG }, { token: TOKEN_MANAGER, optional: true }, { token: SIMPLE_CONFIG, optional: true }, { token: TOKEN_LIFECYCLE, optional: true }], target: i0.Ι΅Ι΅FactoryTarget.Injectable });
1003
1331
  static Ι΅prov = i0.Ι΅Ι΅ngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AuthenticationService, providedIn: 'root' });
1004
1332
  }
1005
1333
  i0.Ι΅Ι΅ngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AuthenticationService, decorators: [{
@@ -1028,6 +1356,11 @@ i0.Ι΅Ι΅ngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1028
1356
  }, {
1029
1357
  type: Inject,
1030
1358
  args: [SIMPLE_CONFIG]
1359
+ }] }, { type: undefined, decorators: [{
1360
+ type: Optional
1361
+ }, {
1362
+ type: Inject,
1363
+ args: [TOKEN_LIFECYCLE]
1031
1364
  }] }] });
1032
1365
 
1033
1366
  /**
@@ -2121,7 +2454,7 @@ i0.Ι΅Ι΅ngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2121
2454
  }] }] });
2122
2455
 
2123
2456
  // ─────────────────────────────────────────────────────────────────────────────
2124
- // Main API (Recommended) β€” blocks expose health(), CreateOrderRequest supports flat + items[]
2457
+ // Main API (Recommended) β€” token lifecycle with auto-refresh and 401 retry
2125
2458
  // ─────────────────────────────────────────────────────────────────────────────
2126
2459
 
2127
2460
  // Angular bindings β€” search, crm, files, onboarding aligned with API strong params
@@ -2130,5 +2463,5 @@ i0.Ι΅Ι΅ngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2130
2463
  * Generated bundle index. Do not edit.
2131
2464
  */
2132
2465
 
2133
- export { ASSETS_CONFIG, ASSETS_TRANSPORT, AUTHENTICATION_CONFIG, AUTHENTICATION_TRANSPORT, AssetsService, AuthenticationService, CAMPAIGNS_CONFIG, CAMPAIGNS_TRANSPORT, COMPANY_CONFIG, COMPANY_TRANSPORT, CONTENT_CONFIG, CONTENT_TRANSPORT, CONVERSATIONS_CONFIG, CONVERSATIONS_TRANSPORT, CRM_CONFIG, CRM_TRANSPORT, CampaignsService, CompanyService, ContentService, ConversationsService, CrmService, FILES_CONFIG, FILES_TRANSPORT, FORMS_CONFIG, FORMS_TRANSPORT, FilesService, FormsService, GEOLOCATION_CONFIG, GEOLOCATION_TRANSPORT, GeolocationService, JARVIS_CONFIG, JARVIS_TRANSPORT, JarvisService, ONBOARDING_CONFIG, ONBOARDING_TRANSPORT, OnboardingService, PRODUCTS_CONFIG, PRODUCTS_TRANSPORT, PROVIDER_CONFIG, ProductsService, RAG_CONFIG, RAG_TRANSPORT, REWARDS_CONFIG, REWARDS_TRANSPORT, RagService, RewardsService, SALES_CONFIG, SALES_TRANSPORT, SEARCH_CONFIG, SEARCH_TRANSPORT, SIMPLE_CONFIG, SalesService, SearchService, TOKEN_MANAGER, TRANSPORT, UNIVERSITY_CONFIG, UNIVERSITY_TRANSPORT, UniversityService, WALLET_CONFIG, WALLET_TRANSPORT, WalletService, get23BlocksProviders, getBlocks23Providers, provide23Blocks, provideBlocks23 };
2466
+ export { ASSETS_CONFIG, ASSETS_TRANSPORT, AUTHENTICATION_CONFIG, AUTHENTICATION_TRANSPORT, AssetsService, AuthenticationService, CAMPAIGNS_CONFIG, CAMPAIGNS_TRANSPORT, COMPANY_CONFIG, COMPANY_TRANSPORT, CONTENT_CONFIG, CONTENT_TRANSPORT, CONVERSATIONS_CONFIG, CONVERSATIONS_TRANSPORT, CRM_CONFIG, CRM_TRANSPORT, CampaignsService, CompanyService, ContentService, ConversationsService, CrmService, FILES_CONFIG, FILES_TRANSPORT, FORMS_CONFIG, FORMS_TRANSPORT, FilesService, FormsService, GEOLOCATION_CONFIG, GEOLOCATION_TRANSPORT, GeolocationService, JARVIS_CONFIG, JARVIS_TRANSPORT, JarvisService, ONBOARDING_CONFIG, ONBOARDING_TRANSPORT, OnboardingService, PRODUCTS_CONFIG, PRODUCTS_TRANSPORT, PROVIDER_CONFIG, ProductsService, RAG_CONFIG, RAG_TRANSPORT, REWARDS_CONFIG, REWARDS_TRANSPORT, RagService, RewardsService, SALES_CONFIG, SALES_TRANSPORT, SEARCH_CONFIG, SEARCH_TRANSPORT, SIMPLE_CONFIG, SalesService, SearchService, TOKEN_LIFECYCLE, TOKEN_MANAGER, TRANSPORT, UNIVERSITY_CONFIG, UNIVERSITY_TRANSPORT, UniversityService, WALLET_CONFIG, WALLET_TRANSPORT, WalletService, get23BlocksProviders, getBlocks23Providers, provide23Blocks, provideBlocks23 };
2134
2467
  //# sourceMappingURL=23blocks-angular.mjs.map