@capitalos/angular 0.1.0-rc.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,369 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, EventEmitter, Component, Input, Output, ViewChild, NgModule } from '@angular/core';
3
+ import { exchangeOneTimeToken, TokenType, TokenParamKey, TokenParamLocation, createLogger, IframeManager, CapitalOSError } from '@capitalos/core';
4
+ export { CapitalOSError, ErrorCode } from '@capitalos/core';
5
+ import { __awaiter } from 'tslib';
6
+ import { BehaviorSubject, combineLatest, map } from 'rxjs';
7
+
8
+ /**
9
+ * Injection token for CapitalOS configuration
10
+ */
11
+ const CAPITALOS_CONFIG = new InjectionToken('CAPITALOS_CONFIG');
12
+ /**
13
+ * Provides the CapitalOS SDK with the specified configuration.
14
+ *
15
+ * Usage in app.config.ts (standalone):
16
+ * ```typescript
17
+ * bootstrapApplication(AppComponent, {
18
+ * providers: [
19
+ * provideCapitalOs({
20
+ * getToken: async () => {
21
+ * const response = await fetch('/api/capitalos/token');
22
+ * const data = await response.json();
23
+ * return data.token;
24
+ * },
25
+ * enableLogging: true,
26
+ * }),
27
+ * ],
28
+ * });
29
+ * ```
30
+ *
31
+ * For NgModule-based apps, use CapitalOsModule.forRoot() instead.
32
+ */
33
+ function provideCapitalOs(config) {
34
+ return [
35
+ {
36
+ provide: CAPITALOS_CONFIG,
37
+ useValue: config,
38
+ },
39
+ TokenExchangeService,
40
+ CapitalOsAuthService,
41
+ ];
42
+ }
43
+
44
+ const TOKEN_EXCHANGE_TIMEOUT_MS = 10000;
45
+ /**
46
+ * Service responsible for exchanging one-time tokens for long-lived JWTs.
47
+ * Creates a hidden iframe to perform the token exchange securely.
48
+ */
49
+ class TokenExchangeService {
50
+ constructor() {
51
+ this.config = inject(CAPITALOS_CONFIG);
52
+ this.isDestroyed = false;
53
+ this.activeAbortController = null;
54
+ }
55
+ ngOnDestroy() {
56
+ var _a;
57
+ this.isDestroyed = true;
58
+ (_a = this.activeAbortController) === null || _a === void 0 ? void 0 : _a.abort();
59
+ this.activeAbortController = null;
60
+ }
61
+ /**
62
+ * Exchanges a one-time token for a long-lived JWT.
63
+ * Delegates to @capitalos/core (browser-only) which handles iframe + Penpal lifecycle.
64
+ */
65
+ exchange(oneTimeToken, options = {}) {
66
+ var _a;
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ if (this.isDestroyed) {
69
+ throw new Error('TokenExchangeService was destroyed');
70
+ }
71
+ // Abort any in-flight exchange when a new one begins.
72
+ (_a = this.activeAbortController) === null || _a === void 0 ? void 0 : _a.abort();
73
+ const abortController = new AbortController();
74
+ this.activeAbortController = abortController;
75
+ try {
76
+ return yield exchangeOneTimeToken({
77
+ oneTimeToken,
78
+ enableLogging: options.enableLogging,
79
+ logger: this.config.logger,
80
+ timeoutMs: TOKEN_EXCHANGE_TIMEOUT_MS,
81
+ signal: abortController.signal,
82
+ });
83
+ }
84
+ finally {
85
+ if (this.activeAbortController === abortController) {
86
+ this.activeAbortController = null;
87
+ }
88
+ }
89
+ });
90
+ }
91
+ }
92
+ TokenExchangeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TokenExchangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
93
+ TokenExchangeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TokenExchangeService });
94
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TokenExchangeService, decorators: [{
95
+ type: Injectable
96
+ }] });
97
+
98
+ /**
99
+ * Converts an unknown error to an Error object
100
+ */
101
+ function toError(error) {
102
+ if (error instanceof Error) {
103
+ return error;
104
+ }
105
+ return new Error(String(error));
106
+ }
107
+ /**
108
+ * Service that manages CapitalOS authentication state.
109
+ * This is the Angular equivalent of React's CapitalOsAuthenticationProvider.
110
+ *
111
+ * It handles:
112
+ * - Fetching one-time tokens via the provided getToken callback
113
+ * - Exchanging one-time tokens for long-lived JWTs
114
+ * - Managing token state via observables
115
+ * - Auto-refreshing tokens when they expire
116
+ */
117
+ class CapitalOsAuthService {
118
+ constructor() {
119
+ this.config = inject(CAPITALOS_CONFIG);
120
+ this.tokenExchangeService = inject(TokenExchangeService);
121
+ // Private BehaviorSubjects for internal state
122
+ this._longLivedToken$ = new BehaviorSubject(undefined);
123
+ this._baseUrl$ = new BehaviorSubject(undefined);
124
+ this._isLoading$ = new BehaviorSubject(false);
125
+ this._error$ = new BehaviorSubject(undefined);
126
+ // Public observable for token data
127
+ this.tokenData$ = combineLatest([this._longLivedToken$, this._baseUrl$]).pipe(map(([token, baseUrl]) => {
128
+ if (!token || !baseUrl) {
129
+ return undefined;
130
+ }
131
+ return {
132
+ token,
133
+ tokenType: TokenType.longLived,
134
+ baseUrl,
135
+ paramKey: TokenParamKey.accessToken,
136
+ paramLocation: TokenParamLocation.hash,
137
+ };
138
+ }));
139
+ // Public observables for UI state
140
+ this.isLoading$ = this._isLoading$.asObservable();
141
+ this.error$ = this._error$.asObservable();
142
+ this.authState$ = combineLatest([this._isLoading$, this._error$, this.tokenData$]).pipe(map(([isLoading, error, tokenData]) => {
143
+ if (isLoading)
144
+ return 'loading';
145
+ if (error)
146
+ return 'error';
147
+ if (tokenData)
148
+ return 'authenticated';
149
+ return 'idle';
150
+ }));
151
+ this.isDestroyed = false;
152
+ this.logger = createLogger(this.config.enableLogging, this.config.logger);
153
+ // Start authentication flow eagerly on construction.
154
+ // This is intentional: auth begins as soon as the app boots so the token
155
+ // is ready when CardsAppComponent renders, reducing perceived load time.
156
+ this.refreshToken();
157
+ }
158
+ ngOnDestroy() {
159
+ this.isDestroyed = true;
160
+ }
161
+ /**
162
+ * Invalidates the current token, triggering a refresh.
163
+ * Called when the iframe signals that the token has expired.
164
+ */
165
+ invalidateToken() {
166
+ this.logger.log('CapitalOsAuthService: Invalidating token');
167
+ this._longLivedToken$.next(undefined);
168
+ this._baseUrl$.next(undefined);
169
+ this._error$.next(undefined);
170
+ this.refreshToken();
171
+ }
172
+ /**
173
+ * Refreshes the token by fetching a new one-time token and exchanging it.
174
+ */
175
+ refreshToken() {
176
+ return __awaiter(this, void 0, void 0, function* () {
177
+ if (this.isDestroyed) {
178
+ return;
179
+ }
180
+ // Prevent concurrent refresh calls - if already loading, skip
181
+ if (this._isLoading$.value) {
182
+ this.logger.log('CapitalOsAuthService: Token refresh already in progress, skipping');
183
+ return;
184
+ }
185
+ this.logger.log('CapitalOsAuthService: Starting token refresh');
186
+ this._isLoading$.next(true);
187
+ this._error$.next(undefined);
188
+ try {
189
+ // Get one-time token from platform
190
+ const oneTimeToken = yield this.config.getToken();
191
+ this.logger.log('CapitalOsAuthService: Received one-time token');
192
+ if (this.isDestroyed) {
193
+ return;
194
+ }
195
+ // Exchange for long-lived token
196
+ const result = yield this.tokenExchangeService.exchange(oneTimeToken, {
197
+ enableLogging: this.config.enableLogging,
198
+ });
199
+ if (this.isDestroyed) {
200
+ return;
201
+ }
202
+ this._longLivedToken$.next(result.longLivedToken);
203
+ this._baseUrl$.next(result.baseUrl);
204
+ this._error$.next(undefined);
205
+ this.logger.log('CapitalOsAuthService: Token exchange complete');
206
+ }
207
+ catch (rawError) {
208
+ if (!this.isDestroyed) {
209
+ const error = toError(rawError);
210
+ this.logger.error(`CapitalOsAuthService: Token refresh failed: ${error.message}`);
211
+ this._error$.next(error);
212
+ }
213
+ }
214
+ finally {
215
+ if (!this.isDestroyed) {
216
+ this._isLoading$.next(false);
217
+ }
218
+ }
219
+ });
220
+ }
221
+ }
222
+ CapitalOsAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
223
+ CapitalOsAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsAuthService });
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsAuthService, decorators: [{
225
+ type: Injectable
226
+ }], ctorParameters: function () { return []; } });
227
+
228
+ // TODO: Automate version injection at build time
229
+ const SDK_VERSION = '0.1.0-rc.1';
230
+ /**
231
+ * CardsApp component that renders the CapitalOS cards interface in an iframe.
232
+ *
233
+ * The component emits events for loading state - consumers should handle their own loading UI:
234
+ *
235
+ * ```html
236
+ * <div *ngIf="!cardsLoaded">
237
+ * <my-loading-spinner></my-loading-spinner>
238
+ * </div>
239
+ * <capitalos-cards-app
240
+ * (loaded)="cardsLoaded = true"
241
+ * (error)="onCardsError($event)"
242
+ * ></capitalos-cards-app>
243
+ * ```
244
+ */
245
+ class CardsAppComponent {
246
+ constructor() {
247
+ // Injected services
248
+ this.authService = inject(CapitalOsAuthService);
249
+ this.config = inject(CAPITALOS_CONFIG);
250
+ this.heightOffsetPx = 12;
251
+ // Outputs
252
+ this.loaded = new EventEmitter();
253
+ this.error = new EventEmitter();
254
+ }
255
+ ngAfterViewInit() {
256
+ // Subscribe to tokenData$ and initialize iframe when ready
257
+ this.tokenDataSubscription = this.authService.tokenData$.subscribe((tokenData) => {
258
+ if (tokenData && this.iframeContainer) {
259
+ this.initializeIframe(tokenData, this.iframeContainer.nativeElement);
260
+ }
261
+ });
262
+ }
263
+ ngOnDestroy() {
264
+ var _a, _b;
265
+ (_a = this.tokenDataSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
266
+ (_b = this.iframeManager) === null || _b === void 0 ? void 0 : _b.destroy();
267
+ }
268
+ initializeIframe(tokenData, container) {
269
+ var _a, _b, _c, _d;
270
+ // Destroy previous iframe if exists
271
+ (_a = this.iframeManager) === null || _a === void 0 ? void 0 : _a.destroy();
272
+ const resolvedEnableLogging = (_c = (_b = this.enableLogging) !== null && _b !== void 0 ? _b : this.config.enableLogging) !== null && _c !== void 0 ? _c : false;
273
+ const resolvedTheme = (_d = this.theme) !== null && _d !== void 0 ? _d : this.config.theme;
274
+ this.iframeManager = new IframeManager({
275
+ container,
276
+ tokenData,
277
+ renderingContext: { entryPoint: 'cardsApp' },
278
+ theme: resolvedTheme,
279
+ enableLogging: resolvedEnableLogging,
280
+ logger: this.config.logger,
281
+ sdkVersion: SDK_VERSION,
282
+ heightOffsetPx: this.heightOffsetPx,
283
+ callbacks: {
284
+ onLoad: () => {
285
+ this.loaded.emit();
286
+ },
287
+ onError: (rawError) => {
288
+ const capitalOsError = new CapitalOSError(rawError);
289
+ this.error.emit(capitalOsError);
290
+ },
291
+ onTokenExpired: () => {
292
+ this.authService.invalidateToken();
293
+ },
294
+ },
295
+ });
296
+ }
297
+ }
298
+ CardsAppComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CardsAppComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
299
+ CardsAppComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CardsAppComponent, isStandalone: true, selector: "capitalos-cards-app", inputs: { theme: "theme", heightOffsetPx: "heightOffsetPx", enableLogging: "enableLogging" }, outputs: { loaded: "loaded", error: "error" }, viewQueries: [{ propertyName: "iframeContainer", first: true, predicate: ["iframeContainer"], descendants: true }], ngImport: i0, template: `<div #iframeContainer class="capitalos-iframe-container"></div>`, isInline: true, styles: [":host{display:block;width:100%}.capitalos-iframe-container{width:100%}\n"] });
300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CardsAppComponent, decorators: [{
301
+ type: Component,
302
+ args: [{ selector: 'capitalos-cards-app', standalone: true, template: `<div #iframeContainer class="capitalos-iframe-container"></div>`, styles: [":host{display:block;width:100%}.capitalos-iframe-container{width:100%}\n"] }]
303
+ }], propDecorators: { theme: [{
304
+ type: Input
305
+ }], heightOffsetPx: [{
306
+ type: Input
307
+ }], enableLogging: [{
308
+ type: Input
309
+ }], loaded: [{
310
+ type: Output
311
+ }], error: [{
312
+ type: Output
313
+ }], iframeContainer: [{
314
+ type: ViewChild,
315
+ args: ['iframeContainer']
316
+ }] } });
317
+
318
+ /**
319
+ * NgModule for CapitalOS SDK.
320
+ *
321
+ * Use this module for NgModule-based Angular applications.
322
+ * For standalone applications, use provideCapitalOs() instead.
323
+ *
324
+ * Usage:
325
+ * ```typescript
326
+ * @NgModule({
327
+ * imports: [
328
+ * CapitalOsModule.forRoot({
329
+ * getToken: async () => {
330
+ * const response = await fetch('/api/capitalos/token');
331
+ * const data = await response.json();
332
+ * return data.token;
333
+ * },
334
+ * enableLogging: true,
335
+ * }),
336
+ * ],
337
+ * })
338
+ * export class AppModule {}
339
+ * ```
340
+ */
341
+ class CapitalOsModule {
342
+ static forRoot(config) {
343
+ return {
344
+ ngModule: CapitalOsModule,
345
+ providers: [{ provide: CAPITALOS_CONFIG, useValue: config }, TokenExchangeService, CapitalOsAuthService],
346
+ };
347
+ }
348
+ }
349
+ CapitalOsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
350
+ CapitalOsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsModule, imports: [CardsAppComponent], exports: [CardsAppComponent] });
351
+ CapitalOsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsModule, imports: [CardsAppComponent] });
352
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CapitalOsModule, decorators: [{
353
+ type: NgModule,
354
+ args: [{
355
+ imports: [CardsAppComponent],
356
+ exports: [CardsAppComponent],
357
+ }]
358
+ }] });
359
+
360
+ /*
361
+ * Public API Surface of @capitalos/angular
362
+ */
363
+
364
+ /**
365
+ * Generated bundle index. Do not edit.
366
+ */
367
+
368
+ export { CAPITALOS_CONFIG, CapitalOsAuthService, CapitalOsModule, CardsAppComponent, provideCapitalOs };
369
+ //# sourceMappingURL=capitalos-angular.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capitalos-angular.mjs","sources":["../../../projects/capitalos-angular/src/lib/provide-capitalos.ts","../../../projects/capitalos-angular/src/lib/token-exchange.service.ts","../../../projects/capitalos-angular/src/lib/capitalos-auth.service.ts","../../../projects/capitalos-angular/src/lib/cards-app.component.ts","../../../projects/capitalos-angular/src/lib/capitalos.module.ts","../../../projects/capitalos-angular/src/public-api.ts","../../../projects/capitalos-angular/src/capitalos-angular.ts"],"sourcesContent":["import { InjectionToken, Provider } from '@angular/core'\nimport { Logger, ThemeColorScheme } from '@capitalos/core'\nimport { CapitalOsAuthService } from './capitalos-auth.service'\nimport { TokenExchangeService } from './token-exchange.service'\n\n/**\n * Configuration for CapitalOS SDK\n */\nexport interface CapitalOsConfig {\n /**\n * Function that returns a promise resolving to a one-time token.\n * This is typically a call to your backend that initiates a CapitalOS login.\n */\n getToken: () => Promise<string>\n\n /**\n * Whether to enable logging for debugging purposes.\n */\n enableLogging?: boolean\n\n /**\n * Optional custom logger for capturing SDK logs.\n */\n logger?: Logger\n\n /**\n * Theme color scheme for the SDK components.\n */\n theme?: ThemeColorScheme\n}\n\n/**\n * Injection token for CapitalOS configuration\n */\nexport const CAPITALOS_CONFIG = new InjectionToken<CapitalOsConfig>('CAPITALOS_CONFIG')\n\n/**\n * Provides the CapitalOS SDK with the specified configuration.\n *\n * Usage in app.config.ts (standalone):\n * ```typescript\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideCapitalOs({\n * getToken: async () => {\n * const response = await fetch('/api/capitalos/token');\n * const data = await response.json();\n * return data.token;\n * },\n * enableLogging: true,\n * }),\n * ],\n * });\n * ```\n *\n * For NgModule-based apps, use CapitalOsModule.forRoot() instead.\n */\nexport function provideCapitalOs(config: CapitalOsConfig): Provider[] {\n return [\n {\n provide: CAPITALOS_CONFIG,\n useValue: config,\n },\n TokenExchangeService,\n CapitalOsAuthService,\n ]\n}\n","import { Injectable, inject, OnDestroy } from '@angular/core'\nimport { exchangeOneTimeToken } from '@capitalos/core'\nimport { CAPITALOS_CONFIG } from './provide-capitalos'\n\nconst TOKEN_EXCHANGE_TIMEOUT_MS = 10_000\n\nexport interface TokenExchangeResult {\n longLivedToken: string\n baseUrl: string\n}\n\n/**\n * Service responsible for exchanging one-time tokens for long-lived JWTs.\n * Creates a hidden iframe to perform the token exchange securely.\n */\n@Injectable()\nexport class TokenExchangeService implements OnDestroy {\n private readonly config = inject(CAPITALOS_CONFIG)\n private isDestroyed = false\n private activeAbortController: AbortController | null = null\n\n ngOnDestroy(): void {\n this.isDestroyed = true\n this.activeAbortController?.abort()\n this.activeAbortController = null\n }\n\n /**\n * Exchanges a one-time token for a long-lived JWT.\n * Delegates to @capitalos/core (browser-only) which handles iframe + Penpal lifecycle.\n */\n async exchange(oneTimeToken: string, options: { enableLogging?: boolean } = {}): Promise<TokenExchangeResult> {\n if (this.isDestroyed) {\n throw new Error('TokenExchangeService was destroyed')\n }\n\n // Abort any in-flight exchange when a new one begins.\n this.activeAbortController?.abort()\n\n const abortController = new AbortController()\n this.activeAbortController = abortController\n\n try {\n return await exchangeOneTimeToken({\n oneTimeToken,\n enableLogging: options.enableLogging,\n logger: this.config.logger,\n timeoutMs: TOKEN_EXCHANGE_TIMEOUT_MS,\n signal: abortController.signal,\n })\n } finally {\n if (this.activeAbortController === abortController) {\n this.activeAbortController = null\n }\n }\n }\n}\n","import { Injectable, inject, OnDestroy } from '@angular/core'\nimport { BehaviorSubject, Observable, combineLatest, map } from 'rxjs'\nimport { TokenData, TokenType, TokenParamKey, TokenParamLocation, createLogger } from '@capitalos/core'\nimport { TokenExchangeService } from './token-exchange.service'\nimport { CAPITALOS_CONFIG } from './provide-capitalos'\n\n/**\n * Converts an unknown error to an Error object\n */\nfunction toError(error: unknown): Error {\n if (error instanceof Error) {\n return error\n }\n return new Error(String(error))\n}\n\n/**\n * Authentication state enum\n */\nexport type AuthState = 'idle' | 'loading' | 'authenticated' | 'error'\n\n/**\n * Service that manages CapitalOS authentication state.\n * This is the Angular equivalent of React's CapitalOsAuthenticationProvider.\n *\n * It handles:\n * - Fetching one-time tokens via the provided getToken callback\n * - Exchanging one-time tokens for long-lived JWTs\n * - Managing token state via observables\n * - Auto-refreshing tokens when they expire\n */\n@Injectable()\nexport class CapitalOsAuthService implements OnDestroy {\n private readonly config = inject(CAPITALOS_CONFIG)\n private readonly tokenExchangeService = inject(TokenExchangeService)\n\n // Private BehaviorSubjects for internal state\n private readonly _longLivedToken$ = new BehaviorSubject<string | undefined>(undefined)\n private readonly _baseUrl$ = new BehaviorSubject<string | undefined>(undefined)\n private readonly _isLoading$ = new BehaviorSubject(false)\n private readonly _error$ = new BehaviorSubject<Error | undefined>(undefined)\n\n // Public observable for token data\n readonly tokenData$: Observable<TokenData | undefined> = combineLatest([this._longLivedToken$, this._baseUrl$]).pipe(\n map(([token, baseUrl]) => {\n if (!token || !baseUrl) {\n return undefined\n }\n\n return {\n token,\n tokenType: TokenType.longLived,\n baseUrl,\n paramKey: TokenParamKey.accessToken,\n paramLocation: TokenParamLocation.hash,\n }\n })\n )\n\n // Public observables for UI state\n readonly isLoading$: Observable<boolean> = this._isLoading$.asObservable()\n readonly error$: Observable<Error | undefined> = this._error$.asObservable()\n readonly authState$: Observable<AuthState> = combineLatest([this._isLoading$, this._error$, this.tokenData$]).pipe(\n map(([isLoading, error, tokenData]) => {\n if (isLoading) return 'loading'\n if (error) return 'error'\n if (tokenData) return 'authenticated'\n return 'idle'\n })\n )\n\n private isDestroyed = false\n private logger: ReturnType<typeof createLogger>\n\n constructor() {\n this.logger = createLogger(this.config.enableLogging, this.config.logger)\n\n // Start authentication flow eagerly on construction.\n // This is intentional: auth begins as soon as the app boots so the token\n // is ready when CardsAppComponent renders, reducing perceived load time.\n this.refreshToken()\n }\n\n ngOnDestroy(): void {\n this.isDestroyed = true\n }\n\n /**\n * Invalidates the current token, triggering a refresh.\n * Called when the iframe signals that the token has expired.\n */\n invalidateToken(): void {\n this.logger.log('CapitalOsAuthService: Invalidating token')\n this._longLivedToken$.next(undefined)\n this._baseUrl$.next(undefined)\n this._error$.next(undefined)\n this.refreshToken()\n }\n\n /**\n * Refreshes the token by fetching a new one-time token and exchanging it.\n */\n async refreshToken(): Promise<void> {\n if (this.isDestroyed) {\n return\n }\n\n // Prevent concurrent refresh calls - if already loading, skip\n if (this._isLoading$.value) {\n this.logger.log('CapitalOsAuthService: Token refresh already in progress, skipping')\n return\n }\n\n this.logger.log('CapitalOsAuthService: Starting token refresh')\n this._isLoading$.next(true)\n this._error$.next(undefined)\n\n try {\n // Get one-time token from platform\n const oneTimeToken = await this.config.getToken()\n this.logger.log('CapitalOsAuthService: Received one-time token')\n\n if (this.isDestroyed) {\n return\n }\n\n // Exchange for long-lived token\n const result = await this.tokenExchangeService.exchange(oneTimeToken, {\n enableLogging: this.config.enableLogging,\n })\n\n if (this.isDestroyed) {\n return\n }\n\n this._longLivedToken$.next(result.longLivedToken)\n this._baseUrl$.next(result.baseUrl)\n this._error$.next(undefined)\n this.logger.log('CapitalOsAuthService: Token exchange complete')\n } catch (rawError) {\n if (!this.isDestroyed) {\n const error = toError(rawError)\n this.logger.error(`CapitalOsAuthService: Token refresh failed: ${error.message}`)\n this._error$.next(error)\n }\n } finally {\n if (!this.isDestroyed) {\n this._isLoading$.next(false)\n }\n }\n }\n}\n","import {\n Component,\n inject,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ElementRef,\n AfterViewInit,\n OnDestroy,\n} from '@angular/core'\nimport { Subscription } from 'rxjs'\nimport { IframeManager, CapitalOSError, TokenData, RawErrorDetails, ThemeColorScheme } from '@capitalos/core'\nimport { CapitalOsAuthService } from './capitalos-auth.service'\nimport { CAPITALOS_CONFIG } from './provide-capitalos'\n\n// TODO: Automate version injection at build time\nconst SDK_VERSION = '0.1.0-rc.1'\n\n/**\n * CardsApp component that renders the CapitalOS cards interface in an iframe.\n *\n * The component emits events for loading state - consumers should handle their own loading UI:\n *\n * ```html\n * <div *ngIf=\"!cardsLoaded\">\n * <my-loading-spinner></my-loading-spinner>\n * </div>\n * <capitalos-cards-app\n * (loaded)=\"cardsLoaded = true\"\n * (error)=\"onCardsError($event)\"\n * ></capitalos-cards-app>\n * ```\n */\n@Component({\n selector: 'capitalos-cards-app',\n standalone: true,\n template: `<div #iframeContainer class=\"capitalos-iframe-container\"></div>`,\n styles: [\n `\n :host {\n display: block;\n width: 100%;\n }\n\n .capitalos-iframe-container {\n width: 100%;\n }\n `,\n ],\n})\nexport class CardsAppComponent implements AfterViewInit, OnDestroy {\n // Injected services\n private readonly authService = inject(CapitalOsAuthService)\n private readonly config = inject(CAPITALOS_CONFIG)\n\n // Inputs\n @Input() theme?: ThemeColorScheme\n @Input() heightOffsetPx = 12\n @Input() enableLogging?: boolean\n\n // Outputs\n @Output() loaded = new EventEmitter<void>()\n @Output() error = new EventEmitter<CapitalOSError>()\n\n // View children\n @ViewChild('iframeContainer') iframeContainer?: ElementRef<HTMLDivElement>\n\n // Internal state\n private iframeManager?: IframeManager\n private tokenDataSubscription?: Subscription\n\n ngAfterViewInit(): void {\n // Subscribe to tokenData$ and initialize iframe when ready\n this.tokenDataSubscription = this.authService.tokenData$.subscribe((tokenData) => {\n if (tokenData && this.iframeContainer) {\n this.initializeIframe(tokenData, this.iframeContainer.nativeElement)\n }\n })\n }\n\n ngOnDestroy(): void {\n this.tokenDataSubscription?.unsubscribe()\n this.iframeManager?.destroy()\n }\n\n private initializeIframe(tokenData: TokenData, container: HTMLElement): void {\n // Destroy previous iframe if exists\n this.iframeManager?.destroy()\n\n const resolvedEnableLogging = this.enableLogging ?? this.config.enableLogging ?? false\n const resolvedTheme = this.theme ?? this.config.theme\n\n this.iframeManager = new IframeManager({\n container,\n tokenData,\n renderingContext: { entryPoint: 'cardsApp' },\n theme: resolvedTheme,\n enableLogging: resolvedEnableLogging,\n logger: this.config.logger,\n sdkVersion: SDK_VERSION,\n heightOffsetPx: this.heightOffsetPx,\n callbacks: {\n onLoad: () => {\n this.loaded.emit()\n },\n onError: (rawError: RawErrorDetails) => {\n const capitalOsError = new CapitalOSError(rawError)\n this.error.emit(capitalOsError)\n },\n onTokenExpired: () => {\n this.authService.invalidateToken()\n },\n },\n })\n }\n}\n","import { ModuleWithProviders, NgModule } from '@angular/core'\nimport { CardsAppComponent } from './cards-app.component'\nimport { CapitalOsConfig, CAPITALOS_CONFIG } from './provide-capitalos'\nimport { CapitalOsAuthService } from './capitalos-auth.service'\nimport { TokenExchangeService } from './token-exchange.service'\n\n/**\n * NgModule for CapitalOS SDK.\n *\n * Use this module for NgModule-based Angular applications.\n * For standalone applications, use provideCapitalOs() instead.\n *\n * Usage:\n * ```typescript\n * @NgModule({\n * imports: [\n * CapitalOsModule.forRoot({\n * getToken: async () => {\n * const response = await fetch('/api/capitalos/token');\n * const data = await response.json();\n * return data.token;\n * },\n * enableLogging: true,\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n@NgModule({\n imports: [CardsAppComponent],\n exports: [CardsAppComponent],\n})\nexport class CapitalOsModule {\n static forRoot(config: CapitalOsConfig): ModuleWithProviders<CapitalOsModule> {\n return {\n ngModule: CapitalOsModule,\n providers: [{ provide: CAPITALOS_CONFIG, useValue: config }, TokenExchangeService, CapitalOsAuthService],\n }\n }\n}\n","/*\n * Public API Surface of @capitalos/angular\n */\n\n// Components\nexport { CardsAppComponent } from './lib/cards-app.component'\n\n// Services\nexport { CapitalOsAuthService } from './lib/capitalos-auth.service'\nexport type { AuthState } from './lib/capitalos-auth.service'\n\n// Provider (standalone)\nexport { provideCapitalOs, CAPITALOS_CONFIG } from './lib/provide-capitalos'\nexport type { CapitalOsConfig } from './lib/provide-capitalos'\n\n// Module (NgModule-based apps)\nexport { CapitalOsModule } from './lib/capitalos.module'\n\n// Re-export commonly used types from core\nexport type { ThemeColorScheme, Logger, TokenData, RawErrorDetails } from '@capitalos/core'\n\nexport { CapitalOSError, ErrorCode } from '@capitalos/core'\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}