@ngbase/adk 0.1.16 → 0.1.18
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/fesm2022/ngbase-adk-a11y.mjs +42 -42
- package/fesm2022/ngbase-adk-a11y.mjs.map +1 -1
- package/fesm2022/ngbase-adk-accordion.mjs +20 -26
- package/fesm2022/ngbase-adk-accordion.mjs.map +1 -1
- package/fesm2022/ngbase-adk-autocomplete.mjs +11 -11
- package/fesm2022/ngbase-adk-autocomplete.mjs.map +1 -1
- package/fesm2022/ngbase-adk-avatar.mjs +13 -13
- package/fesm2022/ngbase-adk-avatar.mjs.map +1 -1
- package/fesm2022/ngbase-adk-bidi.mjs +3 -3
- package/fesm2022/ngbase-adk-bidi.mjs.map +1 -1
- package/fesm2022/ngbase-adk-breadcrumb.mjs +14 -14
- package/fesm2022/ngbase-adk-breadcrumb.mjs.map +1 -1
- package/fesm2022/ngbase-adk-cache.mjs +3 -3
- package/fesm2022/ngbase-adk-cache.mjs.map +1 -1
- package/fesm2022/ngbase-adk-carousel.mjs +18 -18
- package/fesm2022/ngbase-adk-carousel.mjs.map +1 -1
- package/fesm2022/ngbase-adk-checkbox.mjs +15 -21
- package/fesm2022/ngbase-adk-checkbox.mjs.map +1 -1
- package/fesm2022/ngbase-adk-chip.mjs +12 -12
- package/fesm2022/ngbase-adk-chip.mjs.map +1 -1
- package/fesm2022/ngbase-adk-clipboard.mjs +7 -5
- package/fesm2022/ngbase-adk-clipboard.mjs.map +1 -1
- package/fesm2022/ngbase-adk-collections.mjs.map +1 -1
- package/fesm2022/ngbase-adk-color-picker.mjs +44 -53
- package/fesm2022/ngbase-adk-color-picker.mjs.map +1 -1
- package/fesm2022/ngbase-adk-cookies.mjs +3 -3
- package/fesm2022/ngbase-adk-cookies.mjs.map +1 -1
- package/fesm2022/ngbase-adk-datepicker.mjs +70 -89
- package/fesm2022/ngbase-adk-datepicker.mjs.map +1 -1
- package/fesm2022/ngbase-adk-dialog.mjs +17 -39
- package/fesm2022/ngbase-adk-dialog.mjs.map +1 -1
- package/fesm2022/ngbase-adk-drag.mjs +20 -20
- package/fesm2022/ngbase-adk-drag.mjs.map +1 -1
- package/fesm2022/ngbase-adk-form-field.mjs +65 -118
- package/fesm2022/ngbase-adk-form-field.mjs.map +1 -1
- package/fesm2022/ngbase-adk-hover-card.mjs +5 -5
- package/fesm2022/ngbase-adk-hover-card.mjs.map +1 -1
- package/fesm2022/ngbase-adk-icon.mjs +9 -11
- package/fesm2022/ngbase-adk-icon.mjs.map +1 -1
- package/fesm2022/ngbase-adk-inline-edit.mjs +27 -35
- package/fesm2022/ngbase-adk-inline-edit.mjs.map +1 -1
- package/fesm2022/ngbase-adk-jwt.mjs +319 -41
- package/fesm2022/ngbase-adk-jwt.mjs.map +1 -1
- package/fesm2022/ngbase-adk-keys.mjs +6 -6
- package/fesm2022/ngbase-adk-keys.mjs.map +1 -1
- package/fesm2022/ngbase-adk-layout.mjs.map +1 -1
- package/fesm2022/ngbase-adk-list.mjs +10 -10
- package/fesm2022/ngbase-adk-list.mjs.map +1 -1
- package/fesm2022/ngbase-adk-mask.mjs +8 -8
- package/fesm2022/ngbase-adk-mask.mjs.map +1 -1
- package/fesm2022/ngbase-adk-menu.mjs +69 -79
- package/fesm2022/ngbase-adk-menu.mjs.map +1 -1
- package/fesm2022/ngbase-adk-network.mjs +3 -3
- package/fesm2022/ngbase-adk-network.mjs.map +1 -1
- package/fesm2022/ngbase-adk-otp.mjs +24 -45
- package/fesm2022/ngbase-adk-otp.mjs.map +1 -1
- package/fesm2022/ngbase-adk-pagination.mjs +9 -9
- package/fesm2022/ngbase-adk-pagination.mjs.map +1 -1
- package/fesm2022/ngbase-adk-popover.mjs +120 -89
- package/fesm2022/ngbase-adk-popover.mjs.map +1 -1
- package/fesm2022/ngbase-adk-portal.mjs +134 -47
- package/fesm2022/ngbase-adk-portal.mjs.map +1 -1
- package/fesm2022/ngbase-adk-progress.mjs +7 -7
- package/fesm2022/ngbase-adk-progress.mjs.map +1 -1
- package/fesm2022/ngbase-adk-radio.mjs +20 -27
- package/fesm2022/ngbase-adk-radio.mjs.map +1 -1
- package/fesm2022/ngbase-adk-resizable.mjs +138 -48
- package/fesm2022/ngbase-adk-resizable.mjs.map +1 -1
- package/fesm2022/ngbase-adk-scroll-area.mjs +28 -20
- package/fesm2022/ngbase-adk-scroll-area.mjs.map +1 -1
- package/fesm2022/ngbase-adk-select.mjs +58 -80
- package/fesm2022/ngbase-adk-select.mjs.map +1 -1
- package/fesm2022/ngbase-adk-selectable.mjs +19 -30
- package/fesm2022/ngbase-adk-selectable.mjs.map +1 -1
- package/fesm2022/ngbase-adk-sheet.mjs +6 -20
- package/fesm2022/ngbase-adk-sheet.mjs.map +1 -1
- package/fesm2022/ngbase-adk-sidenav.mjs +65 -46
- package/fesm2022/ngbase-adk-sidenav.mjs.map +1 -1
- package/fesm2022/ngbase-adk-slider.mjs +40 -53
- package/fesm2022/ngbase-adk-slider.mjs.map +1 -1
- package/fesm2022/ngbase-adk-sonner.mjs +12 -19
- package/fesm2022/ngbase-adk-sonner.mjs.map +1 -1
- package/fesm2022/ngbase-adk-stepper.mjs +17 -25
- package/fesm2022/ngbase-adk-stepper.mjs.map +1 -1
- package/fesm2022/ngbase-adk-switch.mjs +25 -32
- package/fesm2022/ngbase-adk-switch.mjs.map +1 -1
- package/fesm2022/ngbase-adk-table.mjs +581 -83
- package/fesm2022/ngbase-adk-table.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tabs.mjs +37 -35
- package/fesm2022/ngbase-adk-tabs.mjs.map +1 -1
- package/fesm2022/ngbase-adk-test.mjs.map +1 -1
- package/fesm2022/ngbase-adk-toggle-group.mjs +20 -34
- package/fesm2022/ngbase-adk-toggle-group.mjs.map +1 -1
- package/fesm2022/ngbase-adk-toggle.mjs +14 -19
- package/fesm2022/ngbase-adk-toggle.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tooltip.mjs +12 -19
- package/fesm2022/ngbase-adk-tooltip.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tour.mjs +52 -52
- package/fesm2022/ngbase-adk-tour.mjs.map +1 -1
- package/fesm2022/ngbase-adk-translate.mjs +8 -10
- package/fesm2022/ngbase-adk-translate.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tree.mjs +20 -20
- package/fesm2022/ngbase-adk-tree.mjs.map +1 -1
- package/fesm2022/ngbase-adk-utils.mjs +30 -43
- package/fesm2022/ngbase-adk-utils.mjs.map +1 -1
- package/fesm2022/ngbase-adk-virtualizer.mjs +9 -9
- package/fesm2022/ngbase-adk-virtualizer.mjs.map +1 -1
- package/package.json +91 -91
- package/schematics/components/files/accordion/accordion.ts.template +9 -6
- package/schematics/components/files/audio/AudioPlayer.ts.template +245 -0
- package/schematics/components/files/audio/AudioRecorder.ts.template +377 -0
- package/schematics/components/files/audio/AudioVisualizer.ts.template +175 -0
- package/schematics/components/files/audio/index.ts.template +3 -0
- package/schematics/components/files/button/button-llm.md.template +3 -2
- package/schematics/components/files/charts/area-chart.component.ts.template +278 -0
- package/schematics/components/files/charts/bar-chart.component.ts.template +262 -0
- package/schematics/components/files/charts/chart-tooltip.component.ts.template +168 -0
- package/schematics/components/files/charts/index.ts.template +4 -0
- package/schematics/components/files/charts/line-chart.component.ts.template +238 -0
- package/schematics/components/files/charts/pie-chart.component.ts.template +283 -0
- package/schematics/components/files/checkbox/checkbox.ts.template +2 -2
- package/schematics/components/files/color-picker/color-picker.ts.template +2 -2
- package/schematics/components/files/dialog/dialog.ts.template +18 -14
- package/schematics/components/files/drawer/drawer.ts.template +30 -27
- package/schematics/components/files/form-field/form-field.ts.template +51 -23
- package/schematics/components/files/pagination/pagination.ts.template +4 -4
- package/schematics/components/files/picasa/picasa-base.component.ts.template +15 -30
- package/schematics/components/files/popover/popover.ts.template +15 -4
- package/schematics/components/files/select/list-selection.ts.template +0 -2
- package/schematics/components/files/select/option.ts.template +1 -1
- package/schematics/components/files/selectable/selectable.ts.template +2 -2
- package/schematics/components/files/sheet/sheet.ts.template +26 -14
- package/schematics/components/files/sidenav/sidenav.ts.template +7 -5
- package/schematics/components/files/sonner/sonner.ts.template +1 -2
- package/schematics/components/files/stepper/stepper.ts.template +2 -4
- package/schematics/components/files/switch/switch.ts.template +2 -2
- package/schematics/components/files/table/table.ts.template +43 -3
- package/schematics/components/files/tabs/tab.ts.template +3 -3
- package/schematics/components/files/theme/theme.service.ts.template +3 -3
- package/schematics/components/files/toggle/toggle.ts.template +1 -1
- package/schematics/components/files/toggle-group/toggle-group.ts.template +1 -1
- package/schematics/components/files/tooltip/tooltip.ts.template +2 -3
- package/schematics/components/schema.json +2 -0
- package/{accordion/index.d.ts → types/ngbase-adk-accordion.d.ts} +1 -3
- package/{autocomplete/index.d.ts → types/ngbase-adk-autocomplete.d.ts} +2 -7
- package/{checkbox/index.d.ts → types/ngbase-adk-checkbox.d.ts} +8 -14
- package/types/ngbase-adk-clipboard.d.ts +12 -0
- package/{color-picker/index.d.ts → types/ngbase-adk-color-picker.d.ts} +14 -26
- package/{datepicker/index.d.ts → types/ngbase-adk-datepicker.d.ts} +9 -18
- package/{dialog/index.d.ts → types/ngbase-adk-dialog.d.ts} +3 -8
- package/types/ngbase-adk-form-field.d.ts +88 -0
- package/{inline-edit/index.d.ts → types/ngbase-adk-inline-edit.d.ts} +8 -16
- package/types/ngbase-adk-jwt.d.ts +64 -0
- package/{menu/index.d.ts → types/ngbase-adk-menu.d.ts} +6 -5
- package/{otp/index.d.ts → types/ngbase-adk-otp.d.ts} +8 -16
- package/{popover/index.d.ts → types/ngbase-adk-popover.d.ts} +14 -2
- package/{portal/index.d.ts → types/ngbase-adk-portal.d.ts} +29 -8
- package/{radio/index.d.ts → types/ngbase-adk-radio.d.ts} +9 -12
- package/{resizable/index.d.ts → types/ngbase-adk-resizable.d.ts} +4 -4
- package/{scroll-area/index.d.ts → types/ngbase-adk-scroll-area.d.ts} +2 -1
- package/{select/index.d.ts → types/ngbase-adk-select.d.ts} +8 -22
- package/{selectable/index.d.ts → types/ngbase-adk-selectable.d.ts} +6 -10
- package/{sheet/index.d.ts → types/ngbase-adk-sheet.d.ts} +4 -3
- package/{sidenav/index.d.ts → types/ngbase-adk-sidenav.d.ts} +6 -6
- package/{slider/index.d.ts → types/ngbase-adk-slider.d.ts} +8 -17
- package/{sonner/index.d.ts → types/ngbase-adk-sonner.d.ts} +1 -3
- package/{stepper/index.d.ts → types/ngbase-adk-stepper.d.ts} +1 -4
- package/{switch/index.d.ts → types/ngbase-adk-switch.d.ts} +7 -14
- package/{table/index.d.ts → types/ngbase-adk-table.d.ts} +126 -3
- package/{test/index.d.ts → types/ngbase-adk-test.d.ts} +1 -1
- package/{toggle-group/index.d.ts → types/ngbase-adk-toggle-group.d.ts} +5 -10
- package/types/ngbase-adk-toggle.d.ts +14 -0
- package/{tooltip/index.d.ts → types/ngbase-adk-tooltip.d.ts} +9 -11
- package/{tour/index.d.ts → types/ngbase-adk-tour.d.ts} +4 -6
- package/{utils/index.d.ts → types/ngbase-adk-utils.d.ts} +15 -11
- package/clipboard/index.d.ts +0 -11
- package/form-field/index.d.ts +0 -97
- package/jwt/index.d.ts +0 -20
- package/toggle/index.d.ts +0 -16
- /package/{a11y/index.d.ts → types/ngbase-adk-a11y.d.ts} +0 -0
- /package/{avatar/index.d.ts → types/ngbase-adk-avatar.d.ts} +0 -0
- /package/{bidi/index.d.ts → types/ngbase-adk-bidi.d.ts} +0 -0
- /package/{breadcrumb/index.d.ts → types/ngbase-adk-breadcrumb.d.ts} +0 -0
- /package/{cache/index.d.ts → types/ngbase-adk-cache.d.ts} +0 -0
- /package/{carousel/index.d.ts → types/ngbase-adk-carousel.d.ts} +0 -0
- /package/{chip/index.d.ts → types/ngbase-adk-chip.d.ts} +0 -0
- /package/{collections/index.d.ts → types/ngbase-adk-collections.d.ts} +0 -0
- /package/{cookies/index.d.ts → types/ngbase-adk-cookies.d.ts} +0 -0
- /package/{drag/index.d.ts → types/ngbase-adk-drag.d.ts} +0 -0
- /package/{hover-card/index.d.ts → types/ngbase-adk-hover-card.d.ts} +0 -0
- /package/{icon/index.d.ts → types/ngbase-adk-icon.d.ts} +0 -0
- /package/{keys/index.d.ts → types/ngbase-adk-keys.d.ts} +0 -0
- /package/{layout/index.d.ts → types/ngbase-adk-layout.d.ts} +0 -0
- /package/{list/index.d.ts → types/ngbase-adk-list.d.ts} +0 -0
- /package/{mask/index.d.ts → types/ngbase-adk-mask.d.ts} +0 -0
- /package/{network/index.d.ts → types/ngbase-adk-network.d.ts} +0 -0
- /package/{pagination/index.d.ts → types/ngbase-adk-pagination.d.ts} +0 -0
- /package/{progress/index.d.ts → types/ngbase-adk-progress.d.ts} +0 -0
- /package/{tabs/index.d.ts → types/ngbase-adk-tabs.d.ts} +0 -0
- /package/{translate/index.d.ts → types/ngbase-adk-translate.d.ts} +0 -0
- /package/{tree/index.d.ts → types/ngbase-adk-tree.d.ts} +0 -0
- /package/{virtualizer/index.d.ts → types/ngbase-adk-virtualizer.d.ts} +0 -0
- /package/{index.d.ts → types/ngbase-adk.d.ts} +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, inject, Injectable } from '@angular/core';
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, signal, computed, inject, Injectable } from '@angular/core';
|
|
3
|
+
import { BehaviorSubject, throwError, of } from 'rxjs';
|
|
4
|
+
import { tap, catchError, switchMap, filter, take, map } from 'rxjs/operators';
|
|
3
5
|
|
|
4
6
|
// injectiontoken for getting the token
|
|
5
7
|
const JWT_OPTIONS = new InjectionToken('JWT_OPTIONS');
|
|
@@ -9,41 +11,59 @@ function provideJwt(options) {
|
|
|
9
11
|
{ provide: JwtInterceptor, useClass: JwtInterceptor },
|
|
10
12
|
]);
|
|
11
13
|
}
|
|
12
|
-
class
|
|
13
|
-
constructor() {
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
14
|
+
class TokenHandler {
|
|
15
|
+
constructor(storageKey, tokenGetter, tokenSetter) {
|
|
16
|
+
this.storageKey = storageKey;
|
|
17
|
+
this.tokenGetter = tokenGetter;
|
|
18
|
+
this.tokenSetter = tokenSetter;
|
|
19
|
+
this._token = signal(null, ...(ngDevMode ? [{ debugName: "_token" }] : []));
|
|
20
|
+
this.token = this._token.asReadonly();
|
|
21
|
+
this.decoded = computed(() => {
|
|
22
|
+
const tokenValue = this._token();
|
|
23
|
+
if (!tokenValue)
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
const payload = tokenValue.split('.')[1];
|
|
27
|
+
return JSON.parse(this.base64UrlDecode(payload));
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.error('Error decoding token', e);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}, ...(ngDevMode ? [{ debugName: "decoded" }] : []));
|
|
34
|
+
this.exp = computed(() => {
|
|
35
|
+
const decodedToken = this.decoded();
|
|
36
|
+
return decodedToken?.exp || null;
|
|
37
|
+
}, ...(ngDevMode ? [{ debugName: "exp" }] : []));
|
|
38
|
+
this.expirationDate = computed(() => {
|
|
39
|
+
const exp = this.exp();
|
|
40
|
+
if (!exp)
|
|
41
|
+
return null;
|
|
42
|
+
const date = new Date(0);
|
|
43
|
+
date.setUTCSeconds(exp);
|
|
44
|
+
return date;
|
|
45
|
+
}, ...(ngDevMode ? [{ debugName: "expirationDate" }] : []));
|
|
46
|
+
this.isExpired = () => {
|
|
47
|
+
const expiry = this.expirationDate();
|
|
48
|
+
const ise = expiry ? expiry <= new Date() : true;
|
|
49
|
+
return ise;
|
|
50
|
+
};
|
|
51
|
+
const initialToken = this.tokenGetter?.() ?? localStorage.getItem(this.storageKey);
|
|
52
|
+
this._token.set(initialToken);
|
|
16
53
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
isTokenExpired(token) {
|
|
21
|
-
const inputToken = token ?? this.getToken();
|
|
22
|
-
if (!inputToken)
|
|
23
|
-
return true;
|
|
24
|
-
const expiry = this.getTokenExpirationDate(inputToken);
|
|
25
|
-
return expiry ? expiry <= new Date() : true;
|
|
26
|
-
}
|
|
27
|
-
decodeToken(token) {
|
|
28
|
-
const inputToken = token ?? this.getToken();
|
|
29
|
-
if (!inputToken)
|
|
30
|
-
return null;
|
|
31
|
-
try {
|
|
32
|
-
const payload = inputToken.split('.')[1];
|
|
33
|
-
return JSON.parse(this.base64UrlDecode(payload));
|
|
54
|
+
setToken(token) {
|
|
55
|
+
if (this.tokenSetter) {
|
|
56
|
+
this.tokenSetter(token);
|
|
34
57
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
else {
|
|
59
|
+
if (token) {
|
|
60
|
+
localStorage.setItem(this.storageKey, token);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
localStorage.removeItem(this.storageKey);
|
|
64
|
+
}
|
|
38
65
|
}
|
|
39
|
-
|
|
40
|
-
getTokenExpirationDate(token) {
|
|
41
|
-
const decoded = this.decodeToken(token);
|
|
42
|
-
if (!decoded || !decoded.exp)
|
|
43
|
-
return null;
|
|
44
|
-
const date = new Date(0);
|
|
45
|
-
date.setUTCSeconds(decoded.exp);
|
|
46
|
-
return date;
|
|
66
|
+
this._token.set(token);
|
|
47
67
|
}
|
|
48
68
|
base64UrlDecode(input) {
|
|
49
69
|
input = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
@@ -52,10 +72,44 @@ class JwtService {
|
|
|
52
72
|
}
|
|
53
73
|
return atob(input);
|
|
54
74
|
}
|
|
55
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0", ngImport: i0, type: JwtService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
56
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.0", ngImport: i0, type: JwtService, providedIn: 'root' }); }
|
|
57
75
|
}
|
|
58
|
-
|
|
76
|
+
class JwtService {
|
|
77
|
+
constructor() {
|
|
78
|
+
this.options = inject(JWT_OPTIONS, { optional: true });
|
|
79
|
+
this.accessTokenKey = 'access_token';
|
|
80
|
+
this.refreshTokenKey = 'refresh_token';
|
|
81
|
+
this._accessToken = new TokenHandler(this.accessTokenKey, this.options?.tokenGetter, this.options?.tokenSetter);
|
|
82
|
+
this._refreshToken = new TokenHandler(this.refreshTokenKey, this.options?.refreshTokenGetter, this.options?.refreshTokenSetter);
|
|
83
|
+
this.getAccessToken = this._accessToken.token;
|
|
84
|
+
this.getRefreshToken = this._refreshToken.token;
|
|
85
|
+
this.isAccessTokenExpired = this._accessToken.isExpired;
|
|
86
|
+
this.isRefreshTokenExpired = this._refreshToken.isExpired;
|
|
87
|
+
this.decodeToken = this._accessToken.decoded;
|
|
88
|
+
this.getTokenExpirationDate = this._accessToken.expirationDate;
|
|
89
|
+
}
|
|
90
|
+
setTokens(accessToken, refreshToken) {
|
|
91
|
+
this._accessToken.setToken(accessToken);
|
|
92
|
+
this._refreshToken.setToken(refreshToken);
|
|
93
|
+
}
|
|
94
|
+
clearTokens() {
|
|
95
|
+
this._accessToken.setToken(null);
|
|
96
|
+
this._refreshToken.setToken(null);
|
|
97
|
+
}
|
|
98
|
+
isAccessTokenNearExpiry(minutesBeforeExpiry = 5) {
|
|
99
|
+
const token = this.getAccessToken();
|
|
100
|
+
if (!token)
|
|
101
|
+
return true;
|
|
102
|
+
const expiry = this.getTokenExpirationDate();
|
|
103
|
+
if (!expiry)
|
|
104
|
+
return true;
|
|
105
|
+
console.log('minutesBeforeExpiry ', minutesBeforeExpiry);
|
|
106
|
+
const bufferTime = new Date(Date.now() + 0.5 * 60 * 1000);
|
|
107
|
+
return expiry <= bufferTime;
|
|
108
|
+
}
|
|
109
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JwtService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
110
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JwtService, providedIn: 'root' }); }
|
|
111
|
+
}
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JwtService, decorators: [{
|
|
59
113
|
type: Injectable,
|
|
60
114
|
args: [{ providedIn: 'root' }]
|
|
61
115
|
}] });
|
|
@@ -65,7 +119,7 @@ class JwtInterceptor {
|
|
|
65
119
|
this.jwtService = jwtService;
|
|
66
120
|
}
|
|
67
121
|
intercept(req, next) {
|
|
68
|
-
const token = this.jwtService.
|
|
122
|
+
const token = this.jwtService.getAccessToken();
|
|
69
123
|
if (token) {
|
|
70
124
|
req = req.clone({
|
|
71
125
|
setHeaders: { Authorization: `Bearer ${token}` },
|
|
@@ -73,18 +127,242 @@ class JwtInterceptor {
|
|
|
73
127
|
}
|
|
74
128
|
return next.handle(req);
|
|
75
129
|
}
|
|
76
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
77
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
130
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JwtInterceptor, deps: [{ token: JwtService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
131
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JwtInterceptor, providedIn: 'root' }); }
|
|
78
132
|
}
|
|
79
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JwtInterceptor, decorators: [{
|
|
80
134
|
type: Injectable,
|
|
81
135
|
args: [{ providedIn: 'root' }]
|
|
82
136
|
}], ctorParameters: () => [{ type: JwtService }] });
|
|
83
137
|
const injectJwt = () => inject(JwtService);
|
|
84
138
|
|
|
139
|
+
class TokenRefreshService {
|
|
140
|
+
constructor(refreshApi) {
|
|
141
|
+
this.refreshApi = refreshApi;
|
|
142
|
+
this.jwt = injectJwt();
|
|
143
|
+
this.refreshSubject = new BehaviorSubject(null);
|
|
144
|
+
this.isRefreshing = false;
|
|
145
|
+
/**
|
|
146
|
+
* Returns an observable that emits when refresh completes
|
|
147
|
+
*/
|
|
148
|
+
this.getRefreshStatus$ = this.refreshSubject.asObservable();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Attempts to refresh the access token using the refresh token
|
|
152
|
+
* @returns Observable with new token pair
|
|
153
|
+
*/
|
|
154
|
+
refreshToken() {
|
|
155
|
+
const refreshToken = this.jwt.getRefreshToken();
|
|
156
|
+
if (!refreshToken) {
|
|
157
|
+
return throwError(() => new Error('No refresh token available'));
|
|
158
|
+
}
|
|
159
|
+
if (this.isRefreshing) {
|
|
160
|
+
// If already refreshing, wait for the refresh to complete
|
|
161
|
+
return this.refreshSubject.asObservable();
|
|
162
|
+
}
|
|
163
|
+
this.isRefreshing = true;
|
|
164
|
+
this.refreshSubject.next(null);
|
|
165
|
+
return this.refreshApi().pipe(tap(res => {
|
|
166
|
+
this.isRefreshing = false;
|
|
167
|
+
this.refreshSubject.next(res);
|
|
168
|
+
}), catchError(error => {
|
|
169
|
+
this.isRefreshing = false;
|
|
170
|
+
this.refreshSubject.next(null);
|
|
171
|
+
// Clear tokens on refresh failure
|
|
172
|
+
this.jwt.clearTokens();
|
|
173
|
+
return throwError(() => error);
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Checks if a refresh operation is currently in progress
|
|
178
|
+
*/
|
|
179
|
+
isTokenRefreshing() {
|
|
180
|
+
return this.isRefreshing;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Proactively refresh token if it's expired or near expiry
|
|
184
|
+
* @param minutesBeforeExpiry How many minutes before expiry to refresh (default: 5)
|
|
185
|
+
* @returns Observable that emits true if refresh was needed and successful, false if not needed
|
|
186
|
+
*/
|
|
187
|
+
refreshIfNeeded(minutesBeforeExpiry = 5) {
|
|
188
|
+
if (this.jwt.isRefreshTokenExpired()) {
|
|
189
|
+
// Refresh token is expired, clear tokens and reject
|
|
190
|
+
this.jwt.clearTokens();
|
|
191
|
+
return throwError(() => new Error('Refresh token expired'));
|
|
192
|
+
}
|
|
193
|
+
if (this.jwt.isAccessTokenExpired() || this.jwt.isAccessTokenNearExpiry(minutesBeforeExpiry)) {
|
|
194
|
+
// Need to refresh
|
|
195
|
+
return this.refreshToken().pipe(switchMap(() => of(true)), // Return true to indicate refresh was performed
|
|
196
|
+
catchError(error => throwError(() => error)));
|
|
197
|
+
}
|
|
198
|
+
// No refresh needed
|
|
199
|
+
return of(false);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Centralized authentication service for guards and interceptors
|
|
205
|
+
* Handles token validation and refresh logic consistently
|
|
206
|
+
*/
|
|
207
|
+
class TokenGuardHelper {
|
|
208
|
+
constructor(refreshApi, logout) {
|
|
209
|
+
this.refreshApi = refreshApi;
|
|
210
|
+
this.logout = logout;
|
|
211
|
+
this.jwt = injectJwt();
|
|
212
|
+
/**
|
|
213
|
+
* Checks if user is authenticated, handles token refresh if needed
|
|
214
|
+
* Returns Observable<boolean> - true if authenticated, false if should redirect to login
|
|
215
|
+
*/
|
|
216
|
+
this.checkAuthentication = () => {
|
|
217
|
+
// Check if we have basic tokens
|
|
218
|
+
const accessToken = this.jwt.getAccessToken();
|
|
219
|
+
const refreshToken = this.jwt.getRefreshToken();
|
|
220
|
+
if (!accessToken || !refreshToken) {
|
|
221
|
+
console.log('AuthGuard: No tokens available, redirecting to login');
|
|
222
|
+
return of(false);
|
|
223
|
+
}
|
|
224
|
+
// Check if refresh token is expired
|
|
225
|
+
if (this.jwt.isRefreshTokenExpired()) {
|
|
226
|
+
console.warn('AuthGuard: Refresh token is expired, clearing tokens');
|
|
227
|
+
this.logout();
|
|
228
|
+
return of(false);
|
|
229
|
+
}
|
|
230
|
+
// If access token is valid, allow access
|
|
231
|
+
if (!this.jwt.isAccessTokenExpired() && !this.jwt.isAccessTokenNearExpiry(5)) {
|
|
232
|
+
console.log('AuthGuard: Access token is valid, allowing access');
|
|
233
|
+
return of(true);
|
|
234
|
+
}
|
|
235
|
+
// Access token is expired or near expiry, need to refresh
|
|
236
|
+
console.log('AuthGuard: Access token expired or near expiry, attempting refresh');
|
|
237
|
+
// Check if already refreshing
|
|
238
|
+
if (this.tokenRefreshService.isTokenRefreshing()) {
|
|
239
|
+
console.log('AuthGuard: Token refresh already in progress, waiting...');
|
|
240
|
+
return this.tokenRefreshService.getRefreshStatus$.pipe(filter(refreshed => refreshed === true), take(1), map(() => {
|
|
241
|
+
const newToken = this.jwt.getAccessToken();
|
|
242
|
+
if (newToken && !this.jwt.isAccessTokenExpired()) {
|
|
243
|
+
console.log('AuthGuard: Token refresh completed successfully');
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
console.warn('AuthGuard: No valid token after refresh completion');
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}), catchError(error => {
|
|
251
|
+
console.error('AuthGuard: Failed to wait for token refresh:', error);
|
|
252
|
+
return of(false);
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
255
|
+
// Start token refresh
|
|
256
|
+
return this.tokenRefreshService.refreshToken().pipe(map(() => {
|
|
257
|
+
if (!this.jwt.isAccessTokenExpired()) {
|
|
258
|
+
console.log('AuthGuard: Token refresh successful');
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
console.warn('AuthGuard: Invalid refresh response or token still expired');
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
}), catchError(refreshError => {
|
|
266
|
+
console.warn('AuthGuard: Token refresh failed:', refreshError);
|
|
267
|
+
this.logout();
|
|
268
|
+
return of(false);
|
|
269
|
+
}));
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Enhanced authentication check with automatic retry
|
|
273
|
+
* Attempts refresh once, then falls back to login redirect
|
|
274
|
+
*/
|
|
275
|
+
this.ensureAuthenticated = () => {
|
|
276
|
+
return this.checkAuthentication().pipe(switchMap(isAuthenticated => {
|
|
277
|
+
if (isAuthenticated) {
|
|
278
|
+
return of(true);
|
|
279
|
+
}
|
|
280
|
+
// If not authenticated after refresh attempt, redirect to login
|
|
281
|
+
console.log('AuthGuard: Authentication failed, redirecting to login');
|
|
282
|
+
this.logout();
|
|
283
|
+
return of(false);
|
|
284
|
+
}));
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Quick synchronous check for authentication status
|
|
288
|
+
* Use this only when you don't need token refresh
|
|
289
|
+
*/
|
|
290
|
+
this.isQuickAuthenticated = () => {
|
|
291
|
+
const accessToken = this.jwt.getAccessToken();
|
|
292
|
+
const refreshToken = this.jwt.getRefreshToken();
|
|
293
|
+
if (!accessToken || !refreshToken)
|
|
294
|
+
return false;
|
|
295
|
+
if (this.jwt.isRefreshTokenExpired())
|
|
296
|
+
return false;
|
|
297
|
+
if (this.jwt.isAccessTokenExpired())
|
|
298
|
+
return false;
|
|
299
|
+
return true;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Validates and refreshes token for HTTP requests
|
|
303
|
+
* Returns Observable<string> with valid access token or throws error
|
|
304
|
+
* Used by interceptors
|
|
305
|
+
*/
|
|
306
|
+
this.getValidAccessToken = () => {
|
|
307
|
+
// Check if we have tokens
|
|
308
|
+
const accessToken = this.jwt.getAccessToken();
|
|
309
|
+
if (!accessToken) {
|
|
310
|
+
console.warn('Interceptor: No access token available');
|
|
311
|
+
this.logout();
|
|
312
|
+
throw new Error('No access token available');
|
|
313
|
+
}
|
|
314
|
+
// Check if refresh token is expired
|
|
315
|
+
if (this.jwt.isRefreshTokenExpired()) {
|
|
316
|
+
console.warn('Interceptor: Refresh token is expired, redirecting to login');
|
|
317
|
+
this.logout();
|
|
318
|
+
throw new Error('Refresh token expired');
|
|
319
|
+
}
|
|
320
|
+
// If access token is valid, return it
|
|
321
|
+
if (!this.jwt.isAccessTokenExpired() && !this.jwt.isAccessTokenNearExpiry(5)) {
|
|
322
|
+
return of(accessToken);
|
|
323
|
+
}
|
|
324
|
+
// Access token needs refresh
|
|
325
|
+
console.log('Interceptor: Access token expired or near expiry, refreshing proactively');
|
|
326
|
+
// Check if already refreshing
|
|
327
|
+
if (this.tokenRefreshService.isTokenRefreshing()) {
|
|
328
|
+
return this.tokenRefreshService.getRefreshStatus$.pipe(filter(refreshed => refreshed === true), take(1), map(() => {
|
|
329
|
+
const newToken = this.jwt.getAccessToken();
|
|
330
|
+
if (newToken) {
|
|
331
|
+
return newToken;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
this.logout();
|
|
335
|
+
throw new Error('Failed to get new access token');
|
|
336
|
+
}
|
|
337
|
+
}), catchError(error => {
|
|
338
|
+
console.error('Interceptor: Failed to wait for token refresh:', error);
|
|
339
|
+
this.logout();
|
|
340
|
+
throw error;
|
|
341
|
+
}));
|
|
342
|
+
}
|
|
343
|
+
// Start token refresh
|
|
344
|
+
return this.tokenRefreshService.refreshToken().pipe(map(() => {
|
|
345
|
+
const newToken = this.jwt.getAccessToken();
|
|
346
|
+
if (newToken) {
|
|
347
|
+
return newToken;
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
this.logout();
|
|
351
|
+
throw new Error('Invalid refresh response');
|
|
352
|
+
}
|
|
353
|
+
}), catchError(refreshError => {
|
|
354
|
+
console.warn('Interceptor: Token refresh failed:', refreshError);
|
|
355
|
+
this.logout();
|
|
356
|
+
throw refreshError;
|
|
357
|
+
}));
|
|
358
|
+
};
|
|
359
|
+
this.tokenRefreshService = new TokenRefreshService(this.refreshApi);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
85
363
|
/**
|
|
86
364
|
* Generated bundle index. Do not edit.
|
|
87
365
|
*/
|
|
88
366
|
|
|
89
|
-
export { JwtService, injectJwt, provideJwt };
|
|
367
|
+
export { JwtService, TokenGuardHelper, injectJwt, provideJwt };
|
|
90
368
|
//# sourceMappingURL=ngbase-adk-jwt.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngbase-adk-jwt.mjs","sources":["../../../projects/adk/jwt/jwt.service.ts","../../../projects/adk/jwt/ngbase-adk-jwt.ts"],"sourcesContent":["import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport { inject, Injectable, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { Observable } from 'rxjs';\n\n// injectiontoken for getting the token\nconst JWT_OPTIONS = new InjectionToken<JwtOptions>('JWT_OPTIONS');\n\ninterface JwtOptions {\n tokenGetter: () => string | null | undefined;\n}\n\nexport function provideJwt(options: () => JwtOptions) {\n return makeEnvironmentProviders([\n { provide: JWT_OPTIONS, useFactory: options },\n { provide: JwtInterceptor, useClass: JwtInterceptor },\n ]);\n}\n\n@Injectable({ providedIn: 'root' })\nexport class JwtService<T> {\n private tokenKey = 'auth_token';\n private options = inject(JWT_OPTIONS, { optional: true });\n\n getToken(): string | null {\n return this.options?.tokenGetter() ?? localStorage.getItem(this.tokenKey);\n }\n\n isTokenExpired(token?: string): boolean {\n const inputToken = token ?? this.getToken();\n if (!inputToken) return true;\n\n const expiry = this.getTokenExpirationDate(inputToken);\n return expiry ? expiry <= new Date() : true;\n }\n\n decodeToken(token?: string): T | null {\n const inputToken = token ?? this.getToken();\n if (!inputToken) return null;\n\n try {\n const payload = inputToken.split('.')[1];\n return JSON.parse(this.base64UrlDecode(payload));\n } catch (e) {\n console.error('Error decoding token', e);\n return null;\n }\n }\n\n getTokenExpirationDate(token?: string): Date | null {\n const decoded = this.decodeToken(token) as T extends { exp: number } ? T : null;\n if (!decoded || !decoded.exp) return null;\n\n const date = new Date(0);\n date.setUTCSeconds(decoded.exp);\n return date;\n }\n\n private base64UrlDecode(input: string): string {\n input = input.replace(/-/g, '+').replace(/_/g, '/');\n while (input.length % 4) {\n input += '=';\n }\n return atob(input);\n }\n}\n\n// jwt interceptor\n@Injectable({ providedIn: 'root' })\nexport class JwtInterceptor implements HttpInterceptor {\n constructor(private jwtService: JwtService<any>) {}\n\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n const token = this.jwtService.getToken();\n if (token) {\n req = req.clone({\n setHeaders: { Authorization: `Bearer ${token}` },\n });\n }\n return next.handle(req);\n }\n}\n\nexport const injectJwt = () => inject(JwtService);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAIA;AACA,MAAM,WAAW,GAAG,IAAI,cAAc,CAAa,aAAa,CAAC;AAM3D,SAAU,UAAU,CAAC,OAAyB,EAAA;AAClD,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE;AAC7C,QAAA,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;AACtD,KAAA,CAAC;AACJ;MAGa,UAAU,CAAA;AADvB,IAAA,WAAA,GAAA;QAEU,IAAQ,CAAA,QAAA,GAAG,YAAY;QACvB,IAAO,CAAA,OAAA,GAAG,MAAM,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AA2C1D;IAzCC,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;;AAG3E,IAAA,cAAc,CAAC,KAAc,EAAA;QAC3B,MAAM,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;AAC3C,QAAA,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,IAAI;QAE5B,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC;AACtD,QAAA,OAAO,MAAM,GAAG,MAAM,IAAI,IAAI,IAAI,EAAE,GAAG,IAAI;;AAG7C,IAAA,WAAW,CAAC,KAAc,EAAA;QACxB,MAAM,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;AAC3C,QAAA,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,IAAI;AAE5B,QAAA,IAAI;YACF,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACxC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;;QAChD,OAAO,CAAC,EAAE;AACV,YAAA,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,CAAC,CAAC;AACxC,YAAA,OAAO,IAAI;;;AAIf,IAAA,sBAAsB,CAAC,KAAc,EAAA;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAyC;AAC/E,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG;AAAE,YAAA,OAAO,IAAI;AAEzC,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC;AACxB,QAAA,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC;AAC/B,QAAA,OAAO,IAAI;;AAGL,IAAA,eAAe,CAAC,KAAa,EAAA;AACnC,QAAA,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;AACnD,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YACvB,KAAK,IAAI,GAAG;;AAEd,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC;;8GA3CT,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAV,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAU,cADG,MAAM,EAAA,CAAA,CAAA;;2FACnB,UAAU,EAAA,UAAA,EAAA,CAAA;kBADtB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAgDlC;MAEa,cAAc,CAAA;AACzB,IAAA,WAAA,CAAoB,UAA2B,EAAA;QAA3B,IAAU,CAAA,UAAA,GAAV,UAAU;;IAE9B,SAAS,CAAC,GAAqB,EAAE,IAAiB,EAAA;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;QACxC,IAAI,KAAK,EAAE;AACT,YAAA,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC;AACd,gBAAA,UAAU,EAAE,EAAE,aAAa,EAAE,CAAU,OAAA,EAAA,KAAK,EAAE,EAAE;AACjD,aAAA,CAAC;;AAEJ,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;;8GAVd,cAAc,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAd,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,cAAc,cADD,MAAM,EAAA,CAAA,CAAA;;2FACnB,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AAerB,MAAA,SAAS,GAAG,MAAM,MAAM,CAAC,UAAU;;AClFhD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngbase-adk-jwt.mjs","sources":["../../../projects/adk/jwt/jwt.service.ts","../../../projects/adk/jwt/token-refresh.ts","../../../projects/adk/jwt/token-guard.ts","../../../projects/adk/jwt/ngbase-adk-jwt.ts"],"sourcesContent":["import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport {\n computed,\n inject,\n Injectable,\n InjectionToken,\n makeEnvironmentProviders,\n signal,\n} from '@angular/core';\nimport { Observable } from 'rxjs';\n\n// injectiontoken for getting the token\nconst JWT_OPTIONS = new InjectionToken<JwtOptions>('JWT_OPTIONS');\n\ninterface JwtOptions {\n tokenGetter: () => string | null | undefined;\n tokenSetter?: (token: string | null) => void;\n refreshTokenGetter?: () => string | null | undefined;\n refreshTokenSetter?: (token: string | null) => void;\n}\n\nexport function provideJwt(options: () => JwtOptions) {\n return makeEnvironmentProviders([\n { provide: JWT_OPTIONS, useFactory: options },\n { provide: JwtInterceptor, useClass: JwtInterceptor },\n ]);\n}\n\nclass TokenHandler<T = any> {\n readonly _token = signal<string | null>(null);\n readonly token = this._token.asReadonly();\n\n readonly decoded = computed<T | null>(() => {\n const tokenValue = this._token();\n if (!tokenValue) return null;\n\n try {\n const payload = tokenValue.split('.')[1];\n return JSON.parse(this.base64UrlDecode(payload));\n } catch (e) {\n console.error('Error decoding token', e);\n return null;\n }\n });\n\n readonly exp = computed<number | null>(() => {\n const decodedToken = this.decoded() as T extends { exp: number } ? T : null;\n return decodedToken?.exp || null;\n });\n\n readonly expirationDate = computed<Date | null>(() => {\n const exp = this.exp();\n if (!exp) return null;\n\n const date = new Date(0);\n date.setUTCSeconds(exp);\n return date;\n });\n\n readonly isExpired = () => {\n const expiry = this.expirationDate();\n const ise = expiry ? expiry <= new Date() : true;\n return ise;\n };\n\n constructor(\n private storageKey: string,\n private tokenGetter?: () => string | null | undefined,\n private tokenSetter?: (token: string | null) => void,\n ) {\n const initialToken = this.tokenGetter?.() ?? localStorage.getItem(this.storageKey);\n this._token.set(initialToken);\n }\n\n setToken(token: string | null): void {\n if (this.tokenSetter) {\n this.tokenSetter(token);\n } else {\n if (token) {\n localStorage.setItem(this.storageKey, token);\n } else {\n localStorage.removeItem(this.storageKey);\n }\n }\n this._token.set(token);\n }\n\n private base64UrlDecode(input: string): string {\n input = input.replace(/-/g, '+').replace(/_/g, '/');\n while (input.length % 4) {\n input += '=';\n }\n return atob(input);\n }\n}\n\n@Injectable({ providedIn: 'root' })\nexport class JwtService<T> {\n private options = inject(JWT_OPTIONS, { optional: true });\n\n private accessTokenKey = 'access_token';\n private refreshTokenKey = 'refresh_token';\n\n private _accessToken = new TokenHandler<T>(\n this.accessTokenKey,\n this.options?.tokenGetter,\n this.options?.tokenSetter,\n );\n private _refreshToken = new TokenHandler<T>(\n this.refreshTokenKey,\n this.options?.refreshTokenGetter,\n this.options?.refreshTokenSetter,\n );\n\n getAccessToken = this._accessToken.token;\n\n getRefreshToken = this._refreshToken.token;\n\n setTokens(accessToken: string, refreshToken: string): void {\n this._accessToken.setToken(accessToken);\n this._refreshToken.setToken(refreshToken);\n }\n\n clearTokens(): void {\n this._accessToken.setToken(null);\n this._refreshToken.setToken(null);\n }\n\n isAccessTokenExpired = this._accessToken.isExpired;\n\n isRefreshTokenExpired = this._refreshToken.isExpired;\n\n isAccessTokenNearExpiry(minutesBeforeExpiry: number = 5): boolean {\n const token = this.getAccessToken();\n if (!token) return true;\n\n const expiry = this.getTokenExpirationDate();\n if (!expiry) return true;\n\n console.log('minutesBeforeExpiry ', minutesBeforeExpiry);\n const bufferTime = new Date(Date.now() + 0.5 * 60 * 1000);\n return expiry <= bufferTime;\n }\n\n decodeToken = this._accessToken.decoded;\n\n getTokenExpirationDate = this._accessToken.expirationDate;\n}\n\n// jwt interceptor\n@Injectable({ providedIn: 'root' })\nexport class JwtInterceptor implements HttpInterceptor {\n constructor(private jwtService: JwtService<any>) {}\n\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n const token = this.jwtService.getAccessToken();\n if (token) {\n req = req.clone({\n setHeaders: { Authorization: `Bearer ${token}` },\n });\n }\n return next.handle(req);\n }\n}\n\nexport const injectJwt = <T>() => inject<JwtService<T>>(JwtService);\n","import { BehaviorSubject, Observable, throwError, of } from 'rxjs';\nimport { catchError, tap, switchMap } from 'rxjs/operators';\nimport { injectJwt } from './jwt.service';\n\nexport class TokenRefreshService<T> {\n private jwt = injectJwt();\n private refreshSubject = new BehaviorSubject<T | null>(null);\n private isRefreshing = false;\n\n /**\n * Returns an observable that emits when refresh completes\n */\n getRefreshStatus$ = this.refreshSubject.asObservable();\n\n constructor(private refreshApi: () => Observable<T>) {}\n\n /**\n * Attempts to refresh the access token using the refresh token\n * @returns Observable with new token pair\n */\n refreshToken(): Observable<T | null> {\n const refreshToken = this.jwt.getRefreshToken();\n if (!refreshToken) {\n return throwError(() => new Error('No refresh token available'));\n }\n\n if (this.isRefreshing) {\n // If already refreshing, wait for the refresh to complete\n return this.refreshSubject.asObservable();\n }\n\n this.isRefreshing = true;\n this.refreshSubject.next(null);\n\n return this.refreshApi().pipe(\n tap(res => {\n this.isRefreshing = false;\n this.refreshSubject.next(res);\n }),\n catchError(error => {\n this.isRefreshing = false;\n this.refreshSubject.next(null);\n\n // Clear tokens on refresh failure\n this.jwt.clearTokens();\n\n return throwError(() => error);\n }),\n );\n }\n\n /**\n * Checks if a refresh operation is currently in progress\n */\n isTokenRefreshing(): boolean {\n return this.isRefreshing;\n }\n\n /**\n * Proactively refresh token if it's expired or near expiry\n * @param minutesBeforeExpiry How many minutes before expiry to refresh (default: 5)\n * @returns Observable that emits true if refresh was needed and successful, false if not needed\n */\n refreshIfNeeded(minutesBeforeExpiry: number = 5): Observable<boolean> {\n if (this.jwt.isRefreshTokenExpired()) {\n // Refresh token is expired, clear tokens and reject\n this.jwt.clearTokens();\n return throwError(() => new Error('Refresh token expired'));\n }\n\n if (this.jwt.isAccessTokenExpired() || this.jwt.isAccessTokenNearExpiry(minutesBeforeExpiry)) {\n // Need to refresh\n return this.refreshToken().pipe(\n switchMap(() => of(true)), // Return true to indicate refresh was performed\n catchError(error => throwError(() => error)),\n );\n }\n\n // No refresh needed\n return of(false);\n }\n}\n","import { Observable, of } from 'rxjs';\nimport { map, catchError, switchMap, filter, take } from 'rxjs/operators';\nimport { TokenRefreshService } from './token-refresh';\nimport { injectJwt } from './jwt.service';\n\n/**\n * Centralized authentication service for guards and interceptors\n * Handles token validation and refresh logic consistently\n */\nexport class TokenGuardHelper {\n private readonly tokenRefreshService: TokenRefreshService<any>;\n private readonly jwt = injectJwt();\n\n constructor(\n private refreshApi: () => Observable<any>,\n private logout: () => void,\n ) {\n this.tokenRefreshService = new TokenRefreshService(this.refreshApi);\n }\n\n /**\n * Checks if user is authenticated, handles token refresh if needed\n * Returns Observable<boolean> - true if authenticated, false if should redirect to login\n */\n checkAuthentication = (): Observable<boolean> => {\n // Check if we have basic tokens\n const accessToken = this.jwt.getAccessToken();\n const refreshToken = this.jwt.getRefreshToken();\n\n if (!accessToken || !refreshToken) {\n console.log('AuthGuard: No tokens available, redirecting to login');\n return of(false);\n }\n\n // Check if refresh token is expired\n if (this.jwt.isRefreshTokenExpired()) {\n console.warn('AuthGuard: Refresh token is expired, clearing tokens');\n this.logout();\n return of(false);\n }\n\n // If access token is valid, allow access\n if (!this.jwt.isAccessTokenExpired() && !this.jwt.isAccessTokenNearExpiry(5)) {\n console.log('AuthGuard: Access token is valid, allowing access');\n return of(true);\n }\n\n // Access token is expired or near expiry, need to refresh\n console.log('AuthGuard: Access token expired or near expiry, attempting refresh');\n\n // Check if already refreshing\n if (this.tokenRefreshService.isTokenRefreshing()) {\n console.log('AuthGuard: Token refresh already in progress, waiting...');\n return this.tokenRefreshService.getRefreshStatus$.pipe(\n filter(refreshed => refreshed === true),\n take(1),\n map(() => {\n const newToken = this.jwt.getAccessToken();\n if (newToken && !this.jwt.isAccessTokenExpired()) {\n console.log('AuthGuard: Token refresh completed successfully');\n return true;\n } else {\n console.warn('AuthGuard: No valid token after refresh completion');\n return false;\n }\n }),\n catchError(error => {\n console.error('AuthGuard: Failed to wait for token refresh:', error);\n return of(false);\n }),\n );\n }\n\n // Start token refresh\n return this.tokenRefreshService.refreshToken().pipe(\n map(() => {\n if (!this.jwt.isAccessTokenExpired()) {\n console.log('AuthGuard: Token refresh successful');\n return true;\n } else {\n console.warn('AuthGuard: Invalid refresh response or token still expired');\n return false;\n }\n }),\n catchError(refreshError => {\n console.warn('AuthGuard: Token refresh failed:', refreshError);\n this.logout();\n return of(false);\n }),\n );\n };\n\n /**\n * Enhanced authentication check with automatic retry\n * Attempts refresh once, then falls back to login redirect\n */\n ensureAuthenticated = (): Observable<boolean> => {\n return this.checkAuthentication().pipe(\n switchMap(isAuthenticated => {\n if (isAuthenticated) {\n return of(true);\n }\n\n // If not authenticated after refresh attempt, redirect to login\n console.log('AuthGuard: Authentication failed, redirecting to login');\n this.logout();\n return of(false);\n }),\n );\n };\n\n /**\n * Quick synchronous check for authentication status\n * Use this only when you don't need token refresh\n */\n isQuickAuthenticated = (): boolean => {\n const accessToken = this.jwt.getAccessToken();\n const refreshToken = this.jwt.getRefreshToken();\n\n if (!accessToken || !refreshToken) return false;\n if (this.jwt.isRefreshTokenExpired()) return false;\n if (this.jwt.isAccessTokenExpired()) return false;\n\n return true;\n };\n\n /**\n * Validates and refreshes token for HTTP requests\n * Returns Observable<string> with valid access token or throws error\n * Used by interceptors\n */\n getValidAccessToken = (): Observable<string> => {\n // Check if we have tokens\n const accessToken = this.jwt.getAccessToken();\n\n if (!accessToken) {\n console.warn('Interceptor: No access token available');\n this.logout();\n throw new Error('No access token available');\n }\n\n // Check if refresh token is expired\n if (this.jwt.isRefreshTokenExpired()) {\n console.warn('Interceptor: Refresh token is expired, redirecting to login');\n this.logout();\n throw new Error('Refresh token expired');\n }\n\n // If access token is valid, return it\n if (!this.jwt.isAccessTokenExpired() && !this.jwt.isAccessTokenNearExpiry(5)) {\n return of(accessToken);\n }\n\n // Access token needs refresh\n console.log('Interceptor: Access token expired or near expiry, refreshing proactively');\n\n // Check if already refreshing\n if (this.tokenRefreshService.isTokenRefreshing()) {\n return this.tokenRefreshService.getRefreshStatus$.pipe(\n filter(refreshed => refreshed === true),\n take(1),\n map(() => {\n const newToken = this.jwt.getAccessToken();\n if (newToken) {\n return newToken;\n } else {\n this.logout();\n throw new Error('Failed to get new access token');\n }\n }),\n catchError(error => {\n console.error('Interceptor: Failed to wait for token refresh:', error);\n this.logout();\n throw error;\n }),\n );\n }\n\n // Start token refresh\n return this.tokenRefreshService.refreshToken().pipe(\n map(() => {\n const newToken = this.jwt.getAccessToken();\n if (newToken) {\n return newToken;\n } else {\n this.logout();\n throw new Error('Invalid refresh response');\n }\n }),\n catchError(refreshError => {\n console.warn('Interceptor: Token refresh failed:', refreshError);\n this.logout();\n throw refreshError;\n }),\n );\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -44,10 +44,10 @@ class Keys {
|
|
|
44
44
|
isKey(key) {
|
|
45
45
|
return this.keys.has(key);
|
|
46
46
|
}
|
|
47
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
48
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
47
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Keys, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
48
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Keys, providedIn: 'root' }); }
|
|
49
49
|
}
|
|
50
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Keys, decorators: [{
|
|
51
51
|
type: Injectable,
|
|
52
52
|
args: [{ providedIn: 'root' }]
|
|
53
53
|
}] });
|
|
@@ -181,10 +181,10 @@ class Shortcuts {
|
|
|
181
181
|
this.keydown.on();
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
185
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
184
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Shortcuts, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
185
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Shortcuts, providedIn: 'root' }); }
|
|
186
186
|
}
|
|
187
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
187
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Shortcuts, decorators: [{
|
|
188
188
|
type: Injectable,
|
|
189
189
|
args: [{
|
|
190
190
|
providedIn: 'root',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngbase-adk-keys.mjs","sources":["../../../projects/adk/keys/keys.service.ts","../../../projects/adk/keys/shortcuts.service.ts","../../../projects/adk/keys/public-api.ts","../../../projects/adk/keys/ngbase-adk-keys.ts"],"sourcesContent":["import { Injectable, inject, DOCUMENT } from '@angular/core';\nimport { fromEvent, merge, distinctUntilKeyChanged, filter, finalize, map, share, tap } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class Keys {\n private document = inject(DOCUMENT);\n private keyup$ = fromEvent<KeyboardEvent>(this.document, 'keyup');\n private keydown$ = fromEvent<KeyboardEvent>(this.document, 'keydown');\n private keypress$ = merge(this.keyup$, this.keydown$).pipe(\n tap(ev => {\n if (ev.type === 'keyup') {\n this.keys.delete(ev.key);\n } else {\n this.keys.add(ev.key);\n }\n this.lastEvent = ev;\n }),\n finalize(() => {\n // we have to clear the keys when there is no subscriber\n // because keyup is not considered on last unsubscribe\n this.keys.clear();\n }),\n share(),\n );\n\n lastEvent?: KeyboardEvent;\n\n private keys = new Set<string>();\n\n event(keyCombination: string) {\n keyCombination = [\n ['ctrl', 'Control'],\n ['esc', 'Escape'],\n ].reduce((a, [b, B]) => a.replace(b, B), keyCombination);\n const keys = keyCombination.split('+');\n let isFirstTrueValue = false;\n\n return this.keypress$.pipe(\n map<KeyboardEvent, [boolean, KeyboardEvent]>(ev => {\n // make sure key combination and number of keys should be same\n const isLengthSame = this.keys.size === keys.length;\n // check all the keys are matching\n const isAllKeysSame = [...this.keys].every(k => keys.includes(k));\n const active = isLengthSame && isAllKeysSame;\n\n isFirstTrueValue = isFirstTrueValue || active;\n return [active, ev];\n }),\n filter(() => isFirstTrueValue), //skipValues until positive value comes\n distinctUntilKeyChanged(0), // avoid duplicate values emitting\n );\n }\n\n isKey(key: string) {\n return this.keys.has(key);\n }\n}\n","import { DestroyRef, inject, Injectable, Injector, runInInjectionContext } from '@angular/core';\nimport { documentListener, isClient, uniqueId } from '@ngbase/adk/utils';\n\nconst IGNORED_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];\nconst SHORTCUT_MAP: Record<string, string> = {\n '⇧': 'shift',\n '⌥': 'alt',\n '⌃': 'ctrl',\n '⌘': 'meta',\n '⏎': 'enter',\n esc: 'escape',\n};\n\n// prettier-ignore\nconst SPECIAL_KEYS = new Set([\n 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',\n 'Enter', 'Escape', 'Tab', 'Backspace', 'Delete',\n 'Home', 'End', 'PageUp', 'PageDown',\n 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'\n]);\n\ninterface Shortcut {\n callback: (ev: KeyboardEvent) => void;\n prevent: boolean;\n stop: boolean;\n global: boolean;\n id: string;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class Shortcuts {\n private readonly shortcuts = new Map<string, Shortcut[]>();\n private isActive = false;\n private isClient = isClient();\n\n on(keyCombination: string, data: Shortcut): void {\n const parsedKey = this.getParsedKey(keyCombination);\n for (const key of parsedKey) {\n const shortcuts = this.shortcuts.get(key) || [];\n shortcuts.push(data);\n this.shortcuts.set(key, shortcuts);\n }\n this.turnOn();\n }\n\n off(keyCombination: string, id: string): void {\n const parsedKey = this.getParsedKey(keyCombination);\n for (const key of parsedKey) {\n const shortcuts = this.shortcuts.get(key);\n if (shortcuts) {\n const index = shortcuts.findIndex(s => s.id === id);\n if (index > -1) {\n shortcuts.splice(index, 1);\n }\n if (shortcuts.length === 0) {\n this.shortcuts.delete(key);\n }\n }\n }\n this.turnOff();\n }\n\n /**\n * We need to parse the key combination\n * e.g. ⇧⌘P -> shift+meta+p, ⌥⌘P -> meta+alt+p, ctrl+p -> ctrl+p\n * e.g. esc|prevent|stop|global -> escape\n */\n private getParsedKey(combination: string): string[] {\n const baseSplit = combination.split('|');\n return baseSplit.map(split => {\n const keys = split.split('+');\n const parsedKeys = keys.map(key => {\n // Check if the key is a special character in our map\n if (SHORTCUT_MAP[key]) {\n return SHORTCUT_MAP[key];\n }\n\n // If it's a special key, return it as is (case-sensitive)\n if (SPECIAL_KEYS.has(key)) {\n return key;\n }\n // If not found in the map or special keys, return the lowercase key\n return key.toLowerCase();\n });\n return parsedKeys.join('+');\n });\n }\n\n private handleKeyEvent = (event: KeyboardEvent): void => {\n const key = this.getKeyCombo(event);\n const data = this.shortcuts.get(key);\n if (!data) {\n return;\n }\n let i = data.length;\n while (i--) {\n const item = data[i];\n if (item.global && this.shouldIgnoreEvent(event)) {\n return;\n }\n\n if (item.callback) {\n if (item.prevent) {\n event.preventDefault();\n }\n if (item.stop) {\n event.stopPropagation();\n }\n item.callback(event);\n if (item.stop) {\n break;\n }\n }\n }\n };\n private keydown = documentListener('keydown', this.handleKeyEvent, { lazy: true });\n\n private shouldIgnoreEvent(event: KeyboardEvent): boolean {\n const target = event.target as HTMLElement;\n\n return (\n IGNORED_TAGS.includes(target.tagName) ||\n target.isContentEditable ||\n target.getAttribute('role') === 'textbox'\n );\n }\n\n private getKeyCombo(event: KeyboardEvent): string {\n const modifiers = [];\n\n if (event.ctrlKey) modifiers.push('ctrl');\n if (event.altKey) modifiers.push('alt');\n if (event.shiftKey) modifiers.push('shift');\n if (event.metaKey) modifiers.push('meta');\n\n const key = event.key?.toLowerCase();\n return [...modifiers, ...(key ? [key] : [])].join('+');\n }\n\n private turnOff() {\n if (this.isClient && this.shortcuts.size === 0 && this.isActive) {\n this.isActive = false;\n this.keydown.off();\n }\n }\n\n private turnOn() {\n if (this.isClient && this.shortcuts.size > 0 && !this.isActive) {\n this.isActive = true;\n this.keydown.on();\n }\n }\n}\n\nexport function keyMap(\n key: string,\n callback: (ev: KeyboardEvent) => void,\n data?: {\n injector?: Injector;\n cleanup?: (off: () => void) => void;\n stop?: boolean;\n global?: boolean;\n prevent?: boolean;\n },\n) {\n const { injector, cleanup, stop = false, global = false, prevent = true } = data || {};\n return runInInjectionContext(injector || inject(Injector), () => {\n const shortcuts = inject(Shortcuts);\n const onDestroy = inject(DestroyRef);\n const id = uniqueId();\n\n shortcuts.on(key, { callback, prevent, stop, global, id });\n\n const off = () => {\n shortcuts.off(key, id);\n };\n\n onDestroy?.onDestroy(off);\n cleanup?.(off);\n return off;\n });\n}\n","/*\n * Public API Surface of keys\n */\n\nexport { Keys } from './keys.service';\nexport { keyMap, Shortcuts } from './shortcuts.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngbase-adk-keys.mjs","sources":["../../../projects/adk/keys/keys.service.ts","../../../projects/adk/keys/shortcuts.service.ts","../../../projects/adk/keys/public-api.ts","../../../projects/adk/keys/ngbase-adk-keys.ts"],"sourcesContent":["import { Injectable, inject, DOCUMENT } from '@angular/core';\nimport { fromEvent, merge, distinctUntilKeyChanged, filter, finalize, map, share, tap } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class Keys {\n private document = inject(DOCUMENT);\n private keyup$ = fromEvent<KeyboardEvent>(this.document, 'keyup');\n private keydown$ = fromEvent<KeyboardEvent>(this.document, 'keydown');\n private keypress$ = merge(this.keyup$, this.keydown$).pipe(\n tap(ev => {\n if (ev.type === 'keyup') {\n this.keys.delete(ev.key);\n } else {\n this.keys.add(ev.key);\n }\n this.lastEvent = ev;\n }),\n finalize(() => {\n // we have to clear the keys when there is no subscriber\n // because keyup is not considered on last unsubscribe\n this.keys.clear();\n }),\n share(),\n );\n\n lastEvent?: KeyboardEvent;\n\n private keys = new Set<string>();\n\n event(keyCombination: string) {\n keyCombination = [\n ['ctrl', 'Control'],\n ['esc', 'Escape'],\n ].reduce((a, [b, B]) => a.replace(b, B), keyCombination);\n const keys = keyCombination.split('+');\n let isFirstTrueValue = false;\n\n return this.keypress$.pipe(\n map<KeyboardEvent, [boolean, KeyboardEvent]>(ev => {\n // make sure key combination and number of keys should be same\n const isLengthSame = this.keys.size === keys.length;\n // check all the keys are matching\n const isAllKeysSame = [...this.keys].every(k => keys.includes(k));\n const active = isLengthSame && isAllKeysSame;\n\n isFirstTrueValue = isFirstTrueValue || active;\n return [active, ev];\n }),\n filter(() => isFirstTrueValue), //skipValues until positive value comes\n distinctUntilKeyChanged(0), // avoid duplicate values emitting\n );\n }\n\n isKey(key: string) {\n return this.keys.has(key);\n }\n}\n","import { DestroyRef, inject, Injectable, Injector, runInInjectionContext } from '@angular/core';\nimport { documentListener, isClient, uniqueId } from '@ngbase/adk/utils';\n\nconst IGNORED_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];\nconst SHORTCUT_MAP: Record<string, string> = {\n '⇧': 'shift',\n '⌥': 'alt',\n '⌃': 'ctrl',\n '⌘': 'meta',\n '⏎': 'enter',\n esc: 'escape',\n};\n\n// prettier-ignore\nconst SPECIAL_KEYS = new Set([\n 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',\n 'Enter', 'Escape', 'Tab', 'Backspace', 'Delete',\n 'Home', 'End', 'PageUp', 'PageDown',\n 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'\n]);\n\ninterface Shortcut {\n callback: (ev: KeyboardEvent) => void;\n prevent: boolean;\n stop: boolean;\n global: boolean;\n id: string;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class Shortcuts {\n private readonly shortcuts = new Map<string, Shortcut[]>();\n private isActive = false;\n private isClient = isClient();\n\n on(keyCombination: string, data: Shortcut): void {\n const parsedKey = this.getParsedKey(keyCombination);\n for (const key of parsedKey) {\n const shortcuts = this.shortcuts.get(key) || [];\n shortcuts.push(data);\n this.shortcuts.set(key, shortcuts);\n }\n this.turnOn();\n }\n\n off(keyCombination: string, id: string): void {\n const parsedKey = this.getParsedKey(keyCombination);\n for (const key of parsedKey) {\n const shortcuts = this.shortcuts.get(key);\n if (shortcuts) {\n const index = shortcuts.findIndex(s => s.id === id);\n if (index > -1) {\n shortcuts.splice(index, 1);\n }\n if (shortcuts.length === 0) {\n this.shortcuts.delete(key);\n }\n }\n }\n this.turnOff();\n }\n\n /**\n * We need to parse the key combination\n * e.g. ⇧⌘P -> shift+meta+p, ⌥⌘P -> meta+alt+p, ctrl+p -> ctrl+p\n * e.g. esc|prevent|stop|global -> escape\n */\n private getParsedKey(combination: string): string[] {\n const baseSplit = combination.split('|');\n return baseSplit.map(split => {\n const keys = split.split('+');\n const parsedKeys = keys.map(key => {\n // Check if the key is a special character in our map\n if (SHORTCUT_MAP[key]) {\n return SHORTCUT_MAP[key];\n }\n\n // If it's a special key, return it as is (case-sensitive)\n if (SPECIAL_KEYS.has(key)) {\n return key;\n }\n // If not found in the map or special keys, return the lowercase key\n return key.toLowerCase();\n });\n return parsedKeys.join('+');\n });\n }\n\n private handleKeyEvent = (event: KeyboardEvent): void => {\n const key = this.getKeyCombo(event);\n const data = this.shortcuts.get(key);\n if (!data) {\n return;\n }\n let i = data.length;\n while (i--) {\n const item = data[i];\n if (item.global && this.shouldIgnoreEvent(event)) {\n return;\n }\n\n if (item.callback) {\n if (item.prevent) {\n event.preventDefault();\n }\n if (item.stop) {\n event.stopPropagation();\n }\n item.callback(event);\n if (item.stop) {\n break;\n }\n }\n }\n };\n private keydown = documentListener('keydown', this.handleKeyEvent, { lazy: true });\n\n private shouldIgnoreEvent(event: KeyboardEvent): boolean {\n const target = event.target as HTMLElement;\n\n return (\n IGNORED_TAGS.includes(target.tagName) ||\n target.isContentEditable ||\n target.getAttribute('role') === 'textbox'\n );\n }\n\n private getKeyCombo(event: KeyboardEvent): string {\n const modifiers = [];\n\n if (event.ctrlKey) modifiers.push('ctrl');\n if (event.altKey) modifiers.push('alt');\n if (event.shiftKey) modifiers.push('shift');\n if (event.metaKey) modifiers.push('meta');\n\n const key = event.key?.toLowerCase();\n return [...modifiers, ...(key ? [key] : [])].join('+');\n }\n\n private turnOff() {\n if (this.isClient && this.shortcuts.size === 0 && this.isActive) {\n this.isActive = false;\n this.keydown.off();\n }\n }\n\n private turnOn() {\n if (this.isClient && this.shortcuts.size > 0 && !this.isActive) {\n this.isActive = true;\n this.keydown.on();\n }\n }\n}\n\nexport function keyMap(\n key: string,\n callback: (ev: KeyboardEvent) => void,\n data?: {\n injector?: Injector;\n cleanup?: (off: () => void) => void;\n stop?: boolean;\n global?: boolean;\n prevent?: boolean;\n },\n) {\n const { injector, cleanup, stop = false, global = false, prevent = true } = data || {};\n return runInInjectionContext(injector || inject(Injector), () => {\n const shortcuts = inject(Shortcuts);\n const onDestroy = inject(DestroyRef);\n const id = uniqueId();\n\n shortcuts.on(key, { callback, prevent, stop, global, id });\n\n const off = () => {\n shortcuts.off(key, id);\n };\n\n onDestroy?.onDestroy(off);\n cleanup?.(off);\n return off;\n });\n}\n","/*\n * Public API Surface of keys\n */\n\nexport { Keys } from './keys.service';\nexport { keyMap, Shortcuts } from './shortcuts.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;MAIa,IAAI,CAAA;AADjB,IAAA,WAAA,GAAA;AAEU,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC3B,IAAA,CAAA,MAAM,GAAG,SAAS,CAAgB,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC;QACzD,IAAA,CAAA,QAAQ,GAAG,SAAS,CAAgB,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AAC7D,QAAA,IAAA,CAAA,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CACxD,GAAG,CAAC,EAAE,IAAG;AACP,YAAA,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE;gBACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC;YAC1B;iBAAO;gBACL,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC;YACvB;AACA,YAAA,IAAI,CAAC,SAAS,GAAG,EAAE;AACrB,QAAA,CAAC,CAAC,EACF,QAAQ,CAAC,MAAK;;;AAGZ,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACnB,QAAA,CAAC,CAAC,EACF,KAAK,EAAE,CACR;AAIO,QAAA,IAAA,CAAA,IAAI,GAAG,IAAI,GAAG,EAAU;AA6BjC,IAAA;AA3BC,IAAA,KAAK,CAAC,cAAsB,EAAA;AAC1B,QAAA,cAAc,GAAG;YACf,CAAC,MAAM,EAAE,SAAS,CAAC;YACnB,CAAC,KAAK,EAAE,QAAQ,CAAC;SAClB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC;QACxD,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;QACtC,IAAI,gBAAgB,GAAG,KAAK;QAE5B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CACxB,GAAG,CAA0C,EAAE,IAAG;;YAEhD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM;;YAEnD,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjE,YAAA,MAAM,MAAM,GAAG,YAAY,IAAI,aAAa;AAE5C,YAAA,gBAAgB,GAAG,gBAAgB,IAAI,MAAM;AAC7C,YAAA,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrB,CAAC,CAAC,EACF,MAAM,CAAC,MAAM,gBAAgB,CAAC;AAC9B,QAAA,uBAAuB,CAAC,CAAC,CAAC,CAC3B;IACH;AAEA,IAAA,KAAK,CAAC,GAAW,EAAA;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3B;8GAnDW,IAAI,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAJ,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,IAAI,cADS,MAAM,EAAA,CAAA,CAAA;;2FACnB,IAAI,EAAA,UAAA,EAAA,CAAA;kBADhB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACAlC,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;AACpD,MAAM,YAAY,GAA2B;AAC3C,IAAA,GAAG,EAAE,OAAO;AACZ,IAAA,GAAG,EAAE,KAAK;AACV,IAAA,GAAG,EAAE,MAAM;AACX,IAAA,GAAG,EAAE,MAAM;AACX,IAAA,GAAG,EAAE,OAAO;AACZ,IAAA,GAAG,EAAE,QAAQ;CACd;AAED;AACA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;AAC3B,IAAA,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW;AACjD,IAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ;AAC/C,IAAA,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU;IACnC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;AACrE,CAAA,CAAC;MAaW,SAAS,CAAA;AAHtB,IAAA,WAAA,GAAA;AAImB,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,GAAG,EAAsB;QAClD,IAAA,CAAA,QAAQ,GAAG,KAAK;QAChB,IAAA,CAAA,QAAQ,GAAG,QAAQ,EAAE;AAuDrB,QAAA,IAAA,CAAA,cAAc,GAAG,CAAC,KAAoB,KAAU;YACtD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YACpC,IAAI,CAAC,IAAI,EAAE;gBACT;YACF;AACA,YAAA,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;YACnB,OAAO,CAAC,EAAE,EAAE;AACV,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;gBACpB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE;oBAChD;gBACF;AAEA,gBAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,oBAAA,IAAI,IAAI,CAAC,OAAO,EAAE;wBAChB,KAAK,CAAC,cAAc,EAAE;oBACxB;AACA,oBAAA,IAAI,IAAI,CAAC,IAAI,EAAE;wBACb,KAAK,CAAC,eAAe,EAAE;oBACzB;AACA,oBAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;AACpB,oBAAA,IAAI,IAAI,CAAC,IAAI,EAAE;wBACb;oBACF;gBACF;YACF;AACF,QAAA,CAAC;AACO,QAAA,IAAA,CAAA,OAAO,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAqCnF,IAAA;IArHC,EAAE,CAAC,cAAsB,EAAE,IAAc,EAAA;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;AACnD,QAAA,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE;AAC3B,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;AAC/C,YAAA,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC;QACpC;QACA,IAAI,CAAC,MAAM,EAAE;IACf;IAEA,GAAG,CAAC,cAAsB,EAAE,EAAU,EAAA;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;AACnD,QAAA,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE;YAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YACzC,IAAI,SAAS,EAAE;AACb,gBAAA,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AACnD,gBAAA,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE;AACd,oBAAA,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5B;AACA,gBAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;AAC1B,oBAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC5B;YACF;QACF;QACA,IAAI,CAAC,OAAO,EAAE;IAChB;AAEA;;;;AAIG;AACK,IAAA,YAAY,CAAC,WAAmB,EAAA;QACtC,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC;AACxC,QAAA,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,IAAG;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAG;;AAEhC,gBAAA,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;AACrB,oBAAA,OAAO,YAAY,CAAC,GAAG,CAAC;gBAC1B;;AAGA,gBAAA,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACzB,oBAAA,OAAO,GAAG;gBACZ;;AAEA,gBAAA,OAAO,GAAG,CAAC,WAAW,EAAE;AAC1B,YAAA,CAAC,CAAC;AACF,YAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7B,QAAA,CAAC,CAAC;IACJ;AA+BQ,IAAA,iBAAiB,CAAC,KAAoB,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;QAE1C,QACE,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;AACrC,YAAA,MAAM,CAAC,iBAAiB;YACxB,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS;IAE7C;AAEQ,IAAA,WAAW,CAAC,KAAoB,EAAA;QACtC,MAAM,SAAS,GAAG,EAAE;QAEpB,IAAI,KAAK,CAAC,OAAO;AAAE,YAAA,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QACzC,IAAI,KAAK,CAAC,MAAM;AAAE,YAAA,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QACvC,IAAI,KAAK,CAAC,QAAQ;AAAE,YAAA,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAC3C,IAAI,KAAK,CAAC,OAAO;AAAE,YAAA,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QAEzC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE;QACpC,OAAO,CAAC,GAAG,SAAS,EAAE,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACxD;IAEQ,OAAO,GAAA;AACb,QAAA,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE;AAC/D,YAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;AACrB,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;QACpB;IACF;IAEQ,MAAM,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAC9D,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AACpB,YAAA,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE;QACnB;IACF;8GAzHW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAT,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,SAAS,cAFR,MAAM,EAAA,CAAA,CAAA;;2FAEP,SAAS,EAAA,UAAA,EAAA,CAAA;kBAHrB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;SA6He,MAAM,CACpB,GAAW,EACX,QAAqC,EACrC,IAMC,EAAA;IAED,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE;IACtF,OAAO,qBAAqB,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAK;AAC9D,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AACnC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;AACpC,QAAA,MAAM,EAAE,GAAG,QAAQ,EAAE;AAErB,QAAA,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAE1D,MAAM,GAAG,GAAG,MAAK;AACf,YAAA,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC;AACxB,QAAA,CAAC;AAED,QAAA,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC;AACzB,QAAA,OAAO,GAAG,GAAG,CAAC;AACd,QAAA,OAAO,GAAG;AACZ,IAAA,CAAC,CAAC;AACJ;;ACvLA;;AAEG;;ACFH;;AAEG;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngbase-adk-layout.mjs","sources":["../../../projects/adk/layout/layout.ts","../../../projects/adk/layout/ngbase-adk-layout.ts"],"sourcesContent":["import { DestroyRef, inject, signal, WritableSignal } from '@angular/core';\nimport { isClient } from '@ngbase/adk/utils';\n\nconst mediaQueryListeners = new Map<\n string,\n { mql: MediaQueryList; listeners: Set<(event: MediaQueryListEvent) => void> }\n>();\n\nexport function breakpointObserver() {\n const client = isClient();\n const activeListeners = new Map<any, () => void>();\n\n function observe<T extends string>(queries: Record<T, string>) {\n const breakpointStates = signal({} as Record<T, boolean>);\n\n if (client) {\n const cleanup = setupMediaQueries(queries, breakpointStates);\n activeListeners.set(queries, cleanup);\n }\n\n return {\n state: breakpointStates.asReadonly(),\n unobserve: () => {\n activeListeners.get(queries)?.();\n activeListeners.delete(queries);\n },\n };\n }\n\n function setupMediaQueries(\n queries: Record<string, string>,\n breakpointStates: WritableSignal<Record<string, boolean>>,\n ) {\n const states = {} as Record<string, boolean>;\n const cleanupFns: Array<() => void> = [];\n\n Object.entries(queries).forEach(([name, query]) => {\n let queryData = mediaQueryListeners.get(query);\n\n if (!queryData) {\n const mql = _matchMedia(query);\n if (!mql) return;\n queryData = { mql, listeners: new Set() };\n mediaQueryListeners.set(query, queryData);\n\n mql.addEventListener('change', event => {\n queryData!.listeners.forEach(listener => listener(event));\n });\n }\n\n states[name] = queryData.mql.matches;\n\n const listener = (event: MediaQueryListEvent) => {\n breakpointStates.update(states => ({\n ...states,\n [name]: event.matches,\n }));\n };\n\n queryData.listeners.add(listener);\n cleanupFns.push(() => {\n queryData!.listeners.delete(listener);\n if (queryData!.listeners.size === 0) {\n queryData!.mql.removeEventListener('change', listener);\n mediaQueryListeners.delete(query);\n }\n });\n });\n\n breakpointStates.set(states);\n\n return () => cleanupFns.forEach(fn => fn());\n }\n\n // cleanup all listeners when the component is destroyed\n inject(DestroyRef).onDestroy(() => {\n activeListeners.forEach(cleanup => cleanup());\n });\n\n function matches(queryName: string): boolean {\n if (!client) return false;\n return _matchMedia(queryName)?.matches ?? false;\n }\n\n function _matchMedia(queryName: string) {\n return typeof window.matchMedia !== 'undefined' ? window.matchMedia(queryName) : null;\n }\n\n return { observe, matches };\n}\n\n// This is a mock for testing purposes\nexport function setupTestBreakpoint(fn: Function) {\n const createMockMediaQuery = () => ({\n matches: false,\n addEventListener: fn(),\n removeEventListener: fn(),\n });\n\n const _mediaQueryList = createMockMediaQuery();\n const _matchMedia = fn(() => _mediaQueryList);\n window.matchMedia = _matchMedia;\n\n return {\n reset: () => {\n Object.assign(_mediaQueryList, createMockMediaQuery());\n Object.assign(\n _matchMedia,\n fn(() => _mediaQueryList),\n );\n window.matchMedia = _matchMedia;\n },\n get mediaQueryList() {\n return _mediaQueryList;\n },\n get matchMedia() {\n return _matchMedia;\n },\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAGA,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAGhC;SAEa,kBAAkB,GAAA;AAChC,IAAA,MAAM,MAAM,GAAG,QAAQ,EAAE;AACzB,IAAA,MAAM,eAAe,GAAG,IAAI,GAAG,EAAmB;IAElD,SAAS,OAAO,CAAmB,OAA0B,EAAA;AAC3D,QAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAwB,4DAAC;QAEzD,IAAI,MAAM,EAAE;YACV,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,CAAC;AAC5D,YAAA,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC
|
|
1
|
+
{"version":3,"file":"ngbase-adk-layout.mjs","sources":["../../../projects/adk/layout/layout.ts","../../../projects/adk/layout/ngbase-adk-layout.ts"],"sourcesContent":["import { DestroyRef, inject, signal, WritableSignal } from '@angular/core';\nimport { isClient } from '@ngbase/adk/utils';\n\nconst mediaQueryListeners = new Map<\n string,\n { mql: MediaQueryList; listeners: Set<(event: MediaQueryListEvent) => void> }\n>();\n\nexport function breakpointObserver() {\n const client = isClient();\n const activeListeners = new Map<any, () => void>();\n\n function observe<T extends string>(queries: Record<T, string>) {\n const breakpointStates = signal({} as Record<T, boolean>);\n\n if (client) {\n const cleanup = setupMediaQueries(queries, breakpointStates);\n activeListeners.set(queries, cleanup);\n }\n\n return {\n state: breakpointStates.asReadonly(),\n unobserve: () => {\n activeListeners.get(queries)?.();\n activeListeners.delete(queries);\n },\n };\n }\n\n function setupMediaQueries(\n queries: Record<string, string>,\n breakpointStates: WritableSignal<Record<string, boolean>>,\n ) {\n const states = {} as Record<string, boolean>;\n const cleanupFns: Array<() => void> = [];\n\n Object.entries(queries).forEach(([name, query]) => {\n let queryData = mediaQueryListeners.get(query);\n\n if (!queryData) {\n const mql = _matchMedia(query);\n if (!mql) return;\n queryData = { mql, listeners: new Set() };\n mediaQueryListeners.set(query, queryData);\n\n mql.addEventListener('change', event => {\n queryData!.listeners.forEach(listener => listener(event));\n });\n }\n\n states[name] = queryData.mql.matches;\n\n const listener = (event: MediaQueryListEvent) => {\n breakpointStates.update(states => ({\n ...states,\n [name]: event.matches,\n }));\n };\n\n queryData.listeners.add(listener);\n cleanupFns.push(() => {\n queryData!.listeners.delete(listener);\n if (queryData!.listeners.size === 0) {\n queryData!.mql.removeEventListener('change', listener);\n mediaQueryListeners.delete(query);\n }\n });\n });\n\n breakpointStates.set(states);\n\n return () => cleanupFns.forEach(fn => fn());\n }\n\n // cleanup all listeners when the component is destroyed\n inject(DestroyRef).onDestroy(() => {\n activeListeners.forEach(cleanup => cleanup());\n });\n\n function matches(queryName: string): boolean {\n if (!client) return false;\n return _matchMedia(queryName)?.matches ?? false;\n }\n\n function _matchMedia(queryName: string) {\n return typeof window.matchMedia !== 'undefined' ? window.matchMedia(queryName) : null;\n }\n\n return { observe, matches };\n}\n\n// This is a mock for testing purposes\nexport function setupTestBreakpoint(fn: Function) {\n const createMockMediaQuery = () => ({\n matches: false,\n addEventListener: fn(),\n removeEventListener: fn(),\n });\n\n const _mediaQueryList = createMockMediaQuery();\n const _matchMedia = fn(() => _mediaQueryList);\n window.matchMedia = _matchMedia;\n\n return {\n reset: () => {\n Object.assign(_mediaQueryList, createMockMediaQuery());\n Object.assign(\n _matchMedia,\n fn(() => _mediaQueryList),\n );\n window.matchMedia = _matchMedia;\n },\n get mediaQueryList() {\n return _mediaQueryList;\n },\n get matchMedia() {\n return _matchMedia;\n },\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|