@mgremy/core 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,353 @@
1
- import { InjectionToken } from '@angular/core';
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, signal, provideAppInitializer, afterNextRender, Injector, computed } from '@angular/core';
3
+ import { APP_BASE_HREF, registerLocaleData } from '@angular/common';
4
+ import { takeUntilDestroyed, rxResource } from '@angular/core/rxjs-interop';
5
+ import { OAuthService, AUTH_CONFIG, provideOAuthClient } from 'angular-oauth2-oidc';
6
+ import { jwtDecode } from 'jwt-decode';
7
+ import { filter, tap, from, map } from 'rxjs';
8
+ import { TranslateService, provideTranslateService } from '@ngx-translate/core';
9
+ import { provideTranslateHttpLoader } from '@ngx-translate/http-loader';
10
+ import { provideHttpClient } from '@angular/common/http';
11
+ import localeUS from '@angular/common/locales/en';
12
+ import localeFR from '@angular/common/locales/fr';
2
13
 
3
- const APP_CONFIG_SERVICE = new InjectionToken('APP_CONFIG_SERVICE');
14
+ const ENVIRONMENT_VALUE = new InjectionToken('ENVIRONMENT_VALUE');
15
+ function provideEnvironmentConfig(options) {
16
+ return [{ provide: ENVIRONMENT_VALUE, useValue: options.value }];
17
+ }
4
18
 
5
- const APP_ENVIRONMENT_SERVICE = new InjectionToken('APP_ENVIRONMENT_SERVICE');
19
+ const CONFIG_SERVICE = new InjectionToken('CONFIG_SERVICE');
20
+ class ConfigService {
21
+ _environment = inject(ENVIRONMENT_VALUE);
22
+ _windowKey = 'runtime_config';
23
+ isValidValue(value) {
24
+ // If starts with ${, it's the placeholder used by the build system
25
+ return value !== undefined && value !== null && value !== '' && !value.startsWith('${');
26
+ }
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ getValue(key) {
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ return window[this._windowKey]?.[key];
31
+ }
32
+ get appUrl() {
33
+ const value = this.getValue('APP_URL');
34
+ return this.isValidValue(value) ? value : this._environment.appUrl;
35
+ }
36
+ get appBaseHref() {
37
+ const value = this.getValue('APP_BASE_HREF');
38
+ return this.isValidValue(value) ? value : this._environment.appBaseHref;
39
+ }
40
+ get apiUrl() {
41
+ const value = this.getValue('API_URL');
42
+ return this.isValidValue(value) ? value : this._environment.apiUrl;
43
+ }
44
+ get defaultLanguage() {
45
+ const value = this.getValue('DEFAULT_LANGUAGE');
46
+ return this.isValidValue(value) ? value : this._environment.defaultLanguage;
47
+ }
48
+ get authUrl() {
49
+ const value = this.getValue('AUTH_URL');
50
+ return this.isValidValue(value) ? value : this._environment.authUrl;
51
+ }
52
+ get authRealm() {
53
+ const value = this.getValue('AUTH_REALM');
54
+ return this.isValidValue(value) ? value : this._environment.authRealm;
55
+ }
56
+ get authClientId() {
57
+ const value = this.getValue('AUTH_CLIENT_ID');
58
+ return this.isValidValue(value) ? value : this._environment.authClientId;
59
+ }
60
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
61
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ConfigService, providedIn: 'root' });
62
+ }
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ConfigService, decorators: [{
64
+ type: Injectable,
65
+ args: [{ providedIn: 'root' }]
66
+ }] });
67
+ function provideConfig(options) {
68
+ return [
69
+ { provide: CONFIG_SERVICE, useClass: options?.service ?? ConfigService },
70
+ { provide: APP_BASE_HREF, useFactory: () => inject(CONFIG_SERVICE).appBaseHref },
71
+ ];
72
+ }
6
73
 
7
- const APP_STORAGE_SERVICE = new InjectionToken('APP_STORAGE_SERVICE');
74
+ const AUTH_SERVICE = new InjectionToken('AUTH_SERVICE');
75
+ class AuthService {
76
+ _authService = inject(OAuthService);
77
+ _isAuthenticated = signal(this._authService.hasValidAccessToken(), ...(ngDevMode ? [{ debugName: "_isAuthenticated" }] : []));
78
+ isAuthenticated = this._isAuthenticated.asReadonly();
79
+ constructor() {
80
+ this._authService.configure(inject(AUTH_CONFIG));
81
+ this._authService.setupAutomaticSilentRefresh();
82
+ this._authService.events
83
+ .pipe(takeUntilDestroyed(), filter((event) => event.type == 'token_received'), tap(() => this._isAuthenticated.set(true)))
84
+ .subscribe();
85
+ this._authService.events
86
+ .pipe(takeUntilDestroyed(), filter((event) => event.type == 'logout' || event.type == 'token_expires'), tap(() => this._isAuthenticated.set(false)))
87
+ .subscribe();
88
+ }
89
+ init() {
90
+ return from(this._authService.loadDiscoveryDocumentAndTryLogin()).pipe(map(() => void 0));
91
+ }
92
+ getIdToken() {
93
+ return this._authService.getIdentityClaims();
94
+ }
95
+ getAccessToken() {
96
+ return this._authService.getAccessToken();
97
+ }
98
+ getDecodedAccessToken() {
99
+ const accessToken = this.getAccessToken();
100
+ try {
101
+ return jwtDecode(accessToken);
102
+ }
103
+ catch (error) {
104
+ console.warn(error);
105
+ return undefined;
106
+ }
107
+ }
108
+ hasRoles(roles, mode = 'any') {
109
+ if (this._isAuthenticated() === false)
110
+ return false;
111
+ const accessToken = this.getDecodedAccessToken();
112
+ if (accessToken?.roles == undefined)
113
+ return false;
114
+ if (Array.isArray(roles)) {
115
+ if (mode === 'any') {
116
+ return accessToken.roles.some((role) => roles.includes(role));
117
+ }
118
+ else {
119
+ return accessToken.roles.filter((role) => roles.includes(role)).length === roles.length;
120
+ }
121
+ }
122
+ else {
123
+ return accessToken.roles.includes(roles);
124
+ }
125
+ }
126
+ login() {
127
+ return this._authService.initLoginFlow();
128
+ }
129
+ logout() {
130
+ return this._authService.logOut();
131
+ }
132
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
133
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthService, providedIn: 'root' });
134
+ }
135
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthService, decorators: [{
136
+ type: Injectable,
137
+ args: [{ providedIn: 'root' }]
138
+ }], ctorParameters: () => [] });
139
+ function provideAuthConfig(options) {
140
+ return [
141
+ provideOAuthClient(),
142
+ {
143
+ provide: AUTH_CONFIG,
144
+ useFactory: () => {
145
+ const configService = inject(CONFIG_SERVICE);
146
+ return (options?.authConfig ??
147
+ {
148
+ issuer: `${configService.authUrl}/realms/${configService.authRealm}`,
149
+ clientId: configService.authClientId,
150
+ responseType: 'code',
151
+ scope: 'openid offline_access',
152
+ redirectUri: configService.appUrl,
153
+ showDebugInformation: false,
154
+ });
155
+ },
156
+ deps: [CONFIG_SERVICE],
157
+ },
158
+ { provide: AUTH_SERVICE, useClass: options?.service ?? AuthService },
159
+ provideAppInitializer(() => inject(AUTH_SERVICE).init()),
160
+ ];
161
+ }
8
162
 
