@memberjunction/ng-bootstrap 0.0.1 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,474 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Component, Inject, Injectable, APP_INITIALIZER, NgModule } from '@angular/core';
3
+ import * as i4 from '@angular/common';
4
+ import { DOCUMENT, CommonModule } from '@angular/common';
5
+ import { SetProductionStatus, Metadata, LogError } from '@memberjunction/core';
6
+ import { take } from 'rxjs/operators';
7
+ import * as i1 from '@angular/router';
8
+ import * as i2 from '@memberjunction/ng-auth-services';
9
+ import { AuthErrorType, MJAuthBase } from '@memberjunction/ng-auth-services';
10
+ import { GraphQLProviderConfigData, setupGraphQLClient } from '@memberjunction/graphql-dataprovider';
11
+ import { SharedService } from '@memberjunction/ng-shared';
12
+
13
+ /**
14
+ * Injection token for MJ Environment Configuration
15
+ */
16
+ const MJ_ENVIRONMENT = new InjectionToken('MJ_ENVIRONMENT');
17
+ /**
18
+ * Injection token for optional startup validation service
19
+ */
20
+ const MJ_STARTUP_VALIDATION = new InjectionToken('MJ_STARTUP_VALIDATION', {
21
+ providedIn: 'root',
22
+ factory: () => null // Default to null if not provided
23
+ });
24
+
25
+ /**
26
+ * MemberJunction 3.0 Bootstrap Component
27
+ *
28
+ * Minimal placeholder component for future fully encapsulated bootstrap.
29
+ * Currently applications should use MJInitializationService directly in their app.component.
30
+ */
31
+ class MJBootstrapComponent {
32
+ environment;
33
+ constructor(environment) {
34
+ this.environment = environment;
35
+ }
36
+ ngOnInit() {
37
+ console.log('🚀 MemberJunction 3.0 Bootstrap');
38
+ SetProductionStatus(this.environment.production);
39
+ }
40
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJBootstrapComponent, deps: [{ token: MJ_ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component });
41
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MJBootstrapComponent, selector: "mj-bootstrap", ngImport: i0, template: `
42
+ <div class="mj-bootstrap-container">
43
+ <ng-content></ng-content>
44
+ </div>
45
+ `, isInline: true, styles: [".mj-bootstrap-container{display:block;width:100%;height:100%}\n"] });
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJBootstrapComponent, decorators: [{
48
+ type: Component,
49
+ args: [{ selector: 'mj-bootstrap', template: `
50
+ <div class="mj-bootstrap-container">
51
+ <ng-content></ng-content>
52
+ </div>
53
+ `, styles: [".mj-bootstrap-container{display:block;width:100%;height:100%}\n"] }]
54
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
55
+ type: Inject,
56
+ args: [MJ_ENVIRONMENT]
57
+ }] }] });
58
+
59
+ /**
60
+ * MemberJunction 3.0 Initialization Service
61
+ *
62
+ * Handles all core initialization tasks:
63
+ * - Generated entities loading
64
+ * - GraphQL client setup
65
+ * - Token refresh configuration
66
+ * - System validation
67
+ */
68
+ class MJInitializationService {
69
+ router;
70
+ authBase;
71
+ startupValidationService;
72
+ constructor(router, authBase, startupValidationService) {
73
+ this.router = router;
74
+ this.authBase = authBase;
75
+ this.startupValidationService = startupValidationService;
76
+ }
77
+ /**
78
+ * Initialize GraphQL client with authentication token and refresh callback
79
+ */
80
+ async initializeGraphQL(token, environment) {
81
+ const url = environment.GRAPHQL_URI;
82
+ const wsurl = environment.GRAPHQL_WS_URI;
83
+ const start = Date.now();
84
+ const config = new GraphQLProviderConfigData(token, url, wsurl, async () => {
85
+ // Token refresh callback - refreshToken() returns StandardAuthToken directly or throws
86
+ const token = await this.authBase.refreshToken();
87
+ return token.idToken;
88
+ }, environment.MJ_CORE_SCHEMA_NAME);
89
+ await setupGraphQLClient(config);
90
+ const end = Date.now();
91
+ console.log(`✓ GraphQL Client Setup Complete: ${end - start}ms`);
92
+ }
93
+ /**
94
+ * Refresh shared data and validate user access
95
+ */
96
+ async validateUserAccess() {
97
+ await SharedService.RefreshData(true);
98
+ const md = new Metadata();
99
+ if (!md.CurrentUser) {
100
+ return {
101
+ success: false,
102
+ error: {
103
+ message: "You don't have access to the application, contact your system administrator.",
104
+ type: 'no_access'
105
+ }
106
+ };
107
+ }
108
+ return { success: true };
109
+ }
110
+ /**
111
+ * Run startup validation checks (if validation service is provided)
112
+ */
113
+ runValidationChecks() {
114
+ if (!this.startupValidationService) {
115
+ return; // No validation service provided
116
+ }
117
+ // Small delay to ensure everything is initialized
118
+ setTimeout(() => {
119
+ this.startupValidationService?.validateSystemSetup();
120
+ }, 500);
121
+ }
122
+ /**
123
+ * Navigate to initial route after successful login
124
+ */
125
+ navigateToInitialRoute(initialPath, document) {
126
+ localStorage.removeItem('jwt-retry-ts');
127
+ if (initialPath === '/') {
128
+ // Use first nav item instead
129
+ setTimeout(() => {
130
+ // Find the KendoDrawer element and simulate a click for the first item
131
+ const drawerElement = document.querySelector('li.k-drawer-item.k-level-0');
132
+ if (drawerElement)
133
+ drawerElement.click();
134
+ }, 10); // Wait for the drawer to finish render
135
+ }
136
+ else {
137
+ this.router.navigateByUrl(initialPath, { replaceUrl: true });
138
+ }
139
+ }
140
+ /**
141
+ * Check if error is related to missing user roles
142
+ */
143
+ isNoUserRolesError(err) {
144
+ try {
145
+ if (!err || typeof err !== 'object')
146
+ return false;
147
+ // Check for GraphQL-style errors
148
+ if (err.response && Array.isArray(err.response.errors)) {
149
+ return err.response.errors.some((e) => e && e.message && typeof e.message === 'string' &&
150
+ e.message.includes('does not have read permissions on User Roles'));
151
+ }
152
+ // Check for specific "ResourceTypes" error
153
+ if (err.toString && typeof err.toString === 'function') {
154
+ const errorString = err.toString();
155
+ if (errorString.includes("Cannot read properties of undefined (reading 'ResourceTypes')")) {
156
+ return true;
157
+ }
158
+ }
159
+ // Check for error message directly on the error object
160
+ if (err.message && typeof err.message === 'string') {
161
+ const message = err.message;
162
+ return message.includes('does not have read permissions on User Roles') ||
163
+ message.includes("Cannot read properties of undefined (reading 'ResourceTypes')");
164
+ }
165
+ // Check for nested error object
166
+ if (err.error && typeof err.error === 'object') {
167
+ return this.isNoUserRolesError(err.error);
168
+ }
169
+ return false;
170
+ }
171
+ catch (e) {
172
+ console.error('Error while checking for user roles error:', e);
173
+ return false;
174
+ }
175
+ }
176
+ /**
177
+ * Handle no roles error by showing validation banner (if validation service is provided)
178
+ */
179
+ handleNoRolesError() {
180
+ this.startupValidationService?.addNoRolesValidationIssue();
181
+ return {
182
+ success: false,
183
+ error: {
184
+ message: 'User has no roles assigned',
185
+ type: 'no_roles',
186
+ showValidationOnly: true
187
+ }
188
+ };
189
+ }
190
+ /**
191
+ * Handle authentication retry logic
192
+ */
193
+ async handleAuthRetry(err) {
194
+ const retryKey = 'auth-retry-dt';
195
+ const lastRetryDateTime = localStorage.getItem(retryKey);
196
+ const yesterday = +new Date(Date.now() - 1 * 24 * 60 * 60 * 1000);
197
+ const retriedRecently = lastRetryDateTime && +new Date(lastRetryDateTime) > yesterday;
198
+ const authError = this.authBase.classifyError(err);
199
+ const isTokenExpired = authError.type === AuthErrorType.TOKEN_EXPIRED;
200
+ if (!retriedRecently && isTokenExpired) {
201
+ console.log('JWT Expired, retrying once: ' + err);
202
+ localStorage.setItem(retryKey, new Date().toISOString());
203
+ await this.authBase.login({ appState: { target: window.location.pathname } }).toPromise();
204
+ return true;
205
+ }
206
+ return false;
207
+ }
208
+ /**
209
+ * Get auth error message for display
210
+ */
211
+ getAuthErrorMessage(err) {
212
+ const authError = this.authBase.classifyError(err);
213
+ switch (authError.type) {
214
+ case AuthErrorType.NO_ACTIVE_SESSION:
215
+ return "Welcome back! Please log in to your account.";
216
+ case AuthErrorType.INTERACTION_REQUIRED:
217
+ case AuthErrorType.TOKEN_EXPIRED:
218
+ return "Your session has expired. Please log in to your account.";
219
+ default:
220
+ return authError.userMessage || "Welcome back! Please log in to your account.";
221
+ }
222
+ }
223
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJInitializationService, deps: [{ token: i1.Router }, { token: i2.MJAuthBase }, { token: MJ_STARTUP_VALIDATION }], target: i0.ɵɵFactoryTarget.Injectable });
224
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJInitializationService, providedIn: 'root' });
225
+ }
226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJInitializationService, decorators: [{
227
+ type: Injectable,
228
+ args: [{
229
+ providedIn: 'root'
230
+ }]
231
+ }], ctorParameters: () => [{ type: i1.Router }, { type: i2.MJAuthBase }, { type: undefined, decorators: [{
232
+ type: Inject,
233
+ args: [MJ_STARTUP_VALIDATION]
234
+ }] }] });
235
+
236
+ /**
237
+ * MemberJunction 3.0 Auth Shell Component
238
+ *
239
+ * Handles authentication flow and initialization for MJ applications.
240
+ * This component encapsulates all the auth logic that was previously in app.component.ts
241
+ */
242
+ class MJAuthShellComponent {
243
+ router;
244
+ document;
245
+ authBase;
246
+ initService;
247
+ environment;
248
+ HasError = false;
249
+ ErrorMessage = '';
250
+ showValidationOnly = false;
251
+ subHeaderText = "Welcome back! Please log in to your account.";
252
+ initialPath = '/';
253
+ constructor(router, document, authBase, initService, environment) {
254
+ this.router = router;
255
+ this.document = document;
256
+ this.authBase = authBase;
257
+ this.initService = initService;
258
+ this.environment = environment;
259
+ }
260
+ async ngOnInit() {
261
+ console.log('🚀 MemberJunction 3.0 - Auth Shell Initializing');
262
+ SetProductionStatus(this.environment.production);
263
+ this.initialPath = window.location.pathname + (window.location.search ? window.location.search : '');
264
+ await this.setupAuth();
265
+ }
266
+ /**
267
+ * Handle successful login and initialize the application
268
+ */
269
+ async handleLogin(token, userInfo) {
270
+ if (!token)
271
+ return;
272
+ try {
273
+ // Initialize GraphQL client
274
+ await this.initService.initializeGraphQL(token, this.environment);
275
+ // Validate user access and refresh data
276
+ const validationResult = await this.initService.validateUserAccess();
277
+ if (!validationResult.success) {
278
+ this.HasError = true;
279
+ this.ErrorMessage = validationResult.error.message;
280
+ throw new Error(this.ErrorMessage);
281
+ }
282
+ // Run startup validation checks
283
+ this.initService.runValidationChecks();
284
+ // Navigate to initial route
285
+ this.initService.navigateToInitialRoute(this.initialPath, this.document);
286
+ }
287
+ catch (err) {
288
+ // Check for no roles error
289
+ if (this.initService.isNoUserRolesError(err)) {
290
+ this.showValidationOnly = true;
291
+ this.HasError = true;
292
+ const result = this.initService.handleNoRolesError();
293
+ return; // Don't throw, allow UI to show validation banner
294
+ }
295
+ // Try auth retry if applicable
296
+ const retried = await this.initService.handleAuthRetry(err);
297
+ if (retried) {
298
+ return; // Retry initiated
299
+ }
300
+ // Show error
301
+ this.HasError = true;
302
+ this.ErrorMessage = err;
303
+ LogError('Error Logging In: ' + err);
304
+ throw err;
305
+ }
306
+ }
307
+ /**
308
+ * Setup authentication and handle auth state changes
309
+ */
310
+ async setupAuth() {
311
+ // Auth provider already initialized by APP_INITIALIZER
312
+ // Listen for user info changes
313
+ this.authBase.getUserInfo()
314
+ .pipe(take(1))
315
+ .subscribe({
316
+ next: async (userInfo) => {
317
+ if (userInfo) {
318
+ const token = await this.authBase.getIdToken();
319
+ if (token) {
320
+ await this.handleLogin(token, userInfo);
321
+ }
322
+ else {
323
+ console.error('User info available but no token found');
324
+ }
325
+ }
326
+ },
327
+ error: (err) => {
328
+ LogError('Error Logging In: ' + err);
329
+ this.subHeaderText = this.initService.getAuthErrorMessage(err);
330
+ }
331
+ });
332
+ // Check if user is authenticated
333
+ this.authBase.isAuthenticated()
334
+ .pipe(take(1))
335
+ .subscribe((loggedIn) => {
336
+ if (!loggedIn) {
337
+ // Display login screen - auth state is managed by provider
338
+ console.log('User not authenticated, showing login screen');
339
+ }
340
+ });
341
+ }
342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJAuthShellComponent, deps: [{ token: i1.Router }, { token: DOCUMENT }, { token: i2.MJAuthBase }, { token: MJInitializationService }, { token: MJ_ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component });
343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MJAuthShellComponent, selector: "mj-auth-shell", ngImport: i0, template: `
344
+ <div class="mj-auth-shell">
345
+ <ng-content *ngIf="!HasError || showValidationOnly"></ng-content>
346
+
347
+ <div *ngIf="HasError && !showValidationOnly" class="error-container">
348
+ <h2>Error</h2>
349
+ <p>{{ ErrorMessage }}</p>
350
+ </div>
351
+ </div>
352
+ `, isInline: true, styles: [".mj-auth-shell{width:100%;height:100%;display:block}.error-container{padding:20px;text-align:center}.error-container h2{color:#d32f2f;margin-bottom:10px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
353
+ }
354
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJAuthShellComponent, decorators: [{
355
+ type: Component,
356
+ args: [{ selector: 'mj-auth-shell', template: `
357
+ <div class="mj-auth-shell">
358
+ <ng-content *ngIf="!HasError || showValidationOnly"></ng-content>
359
+
360
+ <div *ngIf="HasError && !showValidationOnly" class="error-container">
361
+ <h2>Error</h2>
362
+ <p>{{ ErrorMessage }}</p>
363
+ </div>
364
+ </div>
365
+ `, styles: [".mj-auth-shell{width:100%;height:100%;display:block}.error-container{padding:20px;text-align:center}.error-container h2{color:#d32f2f;margin-bottom:10px}\n"] }]
366
+ }], ctorParameters: () => [{ type: i1.Router }, { type: Document, decorators: [{
367
+ type: Inject,
368
+ args: [DOCUMENT]
369
+ }] }, { type: i2.MJAuthBase }, { type: MJInitializationService }, { type: undefined, decorators: [{
370
+ type: Inject,
371
+ args: [MJ_ENVIRONMENT]
372
+ }] }] });
373
+
374
+ /**
375
+ * MemberJunction 3.0 Bootstrap Module
376
+ *
377
+ * Provides the MJBootstrapComponent and all necessary services for MemberJunction Angular applications.
378
+ * This module encapsulates all the authentication and initialization logic that was previously
379
+ * spread across app.component.ts and app.module.ts.
380
+ *
381
+ * Usage:
382
+ * ```typescript
383
+ * import { LoadGeneratedEntities } from 'mj_generatedentities';
384
+ * LoadGeneratedEntities(); // Prevent tree shaking
385
+ *
386
+ * @NgModule({
387
+ * imports: [
388
+ * BrowserModule,
389
+ * BrowserAnimationsModule,
390
+ * MJBootstrapModule.forRoot(environment),
391
+ * // ... other MJ modules
392
+ * ],
393
+ * bootstrap: [AppComponent]
394
+ * })
395
+ * export class AppModule {}
396
+ * ```
397
+ */
398
+ /**
399
+ * Initialize auth provider before Angular routing starts
400
+ * This ensures auth providers can process OAuth redirect responses before Angular's router
401
+ * consumes the URL hash
402
+ */
403
+ function initializeAuth(authService) {
404
+ return () => authService.initialize();
405
+ }
406
+ class MJBootstrapModule {
407
+ /**
408
+ * Configure the bootstrap module with environment settings
409
+ *
410
+ * @param environment - Environment configuration for the application
411
+ * @returns ModuleWithProviders with environment configuration and all services
412
+ *
413
+ * @example
414
+ * ```typescript
415
+ * import { environment } from '../environments/environment';
416
+ * import { LoadGeneratedEntities } from 'mj_generatedentities';
417
+ * LoadGeneratedEntities();
418
+ *
419
+ * @NgModule({
420
+ * imports: [
421
+ * MJBootstrapModule.forRoot(environment)
422
+ * ]
423
+ * })
424
+ * export class AppModule {}
425
+ * ```
426
+ */
427
+ static forRoot(environment) {
428
+ return {
429
+ ngModule: MJBootstrapModule,
430
+ providers: [
431
+ { provide: MJ_ENVIRONMENT, useValue: environment },
432
+ // MJInitializationService uses providedIn: 'root'
433
+ {
434
+ provide: APP_INITIALIZER,
435
+ useFactory: initializeAuth,
436
+ deps: [MJAuthBase],
437
+ multi: true
438
+ }
439
+ ]
440
+ };
441
+ }
442
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJBootstrapModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
443
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: MJBootstrapModule, declarations: [MJBootstrapComponent,
444
+ MJAuthShellComponent], imports: [CommonModule], exports: [MJBootstrapComponent,
445
+ MJAuthShellComponent] });
446
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJBootstrapModule, imports: [CommonModule] });
447
+ }
448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MJBootstrapModule, decorators: [{
449
+ type: NgModule,
450
+ args: [{
451
+ declarations: [
452
+ MJBootstrapComponent,
453
+ MJAuthShellComponent
454
+ ],
455
+ imports: [
456
+ CommonModule
457
+ ],
458
+ exports: [
459
+ MJBootstrapComponent,
460
+ MJAuthShellComponent
461
+ ]
462
+ }]
463
+ }] });
464
+
465
+ /**
466
+ * Public API Surface of @memberjunction/ng-bootstrap
467
+ */
468
+
469
+ /**
470
+ * Generated bundle index. Do not edit.
471
+ */
472
+
473
+ export { MJAuthShellComponent, MJBootstrapComponent, MJBootstrapModule, MJInitializationService, MJ_ENVIRONMENT, MJ_STARTUP_VALIDATION, initializeAuth };
474
+ //# sourceMappingURL=memberjunction-ng-bootstrap.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memberjunction-ng-bootstrap.mjs","sources":["../../src/lib/bootstrap.types.ts","../../src/lib/bootstrap.component.ts","../../src/lib/services/initialization.service.ts","../../src/lib/components/auth-shell.component.ts","../../src/lib/bootstrap.module.ts","../../src/public-api.ts","../../src/memberjunction-ng-bootstrap.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * Injection token for MJ Environment Configuration\n */\nexport const MJ_ENVIRONMENT = new InjectionToken<MJEnvironmentConfig>('MJ_ENVIRONMENT');\n\n/**\n * Injection token for optional startup validation service\n */\nexport const MJ_STARTUP_VALIDATION = new InjectionToken<MJStartupValidationService | null>('MJ_STARTUP_VALIDATION', {\n providedIn: 'root',\n factory: () => null // Default to null if not provided\n});\n\n/**\n * Optional interface for startup validation services\n * Applications can provide their own implementation to handle startup validation\n */\nexport interface MJStartupValidationService {\n /**\n * Runs validation checks during application startup\n */\n validateSystemSetup(): void;\n\n /**\n * Adds a validation issue for missing user roles\n */\n addNoRolesValidationIssue(): void;\n}\n\n/**\n * Environment configuration interface for MemberJunction Angular applications\n */\nexport interface MJEnvironmentConfig {\n /**\n * Whether the app is running in production mode\n */\n production: boolean;\n\n /**\n * GraphQL HTTP endpoint URL\n * @example 'http://localhost:4000/graphql'\n */\n GRAPHQL_URI: string;\n\n /**\n * GraphQL WebSocket endpoint URL for subscriptions\n * @example 'ws://localhost:4000/graphql'\n */\n GRAPHQL_WS_URI: string;\n\n /**\n * Authentication provider type\n */\n AUTH_TYPE: 'msal' | 'auth0';\n\n /**\n * MemberJunction core schema name in the database\n * @default '__mj'\n */\n MJ_CORE_SCHEMA_NAME: string;\n\n /**\n * Microsoft Azure AD/Entra Client ID (for MSAL auth)\n */\n CLIENT_ID?: string;\n\n /**\n * Microsoft Azure AD/Entra Tenant ID (for MSAL auth)\n */\n TENANT_ID?: string;\n\n /**\n * Auth0 domain (for Auth0 auth)\n * @example 'myapp.us.auth0.com'\n */\n AUTH0_DOMAIN?: string;\n\n /**\n * Auth0 client ID (for Auth0 auth)\n */\n AUTH0_CLIENTID?: string;\n\n /**\n * Additional custom environment properties\n */\n [key: string]: any;\n}\n","/**\n * MemberJunction 3.0 Bootstrap Component\n *\n * Minimal placeholder component for future fully encapsulated bootstrap.\n * Currently applications should use MJInitializationService directly in their app.component.\n */\n\nimport { Component, Inject, OnInit } from '@angular/core';\nimport { SetProductionStatus } from '@memberjunction/core';\nimport { MJEnvironmentConfig, MJ_ENVIRONMENT } from './bootstrap.types';\n\n@Component({\n selector: 'mj-bootstrap',\n template: `\n <div class=\"mj-bootstrap-container\">\n <ng-content></ng-content>\n </div>\n `,\n styles: [`\n .mj-bootstrap-container {\n display: block;\n width: 100%;\n height: 100%;\n }\n `]\n})\nexport class MJBootstrapComponent implements OnInit {\n constructor(\n @Inject(MJ_ENVIRONMENT) private environment: MJEnvironmentConfig\n ) {}\n\n ngOnInit() {\n console.log('🚀 MemberJunction 3.0 Bootstrap');\n SetProductionStatus(this.environment.production);\n }\n}\n","/**\n * MemberJunction 3.0 Initialization Service\n *\n * Handles all core initialization tasks:\n * - Generated entities loading\n * - GraphQL client setup\n * - Token refresh configuration\n * - System validation\n */\n\nimport { Injectable, Inject } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { Metadata } from '@memberjunction/core';\nimport { setupGraphQLClient, GraphQLProviderConfigData } from '@memberjunction/graphql-dataprovider';\nimport { MJAuthBase, StandardUserInfo, AuthErrorType } from '@memberjunction/ng-auth-services';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { MJEnvironmentConfig, MJ_ENVIRONMENT, MJStartupValidationService, MJ_STARTUP_VALIDATION } from '../bootstrap.types';\n\nexport interface InitializationResult {\n success: boolean;\n error?: {\n message: string;\n type: 'no_access' | 'no_roles' | 'auth_error' | 'unknown';\n showValidationOnly?: boolean;\n };\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MJInitializationService {\n constructor(\n private router: Router,\n private authBase: MJAuthBase,\n @Inject(MJ_STARTUP_VALIDATION) private startupValidationService: MJStartupValidationService | null\n ) {}\n\n /**\n * Initialize GraphQL client with authentication token and refresh callback\n */\n async initializeGraphQL(token: string, environment: MJEnvironmentConfig): Promise<void> {\n const url: string = environment.GRAPHQL_URI;\n const wsurl: string = environment.GRAPHQL_WS_URI;\n\n const start = Date.now();\n const config = new GraphQLProviderConfigData(\n token,\n url,\n wsurl,\n async () => {\n // Token refresh callback - refreshToken() returns StandardAuthToken directly or throws\n const token = await this.authBase.refreshToken();\n return token.idToken;\n },\n environment.MJ_CORE_SCHEMA_NAME\n );\n\n await setupGraphQLClient(config);\n const end = Date.now();\n console.log(`✓ GraphQL Client Setup Complete: ${end - start}ms`);\n }\n\n /**\n * Refresh shared data and validate user access\n */\n async validateUserAccess(): Promise<InitializationResult> {\n await SharedService.RefreshData(true);\n\n const md = new Metadata();\n\n if (!md.CurrentUser) {\n return {\n success: false,\n error: {\n message: \"You don't have access to the application, contact your system administrator.\",\n type: 'no_access'\n }\n };\n }\n\n return { success: true };\n }\n\n /**\n * Run startup validation checks (if validation service is provided)\n */\n runValidationChecks(): void {\n if (!this.startupValidationService) {\n return; // No validation service provided\n }\n\n // Small delay to ensure everything is initialized\n setTimeout(() => {\n this.startupValidationService?.validateSystemSetup();\n }, 500);\n }\n\n /**\n * Navigate to initial route after successful login\n */\n navigateToInitialRoute(initialPath: string, document: Document): void {\n localStorage.removeItem('jwt-retry-ts');\n\n if (initialPath === '/') {\n // Use first nav item instead\n setTimeout(() => {\n // Find the KendoDrawer element and simulate a click for the first item\n const drawerElement = document.querySelector('li.k-drawer-item.k-level-0') as any;\n if (drawerElement) drawerElement.click();\n }, 10); // Wait for the drawer to finish render\n } else {\n this.router.navigateByUrl(initialPath, { replaceUrl: true });\n }\n }\n\n /**\n * Check if error is related to missing user roles\n */\n isNoUserRolesError(err: any): boolean {\n try {\n if (!err || typeof err !== 'object') return false;\n\n // Check for GraphQL-style errors\n if (err.response && Array.isArray(err.response.errors)) {\n return err.response.errors.some((e: any) =>\n e && e.message && typeof e.message === 'string' &&\n e.message.includes('does not have read permissions on User Roles')\n );\n }\n\n // Check for specific \"ResourceTypes\" error\n if (err.toString && typeof err.toString === 'function') {\n const errorString = err.toString();\n if (errorString.includes(\"Cannot read properties of undefined (reading 'ResourceTypes')\")) {\n return true;\n }\n }\n\n // Check for error message directly on the error object\n if (err.message && typeof err.message === 'string') {\n const message = err.message;\n return message.includes('does not have read permissions on User Roles') ||\n message.includes(\"Cannot read properties of undefined (reading 'ResourceTypes')\");\n }\n\n // Check for nested error object\n if (err.error && typeof err.error === 'object') {\n return this.isNoUserRolesError(err.error);\n }\n\n return false;\n } catch (e) {\n console.error('Error while checking for user roles error:', e);\n return false;\n }\n }\n\n /**\n * Handle no roles error by showing validation banner (if validation service is provided)\n */\n handleNoRolesError(): InitializationResult {\n this.startupValidationService?.addNoRolesValidationIssue();\n\n return {\n success: false,\n error: {\n message: 'User has no roles assigned',\n type: 'no_roles',\n showValidationOnly: true\n }\n };\n }\n\n /**\n * Handle authentication retry logic\n */\n async handleAuthRetry(err: any): Promise<boolean> {\n const retryKey = 'auth-retry-dt';\n const lastRetryDateTime = localStorage.getItem(retryKey);\n const yesterday = +new Date(Date.now() - 1 * 24 * 60 * 60 * 1000);\n const retriedRecently = lastRetryDateTime && +new Date(lastRetryDateTime) > yesterday;\n\n const authError = this.authBase.classifyError(err);\n const isTokenExpired = authError.type === AuthErrorType.TOKEN_EXPIRED;\n\n if (!retriedRecently && isTokenExpired) {\n console.log('JWT Expired, retrying once: ' + err);\n localStorage.setItem(retryKey, new Date().toISOString());\n await this.authBase.login({ appState: { target: window.location.pathname } }).toPromise();\n return true;\n }\n\n return false;\n }\n\n /**\n * Get auth error message for display\n */\n getAuthErrorMessage(err: unknown): string {\n const authError = this.authBase.classifyError(err);\n\n switch (authError.type) {\n case AuthErrorType.NO_ACTIVE_SESSION:\n return \"Welcome back! Please log in to your account.\";\n case AuthErrorType.INTERACTION_REQUIRED:\n case AuthErrorType.TOKEN_EXPIRED:\n return \"Your session has expired. Please log in to your account.\";\n default:\n return authError.userMessage || \"Welcome back! Please log in to your account.\";\n }\n }\n}\n","/**\n * MemberJunction 3.0 Auth Shell Component\n *\n * Handles authentication flow and initialization for MJ applications.\n * This component encapsulates all the auth logic that was previously in app.component.ts\n */\n\nimport { Component, OnInit, Inject } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { take } from 'rxjs/operators';\nimport { SetProductionStatus, LogError, LogStatus } from '@memberjunction/core';\nimport { MJAuthBase, StandardUserInfo, AuthErrorType } from '@memberjunction/ng-auth-services';\nimport { MJInitializationService } from '../services/initialization.service';\nimport { MJEnvironmentConfig, MJ_ENVIRONMENT } from '../bootstrap.types';\n\n@Component({\n selector: 'mj-auth-shell',\n template: `\n <div class=\"mj-auth-shell\">\n <ng-content *ngIf=\"!HasError || showValidationOnly\"></ng-content>\n\n <div *ngIf=\"HasError && !showValidationOnly\" class=\"error-container\">\n <h2>Error</h2>\n <p>{{ ErrorMessage }}</p>\n </div>\n </div>\n `,\n styles: [`\n .mj-auth-shell {\n width: 100%;\n height: 100%;\n display: block;\n }\n\n .error-container {\n padding: 20px;\n text-align: center;\n }\n\n .error-container h2 {\n color: #d32f2f;\n margin-bottom: 10px;\n }\n `]\n})\nexport class MJAuthShellComponent implements OnInit {\n public HasError = false;\n public ErrorMessage: any = '';\n public showValidationOnly = false;\n public subHeaderText: string = \"Welcome back! Please log in to your account.\";\n\n private initialPath = '/';\n\n constructor(\n private router: Router,\n @Inject(DOCUMENT) public document: Document,\n public authBase: MJAuthBase,\n private initService: MJInitializationService,\n @Inject(MJ_ENVIRONMENT) private environment: MJEnvironmentConfig\n ) {}\n\n async ngOnInit() {\n console.log('🚀 MemberJunction 3.0 - Auth Shell Initializing');\n\n SetProductionStatus(this.environment.production);\n this.initialPath = window.location.pathname + (window.location.search ? window.location.search : '');\n\n await this.setupAuth();\n }\n\n /**\n * Handle successful login and initialize the application\n */\n async handleLogin(token: string, userInfo: StandardUserInfo): Promise<void> {\n if (!token) return;\n\n try {\n // Initialize GraphQL client\n await this.initService.initializeGraphQL(token, this.environment);\n\n // Validate user access and refresh data\n const validationResult = await this.initService.validateUserAccess();\n\n if (!validationResult.success) {\n this.HasError = true;\n this.ErrorMessage = validationResult.error!.message;\n throw new Error(this.ErrorMessage);\n }\n\n // Run startup validation checks\n this.initService.runValidationChecks();\n\n // Navigate to initial route\n this.initService.navigateToInitialRoute(this.initialPath, this.document);\n\n } catch (err: any) {\n // Check for no roles error\n if (this.initService.isNoUserRolesError(err)) {\n this.showValidationOnly = true;\n this.HasError = true;\n const result = this.initService.handleNoRolesError();\n return; // Don't throw, allow UI to show validation banner\n }\n\n // Try auth retry if applicable\n const retried = await this.initService.handleAuthRetry(err);\n if (retried) {\n return; // Retry initiated\n }\n\n // Show error\n this.HasError = true;\n this.ErrorMessage = err;\n LogError('Error Logging In: ' + err);\n throw err;\n }\n }\n\n /**\n * Setup authentication and handle auth state changes\n */\n async setupAuth(): Promise<void> {\n // Auth provider already initialized by APP_INITIALIZER\n\n // Listen for user info changes\n this.authBase.getUserInfo()\n .pipe(take(1))\n .subscribe({\n next: async (userInfo) => {\n if (userInfo) {\n const token = await this.authBase.getIdToken();\n\n if (token) {\n await this.handleLogin(token, userInfo);\n } else {\n console.error('User info available but no token found');\n }\n }\n },\n error: (err: unknown) => {\n LogError('Error Logging In: ' + err);\n this.subHeaderText = this.initService.getAuthErrorMessage(err);\n }\n });\n\n // Check if user is authenticated\n this.authBase.isAuthenticated()\n .pipe(take(1))\n .subscribe((loggedIn: boolean) => {\n if (!loggedIn) {\n // Display login screen - auth state is managed by provider\n console.log('User not authenticated, showing login screen');\n }\n });\n }\n}\n","/**\n * MemberJunction 3.0 Bootstrap Module\n *\n * Provides the MJBootstrapComponent and all necessary services for MemberJunction Angular applications.\n * This module encapsulates all the authentication and initialization logic that was previously\n * spread across app.component.ts and app.module.ts.\n *\n * Usage:\n * ```typescript\n * import { LoadGeneratedEntities } from 'mj_generatedentities';\n * LoadGeneratedEntities(); // Prevent tree shaking\n *\n * @NgModule({\n * imports: [\n * BrowserModule,\n * BrowserAnimationsModule,\n * MJBootstrapModule.forRoot(environment),\n * // ... other MJ modules\n * ],\n * bootstrap: [AppComponent]\n * })\n * export class AppModule {}\n * ```\n */\n\nimport { NgModule, ModuleWithProviders, APP_INITIALIZER } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MJBootstrapComponent } from './bootstrap.component';\nimport { MJAuthShellComponent } from './components/auth-shell.component';\nimport { MJInitializationService } from './services/initialization.service';\nimport { MJEnvironmentConfig, MJ_ENVIRONMENT } from './bootstrap.types';\nimport { MJAuthBase } from '@memberjunction/ng-auth-services';\n\n/**\n * Initialize auth provider before Angular routing starts\n * This ensures auth providers can process OAuth redirect responses before Angular's router\n * consumes the URL hash\n */\nexport function initializeAuth(authService: MJAuthBase): () => Promise<void> {\n return () => authService.initialize();\n}\n\n@NgModule({\n declarations: [\n MJBootstrapComponent,\n MJAuthShellComponent\n ],\n imports: [\n CommonModule\n ],\n exports: [\n MJBootstrapComponent,\n MJAuthShellComponent\n ]\n})\nexport class MJBootstrapModule {\n /**\n * Configure the bootstrap module with environment settings\n *\n * @param environment - Environment configuration for the application\n * @returns ModuleWithProviders with environment configuration and all services\n *\n * @example\n * ```typescript\n * import { environment } from '../environments/environment';\n * import { LoadGeneratedEntities } from 'mj_generatedentities';\n * LoadGeneratedEntities();\n *\n * @NgModule({\n * imports: [\n * MJBootstrapModule.forRoot(environment)\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n static forRoot(environment: MJEnvironmentConfig): ModuleWithProviders<MJBootstrapModule> {\n return {\n ngModule: MJBootstrapModule,\n providers: [\n { provide: MJ_ENVIRONMENT, useValue: environment },\n // MJInitializationService uses providedIn: 'root'\n {\n provide: APP_INITIALIZER,\n useFactory: initializeAuth,\n deps: [MJAuthBase],\n multi: true\n }\n ]\n };\n }\n}\n","/**\n * Public API Surface of @memberjunction/ng-bootstrap\n */\n\nexport * from './lib/bootstrap.module';\nexport * from './lib/bootstrap.component';\nexport * from './lib/bootstrap.types';\nexport * from './lib/services/initialization.service';\nexport * from './lib/components/auth-shell.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i3.MJInitializationService"],"mappings":";;;;;;;;;;;;AAEA;;AAEG;MACU,cAAc,GAAG,IAAI,cAAc,CAAsB,gBAAgB,EAAE;AAExF;;AAEG;MACU,qBAAqB,GAAG,IAAI,cAAc,CAAoC,uBAAuB,EAAE;AAClH,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,IAAI;AACpB,CAAA;;ACbD;;;;;AAKG;MAqBU,oBAAoB,CAAA;AAEG,IAAA,WAAA,CAAA;AADlC,IAAA,WAAA,CACkC,WAAgC,EAAA;QAAhC,IAAW,CAAA,WAAA,GAAX,WAAW,CAAqB;KAC9D;IAEJ,QAAQ,GAAA;AACN,QAAA,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AAC/C,QAAA,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;KAClD;AARU,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,oBAAoB,kBAErB,cAAc,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAFb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAbrB,QAAA,EAAA,cAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,iEAAA,CAAA,EAAA,CAAA,CAAA;;4FASU,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAfhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EACd,QAAA,EAAA,CAAA;;;;AAIT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,iEAAA,CAAA,EAAA,CAAA;;0BAWE,MAAM;2BAAC,cAAc,CAAA;;;AC5B1B;;;;;;;;AAQG;MAsBU,uBAAuB,CAAA;AAExB,IAAA,MAAA,CAAA;AACA,IAAA,QAAA,CAAA;AAC+B,IAAA,wBAAA,CAAA;AAHzC,IAAA,WAAA,CACU,MAAc,EACd,QAAoB,EACW,wBAA2D,EAAA;QAF1F,IAAM,CAAA,MAAA,GAAN,MAAM,CAAQ;QACd,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAY;QACW,IAAwB,CAAA,wBAAA,GAAxB,wBAAwB,CAAmC;KAChG;AAEJ;;AAEG;AACH,IAAA,MAAM,iBAAiB,CAAC,KAAa,EAAE,WAAgC,EAAA;AACrE,QAAA,MAAM,GAAG,GAAW,WAAW,CAAC,WAAW,CAAC;AAC5C,QAAA,MAAM,KAAK,GAAW,WAAW,CAAC,cAAc,CAAC;AAEjD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACzB,QAAA,MAAM,MAAM,GAAG,IAAI,yBAAyB,CAC1C,KAAK,EACL,GAAG,EACH,KAAK,EACL,YAAW;;YAET,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,SAAC,EACD,WAAW,CAAC,mBAAmB,CAChC,CAAC;AAEF,QAAA,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACjC,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,CAAA,iCAAA,EAAoC,GAAG,GAAG,KAAK,CAAI,EAAA,CAAA,CAAC,CAAC;KAClE;AAED;;AAEG;AACH,IAAA,MAAM,kBAAkB,GAAA;AACtB,QAAA,MAAM,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAEtC,QAAA,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;AAE1B,QAAA,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE;YACnB,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,KAAK,EAAE;AACL,oBAAA,OAAO,EAAE,8EAA8E;AACvF,oBAAA,IAAI,EAAE,WAAW;AAClB,iBAAA;aACF,CAAC;SACH;AAED,QAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KAC1B;AAED;;AAEG;IACH,mBAAmB,GAAA;AACjB,QAAA,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE;AAClC,YAAA,OAAO;SACR;;QAGD,UAAU,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,wBAAwB,EAAE,mBAAmB,EAAE,CAAC;SACtD,EAAE,GAAG,CAAC,CAAC;KACT;AAED;;AAEG;IACH,sBAAsB,CAAC,WAAmB,EAAE,QAAkB,EAAA;AAC5D,QAAA,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAExC,QAAA,IAAI,WAAW,KAAK,GAAG,EAAE;;YAEvB,UAAU,CAAC,MAAK;;gBAEd,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,4BAA4B,CAAQ,CAAC;AAClF,gBAAA,IAAI,aAAa;oBAAE,aAAa,CAAC,KAAK,EAAE,CAAC;AAC3C,aAAC,EAAE,EAAE,CAAC,CAAC;SACR;aAAM;AACL,YAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;SAC9D;KACF;AAED;;AAEG;AACH,IAAA,kBAAkB,CAAC,GAAQ,EAAA;AACzB,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;AAAE,gBAAA,OAAO,KAAK,CAAC;;AAGlD,YAAA,IAAI,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBACtD,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAM,KACrC,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;oBAC/C,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CACnE,CAAC;aACH;;YAGD,IAAI,GAAG,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE;AACtD,gBAAA,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;AACnC,gBAAA,IAAI,WAAW,CAAC,QAAQ,CAAC,+DAA+D,CAAC,EAAE;AACzF,oBAAA,OAAO,IAAI,CAAC;iBACb;aACF;;YAGD,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;AAClD,gBAAA,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;AAC5B,gBAAA,OAAO,OAAO,CAAC,QAAQ,CAAC,8CAA8C,CAAC;AAChE,oBAAA,OAAO,CAAC,QAAQ,CAAC,+DAA+D,CAAC,CAAC;aAC1F;;YAGD,IAAI,GAAG,CAAC,KAAK,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE;gBAC9C,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;aAC3C;AAED,YAAA,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;AACV,YAAA,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,CAAC,CAAC,CAAC;AAC/D,YAAA,OAAO,KAAK,CAAC;SACd;KACF;AAED;;AAEG;IACH,kBAAkB,GAAA;AAChB,QAAA,IAAI,CAAC,wBAAwB,EAAE,yBAAyB,EAAE,CAAC;QAE3D,OAAO;AACL,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,KAAK,EAAE;AACL,gBAAA,OAAO,EAAE,4BAA4B;AACrC,gBAAA,IAAI,EAAE,UAAU;AAChB,gBAAA,kBAAkB,EAAE,IAAI;AACzB,aAAA;SACF,CAAC;KACH;AAED;;AAEG;IACH,MAAM,eAAe,CAAC,GAAQ,EAAA;QAC5B,MAAM,QAAQ,GAAG,eAAe,CAAC;QACjC,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAClE,QAAA,MAAM,eAAe,GAAG,iBAAiB,IAAI,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC;QAEtF,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,KAAK,aAAa,CAAC,aAAa,CAAC;AAEtE,QAAA,IAAI,CAAC,eAAe,IAAI,cAAc,EAAE;AACtC,YAAA,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,GAAG,CAAC,CAAC;AAClD,YAAA,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YACzD,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;AAC1F,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,OAAO,KAAK,CAAC;KACd;AAED;;AAEG;AACH,IAAA,mBAAmB,CAAC,GAAY,EAAA;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAEnD,QAAA,QAAQ,SAAS,CAAC,IAAI;YACpB,KAAK,aAAa,CAAC,iBAAiB;AAClC,gBAAA,OAAO,8CAA8C,CAAC;YACxD,KAAK,aAAa,CAAC,oBAAoB,CAAC;YACxC,KAAK,aAAa,CAAC,aAAa;AAC9B,gBAAA,OAAO,0DAA0D,CAAC;AACpE,YAAA;AACE,gBAAA,OAAO,SAAS,CAAC,WAAW,IAAI,8CAA8C,CAAC;SAClF;KACF;AApLU,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,kEAIxB,qBAAqB,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAJpB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cAFtB,MAAM,EAAA,CAAA,CAAA;;4FAEP,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAHnC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA,CAAA;;0BAKI,MAAM;2BAAC,qBAAqB,CAAA;;;AClCjC;;;;;AAKG;MAyCU,oBAAoB,CAAA;AASrB,IAAA,MAAA,CAAA;AACiB,IAAA,QAAA,CAAA;AAClB,IAAA,QAAA,CAAA;AACC,IAAA,WAAA,CAAA;AACwB,IAAA,WAAA,CAAA;IAZ3B,QAAQ,GAAG,KAAK,CAAC;IACjB,YAAY,GAAQ,EAAE,CAAC;IACvB,kBAAkB,GAAG,KAAK,CAAC;IAC3B,aAAa,GAAW,8CAA8C,CAAC;IAEtE,WAAW,GAAG,GAAG,CAAC;IAE1B,WACU,CAAA,MAAc,EACG,QAAkB,EACpC,QAAoB,EACnB,WAAoC,EACZ,WAAgC,EAAA;QAJxD,IAAM,CAAA,MAAA,GAAN,MAAM,CAAQ;QACG,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAU;QACpC,IAAQ,CAAA,QAAA,GAAR,QAAQ,CAAY;QACnB,IAAW,CAAA,WAAA,GAAX,WAAW,CAAyB;QACZ,IAAW,CAAA,WAAA,GAAX,WAAW,CAAqB;KAC9D;AAEJ,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AAE/D,QAAA,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;AACjD,QAAA,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAErG,QAAA,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;KACxB;AAED;;AAEG;AACH,IAAA,MAAM,WAAW,CAAC,KAAa,EAAE,QAA0B,EAAA;AACzD,QAAA,IAAI,CAAC,KAAK;YAAE,OAAO;AAEnB,QAAA,IAAI;;AAEF,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;;YAGlE,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;AAErE,YAAA,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE;AAC7B,gBAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,YAAY,GAAG,gBAAgB,CAAC,KAAM,CAAC,OAAO,CAAC;AACpD,gBAAA,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;aACpC;;AAGD,YAAA,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;;AAGvC,YAAA,IAAI,CAAC,WAAW,CAAC,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;SAE1E;QAAC,OAAO,GAAQ,EAAE;;YAEjB,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE;AAC5C,gBAAA,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;AAC/B,gBAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;AACrD,gBAAA,OAAO;aACR;;YAGD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAC5D,IAAI,OAAO,EAAE;AACX,gBAAA,OAAO;aACR;;AAGD,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;AACrB,YAAA,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;AACxB,YAAA,QAAQ,CAAC,oBAAoB,GAAG,GAAG,CAAC,CAAC;AACrC,YAAA,MAAM,GAAG,CAAC;SACX;KACF;AAED;;AAEG;AACH,IAAA,MAAM,SAAS,GAAA;;;AAIb,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;AACxB,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACb,aAAA,SAAS,CAAC;AACT,YAAA,IAAI,EAAE,OAAO,QAAQ,KAAI;gBACvB,IAAI,QAAQ,EAAE;oBACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;oBAE/C,IAAI,KAAK,EAAE;wBACT,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;qBACzC;yBAAM;AACL,wBAAA,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;qBACzD;iBACF;aACF;AACD,YAAA,KAAK,EAAE,CAAC,GAAY,KAAI;AACtB,gBAAA,QAAQ,CAAC,oBAAoB,GAAG,GAAG,CAAC,CAAC;gBACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;aAChE;AACF,SAAA,CAAC,CAAC;;AAGL,QAAA,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE;AAC5B,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACb,aAAA,SAAS,CAAC,CAAC,QAAiB,KAAI;YAC/B,IAAI,CAAC,QAAQ,EAAE;;AAEb,gBAAA,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;aAC7D;AACH,SAAC,CAAC,CAAC;KACN;wGA7GU,oBAAoB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAUrB,QAAQ,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,uBAAA,EAAA,EAAA,EAAA,KAAA,EAGR,cAAc,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAbb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EA5BrB,QAAA,EAAA,eAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA;;;;;;;;;AAST,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,6JAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAmBU,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBA9BhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,EACf,QAAA,EAAA,CAAA;;;;;;;;;AAST,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,6JAAA,CAAA,EAAA,CAAA;;0BA6BE,MAAM;2BAAC,QAAQ,CAAA;;0BAGf,MAAM;2BAAC,cAAc,CAAA;;;AC3D1B;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AAUH;;;;AAIG;AACG,SAAU,cAAc,CAAC,WAAuB,EAAA;AACpD,IAAA,OAAO,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC;AACxC,CAAC;MAeY,iBAAiB,CAAA;AAC5B;;;;;;;;;;;;;;;;;;;AAmBG;IACH,OAAO,OAAO,CAAC,WAAgC,EAAA;QAC7C,OAAO;AACL,YAAA,QAAQ,EAAE,iBAAiB;AAC3B,YAAA,SAAS,EAAE;AACT,gBAAA,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE;;AAElD,gBAAA;AACE,oBAAA,OAAO,EAAE,eAAe;AACxB,oBAAA,UAAU,EAAE,cAAc;oBAC1B,IAAI,EAAE,CAAC,UAAU,CAAC;AAClB,oBAAA,KAAK,EAAE,IAAI;AACZ,iBAAA;AACF,aAAA;SACF,CAAC;KACH;wGAnCU,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,iBAX1B,oBAAoB;YACpB,oBAAoB,CAAA,EAAA,OAAA,EAAA,CAGpB,YAAY,CAAA,EAAA,OAAA,EAAA,CAGZ,oBAAoB;YACpB,oBAAoB,CAAA,EAAA,CAAA,CAAA;AAGX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,YAP1B,YAAY,CAAA,EAAA,CAAA,CAAA;;4FAOH,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAb7B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE;wBACZ,oBAAoB;wBACpB,oBAAoB;AACrB,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,YAAY;AACb,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,oBAAoB;wBACpB,oBAAoB;AACrB,qBAAA;AACF,iBAAA,CAAA;;;ACtDD;;AAEG;;ACFH;;AAEG;;;;"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@memberjunction/ng-bootstrap" />
5
+ export * from './public-api';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * MemberJunction 3.0 Bootstrap Component
3
+ *
4
+ * Minimal placeholder component for future fully encapsulated bootstrap.
5
+ * Currently applications should use MJInitializationService directly in their app.component.
6
+ */
7
+ import { OnInit } from '@angular/core';
8
+ import { MJEnvironmentConfig } from './bootstrap.types';
9
+ import * as i0 from "@angular/core";
10
+ export declare class MJBootstrapComponent implements OnInit {
11
+ private environment;
12
+ constructor(environment: MJEnvironmentConfig);
13
+ ngOnInit(): void;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<MJBootstrapComponent, never>;
15
+ static ɵcmp: i0.ɵɵComponentDeclaration<MJBootstrapComponent, "mj-bootstrap", never, {}, {}, never, ["*"], false, never>;
16
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * MemberJunction 3.0 Bootstrap Module
3
+ *
4
+ * Provides the MJBootstrapComponent and all necessary services for MemberJunction Angular applications.
5
+ * This module encapsulates all the authentication and initialization logic that was previously
6
+ * spread across app.component.ts and app.module.ts.
7
+ *
8
+ * Usage:
9
+ * ```typescript
10
+ * import { LoadGeneratedEntities } from 'mj_generatedentities';
11
+ * LoadGeneratedEntities(); // Prevent tree shaking
12
+ *
13
+ * @NgModule({
14
+ * imports: [
15
+ * BrowserModule,
16
+ * BrowserAnimationsModule,
17
+ * MJBootstrapModule.forRoot(environment),
18
+ * // ... other MJ modules
19
+ * ],
20
+ * bootstrap: [AppComponent]
21
+ * })
22
+ * export class AppModule {}
23
+ * ```
24
+ */
25
+ import { ModuleWithProviders } from '@angular/core';
26
+ import { MJEnvironmentConfig } from './bootstrap.types';
27
+ import { MJAuthBase } from '@memberjunction/ng-auth-services';
28
+ import * as i0 from "@angular/core";
29
+ import * as i1 from "./bootstrap.component";
30
+ import * as i2 from "./components/auth-shell.component";
31
+ import * as i3 from "@angular/common";
32
+ /**
33
+ * Initialize auth provider before Angular routing starts
34
+ * This ensures auth providers can process OAuth redirect responses before Angular's router
35
+ * consumes the URL hash
36
+ */
37
+ export declare function initializeAuth(authService: MJAuthBase): () => Promise<void>;
38
+ export declare class MJBootstrapModule {
39
+ /**
40
+ * Configure the bootstrap module with environment settings
41
+ *
42
+ * @param environment - Environment configuration for the application
43
+ * @returns ModuleWithProviders with environment configuration and all services
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * import { environment } from '../environments/environment';
48
+ * import { LoadGeneratedEntities } from 'mj_generatedentities';
49
+ * LoadGeneratedEntities();
50
+ *
51
+ * @NgModule({
52
+ * imports: [
53
+ * MJBootstrapModule.forRoot(environment)
54
+ * ]
55
+ * })
56
+ * export class AppModule {}
57
+ * ```
58
+ */
59
+ static forRoot(environment: MJEnvironmentConfig): ModuleWithProviders<MJBootstrapModule>;
60
+ static ɵfac: i0.ɵɵFactoryDeclaration<MJBootstrapModule, never>;
61
+ static ɵmod: i0.ɵɵNgModuleDeclaration<MJBootstrapModule, [typeof i1.MJBootstrapComponent, typeof i2.MJAuthShellComponent], [typeof i3.CommonModule], [typeof i1.MJBootstrapComponent, typeof i2.MJAuthShellComponent]>;
62
+ static ɵinj: i0.ɵɵInjectorDeclaration<MJBootstrapModule>;
63
+ }