@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.
- package/README.md +119 -0
- package/esm2020/capitalos-angular.mjs +5 -0
- package/esm2020/lib/capitalos-auth.service.mjs +134 -0
- package/esm2020/lib/capitalos.module.mjs +48 -0
- package/esm2020/lib/cards-app.component.mjs +93 -0
- package/esm2020/lib/provide-capitalos.mjs +39 -0
- package/esm2020/lib/token-exchange.service.mjs +54 -0
- package/esm2020/public-api.mjs +13 -0
- package/fesm2015/capitalos-angular.mjs +369 -0
- package/fesm2015/capitalos-angular.mjs.map +1 -0
- package/fesm2020/capitalos-angular.mjs +360 -0
- package/fesm2020/capitalos-angular.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/capitalos-auth.service.d.ts +45 -0
- package/lib/capitalos.module.d.ts +33 -0
- package/lib/cards-app.component.d.ts +35 -0
- package/lib/provide-capitalos.d.ts +50 -0
- package/lib/token-exchange.service.d.ts +25 -0
- package/package.json +40 -0
- package/public-api.d.ts +8 -0
|
@@ -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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"}
|