9
- const APP_THEME_SERVICE = new InjectionToken('APP_THEME_SERVICE');
163
+ const STORAGE_SERVICE = new InjectionToken('STORAGE_SERVICE');
164
+ class StorageService {
165
+ getItem(key) {
166
+ return localStorage.getItem(key) ?? undefined;
167
+ }
168
+ setItem(key, value) {
169
+ localStorage.setItem(key, value);
170
+ }
171
+ removeItem(key) {
172
+ localStorage.removeItem(key);
173
+ }
174
+ clear() {
175
+ localStorage.clear();
176
+ }
177
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: StorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
178
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: StorageService, providedIn: 'root' });
179
+ }
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: StorageService, decorators: [{
181
+ type: Injectable,
182
+ args: [{ providedIn: 'root' }]
183
+ }] });
184
+ function provideStorageConfig(options) {
185
+ return [{ provide: STORAGE_SERVICE, useClass: options?.service ?? StorageService }];
186
+ }
10
187
 
11
- const APP_TRANSLATION_SERVICE = new InjectionToken('APP_TRANSLATION_SERVICE');
188
+ const THEME_SERVICE = new InjectionToken('THEME_SERVICE');
189
+ class ThemeService {
190
+ _storageService = inject(STORAGE_SERVICE);
191
+ _storageKeys = {
192
+ theme: 'theme.current',
193
+ };
194
+ constructor() {
195
+ afterNextRender(() => {
196
+ this.setTheme(this.getTheme());
197
+ });
198
+ }
199
+ getTheme() {
200
+ const storageValue = this._storageService.getItem(this._storageKeys.theme);
201
+ if (storageValue === undefined || (storageValue !== 'light' && storageValue !== 'dark')) {
202
+ return 'light';
203
+ }
204
+ return storageValue;
205
+ }
206
+ setTheme(key) {
207
+ this._storageService.setItem(this._storageKeys.theme, key);
208
+ if (key === 'light')
209
+ document.documentElement.classList.remove('dark');
210
+ else
211
+ document.documentElement.classList.add('dark');
212
+ }
213
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
214
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ThemeService, providedIn: 'root' });
215
+ }
216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ThemeService, decorators: [{
217
+ type: Injectable,
218
+ args: [{ providedIn: 'root' }]
219
+ }], ctorParameters: () => [] });
220
+ function provideThemeConfig(options) {
221
+ return [{ provide: THEME_SERVICE, useClass: options?.service ?? ThemeService }];
222
+ }
223
+
224
+ const TRANSLATION_SERVICE = new InjectionToken('TRANSLATION_SERVICE');
225
+ class TranslationService {
226
+ _storageService = inject(STORAGE_SERVICE);
227
+ _appConfigService = inject(CONFIG_SERVICE);
228
+ _translationService = inject(TranslateService);
229
+ _storageKeys = {
230
+ lang: 'translation.lang',
231
+ };
232
+ _currentLanguage = signal(this._storageService.getItem(this._storageKeys.lang) ?? this._appConfigService.defaultLanguage, ...(ngDevMode ? [{ debugName: "_currentLanguage" }] : []));
233
+ currentLanguage = this._currentLanguage.asReadonly();
234
+ init() {
235
+ this._translationService.use(this._currentLanguage());
236
+ this._storageService.setItem(this._storageKeys.lang, this._currentLanguage());
237
+ }
238
+ setLanguage(code) {
239
+ this._storageService.setItem(this._storageKeys.lang, code);
240
+ this._currentLanguage.set(code);
241
+ this._translationService.use(code);
242
+ }
243
+ instant(key, params) {
244
+ return this._translationService.instant(key, params);
245
+ }
246
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: TranslationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
247
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: TranslationService, providedIn: 'root' });
248
+ }
249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: TranslationService, decorators: [{
250
+ type: Injectable,
251
+ args: [{ providedIn: 'root' }]
252
+ }] });
253
+ function provideTranslationConfig(options) {
254
+ registerLocaleData(localeFR);
255
+ registerLocaleData(localeUS);
256
+ return [
257
+ provideHttpClient(),
258
+ provideTranslateService({
259
+ loader: provideTranslateHttpLoader({ prefix: '/i18n', suffix: '.json' }),
260
+ }),
261
+ { provide: TRANSLATION_SERVICE, useClass: options?.service ?? TranslationService },
262
+ provideAppInitializer(() => inject(TRANSLATION_SERVICE).init()),
263
+ ];
264
+ }
265
+
266
+ class BaseComponent {
267
+ _injector = inject(Injector);
268
+ }
269
+
270
+ /**
271
+ * Wrapper around PaginationRequest/PaginationResponses and RxResources used side by side with API.
272
+ * It supports AutoRefreshing data.
273
+ */
274
+ class PaginationContainer {
275
+ /**
276
+ * Value is computed each time pageNumber | pageSize | sortRequest (if not undefined) is updated.
277
+ */
278
+ _paginationRequest = computed(() => {
279
+ const pageNumber = this.pageNumber();
280
+ const pageSize = this.pageSize();
281
+ const sortRequest = this.sortRequest();
282
+ const filterRequest = this.filterRequest();
283
+ if (pageNumber <= 0 || pageSize <= 0) {
284
+ return undefined;
285
+ }
286
+ const paginationRequest = {
287
+ pageNumber: pageNumber,
288
+ pageSize: pageSize,
289
+ sortRequests: Object.entries(sortRequest)
290
+ .filter(([, v]) => v !== undefined)
291
+ .map(([k, v]) => ({ propertyName: k, isDescending: v })),
292
+ filterRequest: filterRequest,
293
+ };
294
+ return paginationRequest;
295
+ }, ...(ngDevMode ? [{ debugName: "_paginationRequest" }] : []));
296
+ pageNumber = signal(-1, ...(ngDevMode ? [{ debugName: "pageNumber" }] : []));
297
+ pageSize = signal(-1, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
298
+ sortRequest = signal({}, ...(ngDevMode ? [{ debugName: "sortRequest" }] : []));
299
+ filterRequest = signal([], {
300
+ debugName: 'filterRequest',
301
+ equal: () => false,
302
+ });
303
+ resource;
304
+ constructor(resourceOpts) {
305
+ this.resource = rxResource({
306
+ ...resourceOpts,
307
+ params: () => this._paginationRequest(),
308
+ });
309
+ }
310
+ /**
311
+ * Update the sort status on property from TResult.
312
+ *
313
+ * It goes undefined -> false -> true.
314
+ * In terms of usage, it goes undefined -> ASC -> DESC.
315
+ * @param propertyName The name of the property from TResult on which we want to update the sort status
316
+ */
317
+ onSortChange(propertyName) {
318
+ const current = this.sortRequest();
319
+ this.sortRequest.set({
320
+ ...current,
321
+ [propertyName]: current[propertyName] === undefined
322
+ ? false
323
+ : current[propertyName] === false
324
+ ? true
325
+ : undefined,
326
+ });
327
+ }
328
+ }
329
+ function paginationContainer(resourceOpts) {
330
+ return new PaginationContainer(resourceOpts);
331
+ }
332
+
333
+ /**
334
+ * Store a map of unique ids for elements so that there are no collisions.
335
+ */
336
+ const uniqueIdMap = new Map();
337
+ /**
338
+ * Generate a unique id for an element
339
+ * @param prefix - The prefix to use for the id
340
+ * @returns The generated id
341
+ */
342
+ function uniqueId(prefix) {
343
+ const id = uniqueIdMap.get(prefix) ?? 0;
344
+ uniqueIdMap.set(prefix, id + 1);
345
+ return `${prefix}-${id}`;
346
+ }
12
347
 
13
348
  /**
14
349
  * Generated bundle index. Do not edit.
15
350
  */
16
351
 
17
- export { APP_CONFIG_SERVICE, APP_ENVIRONMENT_SERVICE, APP_STORAGE_SERVICE, APP_THEME_SERVICE, APP_TRANSLATION_SERVICE };
352
+ export { AUTH_SERVICE, AuthService, BaseComponent, CONFIG_SERVICE, ConfigService, ENVIRONMENT_VALUE, PaginationContainer, STORAGE_SERVICE, StorageService, THEME_SERVICE, TRANSLATION_SERVICE, ThemeService, TranslationService, paginationContainer, provideAuthConfig, provideConfig, provideEnvironmentConfig, provideStorageConfig, provideThemeConfig, provideTranslationConfig, uniqueId };
18
353
  //# sourceMappingURL=mgremy-core.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mgremy-core.mjs","sources":["../../../../libs/core/src/lib/app-config.ts","../../../../libs/core/src/lib/environment.ts","../../../../libs/core/src/lib/storage.ts","../../../../libs/core/src/lib/theme.ts","../../../../libs/core/src/lib/translation.ts","../../../../libs/core/src/mgremy-core.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport const APP_CONFIG_SERVICE = new InjectionToken<IAppConfigService>('APP_CONFIG_SERVICE');\n\nexport interface IAppConfigService {\n get appUrl(): string;\n get appBaseHref(): string;\n get apiUrl(): string;\n get defaultLanguage(): string;\n get authUrl(): string;\n get authRealm(): string;\n get authClientId(): string;\n}\n","import { InjectionToken } from '@angular/core';\n\nexport const APP_ENVIRONMENT_SERVICE = new InjectionToken<Environment>('APP_ENVIRONMENT_SERVICE');\n\nexport interface Environment {\n production: boolean;\n appUrl: string;\n appBaseHref: string;\n apiUrl: string;\n defaultLanguage: string;\n authUrl: string;\n authRealm: string;\n authClientId: string;\n}\n","import { InjectionToken } from '@angular/core';\n\nexport const APP_STORAGE_SERVICE = new InjectionToken<IStorageService>('APP_STORAGE_SERVICE');\n\nexport interface IStorageService {\n getItem(key: string): string | undefined;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n clear(): void;\n}\n","import { InjectionToken } from '@angular/core';\n\nexport const APP_THEME_SERVICE = new InjectionToken<IAppThemeService>('APP_THEME_SERVICE');\n\nexport type AppTheme = 'light' | 'dark';\n\nexport interface IAppThemeService {\n getTheme(): AppTheme;\n setTheme(value: AppTheme): void;\n}\n","import { InjectionToken, Signal } from '@angular/core';\n\nexport const APP_TRANSLATION_SERVICE = new InjectionToken<ITranslationService>(\n 'APP_TRANSLATION_SERVICE'\n);\n\nexport interface ITranslationService {\n currentLanguage: Signal<string>;\n\n init(): void;\n setLanguage(code: string): void;\n\n instant(key: string, params?: Record<string, string>): string;\n instant(key: string[], params?: Record<string, string>): string[];\n instant(key: string | string[], params?: Record<string, string>): string | string[];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;MAEa,kBAAkB,GAAG,IAAI,cAAc,CAAoB,oBAAoB;;MCA/E,uBAAuB,GAAG,IAAI,cAAc,CAAc,yBAAyB;;MCAnF,mBAAmB,GAAG,IAAI,cAAc,CAAkB,qBAAqB;;MCA/E,iBAAiB,GAAG,IAAI,cAAc,CAAmB,mBAAmB;;MCA5E,uBAAuB,GAAG,IAAI,cAAc,CACvD,yBAAyB;;ACH3B;;AAEG;;;;"}
1
+ {"version":3,"file":"mgremy-core.mjs","sources":["../../../../packages/core/src/lib/services/environment.ts","../../../../packages/core/src/lib/services/app-config.ts","../../../../packages/core/src/lib/services/auth.ts","../../../../packages/core/src/lib/services/storage.ts","../../../../packages/core/src/lib/services/theme.ts","../../../../packages/core/src/lib/services/translation.ts","../../../../packages/core/src/lib/base-component.ts","../../../../packages/core/src/lib/pagination-container.ts","../../../../packages/core/src/lib/unique-id.ts","../../../../packages/core/src/mgremy-core.ts"],"sourcesContent":["import { EnvironmentProviders, InjectionToken, Provider } from '@angular/core';\n\nexport const ENVIRONMENT_VALUE = new InjectionToken<IEnvironment>('ENVIRONMENT_VALUE');\n\nexport interface IEnvironment {\n production: boolean;\n appUrl: string;\n appBaseHref: string;\n apiUrl: string;\n defaultLanguage: string;\n authUrl: string;\n authRealm: string;\n authClientId: string;\n}\n\nexport function provideEnvironmentConfig(options: {\n value: IEnvironment;\n}): (Provider | EnvironmentProviders)[] {\n return [{ provide: ENVIRONMENT_VALUE, useValue: options.value }];\n}\n","import { ENVIRONMENT_VALUE } from './environment';\n\nimport { APP_BASE_HREF } from '@angular/common';\nimport {\n EnvironmentProviders,\n inject,\n Injectable,\n InjectionToken,\n Provider,\n Type,\n} from '@angular/core';\n\nexport const CONFIG_SERVICE = new InjectionToken<IConfigService>('CONFIG_SERVICE');\n\nexport interface IConfigService {\n get appUrl(): string;\n get appBaseHref(): string;\n get apiUrl(): string;\n get defaultLanguage(): string;\n get authUrl(): string;\n get authRealm(): string;\n get authClientId(): string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ConfigService implements IConfigService {\n private readonly _environment = inject(ENVIRONMENT_VALUE);\n private readonly _windowKey = 'runtime_config';\n\n private isValidValue(value: string | undefined | null): boolean {\n // If starts with ${, it's the placeholder used by the build system\n return value !== undefined && value !== null && value !== '' && !value.startsWith('${');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private getValue(key: string): any {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any)[this._windowKey]?.[key];\n }\n\n get appUrl(): string {\n const value = this.getValue('APP_URL');\n\n return this.isValidValue(value) ? value : this._environment.appUrl;\n }\n\n get appBaseHref(): string {\n const value = this.getValue('APP_BASE_HREF');\n\n return this.isValidValue(value) ? value : this._environment.appBaseHref;\n }\n\n get apiUrl(): string {\n const value = this.getValue('API_URL');\n\n return this.isValidValue(value) ? value : this._environment.apiUrl;\n }\n\n get defaultLanguage(): string {\n const value = this.getValue('DEFAULT_LANGUAGE');\n\n return this.isValidValue(value) ? value : this._environment.defaultLanguage;\n }\n\n get authUrl(): string {\n const value = this.getValue('AUTH_URL');\n\n return this.isValidValue(value) ? value : this._environment.authUrl;\n }\n\n get authRealm(): string {\n const value = this.getValue('AUTH_REALM');\n\n return this.isValidValue(value) ? value : this._environment.authRealm;\n }\n\n get authClientId(): string {\n const value = this.getValue('AUTH_CLIENT_ID');\n\n return this.isValidValue(value) ? value : this._environment.authClientId;\n }\n}\n\nexport function provideConfig(options?: {\n service?: Type<IConfigService>;\n}): (Provider | EnvironmentProviders)[] {\n return [\n { provide: CONFIG_SERVICE, useClass: options?.service ?? ConfigService },\n { provide: APP_BASE_HREF, useFactory: () => inject(CONFIG_SERVICE).appBaseHref },\n ];\n}\n","import { CONFIG_SERVICE } from './app-config';\n\nimport {\n EnvironmentProviders,\n inject,\n Injectable,\n InjectionToken,\n provideAppInitializer,\n Provider,\n signal,\n Signal,\n Type,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AUTH_CONFIG, AuthConfig, OAuthService, provideOAuthClient } from 'angular-oauth2-oidc';\nimport { jwtDecode } from 'jwt-decode';\nimport { filter, from, map, Observable, tap } from 'rxjs';\n\nexport const AUTH_SERVICE = new InjectionToken<IAuthService>('AUTH_SERVICE');\n\nexport interface IdToken {\n sub: string;\n iss: string;\n aud: string | string[];\n exp: number;\n iat: number;\n name?: string;\n given_name?: string;\n family_name?: string;\n email?: string;\n email_verified?: boolean;\n preferred_username?: string;\n [key: string]: unknown;\n}\n\nexport interface AccessToken {\n exp: number;\n iat: number;\n jti: string | undefined;\n iss: string;\n aud: string;\n sub: string;\n typ: string | undefined;\n azp: string | undefined;\n sid: string | undefined;\n acr: string | undefined;\n 'allowed-origins': string[] | undefined;\n realm_access: Record<string, string[]> | undefined;\n scope: string | undefined;\n email_verified: boolean | undefined;\n roles: string[] | undefined;\n name: string | undefined;\n preferred_username: string | undefined;\n given_name: string | undefined;\n family_name: string | undefined;\n email: string | undefined;\n}\n\nexport interface IAuthService {\n isAuthenticated: Signal<boolean>;\n\n init(): Observable<void>;\n\n getIdToken(): IdToken;\n\n getAccessToken(): string;\n\n getDecodedAccessToken(): AccessToken | undefined;\n\n hasRoles(roles: string): boolean;\n hasRoles(roles: string[], mode: 'any' | 'all'): boolean;\n\n login(): void;\n\n logout(): void;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AuthService implements IAuthService {\n private readonly _authService = inject(OAuthService);\n\n private readonly _isAuthenticated = signal(this._authService.hasValidAccessToken());\n public readonly isAuthenticated = this._isAuthenticated.asReadonly();\n\n constructor() {\n this._authService.configure(inject(AUTH_CONFIG));\n this._authService.setupAutomaticSilentRefresh();\n\n this._authService.events\n .pipe(\n takeUntilDestroyed(),\n filter((event) => event.type == 'token_received'),\n tap(() => this._isAuthenticated.set(true))\n )\n .subscribe();\n\n this._authService.events\n .pipe(\n takeUntilDestroyed(),\n filter((event) => event.type == 'logout' || event.type == 'token_expires'),\n tap(() => this._isAuthenticated.set(false))\n )\n .subscribe();\n }\n\n init(): Observable<void> {\n return from(this._authService.loadDiscoveryDocumentAndTryLogin()).pipe(map(() => void 0));\n }\n\n getIdToken(): IdToken {\n return this._authService.getIdentityClaims() as IdToken;\n }\n\n getAccessToken(): string {\n return this._authService.getAccessToken();\n }\n\n getDecodedAccessToken(): AccessToken | undefined {\n const accessToken = this.getAccessToken();\n\n try {\n return jwtDecode<AccessToken>(accessToken);\n } catch (error) {\n console.warn(error);\n return undefined;\n }\n }\n\n hasRoles(roles: string): boolean;\n hasRoles(roles: string[], mode: 'any' | 'all'): boolean;\n hasRoles(roles: string | string[], mode: 'any' | 'all' = 'any'): boolean {\n if (this._isAuthenticated() === false) return false;\n\n const accessToken = this.getDecodedAccessToken();\n\n if (accessToken?.roles == undefined) return false;\n\n if (Array.isArray(roles)) {\n if (mode === 'any') {\n return accessToken.roles.some((role) => roles.includes(role));\n } else {\n return accessToken.roles.filter((role) => roles.includes(role)).length === roles.length;\n }\n } else {\n return accessToken.roles.includes(roles);\n }\n }\n\n login(): void {\n return this._authService.initLoginFlow();\n }\n\n logout(): void {\n return this._authService.logOut();\n }\n}\n\nexport function provideAuthConfig(options?: {\n service?: Type<IAuthService>;\n authConfig?: AuthConfig;\n}): (Provider | EnvironmentProviders)[] {\n return [\n provideOAuthClient(),\n {\n provide: AUTH_CONFIG,\n useFactory: () => {\n const configService = inject(CONFIG_SERVICE);\n\n return (\n options?.authConfig ??\n ({\n issuer: `${configService.authUrl}/realms/${configService.authRealm}`,\n clientId: configService.authClientId,\n responseType: 'code',\n scope: 'openid offline_access',\n redirectUri: configService.appUrl,\n showDebugInformation: false,\n } as AuthConfig)\n );\n },\n deps: [CONFIG_SERVICE],\n },\n { provide: AUTH_SERVICE, useClass: options?.service ?? AuthService },\n provideAppInitializer(() => inject(AUTH_SERVICE).init()),\n ];\n}\n","import { EnvironmentProviders, Injectable, InjectionToken, Provider, Type } from '@angular/core';\n\nexport const STORAGE_SERVICE = new InjectionToken<IStorageService>('STORAGE_SERVICE');\n\nexport interface IStorageService {\n getItem(key: string): string | undefined;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n clear(): void;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class StorageService implements IStorageService {\n getItem(key: string): string | undefined {\n return localStorage.getItem(key) ?? undefined;\n }\n\n setItem(key: string, value: string): void {\n localStorage.setItem(key, value);\n }\n\n removeItem(key: string): void {\n localStorage.removeItem(key);\n }\n\n clear(): void {\n localStorage.clear();\n }\n}\n\nexport function provideStorageConfig(options?: {\n service?: Type<IStorageService>;\n}): (Provider | EnvironmentProviders)[] {\n return [{ provide: STORAGE_SERVICE, useClass: options?.service ?? StorageService }];\n}\n","import { STORAGE_SERVICE } from './storage';\n\nimport {\n afterNextRender,\n EnvironmentProviders,\n inject,\n Injectable,\n InjectionToken,\n Provider,\n Type,\n} from '@angular/core';\n\nexport const THEME_SERVICE = new InjectionToken<IThemeService>('THEME_SERVICE');\n\nexport type Theme = 'light' | 'dark';\n\nexport interface IThemeService {\n getTheme(): Theme;\n setTheme(value: Theme): void;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService implements IThemeService {\n private readonly _storageService = inject(STORAGE_SERVICE);\n\n protected readonly _storageKeys = {\n theme: 'theme.current',\n };\n\n constructor() {\n afterNextRender(() => {\n this.setTheme(this.getTheme());\n });\n }\n\n getTheme(): Theme {\n const storageValue = this._storageService.getItem(this._storageKeys.theme);\n\n if (storageValue === undefined || (storageValue !== 'light' && storageValue !== 'dark')) {\n return 'light';\n }\n\n return storageValue;\n }\n\n setTheme(key: Theme): void {\n this._storageService.setItem(this._storageKeys.theme, key);\n\n if (key === 'light') document.documentElement.classList.remove('dark');\n else document.documentElement.classList.add('dark');\n }\n}\n\nexport function provideThemeConfig(options?: {\n service?: Type<IThemeService>;\n}): (Provider | EnvironmentProviders)[] {\n return [{ provide: THEME_SERVICE, useClass: options?.service ?? ThemeService }];\n}\n","import { CONFIG_SERVICE } from './app-config';\nimport { STORAGE_SERVICE } from './storage';\n\nimport { provideTranslateService, TranslateService } from '@ngx-translate/core';\nimport { provideTranslateHttpLoader } from '@ngx-translate/http-loader';\n\nimport { registerLocaleData } from '@angular/common';\nimport { provideHttpClient } from '@angular/common/http';\nimport localeUS from '@angular/common/locales/en';\nimport localeFR from '@angular/common/locales/fr';\nimport {\n EnvironmentProviders,\n inject,\n Injectable,\n InjectionToken,\n provideAppInitializer,\n Provider,\n signal,\n Signal,\n Type,\n} from '@angular/core';\n\nexport const TRANSLATION_SERVICE = new InjectionToken<ITranslationService>('TRANSLATION_SERVICE');\n\nexport interface ITranslationService {\n currentLanguage: Signal<string>;\n\n init(): void;\n setLanguage(code: string): void;\n\n instant(key: string, params?: Record<string, string>): string;\n instant(key: string[], params?: Record<string, string>): string[];\n instant(key: string | string[], params?: Record<string, string>): string | string[];\n}\n\n@Injectable({ providedIn: 'root' })\nexport class TranslationService implements ITranslationService {\n private readonly _storageService = inject(STORAGE_SERVICE);\n private readonly _appConfigService = inject(CONFIG_SERVICE);\n private readonly _translationService = inject(TranslateService);\n\n protected readonly _storageKeys = {\n lang: 'translation.lang',\n };\n\n protected readonly _currentLanguage = signal(\n this._storageService.getItem(this._storageKeys.lang) ?? this._appConfigService.defaultLanguage\n );\n public readonly currentLanguage = this._currentLanguage.asReadonly();\n\n public init(): void {\n this._translationService.use(this._currentLanguage());\n this._storageService.setItem(this._storageKeys.lang, this._currentLanguage());\n }\n\n public setLanguage(code: string): void {\n this._storageService.setItem(this._storageKeys.lang, code);\n this._currentLanguage.set(code);\n this._translationService.use(code);\n }\n\n public instant(key: string, params?: Record<string, string>): string;\n public instant(key: string[], params?: Record<string, string>): string[];\n public instant(key: string | string[], params?: Record<string, string>): string | string[] {\n return this._translationService.instant(key, params);\n }\n}\n\nexport function provideTranslationConfig(options?: {\n service?: Type<ITranslationService>;\n}): (Provider | EnvironmentProviders)[] {\n registerLocaleData(localeFR);\n registerLocaleData(localeUS);\n\n return [\n provideHttpClient(),\n provideTranslateService({\n loader: provideTranslateHttpLoader({ prefix: '/i18n', suffix: '.json' }),\n }),\n { provide: TRANSLATION_SERVICE, useClass: options?.service ?? TranslationService },\n provideAppInitializer(() => inject(TRANSLATION_SERVICE).init()),\n ];\n}\n","import { inject, Injector } from '@angular/core';\n\nexport abstract class BaseComponent {\n protected readonly _injector = inject(Injector);\n}\n","import {\n FilterRequest,\n PaginationRequest,\n PaginationResponse,\n SortRequest,\n} from '@mgremy/core/models';\n\nimport { computed, ResourceRef, signal } from '@angular/core';\nimport { rxResource, RxResourceOptions } from '@angular/core/rxjs-interop';\n\n/**\n * Wrapper around PaginationRequest/PaginationResponses and RxResources used side by side with API.\n * It supports AutoRefreshing data.\n */\nexport class PaginationContainer<TResult> {\n /**\n * Value is computed each time pageNumber | pageSize | sortRequest (if not undefined) is updated.\n */\n private readonly _paginationRequest = computed<PaginationRequest<TResult> | undefined>(() => {\n const pageNumber = this.pageNumber();\n const pageSize = this.pageSize();\n const sortRequest = this.sortRequest();\n const filterRequest = this.filterRequest();\n\n if (pageNumber <= 0 || pageSize <= 0) {\n return undefined;\n }\n\n const paginationRequest: PaginationRequest<TResult> = {\n pageNumber: pageNumber,\n pageSize: pageSize,\n sortRequests: Object.entries(sortRequest)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => ({ propertyName: k, isDescending: v }) as SortRequest<TResult>),\n filterRequest: filterRequest,\n };\n\n return paginationRequest;\n });\n\n public readonly pageNumber = signal<number>(-1);\n public readonly pageSize = signal<number>(-1);\n public readonly sortRequest = signal<Record<keyof TResult, boolean | undefined>>(\n {} as Record<keyof TResult, boolean | undefined>\n );\n public readonly filterRequest = signal<FilterRequest<TResult>[]>([], {\n debugName: 'filterRequest',\n equal: () => false,\n });\n public readonly resource: ResourceRef<PaginationResponse<TResult> | undefined>;\n\n constructor(\n resourceOpts: Omit<\n RxResourceOptions<PaginationResponse<TResult>, PaginationRequest<TResult> | undefined>,\n 'params'\n >\n ) {\n this.resource = rxResource<PaginationResponse<TResult>, PaginationRequest<TResult> | undefined>(\n {\n ...resourceOpts,\n params: () => this._paginationRequest(),\n }\n );\n }\n\n /**\n * Update the sort status on property from TResult.\n *\n * It goes undefined -> false -> true.\n * In terms of usage, it goes undefined -> ASC -> DESC.\n * @param propertyName The name of the property from TResult on which we want to update the sort status\n */\n public onSortChange(propertyName: keyof TResult): void {\n const current = this.sortRequest();\n\n this.sortRequest.set({\n ...current,\n [propertyName]:\n current[propertyName] === undefined\n ? false\n : current[propertyName] === false\n ? true\n : undefined,\n });\n }\n}\n\nexport function paginationContainer<TResult>(\n resourceOpts: Omit<\n RxResourceOptions<PaginationResponse<TResult>, PaginationRequest<TResult> | undefined>,\n 'params'\n >\n): PaginationContainer<TResult> {\n return new PaginationContainer(resourceOpts);\n}\n","/**\n * Store a map of unique ids for elements so that there are no collisions.\n */\nconst uniqueIdMap = new Map<string, number>();\n\n/**\n * Generate a unique id for an element\n * @param prefix - The prefix to use for the id\n * @returns The generated id\n */\nexport function uniqueId(prefix: string): string {\n const id = uniqueIdMap.get(prefix) ?? 0;\n uniqueIdMap.set(prefix, id + 1);\n return `${prefix}-${id}`;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ # @mgremy/core/src/lib/guards
2
+
3
+ Secondary entry point of `@mgremy/core`. It can be used by importing from `@mgremy/core/guards`.
@@ -0,0 +1,4 @@
1
+ # @mgremy/core/src/lib/interceptors
2
+
3
+ Secondary entry point of `@mgremy/core`. It can be used by importing from
4
+ `@mgremy/core/interceptors`.
@@ -0,0 +1,3 @@
1
+ # @mgremy/core/src/lib/models
2
+
3
+ Secondary entry point of `@mgremy/core`. It can be used by importing from `@mgremy/core/models`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mgremy/core",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -9,7 +9,13 @@
9
9
  "url": "https://github.com/MGREMY/nx_source"
10
10
  },
11
11
  "peerDependencies": {
12
- "@angular/core": "^21.1.0"
12
+ "@angular/core": "^21.1.0",
13
+ "@ngx-translate/core": "^18.0.0",
14
+ "@ngx-translate/http-loader": "^18.0.0",
15
+ "angular-oauth2-oidc": "^22.0.0",
16
+ "jwt-decode": "^4.0.0",
17
+ "rxjs": "^7.8.0",
18
+ "zod": "^4.4.3"
13
19
  },
14
20
  "sideEffects": false,
15
21
  "module": "fesm2022/mgremy-core.mjs",
@@ -21,6 +27,34 @@
21
27
  ".": {
22
28
  "types": "./types/mgremy-core.d.ts",
23
29
  "default": "./fesm2022/mgremy-core.mjs"
30
+ },
31
+ "./guards": {
32
+ "types": "./types/mgremy-core-guards.d.ts",
33
+ "default": "./fesm2022/mgremy-core-guards.mjs"
34
+ },
35
+ "./interceptors": {
36
+ "types": "./types/mgremy-core-interceptors.d.ts",
37
+ "default": "./fesm2022/mgremy-core-interceptors.mjs"
38
+ },
39
+ "./models": {
40
+ "types": "./types/mgremy-core-models.d.ts",
41
+ "default": "./fesm2022/mgremy-core-models.mjs"
42
+ },
43
+ "./pipes": {
44
+ "types": "./types/mgremy-core-pipes.d.ts",
45
+ "default": "./fesm2022/mgremy-core-pipes.mjs"
46
+ },
47
+ "./resolvers": {
48
+ "types": "./types/mgremy-core-resolvers.d.ts",
49
+ "default": "./fesm2022/mgremy-core-resolvers.mjs"
50
+ },
51
+ "./types": {
52
+ "types": "./types/mgremy-core-types.d.ts",
53
+ "default": "./fesm2022/mgremy-core-types.mjs"
54
+ },
55
+ "./utils": {
56
+ "types": "./types/mgremy-core-utils.d.ts",
57
+ "default": "./fesm2022/mgremy-core-utils.mjs"
24
58
  }
25
59
  },
26
60
  "dependencies": {
@@ -0,0 +1,3 @@
1
+ # @mgremy/core/src/lib/pipes
2
+
3
+ Secondary entry point of `@mgremy/core`. It can be used by importing from `@mgremy/core/pipes`.
@@ -0,0 +1,3 @@
1
+ # @mgremy/core/src/lib/resolvers
2
+
3
+ Secondary entry point of `@mgremy/core`. It can be used by importing from `@mgremy/core/resolvers`.
@@ -0,0 +1,3 @@
1
+ # @mgremy/core/src/lib/types
2
+
3
+ Secondary entry point of `@mgremy/core`. It can be used by importing from `@mgremy/core/types`.
@@ -0,0 +1,49 @@
1
+ import { CanActivateFn } from '@angular/router';
2
+
3
+ declare const authGuard: CanActivateFn;
4
+ /**
5
+ * Check if user is not connected
6
+ *
7
+ * @remarks
8
+ * The returnPath has a default value of `['/']`
9
+ *
10
+ * @example
11
+ {
12
+ path: 'feat',
13
+ loadChildren: () => import('./feat/feat.routes'),
14
+ canActivate: [notAuthGuard],
15
+ data: {
16
+ notAuthGuard: {
17
+ returnPath: ['/', 'some', 'path'],
18
+ },
19
+ },
20
+ }
21
+ */
22
+ declare const notAuthGuard: CanActivateFn;
23
+
24
+ /**
25
+ * Check if connected user has role
26
+ *
27
+ * @remarks
28
+ * This guards waits for `hasRoleGuard.roles` as data from angular route (as shown in the example)
29
+ * The behavior can be changed between `any` and `all`
30
+ *
31
+ * `any` checks if the user has at least one role provided
32
+ *
33
+ * `all` checks if the user has every role provided
34
+ *
35
+ * @example
36
+ {
37
+ path: 'feat',
38
+ canActivate: [hasRoleGuard],
39
+ data: {
40
+ hasRoleGuard: {
41
+ mode: 'any',
42
+ roles: [roles.Admin],
43
+ },
44
+ },
45
+ },
46
+ */
47
+ declare const hasRoleGuard: CanActivateFn;
48
+
49
+ export { authGuard, hasRoleGuard, notAuthGuard };
@@ -0,0 +1,8 @@
1
+ import { HttpRequest, HttpHandlerFn, HttpEvent } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+
4
+ declare function authInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>;
5
+
6
+ declare function langInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>;
7
+
8
+ export { authInterceptor, langInterceptor };
@@ -0,0 +1,75 @@
1
+ import * as z from 'zod';
2
+ import z__default from 'zod';
3
+
4
+ type ErrorResponse = {
5
+ errors: Record<string, string[]>;
6
+ message: string;
7
+ statusCode: number;
8
+ };
9
+ declare const ZErrorResponse: z.ZodType<ErrorResponse>;
10
+
11
+ declare enum FilterRequestOperator {
12
+ Equal = 0,
13
+ NotEqual = 1,
14
+ LessThan = 2,
15
+ LessThanOrEqual = 3,
16
+ GreaterThan = 4,
17
+ GreaterThanOrEqual = 5,
18
+ Contains = 6,
19
+ NotContains = 7,
20
+ StartWith = 8,
21
+ EndWith = 9
22
+ }
23
+ declare enum FilterRequestLogic {
24
+ And = 0,
25
+ Or = 1
26
+ }
27
+ type FilterRequest<T> = {
28
+ propertyName: keyof T;
29
+ filterOperator: FilterRequestOperator;
30
+ value: string;
31
+ filterLogic: FilterRequestLogic;
32
+ filters?: FilterRequest<T>[] | undefined;
33
+ };
34
+ type SortRequest<T> = {
35
+ propertyName: keyof T;
36
+ isDescending: boolean;
37
+ };
38
+ type PaginationRequest<T> = {
39
+ pageNumber: number;
40
+ pageSize: number;
41
+ sortRequests?: SortRequest<T>[] | undefined;
42
+ filterRequest?: FilterRequest<T>[] | undefined;
43
+ };
44
+ type PaginationResponse<T> = {
45
+ pageNumber: number;
46
+ pageSize: number;
47
+ hasNextPage: boolean;
48
+ hasPreviousPage: boolean;
49
+ totalPages: number;
50
+ data: T[];
51
+ };
52
+ declare const ZPaginationResponse: <T extends z__default.ZodType<any, any>>(itemSchema: T) => z__default.ZodObject<{
53
+ pageNumber: z__default.ZodNumber;
54
+ pageSize: z__default.ZodNumber;
55
+ hasNextPage: z__default.ZodBoolean;
56
+ hasPreviousPage: z__default.ZodBoolean;
57
+ totalPages: z__default.ZodNumber;
58
+ data: z__default.ZodArray<T>;
59
+ }, z__default.core.$strip>;
60
+
61
+ type PossibleFilter<T> = {
62
+ property: keyof T;
63
+ operators: FilterRequestOperator[];
64
+ type: 'text' | 'guid' | 'number' | 'date' | 'boolean';
65
+ };
66
+
67
+ type TableFilterOption<T> = {
68
+ defaultFilterProperty: keyof T;
69
+ defaultFilterValue: string;
70
+ objectTranslationKey: string;
71
+ possibleFilters: PossibleFilter<T>[];
72
+ };
73
+
74
+ export { FilterRequestLogic, FilterRequestOperator, ZErrorResponse, ZPaginationResponse };
75
+ export type { ErrorResponse, FilterRequest, PaginationRequest, PaginationResponse, PossibleFilter, SortRequest, TableFilterOption };