@securitydept/session-context-client 0.3.0-beta.5 → 0.3.0-beta.7
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/dist/index.d.mts +42 -24
- package/dist/index.mjs +47 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,19 +1,5 @@
|
|
|
1
|
-
import { CancellationTokenOptions,
|
|
2
|
-
import * as _$arktype from "arktype";
|
|
3
|
-
import * as _$arktype_internal_variants_object_ts0 from "arktype/internal/variants/object.ts";
|
|
4
|
-
|
|
1
|
+
import { CancellationTokenOptions, ClientError, DisposableTrait, EventStreamTrait, FoundationEnvironment, IdentityPrincipal, OperationSpanTrait, ReadableSignalTrait, ResourceSnapshot, ResourceTrait, SYMBOL_DISPOSE, SecuritydeptInjectorTrait, SecuritydeptProvider, SpanTrait } from "@securitydept/client";
|
|
5
2
|
//#region src/types.d.ts
|
|
6
|
-
declare const SessionContextErrorCode: {
|
|
7
|
-
readonly OperationFailed: "session.operation_failed";
|
|
8
|
-
readonly ClientDisposed: "session.client_disposed";
|
|
9
|
-
readonly RouterUnavailable: "session.router_unavailable";
|
|
10
|
-
readonly InvalidSessionPayload: "session.invalid_user_info_payload";
|
|
11
|
-
};
|
|
12
|
-
type SessionContextErrorCode = (typeof SessionContextErrorCode)[keyof typeof SessionContextErrorCode];
|
|
13
|
-
declare const SessionContextSource: {
|
|
14
|
-
readonly SessionContext: "session-context";
|
|
15
|
-
};
|
|
16
|
-
type SessionContextSource = (typeof SessionContextSource)[keyof typeof SessionContextSource];
|
|
17
3
|
/** Session principal — shared authenticated principal semantics via @securitydept/client. */
|
|
18
4
|
type SessionPrincipal = IdentityPrincipal;
|
|
19
5
|
/** Session info returned from the server. */
|
|
@@ -61,15 +47,34 @@ declare const SessionContextEventType: {
|
|
|
61
47
|
readonly SessionLogoutFailed: "session.logout.failed";
|
|
62
48
|
};
|
|
63
49
|
type SessionContextEventType = (typeof SessionContextEventType)[keyof typeof SessionContextEventType];
|
|
64
|
-
interface
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
id: string;
|
|
50
|
+
interface SessionContextEventBase {
|
|
51
|
+
readonly at: number;
|
|
52
|
+
readonly client: {
|
|
53
|
+
readonly id: string;
|
|
69
54
|
};
|
|
70
|
-
session?: SessionInfo | null;
|
|
71
|
-
errorSummary?: ErrorSummary;
|
|
72
55
|
}
|
|
56
|
+
type SessionContextEventData = {
|
|
57
|
+
readonly type: typeof SessionContextEventType.SessionRefreshStarted;
|
|
58
|
+
readonly session: SessionInfo | null;
|
|
59
|
+
} | {
|
|
60
|
+
readonly type: typeof SessionContextEventType.SessionRefreshSucceeded;
|
|
61
|
+
readonly session: SessionInfo | null;
|
|
62
|
+
} | {
|
|
63
|
+
readonly type: typeof SessionContextEventType.SessionRefreshFailed;
|
|
64
|
+
readonly session: SessionInfo | null;
|
|
65
|
+
readonly error: ClientError;
|
|
66
|
+
} | {
|
|
67
|
+
readonly type: typeof SessionContextEventType.SessionLogoutStarted;
|
|
68
|
+
readonly session: SessionInfo | null;
|
|
69
|
+
} | {
|
|
70
|
+
readonly type: typeof SessionContextEventType.SessionLogoutSucceeded;
|
|
71
|
+
readonly session: null;
|
|
72
|
+
} | {
|
|
73
|
+
readonly type: typeof SessionContextEventType.SessionLogoutFailed;
|
|
74
|
+
readonly session: SessionInfo | null;
|
|
75
|
+
readonly error: ClientError;
|
|
76
|
+
};
|
|
77
|
+
type SessionContextEvent = SessionContextEventBase & SessionContextEventData;
|
|
73
78
|
//#endregion
|
|
74
79
|
//#region src/client.d.ts
|
|
75
80
|
interface SessionContextOperationSignals {
|
|
@@ -148,11 +153,24 @@ declare class SessionContextClient implements DisposableTrait {
|
|
|
148
153
|
declare function parseSessionInfoPayload(body: unknown): SessionInfo;
|
|
149
154
|
//#endregion
|
|
150
155
|
//#region src/contracts/schemas.d.ts
|
|
151
|
-
declare const SessionInfoSchema:
|
|
156
|
+
declare const SessionInfoSchema: import("arktype/internal/variants/object.ts").ObjectType<(In: {
|
|
152
157
|
[x: string]: any;
|
|
153
|
-
}) =>
|
|
158
|
+
}) => import("arktype").Out<SessionInfo>, {}>;
|
|
154
159
|
declare const SessionUserInfoResponseSchema: any;
|
|
155
160
|
//#endregion
|
|
161
|
+
//#region src/error.d.ts
|
|
162
|
+
declare const SessionContextErrorCode: {
|
|
163
|
+
readonly OperationFailed: "session.operation_failed";
|
|
164
|
+
readonly ClientDisposed: "session.client_disposed";
|
|
165
|
+
readonly RouterUnavailable: "session.router_unavailable";
|
|
166
|
+
readonly InvalidSessionPayload: "session.invalid_user_info_payload";
|
|
167
|
+
};
|
|
168
|
+
type SessionContextErrorCode = (typeof SessionContextErrorCode)[keyof typeof SessionContextErrorCode];
|
|
169
|
+
declare const SessionContextSource: {
|
|
170
|
+
readonly SessionContext: "session-context";
|
|
171
|
+
};
|
|
172
|
+
type SessionContextSource = (typeof SessionContextSource)[keyof typeof SessionContextSource];
|
|
173
|
+
//#endregion
|
|
156
174
|
//#region src/providers.d.ts
|
|
157
175
|
interface ProvideSessionContextOptions {
|
|
158
176
|
readonly config: SessionContextClientConfig;
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ClientError, ClientErrorKind, ENVIRONMENT_TOKEN, INJECTOR_TOKEN, IdentityPrincipalSchema, IdentityPrincipalWireSchema, ResourceSnapshotUpdateKind, ResourceStatus, RouterNavigationIntent, RouterNavigationMode, SYMBOL_DISPOSE, SecuritydeptDestroyRef, SecuritydeptInjectionToken, UriReferenceString, createCancellationTokenSource, createLinkedCancellationToken, createOnceAsyncLockCallable, createSignal, defineInstrumentMethodDecorator,
|
|
2
|
-
import {
|
|
1
|
+
import { ClientError, ClientErrorKind, ENVIRONMENT_TOKEN, INJECTOR_TOKEN, IdentityPrincipalSchema, IdentityPrincipalWireSchema, ResourceSnapshotUpdateKind, ResourceStatus, RouterNavigationIntent, RouterNavigationMode, SYMBOL_DISPOSE, SecuritydeptDestroyRef, SecuritydeptInjectionToken, SpanSharedAttributeName, UriReferenceString, createCancellationTokenSource, createLinkedCancellationToken, createOnceAsyncLockCallable, createSignal, defineInstrumentMethodDecorator, formatValidationFailure, injectDisposableStackFrom, mapResource, readonlySignal, reduceResourceSnapshot, resourceFromSnapshots, validateWithSchemaSync, withDisposableStack } from "@securitydept/client";
|
|
2
|
+
import { RxEventSubject, RxStateSignal, commandResponseData, concatCommand, dispatchCommandLocallyToStream } from "@securitydept/client/rx";
|
|
3
3
|
import { filter, from, lastValueFrom, take, takeUntil } from "rxjs";
|
|
4
4
|
import { v7 } from "uuid";
|
|
5
5
|
import { type } from "arktype";
|
|
6
|
-
//#region src/
|
|
6
|
+
//#region src/error.ts
|
|
7
7
|
const SessionContextErrorCode = {
|
|
8
8
|
OperationFailed: "session.operation_failed",
|
|
9
9
|
ClientDisposed: "session.client_disposed",
|
|
@@ -11,14 +11,14 @@ const SessionContextErrorCode = {
|
|
|
11
11
|
InvalidSessionPayload: "session.invalid_user_info_payload"
|
|
12
12
|
};
|
|
13
13
|
const SessionContextSource = { SessionContext: "session-context" };
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
14
|
+
function clientErrorFromSessionError(error, options) {
|
|
15
|
+
return ClientError.fromUnknown(error, {
|
|
16
|
+
code: SessionContextErrorCode.OperationFailed,
|
|
17
|
+
message: "The session operation failed unexpectedly",
|
|
18
|
+
source: SessionContextSource.SessionContext,
|
|
19
|
+
span: options.span
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region src/contracts/schemas.ts
|
|
24
24
|
const SessionInfoSchema = type({
|
|
@@ -56,6 +56,16 @@ function parseSessionInfoPayload(body) {
|
|
|
56
56
|
const SESSION_CONTEXT_CLIENT = new SecuritydeptInjectionToken("SESSION_CONTEXT_CLIENT");
|
|
57
57
|
const SESSION_CONTEXT_CLIENT_CONFIG = new SecuritydeptInjectionToken("SESSION_CONTEXT_CLIENT_CONFIG");
|
|
58
58
|
//#endregion
|
|
59
|
+
//#region src/types.ts
|
|
60
|
+
const SessionContextEventType = {
|
|
61
|
+
SessionRefreshStarted: "session.refresh.started",
|
|
62
|
+
SessionRefreshSucceeded: "session.refresh.succeeded",
|
|
63
|
+
SessionRefreshFailed: "session.refresh.failed",
|
|
64
|
+
SessionLogoutStarted: "session.logout.started",
|
|
65
|
+
SessionLogoutSucceeded: "session.logout.succeeded",
|
|
66
|
+
SessionLogoutFailed: "session.logout.failed"
|
|
67
|
+
};
|
|
68
|
+
//#endregion
|
|
59
69
|
//#region src/client.ts
|
|
60
70
|
function toPrimitive(input, hint) {
|
|
61
71
|
if (typeof input !== "object" || input === null) return input;
|
|
@@ -266,7 +276,14 @@ function _apply_decs_2311(targetClass, classDecs, memberDecs, classDecsHaveThis,
|
|
|
266
276
|
}
|
|
267
277
|
};
|
|
268
278
|
}
|
|
269
|
-
let _dec
|
|
279
|
+
let _dec;
|
|
280
|
+
let _dec1;
|
|
281
|
+
let _dec2;
|
|
282
|
+
let _dec3;
|
|
283
|
+
let _dec4;
|
|
284
|
+
let _dec5;
|
|
285
|
+
let _dec6;
|
|
286
|
+
let _initProto;
|
|
270
287
|
const POST_AUTH_REDIRECT_PARAM = "post_auth_redirect_uri";
|
|
271
288
|
const instrumentSessionMethod = defineInstrumentMethodDecorator(({ factoryArgs: [operation] }) => function() {
|
|
272
289
|
return {
|
|
@@ -274,12 +291,8 @@ const instrumentSessionMethod = defineInstrumentMethodDecorator(({ factoryArgs:
|
|
|
274
291
|
span: this.span,
|
|
275
292
|
name: `${this.config.tracing.prefix}.${operation}`,
|
|
276
293
|
target: this.config.tracing.target,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
code: SessionContextErrorCode.OperationFailed,
|
|
280
|
-
message: "The session operation failed unexpectedly",
|
|
281
|
-
source: SessionContextSource.SessionContext
|
|
282
|
-
})
|
|
294
|
+
traceAttributes: { operation },
|
|
295
|
+
clientErrorFromUnknown: (error, options) => clientErrorFromSessionError(error, options)
|
|
283
296
|
};
|
|
284
297
|
});
|
|
285
298
|
_dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _dec2 = instrumentSessionMethod("refresh"), _dec3 = withDisposableStack(0, true), _dec4 = instrumentSessionMethod("logout"), _dec5 = withDisposableStack(0, true), _dec6 = instrumentSessionMethod("login.redirect");
|
|
@@ -351,7 +364,7 @@ _dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _
|
|
|
351
364
|
logoutPending: createSignal(false),
|
|
352
365
|
loginRedirectPending: createSignal(false)
|
|
353
366
|
};
|
|
354
|
-
_eventSubject = new
|
|
367
|
+
_eventSubject = new RxEventSubject();
|
|
355
368
|
_refreshCommandSubject = new RxEventSubject();
|
|
356
369
|
_refreshResponseSubject = new RxEventSubject();
|
|
357
370
|
_logoutCommandSubject = new RxEventSubject();
|
|
@@ -407,8 +420,8 @@ _dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _
|
|
|
407
420
|
};
|
|
408
421
|
this.id = this._config.id;
|
|
409
422
|
this._span = environment.span.fork({ attributes: {
|
|
410
|
-
|
|
411
|
-
|
|
423
|
+
[SpanSharedAttributeName.ClientName]: this.constructor.name,
|
|
424
|
+
[SpanSharedAttributeName.ClientId]: this.id
|
|
412
425
|
} });
|
|
413
426
|
this.sessionSnapshot = readonlySignal(this._sessionSnapshotSignal);
|
|
414
427
|
this.sessionResource = resourceFromSnapshots(() => this._sessionSnapshotSignal.get());
|
|
@@ -487,6 +500,7 @@ _dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _
|
|
|
487
500
|
}
|
|
488
501
|
dispose() {
|
|
489
502
|
this._destroyed.set(true);
|
|
503
|
+
this._eventSubject.complete();
|
|
490
504
|
}
|
|
491
505
|
[SYMBOL_DISPOSE]() {
|
|
492
506
|
this.dispose();
|
|
@@ -536,23 +550,24 @@ _dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _
|
|
|
536
550
|
kind: ResourceSnapshotUpdateKind.Resolve,
|
|
537
551
|
value: sessionInfo
|
|
538
552
|
}));
|
|
539
|
-
operationSpan?.
|
|
553
|
+
operationSpan?.setTraceAttributes({ authenticated: sessionInfo !== null });
|
|
540
554
|
this._emitSessionEvent({
|
|
541
555
|
type: SessionContextEventType.SessionRefreshSucceeded,
|
|
542
556
|
session: sessionInfo
|
|
543
557
|
});
|
|
544
558
|
return sessionInfo;
|
|
545
559
|
} catch (error) {
|
|
560
|
+
const clientError = clientErrorFromSessionError(error, { span: operationSpan?.span });
|
|
546
561
|
this._sessionSnapshotSignal.set(reduceResourceSnapshot(loadingSnapshot, {
|
|
547
562
|
kind: ResourceSnapshotUpdateKind.Fail,
|
|
548
|
-
error
|
|
563
|
+
error: clientError
|
|
549
564
|
}));
|
|
550
565
|
this._emitSessionEvent({
|
|
551
566
|
type: SessionContextEventType.SessionRefreshFailed,
|
|
552
567
|
session: previousValue,
|
|
553
|
-
|
|
568
|
+
error: clientError
|
|
554
569
|
});
|
|
555
|
-
throw
|
|
570
|
+
throw clientError;
|
|
556
571
|
} finally {
|
|
557
572
|
this._operationSignals.refreshPending.set(false);
|
|
558
573
|
}
|
|
@@ -560,7 +575,8 @@ _dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _
|
|
|
560
575
|
async _executeLogout(cancellationToken, operationSpan) {
|
|
561
576
|
cancellationToken.throwIfCancellationRequested();
|
|
562
577
|
this._operationSignals.logoutPending.set(true);
|
|
563
|
-
const
|
|
578
|
+
const previous = this._sessionSnapshotSignal.get();
|
|
579
|
+
const loadingSnapshot = reduceResourceSnapshot(previous, { kind: ResourceSnapshotUpdateKind.Load });
|
|
564
580
|
this._sessionSnapshotSignal.set(loadingSnapshot);
|
|
565
581
|
this._emitSessionEvent({
|
|
566
582
|
type: SessionContextEventType.SessionLogoutStarted,
|
|
@@ -583,22 +599,23 @@ _dec = instrumentSessionMethod("start"), _dec1 = withDisposableStack(0, true), _
|
|
|
583
599
|
kind: ResourceSnapshotUpdateKind.Resolve,
|
|
584
600
|
value: null
|
|
585
601
|
}));
|
|
586
|
-
operationSpan?.
|
|
602
|
+
operationSpan?.setTraceAttributes({ authenticated: false });
|
|
587
603
|
this._emitSessionEvent({
|
|
588
604
|
type: SessionContextEventType.SessionLogoutSucceeded,
|
|
589
605
|
session: null
|
|
590
606
|
});
|
|
591
607
|
} catch (error) {
|
|
608
|
+
const clientError = clientErrorFromSessionError(error, { span: operationSpan?.span });
|
|
592
609
|
this._sessionSnapshotSignal.set(reduceResourceSnapshot(loadingSnapshot, {
|
|
593
610
|
kind: ResourceSnapshotUpdateKind.Fail,
|
|
594
|
-
error
|
|
611
|
+
error: clientError
|
|
595
612
|
}));
|
|
596
613
|
this._emitSessionEvent({
|
|
597
614
|
type: SessionContextEventType.SessionLogoutFailed,
|
|
598
615
|
session: this._readCurrentSession(),
|
|
599
|
-
|
|
616
|
+
error: clientError
|
|
600
617
|
});
|
|
601
|
-
throw
|
|
618
|
+
throw clientError;
|
|
602
619
|
} finally {
|
|
603
620
|
this._operationSignals.logoutPending.set(false);
|
|
604
621
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["SessionContextErrorCode","OperationFailed","ClientDisposed","RouterUnavailable","InvalidSessionPayload","SessionContextSource","SessionContext","SessionContextEventType","SessionRefreshStarted","SessionRefreshSucceeded","SessionRefreshFailed","SessionLogoutStarted","SessionLogoutSucceeded","SessionLogoutFailed","IdentityPrincipalSchema","IdentityPrincipalWireSchema","type","defineType","SessionInfoSchema","principal","pipe","input","attributes","extra","SessionUserInfoResponseSchema","ClientError","ClientErrorKind","formatValidationFailure","validateWithSchemaSync","SessionContextErrorCode","SessionContextSource","SessionInfoSchema","SessionUserInfoResponseSchema","parseSessionInfoPayload","body","infoResult","success","value","userInfoResult","failure","issues","issueSummary","kind","Protocol","code","InvalidSessionPayload","message","source","SessionContext","cause","SecuritydeptInjectionToken","SESSION_CONTEXT_CLIENT","SESSION_CONTEXT_CLIENT_CONFIG","ClientError","ClientErrorKind","createCancellationTokenSource","createLinkedCancellationToken","createOnceAsyncLockCallable","createSignal","defineInstrumentMethodDecorator","describeError","ENVIRONMENT_TOKEN","injectDisposableStackFrom","mapResource","ResourceSnapshotUpdateKind","ResourceStatus","RouterNavigationIntent","RouterNavigationMode","readonlySignal","reduceResourceSnapshot","resourceFromSnapshots","SecuritydeptDestroyRef","SYMBOL_DISPOSE","UriReferenceString","withDisposableStack","commandResponseData","concatCommand","dispatchCommandLocallyToStream","RxEventReplaySubject","RxEventSubject","RxStateSignal","filter","from","lastValueFrom","take","takeUntil","v7","uuidv7","parseSessionInfoPayload","SESSION_CONTEXT_CLIENT_CONFIG","SessionContextErrorCode","SessionContextEventType","SessionContextSource","POST_AUTH_REDIRECT_PARAM","instrumentSessionMethod","factoryArgs","operation","environment","span","name","config","tracing","prefix","target","fields","normalizeError","error","fromUnknown","code","OperationFailed","message","source","SessionContext","SessionContextClient","start","refresh","_refresh","logout","_logout","loginWithRedirect","_loginWithRedirect","defaultOptions","loginPath","logoutPath","userInfoPath","_environment","_config","_span","_rootCancellation","_destroyed","fromInitialValue","destroyed$","pipe","value","_sessionSnapshotSignal","status","Idle","_operationSignals","startPending","refreshPending","logoutPending","loginRedirectPending","_eventSubject","_refreshCommandSubject","_refreshResponseSubject","_logoutCommandSubject","_logoutResponseSubject","_startOnce","cancellationToken","operationSpan","throwIfCancellationRequested","set","_dispatchRefresh","id","sessionSnapshot","sessionResource","isAuthenticated","sessionOperations","events","fromEnvironmentConfig","options","fromInjector","injector","client","get","onDestroy","dispose","baseUrl","replace","fork","attributes","clientName","sessionInfo","subscribe","cancel","kind","Cancelled","ClientDisposed","command","_executeRefresh","_executeLogout","autoStart","catch","token","disposableStack","use","_dispatchLogout","_operationSpan","router","Configuration","RouterUnavailable","navigate","url","parse","_createLoginRedirectUrl","postAuthRedirectUri","intent","AuthRedirect","mode","External","payload","undefined","requestStream","responseStream","createCommandExtra","previous","previousValue","Reloading","Resolved","Error","loadingSnapshot","Load","_emitSessionEvent","type","SessionRefreshStarted","session","_fetchSessionInfo","Resolve","setAttributes","authenticated","SessionRefreshSucceeded","Fail","SessionRefreshFailed","errorSummary","SessionLogoutStarted","_readCurrentSession","response","transport","execute","_createLogoutUrl","method","headers","body","JSON","stringify","fromHttpResponse","SessionLogoutSucceeded","SessionLogoutFailed","base","params","URLSearchParams","toString","snapshot","input","next","at","time","now","INJECTOR_TOKEN","SessionContextClient","SESSION_CONTEXT_CLIENT","SESSION_CONTEXT_CLIENT_CONFIG","provideSessionContext","options","provide","useValue","config","useFactory","injector","fromInjector","deps"],"sources":["../src/types.ts","../src/contracts/schemas.ts","../src/contracts/parsers.ts","../src/tokens.ts","../src/client.ts","../src/providers.ts"],"sourcesContent":["import {\n\ttype CancellationTokenOptions,\n\ttype ErrorSummary,\n\ttype IdentityPrincipal,\n} from \"@securitydept/client\";\n\n// --- Session Context Client types ---\n\nexport const SessionContextErrorCode = {\n\tOperationFailed: \"session.operation_failed\",\n\tClientDisposed: \"session.client_disposed\",\n\tRouterUnavailable: \"session.router_unavailable\",\n\tInvalidSessionPayload: \"session.invalid_user_info_payload\",\n} as const;\n\nexport type SessionContextErrorCode =\n\t(typeof SessionContextErrorCode)[keyof typeof SessionContextErrorCode];\n\nexport const SessionContextSource = {\n\tSessionContext: \"session-context\",\n} as const;\n\nexport type SessionContextSource =\n\t(typeof SessionContextSource)[keyof typeof SessionContextSource];\n\n/** Session principal — shared authenticated principal semantics via @securitydept/client. */\nexport type SessionPrincipal = IdentityPrincipal;\n\n/** Session info returned from the server. */\nexport interface SessionInfo {\n\tprincipal: SessionPrincipal;\n\tattributes?: Record<string, unknown>;\n\textra?: Record<string, unknown>;\n}\n\nexport interface SessionContextClientTracingOptions {\n\ttarget?: string;\n\tprefix?: string;\n}\n\nexport interface SessionContextOperationOptions\n\textends CancellationTokenOptions {}\n\nexport interface SessionLoginWithRedirectOptions\n\textends CancellationTokenOptions {\n\tpostAuthRedirectUri?: string;\n}\n\n/** Configuration for the Session Context Client. */\nexport interface SessionContextClientConfig {\n\tid?: string;\n\t/** Base URL of the SecurityDept server. */\n\tbaseUrl: string;\n\t/** Login path (default: \"/auth/session/login\"). */\n\tloginPath?: string;\n\t/** Logout path (default: \"/auth/session/logout\"). */\n\tlogoutPath?: string;\n\t/** User info endpoint path (default: \"/auth/session/user-info\"). */\n\tuserInfoPath?: string;\n\tautoStart?: boolean;\n\ttracing?: SessionContextClientTracingOptions;\n}\n\nexport interface ResolvedSessionContextClientConfig {\n\tid: string;\n\tbaseUrl: string;\n\tloginPath: string;\n\tlogoutPath: string;\n\tuserInfoPath: string;\n\ttracing: Required<SessionContextClientTracingOptions>;\n}\n\nexport const SessionContextEventType = {\n\tSessionRefreshStarted: \"session.refresh.started\",\n\tSessionRefreshSucceeded: \"session.refresh.succeeded\",\n\tSessionRefreshFailed: \"session.refresh.failed\",\n\tSessionLogoutStarted: \"session.logout.started\",\n\tSessionLogoutSucceeded: \"session.logout.succeeded\",\n\tSessionLogoutFailed: \"session.logout.failed\",\n} as const;\n\nexport type SessionContextEventType =\n\t(typeof SessionContextEventType)[keyof typeof SessionContextEventType];\n\nexport interface SessionContextEvent {\n\ttype: SessionContextEventType;\n\tat: number;\n\tclient: {\n\t\tid: string;\n\t};\n\tsession?: SessionInfo | null;\n\terrorSummary?: ErrorSummary;\n}\n","import {\n\tIdentityPrincipalSchema,\n\tIdentityPrincipalWireSchema,\n} from \"@securitydept/client\";\nimport { type as defineType } from \"arktype\";\nimport { type SessionInfo } from \"../types\";\n\nexport const SessionInfoSchema = defineType({\n\tprincipal: IdentityPrincipalSchema,\n\t\"attributes?\": \"object\",\n\t\"extra?\": \"object\",\n}).pipe(\n\t(input): SessionInfo => ({\n\t\tprincipal: input.principal,\n\t\tattributes: input.attributes as Record<string, unknown> | undefined,\n\t\textra: input.extra as Record<string, unknown> | undefined,\n\t}),\n);\n\nexport const SessionUserInfoResponseSchema = IdentityPrincipalWireSchema.pipe(\n\t(principal): SessionInfo => ({ principal }),\n);\n","import {\n\tClientError,\n\tClientErrorKind,\n\tformatValidationFailure,\n\tvalidateWithSchemaSync,\n} from \"@securitydept/client\";\nimport {\n\tSessionContextErrorCode,\n\tSessionContextSource,\n\ttype SessionInfo,\n} from \"../types\";\nimport { SessionInfoSchema, SessionUserInfoResponseSchema } from \"./schemas\";\n\nexport function parseSessionInfoPayload(body: unknown): SessionInfo {\n\tconst infoResult = validateWithSchemaSync(SessionInfoSchema, body);\n\tif (infoResult.success) {\n\t\treturn infoResult.value;\n\t}\n\n\tconst userInfoResult = validateWithSchemaSync(\n\t\tSessionUserInfoResponseSchema,\n\t\tbody,\n\t);\n\tif (userInfoResult.success) {\n\t\treturn userInfoResult.value;\n\t}\n\n\tconst failure = {\n\t\tsuccess: false as const,\n\t\tissues: [...infoResult.issues, ...userInfoResult.issues],\n\t};\n\tconst issueSummary = formatValidationFailure(failure);\n\tthrow new ClientError({\n\t\tkind: ClientErrorKind.Protocol,\n\t\tcode: SessionContextErrorCode.InvalidSessionPayload,\n\t\tmessage: issueSummary\n\t\t\t? `Session /user-info payload is invalid: ${issueSummary}.`\n\t\t\t: \"Session /user-info payload is invalid.\",\n\t\tsource: SessionContextSource.SessionContext,\n\t\tcause: failure.issues,\n\t});\n}\n","import { SecuritydeptInjectionToken } from \"@securitydept/client\";\nimport { type SessionContextClient } from \"./client\";\nimport { type SessionContextClientConfig } from \"./types\";\n\nexport const SESSION_CONTEXT_CLIENT =\n\tnew SecuritydeptInjectionToken<SessionContextClient>(\n\t\t\"SESSION_CONTEXT_CLIENT\",\n\t);\n\nexport const SESSION_CONTEXT_CLIENT_CONFIG =\n\tnew SecuritydeptInjectionToken<SessionContextClientConfig>(\n\t\t\"SESSION_CONTEXT_CLIENT_CONFIG\",\n\t);\n","import {\n\ttype CancellationTokenSourceTrait,\n\ttype CancellationTokenTrait,\n\tClientError,\n\tClientErrorKind,\n\tcreateCancellationTokenSource,\n\tcreateLinkedCancellationToken,\n\tcreateOnceAsyncLockCallable,\n\tcreateSignal,\n\ttype DisposableTrait,\n\tdefineInstrumentMethodDecorator,\n\tdescribeError,\n\tENVIRONMENT_TOKEN,\n\ttype EventStreamTrait,\n\ttype FoundationEnvironment,\n\tinjectDisposableStackFrom,\n\tmapResource,\n\ttype OperationSpanTrait,\n\ttype ReadableSignalTrait,\n\ttype ResourceSnapshot,\n\tResourceSnapshotUpdateKind,\n\tResourceStatus,\n\ttype ResourceTrait,\n\tRouterNavigationIntent,\n\tRouterNavigationMode,\n\treadonlySignal,\n\treduceResourceSnapshot,\n\tresourceFromSnapshots,\n\tSecuritydeptDestroyRef,\n\ttype SecuritydeptInjectorTrait,\n\ttype SpanTrait,\n\tSYMBOL_DISPOSE,\n\tUriReferenceString,\n\ttype WritableSignalTrait,\n\twithDisposableStack,\n} from \"@securitydept/client\";\nimport {\n\ttype Command,\n\ttype CommandResponse,\n\tcommandResponseData,\n\tconcatCommand,\n\tdispatchCommandLocallyToStream,\n\tRxEventReplaySubject,\n\tRxEventSubject,\n\tRxStateSignal,\n} from \"@securitydept/client/rx\";\nimport { filter, from, lastValueFrom, take, takeUntil } from \"rxjs\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport { parseSessionInfoPayload } from \"./contracts/parsers\";\nimport { SESSION_CONTEXT_CLIENT_CONFIG } from \"./tokens\";\nimport {\n\ttype ResolvedSessionContextClientConfig,\n\ttype SessionContextClientConfig,\n\tSessionContextErrorCode,\n\ttype SessionContextEvent,\n\tSessionContextEventType,\n\ttype SessionContextOperationOptions,\n\tSessionContextSource,\n\ttype SessionInfo,\n\ttype SessionLoginWithRedirectOptions,\n} from \"./types\";\n\ninterface SessionContextOperationSignals {\n\treadonly startPending: ReadableSignalTrait<boolean>;\n\treadonly refreshPending: ReadableSignalTrait<boolean>;\n\treadonly logoutPending: ReadableSignalTrait<boolean>;\n\treadonly loginRedirectPending: ReadableSignalTrait<boolean>;\n}\n\ninterface SessionCommandExtra {\n\tcancellationToken: CancellationTokenTrait;\n\toperationSpan?: OperationSpanTrait;\n}\n\ntype SessionRefreshCommand = Command<void, SessionCommandExtra>;\ntype SessionLogoutCommand = Command<void, SessionCommandExtra>;\n\nconst POST_AUTH_REDIRECT_PARAM = \"post_auth_redirect_uri\";\n\nconst instrumentSessionMethod = defineInstrumentMethodDecorator<\n\t[operation: string],\n\tSessionContextClient\n>(\n\t({ factoryArgs: [operation] }) =>\n\t\tfunction (this: SessionContextClient) {\n\t\t\treturn {\n\t\t\t\tenvironment: this.environment,\n\t\t\t\tspan: this.span,\n\t\t\t\tname: `${this.config.tracing.prefix}.${operation}`,\n\t\t\t\ttarget: this.config.tracing.target,\n\t\t\t\tfields: { operation },\n\t\t\t\tnormalizeError: (error: unknown) =>\n\t\t\t\t\tClientError.fromUnknown(error, {\n\t\t\t\t\t\tcode: SessionContextErrorCode.OperationFailed,\n\t\t\t\t\t\tmessage: \"The session operation failed unexpectedly\",\n\t\t\t\t\t\tsource: SessionContextSource.SessionContext,\n\t\t\t\t\t}),\n\t\t\t};\n\t\t},\n);\n\n/**\n * Session Context Client.\n *\n * Owns session state, lifecycle, login/logout navigation, and tracing.\n * Host capabilities are resolved once through FoundationEnvironment at\n * construction time.\n */\nexport class SessionContextClient implements DisposableTrait {\n\tstatic defaultOptions = {\n\t\tloginPath: \"/auth/session/login\",\n\t\tlogoutPath: \"/auth/session/logout\",\n\t\tuserInfoPath: \"/auth/session/user-info\",\n\t\ttracing: {\n\t\t\ttarget: \"session-context-client\",\n\t\t\tprefix: \"session_context\",\n\t\t},\n\t} as const;\n\n\tprivate readonly _environment: FoundationEnvironment;\n\tprivate readonly _config: ResolvedSessionContextClientConfig;\n\tprivate readonly _span: SpanTrait;\n\tprivate readonly _rootCancellation: CancellationTokenSourceTrait =\n\t\tcreateCancellationTokenSource();\n\tprivate readonly _destroyed = RxStateSignal.fromInitialValue(false);\n\tprivate readonly destroyed$ = from(this._destroyed).pipe(\n\t\tfilter((value): value is true => value),\n\t\ttake(1),\n\t);\n\tprivate readonly _sessionSnapshotSignal = RxStateSignal.fromInitialValue<\n\t\tResourceSnapshot<SessionInfo | null>\n\t>({ status: ResourceStatus.Idle });\n\tprivate readonly _operationSignals: {\n\t\treadonly startPending: WritableSignalTrait<boolean>;\n\t\treadonly refreshPending: WritableSignalTrait<boolean>;\n\t\treadonly logoutPending: WritableSignalTrait<boolean>;\n\t\treadonly loginRedirectPending: WritableSignalTrait<boolean>;\n\t} = {\n\t\tstartPending: createSignal(false),\n\t\trefreshPending: createSignal(false),\n\t\tlogoutPending: createSignal(false),\n\t\tloginRedirectPending: createSignal(false),\n\t};\n\tprivate readonly _eventSubject =\n\t\tnew RxEventReplaySubject<SessionContextEvent>(100);\n\tprivate readonly _refreshCommandSubject =\n\t\tnew RxEventSubject<SessionRefreshCommand>();\n\tprivate readonly _refreshResponseSubject = new RxEventSubject<\n\t\tCommandResponse<SessionRefreshCommand, SessionInfo | null>\n\t>();\n\tprivate readonly _logoutCommandSubject =\n\t\tnew RxEventSubject<SessionLogoutCommand>();\n\tprivate readonly _logoutResponseSubject = new RxEventSubject<\n\t\tCommandResponse<SessionLogoutCommand, void>\n\t>();\n\tprivate readonly _startOnce = createOnceAsyncLockCallable(\n\t\tasync (\n\t\t\tcancellationToken: CancellationTokenTrait,\n\t\t\toperationSpan?: OperationSpanTrait,\n\t\t) => {\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t\tthis._operationSignals.startPending.set(true);\n\t\t\ttry {\n\t\t\t\treturn await this._dispatchRefresh(cancellationToken, operationSpan);\n\t\t\t} finally {\n\t\t\t\tthis._operationSignals.startPending.set(false);\n\t\t\t}\n\t\t},\n\t);\n\n\treadonly id: string;\n\treadonly sessionSnapshot: ReadableSignalTrait<\n\t\tResourceSnapshot<SessionInfo | null>\n\t>;\n\treadonly sessionResource: ResourceTrait<SessionInfo | null>;\n\treadonly isAuthenticated: ResourceTrait<boolean>;\n\treadonly sessionOperations: SessionContextOperationSignals;\n\treadonly events: EventStreamTrait<SessionContextEvent>;\n\n\tprotected get environment(): FoundationEnvironment {\n\t\treturn this._environment;\n\t}\n\n\tprotected get span(): SpanTrait {\n\t\treturn this._span;\n\t}\n\n\tprotected get config(): ResolvedSessionContextClientConfig {\n\t\treturn this._config;\n\t}\n\n\tstatic fromEnvironmentConfig(options: {\n\t\treadonly config: SessionContextClientConfig;\n\t\treadonly environment: FoundationEnvironment;\n\t}): SessionContextClient {\n\t\treturn new SessionContextClient(options.config, options.environment);\n\t}\n\n\tstatic fromInjector(\n\t\tinjector: SecuritydeptInjectorTrait,\n\t): SessionContextClient {\n\t\tconst client = SessionContextClient.fromEnvironmentConfig({\n\t\t\tconfig: injector.get(SESSION_CONTEXT_CLIENT_CONFIG),\n\t\t\tenvironment: injector.get(ENVIRONMENT_TOKEN),\n\t\t});\n\t\tinjector\n\t\t\t.get(SecuritydeptDestroyRef, null)\n\t\t\t?.onDestroy(() => client.dispose());\n\t\treturn client;\n\t}\n\n\tprotected constructor(\n\t\tconfig: SessionContextClientConfig,\n\t\tenvironment: FoundationEnvironment,\n\t) {\n\t\tthis._environment = environment;\n\t\tconst baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n\t\tthis._config = {\n\t\t\tid: config.id ?? uuidv7(),\n\t\t\tbaseUrl,\n\t\t\tloginPath:\n\t\t\t\tconfig.loginPath ?? SessionContextClient.defaultOptions.loginPath,\n\t\t\tlogoutPath:\n\t\t\t\tconfig.logoutPath ?? SessionContextClient.defaultOptions.logoutPath,\n\t\t\tuserInfoPath:\n\t\t\t\tconfig.userInfoPath ?? SessionContextClient.defaultOptions.userInfoPath,\n\t\t\ttracing: {\n\t\t\t\ttarget:\n\t\t\t\t\tconfig.tracing?.target ??\n\t\t\t\t\tSessionContextClient.defaultOptions.tracing.target,\n\t\t\t\tprefix:\n\t\t\t\t\tconfig.tracing?.prefix ??\n\t\t\t\t\tSessionContextClient.defaultOptions.tracing.prefix,\n\t\t\t},\n\t\t};\n\t\tthis.id = this._config.id;\n\t\tthis._span = environment.span.fork({\n\t\t\tattributes: {\n\t\t\t\tclientName: this.constructor.name,\n\t\t\t\tid: this.id,\n\t\t\t},\n\t\t});\n\t\tthis.sessionSnapshot = readonlySignal(this._sessionSnapshotSignal);\n\t\tthis.sessionResource = resourceFromSnapshots(() =>\n\t\t\tthis._sessionSnapshotSignal.get(),\n\t\t);\n\t\tthis.isAuthenticated = mapResource(\n\t\t\tthis.sessionResource,\n\t\t\t(sessionInfo) => sessionInfo !== null,\n\t\t);\n\t\tthis.sessionOperations = {\n\t\t\tstartPending: readonlySignal(this._operationSignals.startPending),\n\t\t\trefreshPending: readonlySignal(this._operationSignals.refreshPending),\n\t\t\tlogoutPending: readonlySignal(this._operationSignals.logoutPending),\n\t\t\tloginRedirectPending: readonlySignal(\n\t\t\t\tthis._operationSignals.loginRedirectPending,\n\t\t\t),\n\t\t};\n\t\tthis.events = this._eventSubject;\n\t\tthis.destroyed$.subscribe(() => {\n\t\t\tthis._rootCancellation.cancel(\n\t\t\t\tnew ClientError({\n\t\t\t\t\tkind: ClientErrorKind.Cancelled,\n\t\t\t\t\tcode: SessionContextErrorCode.ClientDisposed,\n\t\t\t\t\tmessage: \"SessionContextClient has been disposed.\",\n\t\t\t\t\tsource: SessionContextSource.SessionContext,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis.isAuthenticated.dispose();\n\t\t\tthis.sessionResource.dispose();\n\t\t});\n\n\t\tfrom(this._refreshCommandSubject)\n\t\t\t.pipe(\n\t\t\t\ttakeUntil(this.destroyed$),\n\t\t\t\tconcatCommand((command) =>\n\t\t\t\t\tthis._executeRefresh(\n\t\t\t\t\t\tcommand.cancellationToken,\n\t\t\t\t\t\tcommand.operationSpan,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.subscribe(this._refreshResponseSubject);\n\n\t\tfrom(this._logoutCommandSubject)\n\t\t\t.pipe(\n\t\t\t\ttakeUntil(this.destroyed$),\n\t\t\t\tconcatCommand((command) =>\n\t\t\t\t\tthis._executeLogout(command.cancellationToken, command.operationSpan),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.subscribe(this._logoutResponseSubject);\n\n\t\tif (config.autoStart === true) {\n\t\t\tthis.start().catch(() => {\n\t\t\t\t// Startup failure is reflected by sessionSnapshot.\n\t\t\t});\n\t\t}\n\t}\n\n\t@instrumentSessionMethod(\"start\")\n\tasync start(operationSpan?: OperationSpanTrait): Promise<SessionInfo | null> {\n\t\tconst cancellationToken = this._rootCancellation.token;\n\t\treturn await this._startOnce(cancellationToken, operationSpan);\n\t}\n\n\t@withDisposableStack(0, true)\n\tasync refresh(\n\t\toptions: SessionContextOperationOptions = {},\n\t): Promise<SessionInfo | null> {\n\t\tconst disposableStack = injectDisposableStackFrom(options, true);\n\t\tconst cancellationToken = createLinkedCancellationToken(\n\t\t\tthis._rootCancellation.token,\n\t\t\toptions.cancellationToken,\n\t\t);\n\t\tdisposableStack?.use(cancellationToken);\n\t\treturn await this._refresh(cancellationToken);\n\t}\n\n\t@instrumentSessionMethod(\"refresh\")\n\tprivate async _refresh(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\treturn await this._dispatchRefresh(cancellationToken, operationSpan);\n\t}\n\n\t@withDisposableStack(0, true)\n\tasync logout(options: SessionContextOperationOptions = {}): Promise<void> {\n\t\tconst disposableStack = injectDisposableStackFrom(options, true);\n\t\tconst cancellationToken = createLinkedCancellationToken(\n\t\t\tthis._rootCancellation.token,\n\t\t\toptions.cancellationToken,\n\t\t);\n\t\tdisposableStack?.use(cancellationToken);\n\t\tawait this._logout(cancellationToken);\n\t}\n\n\t@instrumentSessionMethod(\"logout\")\n\tprivate async _logout(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tawait this._dispatchLogout(cancellationToken, operationSpan);\n\t}\n\n\t@withDisposableStack(0, true)\n\tasync loginWithRedirect(\n\t\toptions: SessionLoginWithRedirectOptions = {},\n\t): Promise<void> {\n\t\tconst disposableStack = injectDisposableStackFrom(options, true);\n\t\tconst cancellationToken = createLinkedCancellationToken(\n\t\t\tthis._rootCancellation.token,\n\t\t\toptions.cancellationToken,\n\t\t);\n\t\tdisposableStack?.use(cancellationToken);\n\t\tawait this._loginWithRedirect(options, cancellationToken);\n\t}\n\n\t@instrumentSessionMethod(\"login.redirect\")\n\tprivate async _loginWithRedirect(\n\t\toptions: SessionLoginWithRedirectOptions,\n\t\tcancellationToken: CancellationTokenTrait,\n\t\t_operationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tconst router = this._environment.router;\n\t\tif (!router) {\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: SessionContextErrorCode.RouterUnavailable,\n\t\t\t\tmessage: \"loginWithRedirect() requires environment.router.\",\n\t\t\t\tsource: SessionContextSource.SessionContext,\n\t\t\t});\n\t\t}\n\t\tthis._operationSignals.loginRedirectPending.set(true);\n\t\ttry {\n\t\t\tawait router.navigate({\n\t\t\t\turl: UriReferenceString.parse(\n\t\t\t\t\tthis._createLoginRedirectUrl(options.postAuthRedirectUri),\n\t\t\t\t),\n\t\t\t\tintent: RouterNavigationIntent.AuthRedirect,\n\t\t\t\tmode: RouterNavigationMode.External,\n\t\t\t});\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t} finally {\n\t\t\tthis._operationSignals.loginRedirectPending.set(false);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis._destroyed.set(true);\n\t}\n\n\t[SYMBOL_DISPOSE](): void {\n\t\tthis.dispose();\n\t}\n\n\tprivate async _dispatchRefresh(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tconst sessionInfo = await lastValueFrom(\n\t\t\tdispatchCommandLocallyToStream<\n\t\t\t\tvoid,\n\t\t\t\tSessionCommandExtra,\n\t\t\t\tSessionInfo | null,\n\t\t\t\tSessionRefreshCommand\n\t\t\t>({\n\t\t\t\tpayload: undefined,\n\t\t\t\trequestStream: this._refreshCommandSubject,\n\t\t\t\tresponseStream: this._refreshResponseSubject,\n\t\t\t\tcreateCommandExtra: () => ({ cancellationToken, operationSpan }),\n\t\t\t}).pipe(commandResponseData()),\n\t\t);\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\treturn sessionInfo;\n\t}\n\n\tprivate async _dispatchLogout(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tawait lastValueFrom(\n\t\t\tdispatchCommandLocallyToStream<\n\t\t\t\tvoid,\n\t\t\t\tSessionCommandExtra,\n\t\t\t\tvoid,\n\t\t\t\tSessionLogoutCommand\n\t\t\t>({\n\t\t\t\tpayload: undefined,\n\t\t\t\trequestStream: this._logoutCommandSubject,\n\t\t\t\tresponseStream: this._logoutResponseSubject,\n\t\t\t\tcreateCommandExtra: () => ({ cancellationToken, operationSpan }),\n\t\t\t}).pipe(commandResponseData()),\n\t\t);\n\t\tcancellationToken.throwIfCancellationRequested();\n\t}\n\n\tprivate async _executeRefresh(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tthis._operationSignals.refreshPending.set(true);\n\t\tconst previous = this._sessionSnapshotSignal.get();\n\t\tconst previousValue =\n\t\t\tprevious.status === ResourceStatus.Reloading ||\n\t\t\tprevious.status === ResourceStatus.Resolved ||\n\t\t\tprevious.status === ResourceStatus.Error\n\t\t\t\t? previous.value\n\t\t\t\t: null;\n\t\tconst loadingSnapshot = reduceResourceSnapshot(previous, {\n\t\t\tkind: ResourceSnapshotUpdateKind.Load,\n\t\t});\n\t\tthis._sessionSnapshotSignal.set(loadingSnapshot);\n\t\tthis._emitSessionEvent({\n\t\t\ttype: SessionContextEventType.SessionRefreshStarted,\n\t\t\tsession: previousValue,\n\t\t});\n\t\ttry {\n\t\t\tconst sessionInfo = await this._fetchSessionInfo(cancellationToken);\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Resolve,\n\t\t\t\t\tvalue: sessionInfo,\n\t\t\t\t}),\n\t\t\t);\n\t\t\toperationSpan?.setAttributes({\n\t\t\t\tauthenticated: sessionInfo !== null,\n\t\t\t});\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionRefreshSucceeded,\n\t\t\t\tsession: sessionInfo,\n\t\t\t});\n\t\t\treturn sessionInfo;\n\t\t} catch (error) {\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Fail,\n\t\t\t\t\terror,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionRefreshFailed,\n\t\t\t\tsession: previousValue,\n\t\t\t\terrorSummary: describeError(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis._operationSignals.refreshPending.set(false);\n\t\t}\n\t}\n\n\tprivate async _executeLogout(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tthis._operationSignals.logoutPending.set(true);\n\t\tconst previous = this._sessionSnapshotSignal.get();\n\t\tconst loadingSnapshot = reduceResourceSnapshot(previous, {\n\t\t\tkind: ResourceSnapshotUpdateKind.Load,\n\t\t});\n\t\tthis._sessionSnapshotSignal.set(loadingSnapshot);\n\t\tthis._emitSessionEvent({\n\t\t\ttype: SessionContextEventType.SessionLogoutStarted,\n\t\t\tsession: this._readCurrentSession(),\n\t\t});\n\t\ttry {\n\t\t\tconst response = await this._environment.transport.execute({\n\t\t\t\turl: this._createLogoutUrl(),\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({}),\n\t\t\t\tcancellationToken,\n\t\t\t});\n\n\t\t\tif (response.status < 200 || response.status >= 300) {\n\t\t\t\tthrow ClientError.fromHttpResponse({\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\tbody: response.body,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Resolve,\n\t\t\t\t\tvalue: null,\n\t\t\t\t}),\n\t\t\t);\n\t\t\toperationSpan?.setAttributes({ authenticated: false });\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionLogoutSucceeded,\n\t\t\t\tsession: null,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Fail,\n\t\t\t\t\terror,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionLogoutFailed,\n\t\t\t\tsession: this._readCurrentSession(),\n\t\t\t\terrorSummary: describeError(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis._operationSignals.logoutPending.set(false);\n\t\t}\n\t}\n\n\tprivate async _fetchSessionInfo(\n\t\tcancellationToken: CancellationTokenTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tconst response = await this._environment.transport.execute({\n\t\t\turl: this._config.baseUrl + this._config.userInfoPath,\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {},\n\t\t\tcancellationToken,\n\t\t});\n\t\tcancellationToken.throwIfCancellationRequested();\n\n\t\tif (response.status === 401 || response.status === 403) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (response.status >= 200 && response.status < 300) {\n\t\t\treturn parseSessionInfoPayload(response.body);\n\t\t}\n\n\t\tthrow ClientError.fromHttpResponse({\n\t\t\tstatus: response.status,\n\t\t\tbody: response.body,\n\t\t});\n\t}\n\n\tprivate _createLoginRedirectUrl(postAuthRedirectUri?: string): string {\n\t\tconst base = this._config.baseUrl + this._config.loginPath;\n\t\tif (postAuthRedirectUri) {\n\t\t\tconst params = new URLSearchParams({\n\t\t\t\t[POST_AUTH_REDIRECT_PARAM]: postAuthRedirectUri,\n\t\t\t});\n\t\t\treturn `${base}?${params.toString()}`;\n\t\t}\n\t\treturn base;\n\t}\n\n\tprivate _createLogoutUrl(): string {\n\t\treturn this._config.baseUrl + this._config.logoutPath;\n\t}\n\n\tprivate _readCurrentSession(): SessionInfo | null {\n\t\tconst snapshot = this._sessionSnapshotSignal.get();\n\t\treturn snapshot.status === ResourceStatus.Reloading ||\n\t\t\tsnapshot.status === ResourceStatus.Resolved ||\n\t\t\tsnapshot.status === ResourceStatus.Error\n\t\t\t? snapshot.value\n\t\t\t: null;\n\t}\n\n\tprivate _emitSessionEvent(\n\t\tinput: Omit<SessionContextEvent, \"at\" | \"client\">,\n\t): void {\n\t\tthis._eventSubject.next({\n\t\t\t...input,\n\t\t\tat: this._environment.time.now(),\n\t\t\tclient: {\n\t\t\t\tid: this.id,\n\t\t\t},\n\t\t});\n\t}\n}\n","import {\n\tINJECTOR_TOKEN,\n\ttype SecuritydeptInjectorTrait,\n\ttype SecuritydeptProvider,\n} from \"@securitydept/client\";\nimport { SessionContextClient } from \"./client\";\nimport {\n\tSESSION_CONTEXT_CLIENT,\n\tSESSION_CONTEXT_CLIENT_CONFIG,\n} from \"./tokens\";\nimport { type SessionContextClientConfig } from \"./types\";\n\nexport interface ProvideSessionContextOptions {\n\treadonly config: SessionContextClientConfig;\n}\n\nexport function provideSessionContext(\n\toptions: ProvideSessionContextOptions,\n): readonly SecuritydeptProvider[] {\n\treturn [\n\t\t{\n\t\t\tprovide: SESSION_CONTEXT_CLIENT_CONFIG,\n\t\t\tuseValue: options.config,\n\t\t},\n\t\t{\n\t\t\tprovide: SESSION_CONTEXT_CLIENT,\n\t\t\tuseFactory: (injector: SecuritydeptInjectorTrait) =>\n\t\t\t\tSessionContextClient.fromInjector(injector),\n\t\t\tdeps: [INJECTOR_TOKEN],\n\t\t},\n\t];\n}\n"],"mappings":";;;;;;AAQA,MAAaA,0BAA0B;CACtCC,iBAAiB;CACjBC,gBAAgB;CAChBC,mBAAmB;CACnBC,uBAAuB;CACxB;AAKA,MAAaC,uBAAuB,EACnCC,gBAAgB,mBACjB;AAoDA,MAAaC,0BAA0B;CACtCC,uBAAuB;CACvBC,yBAAyB;CACzBC,sBAAsB;CACtBC,sBAAsB;CACtBC,wBAAwB;CACxBC,qBAAqB;CACtB;;;ACxEA,MAAaK,oBAAoBD,KAAW;CAC3CE,WAAWL;CACX,eAAe;CACf,UAAU;CACX,CAAA,CAAGM,MACDC,WAAwB;CACxBF,WAAWE,MAAMF;CACjBG,YAAYD,MAAMC;CAClBC,OAAOF,MAAME;CACd,EAAA;AAGD,MAAaC,gCAAgCT,4BAA4BK,MACvED,eAA4B,EAAEA,WAAU,EAAA;;;ACP1C,SAAgBc,wBAAwBC,MAAa;CACpD,MAAMC,aAAaP,uBAAuBG,mBAAmBG,KAAAA;CAC7D,IAAIC,WAAWC,SACd,OAAOD,WAAWE;CAGnB,MAAMC,iBAAiBV,uBACtBI,+BACAE,KAAAA;CAED,IAAII,eAAeF,SAClB,OAAOE,eAAeD;CAGvB,MAAME,UAAU;EACfH,SAAS;EACTI,QAAQ,CAAA,GAAIL,WAAWK,QAAAA,GAAWF,eAAeE,OAAO;EACzD;CACA,MAAMC,eAAed,wBAAwBY,QAAAA;CAC7C,MAAM,IAAId,YAAY;EACrBiB,MAAMhB,gBAAgBiB;EACtBC,MAAMf,wBAAwBgB;EAC9BC,SAASL,eACN,0CAA0CA,aAAa,KACvD;EACHM,QAAQjB,qBAAqBkB;EAC7BC,OAAOV,QAAQC;EAChB,CAAA;;;;ACpCD,MAAaW,yBACZ,IAAID,2BACH,yBAAA;AAGF,MAAaE,gCACZ,IAAIF,2BACH,gCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACkEF,MAAM2C,2BAA2B;AAEjC,MAAMC,0BAA0BnC,iCAI9B,EAAEoC,aAAa,CAACC,iBAChB,WAAA;CACC,OAAO;EACNC,aAAa,KAAKA;EAClBC,MAAM,KAAKA;EACXC,MAAM,GAAG,KAAKC,OAAOC,QAAQC,OAAO,GAAGN;EACvCO,QAAQ,KAAKH,OAAOC,QAAQE;EAC5BC,QAAQ,EAAER,WAAU;EACpBS,iBAAiBC,UAChBrD,YAAYsD,YAAYD,OAAO;GAC9BE,MAAMlB,wBAAwBmB;GAC9BC,SAAS;GACTC,QAAQnB,qBAAqBoB;GAC9B,CAAA;EACF;EACD;OA0MAlB,wBAAwB,QAAA,EAAA,QAMxBpB,oBAAoB,GAAG,KAAA,EAAA,QAavBoB,wBAAwB,UAAA,EAAA,QASxBpB,oBAAoB,GAAG,KAAA,EAAA,QAWvBoB,wBAAwB,SAAA,EAAA,QASxBpB,oBAAoB,GAAG,KAAA,EAAA,QAavBoB,wBAAwB,iBAAA;;;;;;;GA7P1B,IAAamB,uBAAb,MAAaA,qBAAAA;;;;;;IAiMNC;;;;;IAMAC;;;;;IAaQC;;;;;IASRC;;;;;IAWQC;;;;;IASRC;;;;;IAaQC;;;;CA7Pd,OAAOC,iBAAiB;EACvBC,WAAW;EACXC,YAAY;EACZC,cAAc;EACdvB,SAAS;GACRE,QAAQ;GACRD,QAAQ;GACT;EACD;CAEiBuB;CACAC;CACAC;CACAC,qBAAAA,WAAAA,KAAAA,EAChBzE,+BAAAA;CACgB0E,aAAajD,cAAckD,iBAAiB,MAAA;CAC5CC,aAAajD,KAAK,KAAK+C,WAAU,CAAEG,KACnDnD,QAAQoD,UAAyBA,MAAAA,EACjCjD,KAAK,EAAA,CAAA;CAEWkD,yBAAyBtD,cAAckD,iBAEtD,EAAEK,QAAQtE,eAAeuE,MAAK,CAAA;CACfC,oBAKb;EACHC,cAAchF,aAAa,MAAA;EAC3BiF,gBAAgBjF,aAAa,MAAA;EAC7BkF,eAAelF,aAAa,MAAA;EAC5BmF,sBAAsBnF,aAAa,MAAA;EACpC;CACiBoF,gBAChB,IAAIhE,qBAA0C,IAAA;CAC9BiE,yBAChB,IAAIhE,gBAAAA;CACYiE,0BAA0B,IAAIjE,gBAAAA;CAG9BkE,wBAChB,IAAIlE,gBAAAA;CACYmE,yBAAyB,IAAInE,gBAAAA;CAG7BoE,aAAa1F,4BAC7B,OACC2F,mBACAC,kBAAAA;EAEAD,kBAAkBE,8BAA4B;EAC9C,KAAKb,kBAAkBC,aAAaa,IAAI,KAAA;EACxC,IAAI;GACH,OAAO,MAAM,KAAKC,iBAAiBJ,mBAAmBC,cAAAA;YAC7C;GACT,KAAKZ,kBAAkBC,aAAaa,IAAI,MAAA;;GAE1C;CAGQE;CACAC;CAGAC;CACAC;CACAC;CACAC;CAET,IAAc7D,cAAqC;EAClD,OAAO,KAAK4B;;CAGb,IAAc3B,OAAkB;EAC/B,OAAO,KAAK6B;;CAGb,IAAc3B,SAA6C;EAC1D,OAAO,KAAK0B;;CAGb,OAAOiC,sBAAsBC,SAGJ;EACxB,OAAO,IAAI/C,qBAAqB+C,QAAQ5D,QAAQ4D,QAAQ/D,YAAW;;CAGpE,OAAOgE,aACNC,UACuB;EACvB,MAAMC,SAASlD,qBAAqB8C,sBAAsB;GACzD3D,QAAQ8D,SAASE,IAAI3E,8BAAAA;GACrBQ,aAAaiE,SAASE,IAAIvG,kBAAAA;GAC3B,CAAA;EACAqG,SACEE,IAAI7F,wBAAwB,KAAA,EAC3B8F,gBAAgBF,OAAOG,SAAO,CAAA;EACjC,OAAOH;;CAGR,YACC/D,QACAH,aACC;EACD,KAAK4B,eAAe5B;EACpB,MAAMsE,UAAUnE,OAAOmE,QAAQC,QAAQ,QAAQ,GAAA;EAC/C,KAAK1C,UAAU;GACd2B,IAAIrD,OAAOqD,MAAMlE,IAAAA;GACjBgF;GACA7C,WACCtB,OAAOsB,aAAaT,qBAAqBQ,eAAeC;GACzDC,YACCvB,OAAOuB,cAAcV,qBAAqBQ,eAAeE;GAC1DC,cACCxB,OAAOwB,gBAAgBX,qBAAqBQ,eAAeG;GAC5DvB,SAAS;IACRE,QACCH,OAAOC,SAASE,UAChBU,qBAAqBQ,eAAepB,QAAQE;IAC7CD,QACCF,OAAOC,SAASC,UAChBW,qBAAqBQ,eAAepB,QAAQC;IAC9C;GACD;EACA,KAAKmD,KAAK,KAAK3B,QAAQ2B;EACvB,KAAK1B,QAAQ9B,YAAYC,KAAKuE,KAAK,EAClCC,YAAY;GACXC,YAAY,KAAK,YAAYxE;GAC7BsD,IAAI,KAAKA;GACV,EACD,CAAA;EACA,KAAKC,kBAAkBtF,eAAe,KAAKkE,uBAAsB;EACjE,KAAKqB,kBAAkBrF,4BACtB,KAAKgE,uBAAuB8B,KAAG,CAAA;EAEhC,KAAKR,kBAAkB7F,YACtB,KAAK4F,kBACJiB,gBAAgBA,gBAAgB,KAAA;EAElC,KAAKf,oBAAoB;GACxBnB,cAActE,eAAe,KAAKqE,kBAAkBC,aAAY;GAChEC,gBAAgBvE,eAAe,KAAKqE,kBAAkBE,eAAc;GACpEC,eAAexE,eAAe,KAAKqE,kBAAkBG,cAAa;GAClEC,sBAAsBzE,eACrB,KAAKqE,kBAAkBI,qBAAoB;GAE7C;EACA,KAAKiB,SAAS,KAAKhB;EACnB,KAAKX,WAAW0C,gBAAU;GACzB,KAAK7C,kBAAkB8C,OACtB,IAAIzH,YAAY;IACf0H,MAAMzH,gBAAgB0H;IACtBpE,MAAMlB,wBAAwBuF;IAC9BnE,SAAS;IACTC,QAAQnB,qBAAqBoB;IAC9B,CAAA,CAAA;GAED,KAAK4C,gBAAgBU,SAAO;GAC5B,KAAKX,gBAAgBW,SAAO;IAC7B;EAEApF,KAAK,KAAK6D,uBAAsB,CAC9BX,KACA/C,UAAU,KAAK8C,WAAU,EACzBvD,eAAesG,YACd,KAAKC,gBACJD,QAAQ9B,mBACR8B,QAAQ7B,cAAa,CAAA,CAAA,CAIvBwB,UAAU,KAAK7B,wBAAuB;EAExC9D,KAAK,KAAK+D,sBAAqB,CAC7Bb,KACA/C,UAAU,KAAK8C,WAAU,EACzBvD,eAAesG,YACd,KAAKE,eAAeF,QAAQ9B,mBAAmB8B,QAAQ7B,cAAa,CAAA,CAAA,CAGrEwB,UAAU,KAAK3B,uBAAsB;EAEvC,IAAI9C,OAAOiF,cAAc,MACxB,KAAKnE,OAAK,CAAGoE,YAAM,GAEnB;;CAIF,MACMpE,MAAMmC,eAAiE;EAC5E,MAAMD,oBAAoB,KAAKpB,kBAAkBuD;EACjD,OAAO,MAAM,KAAKpC,WAAWC,mBAAmBC,cAAAA;;CAGjD,MACMlC,QACL6C,UAA0C,EAAE,EACd;EAC9B,MAAMwB,kBAAkB1H,0BAA0BkG,SAAS,KAAA;EAC3D,MAAMZ,oBAAoB5F,8BACzB,KAAKwE,kBAAkBuD,OACvBvB,QAAQZ,kBAAiB;EAE1BoC,iBAAiBC,IAAIrC,kBAAAA;EACrB,OAAO,MAAM,KAAKhC,SAASgC,kBAAAA;;CAG5B,MACchC,SACbgC,mBACAC,eAC8B;EAC9BD,kBAAkBE,8BAA4B;EAC9C,OAAO,MAAM,KAAKE,iBAAiBJ,mBAAmBC,cAAAA;;CAGvD,MACMhC,OAAO2C,UAA0C,EAAE,EAAiB;EACzE,MAAMwB,kBAAkB1H,0BAA0BkG,SAAS,KAAA;EAC3D,MAAMZ,oBAAoB5F,8BACzB,KAAKwE,kBAAkBuD,OACvBvB,QAAQZ,kBAAiB;EAE1BoC,iBAAiBC,IAAIrC,kBAAAA;EACrB,MAAM,KAAK9B,QAAQ8B,kBAAAA;;CAGpB,MACc9B,QACb8B,mBACAC,eACgB;EAChBD,kBAAkBE,8BAA4B;EAC9C,MAAM,KAAKoC,gBAAgBtC,mBAAmBC,cAAAA;;CAG/C,MACM9B,kBACLyC,UAA2C,EAAE,EAC7B;EAChB,MAAMwB,kBAAkB1H,0BAA0BkG,SAAS,KAAA;EAC3D,MAAMZ,oBAAoB5F,8BACzB,KAAKwE,kBAAkBuD,OACvBvB,QAAQZ,kBAAiB;EAE1BoC,iBAAiBC,IAAIrC,kBAAAA;EACrB,MAAM,KAAK5B,mBAAmBwC,SAASZ,kBAAAA;;CAGxC,MACc5B,mBACbwC,SACAZ,mBACAuC,gBACgB;EAChBvC,kBAAkBE,8BAA4B;EAC9C,MAAMsC,SAAS,KAAK/D,aAAa+D;EACjC,IAAI,CAACA,QACJ,MAAM,IAAIvI,YAAY;GACrB0H,MAAMzH,gBAAgBuI;GACtBjF,MAAMlB,wBAAwBoG;GAC9BhF,SAAS;GACTC,QAAQnB,qBAAqBoB;GAC9B,CAAA;EAED,KAAKyB,kBAAkBI,qBAAqBU,IAAI,KAAA;EAChD,IAAI;GACH,MAAMqC,OAAOG,SAAS;IACrBC,KAAKvH,mBAAmBwH,MACvB,KAAKC,wBAAwBlC,QAAQmC,oBAAmB,CAAA;IAEzDC,QAAQlI,uBAAuBmI;IAC/BC,MAAMnI,qBAAqBoI;IAC5B,CAAA;GACAnD,kBAAkBE,8BAA4B;YACrC;GACT,KAAKb,kBAAkBI,qBAAqBU,IAAI,MAAA;;;CAIlDe,UAAgB;EACf,KAAKrC,WAAWsB,IAAI,KAAA;;CAGrB,CAAC/E,kBAAwB;EACxB,KAAK8F,SAAO;;CAGb,MAAcd,iBACbJ,mBACAC,eAC8B;EAC9BD,kBAAkBE,8BAA4B;EAC9C,MAAMsB,cAAc,MAAMzF,cACzBN,+BAKE;GACD2H,SAASC,KAAAA;GACTC,eAAe,KAAK3D;GACpB4D,gBAAgB,KAAK3D;GACrB4D,2BAA2B;IAAExD;IAAmBC;IAAc;GAC/D,CAAA,CAAGjB,KAAKzD,qBAAAA,CAAAA,CAAAA;EAETyE,kBAAkBE,8BAA4B;EAC9C,OAAOsB;;CAGR,MAAcc,gBACbtC,mBACAC,eACgB;EAChBD,kBAAkBE,8BAA4B;EAC9C,MAAMnE,cACLN,+BAKE;GACD2H,SAASC,KAAAA;GACTC,eAAe,KAAKzD;GACpB0D,gBAAgB,KAAKzD;GACrB0D,2BAA2B;IAAExD;IAAmBC;IAAc;GAC/D,CAAA,CAAGjB,KAAKzD,qBAAAA,CAAAA,CAAAA;EAETyE,kBAAkBE,8BAA4B;;CAG/C,MAAc6B,gBACb/B,mBACAC,eAC8B;EAC9BD,kBAAkBE,8BAA4B;EAC9C,KAAKb,kBAAkBE,eAAeY,IAAI,KAAA;EAC1C,MAAMsD,WAAW,KAAKvE,uBAAuB8B,KAAG;EAChD,MAAM0C,gBACLD,SAAStE,WAAWtE,eAAe8I,aACnCF,SAAStE,WAAWtE,eAAe+I,YACnCH,SAAStE,WAAWtE,eAAegJ,QAChCJ,SAASxE,QACT;EACJ,MAAM6E,kBAAkB7I,uBAAuBwI,UAAU,EACxD9B,MAAM/G,2BAA2BmJ,MAClC,CAAA;EACA,KAAK7E,uBAAuBiB,IAAI2D,gBAAAA;EAChC,KAAKE,kBAAkB;GACtBC,MAAM1H,wBAAwB2H;GAC9BC,SAAST;GACV,CAAA;EACA,IAAI;GACH,MAAMlC,cAAc,MAAM,KAAK4C,kBAAkBpE,kBAAAA;GACjDA,kBAAkBE,8BAA4B;GAC9C,KAAKhB,uBAAuBiB,IAC3BlF,uBAAuB6I,iBAAiB;IACvCnC,MAAM/G,2BAA2ByJ;IACjCpF,OAAOuC;IACR,CAAA,CAAA;GAEDvB,eAAeqE,cAAc,EAC5BC,eAAe/C,gBAAgB,MAChC,CAAA;GACA,KAAKwC,kBAAkB;IACtBC,MAAM1H,wBAAwBiI;IAC9BL,SAAS3C;IACV,CAAA;GACA,OAAOA;WACClE,OAAO;GACf,KAAK4B,uBAAuBiB,IAC3BlF,uBAAuB6I,iBAAiB;IACvCnC,MAAM/G,2BAA2B6J;IACjCnH;IACD,CAAA,CAAA;GAED,KAAK0G,kBAAkB;IACtBC,MAAM1H,wBAAwBmI;IAC9BP,SAAST;IACTiB,cAAcnK,cAAc8C,MAAAA;IAC7B,CAAA;GACA,MAAMA;YACG;GACT,KAAK+B,kBAAkBE,eAAeY,IAAI,MAAA;;;CAI5C,MAAc6B,eACbhC,mBACAC,eACgB;EAChBD,kBAAkBE,8BAA4B;EAC9C,KAAKb,kBAAkBG,cAAcW,IAAI,KAAA;EAEzC,MAAM2D,kBAAkB7I,uBADP,KAAKiE,uBAAuB8B,KACEyC,EAAU,EACxD9B,MAAM/G,2BAA2BmJ,MAClC,CAAA;EACA,KAAK7E,uBAAuBiB,IAAI2D,gBAAAA;EAChC,KAAKE,kBAAkB;GACtBC,MAAM1H,wBAAwBqI;GAC9BT,SAAS,KAAKU,qBAAmB;GAClC,CAAA;EACA,IAAI;GACH,MAAMC,WAAW,MAAM,KAAKrG,aAAasG,UAAUC,QAAQ;IAC1DpC,KAAK,KAAKqC,kBAAgB;IAC1BC,QAAQ;IACRC,SAAS,EAAE,gBAAgB,oBAAmB;IAC9CC,MAAMC,KAAKC,UAAU,EAAC,CAAA;IACtBtF;IACD,CAAA;GAEA,IAAI8E,SAAS3F,SAAS,OAAO2F,SAAS3F,UAAU,KAC/C,MAAMlF,YAAYsL,iBAAiB;IAClCpG,QAAQ2F,SAAS3F;IACjBiG,MAAMN,SAASM;IAChB,CAAA;GAGDpF,kBAAkBE,8BAA4B;GAC9C,KAAKhB,uBAAuBiB,IAC3BlF,uBAAuB6I,iBAAiB;IACvCnC,MAAM/G,2BAA2ByJ;IACjCpF,OAAO;IACR,CAAA,CAAA;GAEDgB,eAAeqE,cAAc,EAAEC,eAAe,OAAM,CAAA;GACpD,KAAKP,kBAAkB;IACtBC,MAAM1H,wBAAwBiJ;IAC9BrB,SAAS;IACV,CAAA;WACQ7G,OAAO;GACf,KAAK4B,uBAAuBiB,IAC3BlF,uBAAuB6I,iBAAiB;IACvCnC,MAAM/G,2BAA2B6J;IACjCnH;IACD,CAAA,CAAA;GAED,KAAK0G,kBAAkB;IACtBC,MAAM1H,wBAAwBkJ;IAC9BtB,SAAS,KAAKU,qBAAmB;IACjCF,cAAcnK,cAAc8C,MAAAA;IAC7B,CAAA;GACA,MAAMA;YACG;GACT,KAAK+B,kBAAkBG,cAAcW,IAAI,MAAA;;;CAI3C,MAAciE,kBACbpE,mBAC8B;EAC9BA,kBAAkBE,8BAA4B;EAC9C,MAAM4E,WAAW,MAAM,KAAKrG,aAAasG,UAAUC,QAAQ;GAC1DpC,KAAK,KAAKlE,QAAQyC,UAAU,KAAKzC,QAAQF;GACzC0G,QAAQ;GACRC,SAAS,EAAC;GACVnF;GACD,CAAA;EACAA,kBAAkBE,8BAA4B;EAE9C,IAAI4E,SAAS3F,WAAW,OAAO2F,SAAS3F,WAAW,KAClD,OAAO;EAGR,IAAI2F,SAAS3F,UAAU,OAAO2F,SAAS3F,SAAS,KAC/C,OAAO/C,wBAAwB0I,SAASM,KAAI;EAG7C,MAAMnL,YAAYsL,iBAAiB;GAClCpG,QAAQ2F,SAAS3F;GACjBiG,MAAMN,SAASM;GAChB,CAAA;;CAGOtC,wBAAwBC,qBAAsC;EACrE,MAAM2C,OAAO,KAAKhH,QAAQyC,UAAU,KAAKzC,QAAQJ;EACjD,IAAIyE,qBAIH,OAAO,GAAG2C,KAAK,GAAGC,IAHCC,gBAAgB,GACjCnJ,2BAA2BsG,qBAC7B,CACkB4C,CAAOE,UAAQ;EAElC,OAAOH;;CAGAT,mBAA2B;EAClC,OAAO,KAAKvG,QAAQyC,UAAU,KAAKzC,QAAQH;;CAGpCsG,sBAA0C;EACjD,MAAMiB,WAAW,KAAK5G,uBAAuB8B,KAAG;EAChD,OAAO8E,SAAS3G,WAAWtE,eAAe8I,aACzCmC,SAAS3G,WAAWtE,eAAe+I,YACnCkC,SAAS3G,WAAWtE,eAAegJ,QACjCiC,SAAS7G,QACT;;CAGI+E,kBACP+B,OACO;EACP,KAAKrG,cAAcsG,KAAK;GACvB,GAAGD;GACHE,IAAI,KAAKxH,aAAayH,KAAKC,KAAG;GAC9BpF,QAAQ,EACPV,IAAI,KAAKA,IACV;GACD,CAAA;;;;;AC3lBF,SAAgBmG,sBACfC,SAAqC;CAErC,OAAO,CACN;EACCC,SAASH;EACTI,UAAUF,QAAQG;EACnB,EACA;EACCF,SAASJ;EACTO,aAAaC,aACZT,qBAAqBU,aAAaD,SAAAA;EACnCE,MAAM,CAACZ,eAAe;EACvB,CACA"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["ClientError","SessionContextErrorCode","OperationFailed","ClientDisposed","RouterUnavailable","InvalidSessionPayload","SessionContextSource","SessionContext","clientErrorFromSessionError","error","options","fromUnknown","code","message","source","span","IdentityPrincipalSchema","IdentityPrincipalWireSchema","type","defineType","SessionInfoSchema","principal","pipe","input","attributes","extra","SessionUserInfoResponseSchema","ClientError","ClientErrorKind","formatValidationFailure","validateWithSchemaSync","SessionContextErrorCode","SessionContextSource","SessionInfoSchema","SessionUserInfoResponseSchema","parseSessionInfoPayload","body","infoResult","success","value","userInfoResult","failure","issues","issueSummary","kind","Protocol","code","InvalidSessionPayload","message","source","SessionContext","cause","SecuritydeptInjectionToken","SESSION_CONTEXT_CLIENT","SESSION_CONTEXT_CLIENT_CONFIG","SessionContextEventType","SessionRefreshStarted","SessionRefreshSucceeded","SessionRefreshFailed","SessionLogoutStarted","SessionLogoutSucceeded","SessionLogoutFailed","ClientError","ClientErrorKind","createCancellationTokenSource","createLinkedCancellationToken","createOnceAsyncLockCallable","createSignal","defineInstrumentMethodDecorator","ENVIRONMENT_TOKEN","injectDisposableStackFrom","mapResource","ResourceSnapshotUpdateKind","ResourceStatus","RouterNavigationIntent","RouterNavigationMode","readonlySignal","reduceResourceSnapshot","resourceFromSnapshots","SecuritydeptDestroyRef","SpanSharedAttributeName","SYMBOL_DISPOSE","UriReferenceString","withDisposableStack","commandResponseData","concatCommand","dispatchCommandLocallyToStream","RxEventSubject","RxStateSignal","filter","from","lastValueFrom","take","takeUntil","v7","uuidv7","parseSessionInfoPayload","clientErrorFromSessionError","SessionContextErrorCode","SessionContextSource","SESSION_CONTEXT_CLIENT_CONFIG","SessionContextEventType","POST_AUTH_REDIRECT_PARAM","instrumentSessionMethod","factoryArgs","operation","environment","span","name","config","tracing","prefix","target","traceAttributes","clientErrorFromUnknown","error","options","SessionContextClient","start","refresh","_refresh","logout","_logout","loginWithRedirect","_loginWithRedirect","defaultOptions","loginPath","logoutPath","userInfoPath","_environment","_config","_span","_rootCancellation","_destroyed","fromInitialValue","destroyed$","pipe","value","_sessionSnapshotSignal","status","Idle","_operationSignals","startPending","refreshPending","logoutPending","loginRedirectPending","_eventSubject","_refreshCommandSubject","_refreshResponseSubject","_logoutCommandSubject","_logoutResponseSubject","_startOnce","cancellationToken","operationSpan","throwIfCancellationRequested","set","_dispatchRefresh","id","sessionSnapshot","sessionResource","isAuthenticated","sessionOperations","events","fromEnvironmentConfig","fromInjector","injector","client","get","onDestroy","dispose","baseUrl","replace","fork","attributes","ClientName","ClientId","sessionInfo","subscribe","cancel","kind","Cancelled","code","ClientDisposed","message","source","SessionContext","command","_executeRefresh","_executeLogout","autoStart","catch","token","disposableStack","use","_dispatchLogout","_operationSpan","router","Configuration","RouterUnavailable","navigate","url","parse","_createLoginRedirectUrl","postAuthRedirectUri","intent","AuthRedirect","mode","External","complete","payload","undefined","requestStream","responseStream","createCommandExtra","previous","previousValue","Reloading","Resolved","Error","loadingSnapshot","Load","_emitSessionEvent","type","SessionRefreshStarted","session","_fetchSessionInfo","Resolve","setTraceAttributes","authenticated","SessionRefreshSucceeded","clientError","Fail","SessionRefreshFailed","SessionLogoutStarted","_readCurrentSession","response","transport","execute","_createLogoutUrl","method","headers","body","JSON","stringify","fromHttpResponse","SessionLogoutSucceeded","SessionLogoutFailed","base","params","URLSearchParams","toString","snapshot","input","next","at","time","now","INJECTOR_TOKEN","SessionContextClient","SESSION_CONTEXT_CLIENT","SESSION_CONTEXT_CLIENT_CONFIG","provideSessionContext","options","provide","useValue","config","useFactory","injector","fromInjector","deps"],"sources":["../src/error.ts","../src/contracts/schemas.ts","../src/contracts/parsers.ts","../src/tokens.ts","../src/types.ts","../src/client.ts","../src/providers.ts"],"sourcesContent":["import { ClientError, type SpanTrait } from \"@securitydept/client\";\n\nexport const SessionContextErrorCode = {\n\tOperationFailed: \"session.operation_failed\",\n\tClientDisposed: \"session.client_disposed\",\n\tRouterUnavailable: \"session.router_unavailable\",\n\tInvalidSessionPayload: \"session.invalid_user_info_payload\",\n} as const;\n\nexport type SessionContextErrorCode =\n\t(typeof SessionContextErrorCode)[keyof typeof SessionContextErrorCode];\n\nexport const SessionContextSource = {\n\tSessionContext: \"session-context\",\n} as const;\n\nexport type SessionContextSource =\n\t(typeof SessionContextSource)[keyof typeof SessionContextSource];\n\nexport function clientErrorFromSessionError(\n\terror: unknown,\n\toptions: { span: SpanTrait | undefined },\n): ClientError {\n\treturn ClientError.fromUnknown(error, {\n\t\tcode: SessionContextErrorCode.OperationFailed,\n\t\tmessage: \"The session operation failed unexpectedly\",\n\t\tsource: SessionContextSource.SessionContext,\n\t\tspan: options.span,\n\t});\n}\n","import {\n\tIdentityPrincipalSchema,\n\tIdentityPrincipalWireSchema,\n} from \"@securitydept/client\";\nimport { type as defineType } from \"arktype\";\nimport { type SessionInfo } from \"../types\";\n\nexport const SessionInfoSchema = defineType({\n\tprincipal: IdentityPrincipalSchema,\n\t\"attributes?\": \"object\",\n\t\"extra?\": \"object\",\n}).pipe(\n\t(input): SessionInfo => ({\n\t\tprincipal: input.principal,\n\t\tattributes: input.attributes as Record<string, unknown> | undefined,\n\t\textra: input.extra as Record<string, unknown> | undefined,\n\t}),\n);\n\nexport const SessionUserInfoResponseSchema = IdentityPrincipalWireSchema.pipe(\n\t(principal): SessionInfo => ({ principal }),\n);\n","import {\n\tClientError,\n\tClientErrorKind,\n\tformatValidationFailure,\n\tvalidateWithSchemaSync,\n} from \"@securitydept/client\";\nimport { SessionContextErrorCode, SessionContextSource } from \"../error\";\nimport { type SessionInfo } from \"../types\";\nimport { SessionInfoSchema, SessionUserInfoResponseSchema } from \"./schemas\";\n\nexport function parseSessionInfoPayload(body: unknown): SessionInfo {\n\tconst infoResult = validateWithSchemaSync(SessionInfoSchema, body);\n\tif (infoResult.success) {\n\t\treturn infoResult.value;\n\t}\n\n\tconst userInfoResult = validateWithSchemaSync(\n\t\tSessionUserInfoResponseSchema,\n\t\tbody,\n\t);\n\tif (userInfoResult.success) {\n\t\treturn userInfoResult.value;\n\t}\n\n\tconst failure = {\n\t\tsuccess: false as const,\n\t\tissues: [...infoResult.issues, ...userInfoResult.issues],\n\t};\n\tconst issueSummary = formatValidationFailure(failure);\n\tthrow new ClientError({\n\t\tkind: ClientErrorKind.Protocol,\n\t\tcode: SessionContextErrorCode.InvalidSessionPayload,\n\t\tmessage: issueSummary\n\t\t\t? `Session /user-info payload is invalid: ${issueSummary}.`\n\t\t\t: \"Session /user-info payload is invalid.\",\n\t\tsource: SessionContextSource.SessionContext,\n\t\tcause: failure.issues,\n\t});\n}\n","import { SecuritydeptInjectionToken } from \"@securitydept/client\";\nimport { type SessionContextClient } from \"./client\";\nimport { type SessionContextClientConfig } from \"./types\";\n\nexport const SESSION_CONTEXT_CLIENT =\n\tnew SecuritydeptInjectionToken<SessionContextClient>(\n\t\t\"SESSION_CONTEXT_CLIENT\",\n\t);\n\nexport const SESSION_CONTEXT_CLIENT_CONFIG =\n\tnew SecuritydeptInjectionToken<SessionContextClientConfig>(\n\t\t\"SESSION_CONTEXT_CLIENT_CONFIG\",\n\t);\n","import {\n\ttype CancellationTokenOptions,\n\ttype ClientError,\n\ttype IdentityPrincipal,\n} from \"@securitydept/client\";\n\n// --- Session Context Client types ---\n\n/** Session principal — shared authenticated principal semantics via @securitydept/client. */\nexport type SessionPrincipal = IdentityPrincipal;\n\n/** Session info returned from the server. */\nexport interface SessionInfo {\n\tprincipal: SessionPrincipal;\n\tattributes?: Record<string, unknown>;\n\textra?: Record<string, unknown>;\n}\n\nexport interface SessionContextClientTracingOptions {\n\ttarget?: string;\n\tprefix?: string;\n}\n\nexport interface SessionContextOperationOptions\n\textends CancellationTokenOptions {}\n\nexport interface SessionLoginWithRedirectOptions\n\textends CancellationTokenOptions {\n\tpostAuthRedirectUri?: string;\n}\n\n/** Configuration for the Session Context Client. */\nexport interface SessionContextClientConfig {\n\tid?: string;\n\t/** Base URL of the SecurityDept server. */\n\tbaseUrl: string;\n\t/** Login path (default: \"/auth/session/login\"). */\n\tloginPath?: string;\n\t/** Logout path (default: \"/auth/session/logout\"). */\n\tlogoutPath?: string;\n\t/** User info endpoint path (default: \"/auth/session/user-info\"). */\n\tuserInfoPath?: string;\n\tautoStart?: boolean;\n\ttracing?: SessionContextClientTracingOptions;\n}\n\nexport interface ResolvedSessionContextClientConfig {\n\tid: string;\n\tbaseUrl: string;\n\tloginPath: string;\n\tlogoutPath: string;\n\tuserInfoPath: string;\n\ttracing: Required<SessionContextClientTracingOptions>;\n}\n\nexport const SessionContextEventType = {\n\tSessionRefreshStarted: \"session.refresh.started\",\n\tSessionRefreshSucceeded: \"session.refresh.succeeded\",\n\tSessionRefreshFailed: \"session.refresh.failed\",\n\tSessionLogoutStarted: \"session.logout.started\",\n\tSessionLogoutSucceeded: \"session.logout.succeeded\",\n\tSessionLogoutFailed: \"session.logout.failed\",\n} as const;\n\nexport type SessionContextEventType =\n\t(typeof SessionContextEventType)[keyof typeof SessionContextEventType];\n\ninterface SessionContextEventBase {\n\treadonly at: number;\n\treadonly client: {\n\t\treadonly id: string;\n\t};\n}\n\ntype SessionContextEventData =\n\t| {\n\t\t\treadonly type: typeof SessionContextEventType.SessionRefreshStarted;\n\t\t\treadonly session: SessionInfo | null;\n\t }\n\t| {\n\t\t\treadonly type: typeof SessionContextEventType.SessionRefreshSucceeded;\n\t\t\treadonly session: SessionInfo | null;\n\t }\n\t| {\n\t\t\treadonly type: typeof SessionContextEventType.SessionRefreshFailed;\n\t\t\treadonly session: SessionInfo | null;\n\t\t\treadonly error: ClientError;\n\t }\n\t| {\n\t\t\treadonly type: typeof SessionContextEventType.SessionLogoutStarted;\n\t\t\treadonly session: SessionInfo | null;\n\t }\n\t| {\n\t\t\treadonly type: typeof SessionContextEventType.SessionLogoutSucceeded;\n\t\t\treadonly session: null;\n\t }\n\t| {\n\t\t\treadonly type: typeof SessionContextEventType.SessionLogoutFailed;\n\t\t\treadonly session: SessionInfo | null;\n\t\t\treadonly error: ClientError;\n\t };\n\nexport type SessionContextEvent = SessionContextEventBase &\n\tSessionContextEventData;\n\nexport type SessionContextEventInput = SessionContextEventData;\n","import {\n\ttype CancellationTokenSourceTrait,\n\ttype CancellationTokenTrait,\n\tClientError,\n\tClientErrorKind,\n\tcreateCancellationTokenSource,\n\tcreateLinkedCancellationToken,\n\tcreateOnceAsyncLockCallable,\n\tcreateSignal,\n\ttype DisposableTrait,\n\tdefineInstrumentMethodDecorator,\n\tENVIRONMENT_TOKEN,\n\ttype EventStreamTrait,\n\ttype FoundationEnvironment,\n\tinjectDisposableStackFrom,\n\tmapResource,\n\ttype OperationSpanTrait,\n\ttype ReadableSignalTrait,\n\ttype ResourceSnapshot,\n\tResourceSnapshotUpdateKind,\n\tResourceStatus,\n\ttype ResourceTrait,\n\tRouterNavigationIntent,\n\tRouterNavigationMode,\n\treadonlySignal,\n\treduceResourceSnapshot,\n\tresourceFromSnapshots,\n\tSecuritydeptDestroyRef,\n\ttype SecuritydeptInjectorTrait,\n\tSpanSharedAttributeName,\n\ttype SpanTrait,\n\tSYMBOL_DISPOSE,\n\tUriReferenceString,\n\ttype WritableSignalTrait,\n\twithDisposableStack,\n} from \"@securitydept/client\";\nimport {\n\ttype Command,\n\ttype CommandResponse,\n\tcommandResponseData,\n\tconcatCommand,\n\tdispatchCommandLocallyToStream,\n\tRxEventSubject,\n\tRxStateSignal,\n} from \"@securitydept/client/rx\";\nimport { filter, from, lastValueFrom, take, takeUntil } from \"rxjs\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport { parseSessionInfoPayload } from \"./contracts/parsers\";\nimport {\n\tclientErrorFromSessionError,\n\tSessionContextErrorCode,\n\tSessionContextSource,\n} from \"./error\";\nimport { SESSION_CONTEXT_CLIENT_CONFIG } from \"./tokens\";\nimport {\n\ttype ResolvedSessionContextClientConfig,\n\ttype SessionContextClientConfig,\n\ttype SessionContextEvent,\n\ttype SessionContextEventInput,\n\tSessionContextEventType,\n\ttype SessionContextOperationOptions,\n\ttype SessionInfo,\n\ttype SessionLoginWithRedirectOptions,\n} from \"./types\";\n\ninterface SessionContextOperationSignals {\n\treadonly startPending: ReadableSignalTrait<boolean>;\n\treadonly refreshPending: ReadableSignalTrait<boolean>;\n\treadonly logoutPending: ReadableSignalTrait<boolean>;\n\treadonly loginRedirectPending: ReadableSignalTrait<boolean>;\n}\n\ninterface SessionCommandExtra {\n\tcancellationToken: CancellationTokenTrait;\n\toperationSpan?: OperationSpanTrait;\n}\n\ntype SessionRefreshCommand = Command<void, SessionCommandExtra>;\ntype SessionLogoutCommand = Command<void, SessionCommandExtra>;\n\nconst POST_AUTH_REDIRECT_PARAM = \"post_auth_redirect_uri\";\n\nconst instrumentSessionMethod = defineInstrumentMethodDecorator<\n\t[operation: string],\n\tSessionContextClient\n>(\n\t({ factoryArgs: [operation] }) =>\n\t\tfunction (this: SessionContextClient) {\n\t\t\treturn {\n\t\t\t\tenvironment: this.environment,\n\t\t\t\tspan: this.span,\n\t\t\t\tname: `${this.config.tracing.prefix}.${operation}`,\n\t\t\t\ttarget: this.config.tracing.target,\n\t\t\t\ttraceAttributes: { operation },\n\t\t\t\tclientErrorFromUnknown: (error, options) =>\n\t\t\t\t\tclientErrorFromSessionError(error, options),\n\t\t\t};\n\t\t},\n);\n\n/**\n * Session Context Client.\n *\n * Owns session state, lifecycle, login/logout navigation, and tracing.\n * Host capabilities are resolved once through FoundationEnvironment at\n * construction time.\n */\nexport class SessionContextClient implements DisposableTrait {\n\tstatic defaultOptions = {\n\t\tloginPath: \"/auth/session/login\",\n\t\tlogoutPath: \"/auth/session/logout\",\n\t\tuserInfoPath: \"/auth/session/user-info\",\n\t\ttracing: {\n\t\t\ttarget: \"session-context-client\",\n\t\t\tprefix: \"session_context\",\n\t\t},\n\t} as const;\n\n\tprivate readonly _environment: FoundationEnvironment;\n\tprivate readonly _config: ResolvedSessionContextClientConfig;\n\tprivate readonly _span: SpanTrait;\n\tprivate readonly _rootCancellation: CancellationTokenSourceTrait =\n\t\tcreateCancellationTokenSource();\n\tprivate readonly _destroyed = RxStateSignal.fromInitialValue(false);\n\tprivate readonly destroyed$ = from(this._destroyed).pipe(\n\t\tfilter((value): value is true => value),\n\t\ttake(1),\n\t);\n\tprivate readonly _sessionSnapshotSignal = RxStateSignal.fromInitialValue<\n\t\tResourceSnapshot<SessionInfo | null>\n\t>({ status: ResourceStatus.Idle });\n\tprivate readonly _operationSignals: {\n\t\treadonly startPending: WritableSignalTrait<boolean>;\n\t\treadonly refreshPending: WritableSignalTrait<boolean>;\n\t\treadonly logoutPending: WritableSignalTrait<boolean>;\n\t\treadonly loginRedirectPending: WritableSignalTrait<boolean>;\n\t} = {\n\t\tstartPending: createSignal(false),\n\t\trefreshPending: createSignal(false),\n\t\tlogoutPending: createSignal(false),\n\t\tloginRedirectPending: createSignal(false),\n\t};\n\tprivate readonly _eventSubject = new RxEventSubject<SessionContextEvent>();\n\tprivate readonly _refreshCommandSubject =\n\t\tnew RxEventSubject<SessionRefreshCommand>();\n\tprivate readonly _refreshResponseSubject = new RxEventSubject<\n\t\tCommandResponse<SessionRefreshCommand, SessionInfo | null>\n\t>();\n\tprivate readonly _logoutCommandSubject =\n\t\tnew RxEventSubject<SessionLogoutCommand>();\n\tprivate readonly _logoutResponseSubject = new RxEventSubject<\n\t\tCommandResponse<SessionLogoutCommand, void>\n\t>();\n\tprivate readonly _startOnce = createOnceAsyncLockCallable(\n\t\tasync (\n\t\t\tcancellationToken: CancellationTokenTrait,\n\t\t\toperationSpan?: OperationSpanTrait,\n\t\t) => {\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t\tthis._operationSignals.startPending.set(true);\n\t\t\ttry {\n\t\t\t\treturn await this._dispatchRefresh(cancellationToken, operationSpan);\n\t\t\t} finally {\n\t\t\t\tthis._operationSignals.startPending.set(false);\n\t\t\t}\n\t\t},\n\t);\n\n\treadonly id: string;\n\treadonly sessionSnapshot: ReadableSignalTrait<\n\t\tResourceSnapshot<SessionInfo | null>\n\t>;\n\treadonly sessionResource: ResourceTrait<SessionInfo | null>;\n\treadonly isAuthenticated: ResourceTrait<boolean>;\n\treadonly sessionOperations: SessionContextOperationSignals;\n\treadonly events: EventStreamTrait<SessionContextEvent>;\n\n\tprotected get environment(): FoundationEnvironment {\n\t\treturn this._environment;\n\t}\n\n\tprotected get span(): SpanTrait {\n\t\treturn this._span;\n\t}\n\n\tprotected get config(): ResolvedSessionContextClientConfig {\n\t\treturn this._config;\n\t}\n\n\tstatic fromEnvironmentConfig(options: {\n\t\treadonly config: SessionContextClientConfig;\n\t\treadonly environment: FoundationEnvironment;\n\t}): SessionContextClient {\n\t\treturn new SessionContextClient(options.config, options.environment);\n\t}\n\n\tstatic fromInjector(\n\t\tinjector: SecuritydeptInjectorTrait,\n\t): SessionContextClient {\n\t\tconst client = SessionContextClient.fromEnvironmentConfig({\n\t\t\tconfig: injector.get(SESSION_CONTEXT_CLIENT_CONFIG),\n\t\t\tenvironment: injector.get(ENVIRONMENT_TOKEN),\n\t\t});\n\t\tinjector\n\t\t\t.get(SecuritydeptDestroyRef, null)\n\t\t\t?.onDestroy(() => client.dispose());\n\t\treturn client;\n\t}\n\n\tprotected constructor(\n\t\tconfig: SessionContextClientConfig,\n\t\tenvironment: FoundationEnvironment,\n\t) {\n\t\tthis._environment = environment;\n\t\tconst baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n\t\tthis._config = {\n\t\t\tid: config.id ?? uuidv7(),\n\t\t\tbaseUrl,\n\t\t\tloginPath:\n\t\t\t\tconfig.loginPath ?? SessionContextClient.defaultOptions.loginPath,\n\t\t\tlogoutPath:\n\t\t\t\tconfig.logoutPath ?? SessionContextClient.defaultOptions.logoutPath,\n\t\t\tuserInfoPath:\n\t\t\t\tconfig.userInfoPath ?? SessionContextClient.defaultOptions.userInfoPath,\n\t\t\ttracing: {\n\t\t\t\ttarget:\n\t\t\t\t\tconfig.tracing?.target ??\n\t\t\t\t\tSessionContextClient.defaultOptions.tracing.target,\n\t\t\t\tprefix:\n\t\t\t\t\tconfig.tracing?.prefix ??\n\t\t\t\t\tSessionContextClient.defaultOptions.tracing.prefix,\n\t\t\t},\n\t\t};\n\t\tthis.id = this._config.id;\n\t\tthis._span = environment.span.fork({\n\t\t\tattributes: {\n\t\t\t\t[SpanSharedAttributeName.ClientName]: this.constructor.name,\n\t\t\t\t[SpanSharedAttributeName.ClientId]: this.id,\n\t\t\t},\n\t\t});\n\t\tthis.sessionSnapshot = readonlySignal(this._sessionSnapshotSignal);\n\t\tthis.sessionResource = resourceFromSnapshots(() =>\n\t\t\tthis._sessionSnapshotSignal.get(),\n\t\t);\n\t\tthis.isAuthenticated = mapResource(\n\t\t\tthis.sessionResource,\n\t\t\t(sessionInfo) => sessionInfo !== null,\n\t\t);\n\t\tthis.sessionOperations = {\n\t\t\tstartPending: readonlySignal(this._operationSignals.startPending),\n\t\t\trefreshPending: readonlySignal(this._operationSignals.refreshPending),\n\t\t\tlogoutPending: readonlySignal(this._operationSignals.logoutPending),\n\t\t\tloginRedirectPending: readonlySignal(\n\t\t\t\tthis._operationSignals.loginRedirectPending,\n\t\t\t),\n\t\t};\n\t\tthis.events = this._eventSubject;\n\t\tthis.destroyed$.subscribe(() => {\n\t\t\tthis._rootCancellation.cancel(\n\t\t\t\tnew ClientError({\n\t\t\t\t\tkind: ClientErrorKind.Cancelled,\n\t\t\t\t\tcode: SessionContextErrorCode.ClientDisposed,\n\t\t\t\t\tmessage: \"SessionContextClient has been disposed.\",\n\t\t\t\t\tsource: SessionContextSource.SessionContext,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis.isAuthenticated.dispose();\n\t\t\tthis.sessionResource.dispose();\n\t\t});\n\n\t\tfrom(this._refreshCommandSubject)\n\t\t\t.pipe(\n\t\t\t\ttakeUntil(this.destroyed$),\n\t\t\t\tconcatCommand((command) =>\n\t\t\t\t\tthis._executeRefresh(\n\t\t\t\t\t\tcommand.cancellationToken,\n\t\t\t\t\t\tcommand.operationSpan,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.subscribe(this._refreshResponseSubject);\n\n\t\tfrom(this._logoutCommandSubject)\n\t\t\t.pipe(\n\t\t\t\ttakeUntil(this.destroyed$),\n\t\t\t\tconcatCommand((command) =>\n\t\t\t\t\tthis._executeLogout(command.cancellationToken, command.operationSpan),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.subscribe(this._logoutResponseSubject);\n\n\t\tif (config.autoStart === true) {\n\t\t\tthis.start().catch(() => {\n\t\t\t\t// Startup failure is reflected by sessionSnapshot.\n\t\t\t});\n\t\t}\n\t}\n\n\t@instrumentSessionMethod(\"start\")\n\tasync start(operationSpan?: OperationSpanTrait): Promise<SessionInfo | null> {\n\t\tconst cancellationToken = this._rootCancellation.token;\n\t\treturn await this._startOnce(cancellationToken, operationSpan);\n\t}\n\n\t@withDisposableStack(0, true)\n\tasync refresh(\n\t\toptions: SessionContextOperationOptions = {},\n\t): Promise<SessionInfo | null> {\n\t\tconst disposableStack = injectDisposableStackFrom(options, true);\n\t\tconst cancellationToken = createLinkedCancellationToken(\n\t\t\tthis._rootCancellation.token,\n\t\t\toptions.cancellationToken,\n\t\t);\n\t\tdisposableStack?.use(cancellationToken);\n\t\treturn await this._refresh(cancellationToken);\n\t}\n\n\t@instrumentSessionMethod(\"refresh\")\n\tprivate async _refresh(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\treturn await this._dispatchRefresh(cancellationToken, operationSpan);\n\t}\n\n\t@withDisposableStack(0, true)\n\tasync logout(options: SessionContextOperationOptions = {}): Promise<void> {\n\t\tconst disposableStack = injectDisposableStackFrom(options, true);\n\t\tconst cancellationToken = createLinkedCancellationToken(\n\t\t\tthis._rootCancellation.token,\n\t\t\toptions.cancellationToken,\n\t\t);\n\t\tdisposableStack?.use(cancellationToken);\n\t\tawait this._logout(cancellationToken);\n\t}\n\n\t@instrumentSessionMethod(\"logout\")\n\tprivate async _logout(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tawait this._dispatchLogout(cancellationToken, operationSpan);\n\t}\n\n\t@withDisposableStack(0, true)\n\tasync loginWithRedirect(\n\t\toptions: SessionLoginWithRedirectOptions = {},\n\t): Promise<void> {\n\t\tconst disposableStack = injectDisposableStackFrom(options, true);\n\t\tconst cancellationToken = createLinkedCancellationToken(\n\t\t\tthis._rootCancellation.token,\n\t\t\toptions.cancellationToken,\n\t\t);\n\t\tdisposableStack?.use(cancellationToken);\n\t\tawait this._loginWithRedirect(options, cancellationToken);\n\t}\n\n\t@instrumentSessionMethod(\"login.redirect\")\n\tprivate async _loginWithRedirect(\n\t\toptions: SessionLoginWithRedirectOptions,\n\t\tcancellationToken: CancellationTokenTrait,\n\t\t_operationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tconst router = this._environment.router;\n\t\tif (!router) {\n\t\t\tthrow new ClientError({\n\t\t\t\tkind: ClientErrorKind.Configuration,\n\t\t\t\tcode: SessionContextErrorCode.RouterUnavailable,\n\t\t\t\tmessage: \"loginWithRedirect() requires environment.router.\",\n\t\t\t\tsource: SessionContextSource.SessionContext,\n\t\t\t});\n\t\t}\n\t\tthis._operationSignals.loginRedirectPending.set(true);\n\t\ttry {\n\t\t\tawait router.navigate({\n\t\t\t\turl: UriReferenceString.parse(\n\t\t\t\t\tthis._createLoginRedirectUrl(options.postAuthRedirectUri),\n\t\t\t\t),\n\t\t\t\tintent: RouterNavigationIntent.AuthRedirect,\n\t\t\t\tmode: RouterNavigationMode.External,\n\t\t\t});\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t} finally {\n\t\t\tthis._operationSignals.loginRedirectPending.set(false);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis._destroyed.set(true);\n\t\tthis._eventSubject.complete();\n\t}\n\n\t[SYMBOL_DISPOSE](): void {\n\t\tthis.dispose();\n\t}\n\n\tprivate async _dispatchRefresh(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tconst sessionInfo = await lastValueFrom(\n\t\t\tdispatchCommandLocallyToStream<\n\t\t\t\tvoid,\n\t\t\t\tSessionCommandExtra,\n\t\t\t\tSessionInfo | null,\n\t\t\t\tSessionRefreshCommand\n\t\t\t>({\n\t\t\t\tpayload: undefined,\n\t\t\t\trequestStream: this._refreshCommandSubject,\n\t\t\t\tresponseStream: this._refreshResponseSubject,\n\t\t\t\tcreateCommandExtra: () => ({ cancellationToken, operationSpan }),\n\t\t\t}).pipe(commandResponseData()),\n\t\t);\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\treturn sessionInfo;\n\t}\n\n\tprivate async _dispatchLogout(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tawait lastValueFrom(\n\t\t\tdispatchCommandLocallyToStream<\n\t\t\t\tvoid,\n\t\t\t\tSessionCommandExtra,\n\t\t\t\tvoid,\n\t\t\t\tSessionLogoutCommand\n\t\t\t>({\n\t\t\t\tpayload: undefined,\n\t\t\t\trequestStream: this._logoutCommandSubject,\n\t\t\t\tresponseStream: this._logoutResponseSubject,\n\t\t\t\tcreateCommandExtra: () => ({ cancellationToken, operationSpan }),\n\t\t\t}).pipe(commandResponseData()),\n\t\t);\n\t\tcancellationToken.throwIfCancellationRequested();\n\t}\n\n\tprivate async _executeRefresh(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tthis._operationSignals.refreshPending.set(true);\n\t\tconst previous = this._sessionSnapshotSignal.get();\n\t\tconst previousValue =\n\t\t\tprevious.status === ResourceStatus.Reloading ||\n\t\t\tprevious.status === ResourceStatus.Resolved ||\n\t\t\tprevious.status === ResourceStatus.Error\n\t\t\t\t? previous.value\n\t\t\t\t: null;\n\t\tconst loadingSnapshot = reduceResourceSnapshot(previous, {\n\t\t\tkind: ResourceSnapshotUpdateKind.Load,\n\t\t});\n\t\tthis._sessionSnapshotSignal.set(loadingSnapshot);\n\t\tthis._emitSessionEvent({\n\t\t\ttype: SessionContextEventType.SessionRefreshStarted,\n\t\t\tsession: previousValue,\n\t\t});\n\t\ttry {\n\t\t\tconst sessionInfo = await this._fetchSessionInfo(cancellationToken);\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Resolve,\n\t\t\t\t\tvalue: sessionInfo,\n\t\t\t\t}),\n\t\t\t);\n\t\t\toperationSpan?.setTraceAttributes({\n\t\t\t\tauthenticated: sessionInfo !== null,\n\t\t\t});\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionRefreshSucceeded,\n\t\t\t\tsession: sessionInfo,\n\t\t\t});\n\t\t\treturn sessionInfo;\n\t\t} catch (error) {\n\t\t\tconst clientError = clientErrorFromSessionError(error, {\n\t\t\t\tspan: operationSpan?.span,\n\t\t\t});\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Fail,\n\t\t\t\t\terror: clientError,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionRefreshFailed,\n\t\t\t\tsession: previousValue,\n\t\t\t\terror: clientError,\n\t\t\t});\n\t\t\tthrow clientError;\n\t\t} finally {\n\t\t\tthis._operationSignals.refreshPending.set(false);\n\t\t}\n\t}\n\n\tprivate async _executeLogout(\n\t\tcancellationToken: CancellationTokenTrait,\n\t\toperationSpan?: OperationSpanTrait,\n\t): Promise<void> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tthis._operationSignals.logoutPending.set(true);\n\t\tconst previous = this._sessionSnapshotSignal.get();\n\t\tconst loadingSnapshot = reduceResourceSnapshot(previous, {\n\t\t\tkind: ResourceSnapshotUpdateKind.Load,\n\t\t});\n\t\tthis._sessionSnapshotSignal.set(loadingSnapshot);\n\t\tthis._emitSessionEvent({\n\t\t\ttype: SessionContextEventType.SessionLogoutStarted,\n\t\t\tsession: this._readCurrentSession(),\n\t\t});\n\t\ttry {\n\t\t\tconst response = await this._environment.transport.execute({\n\t\t\t\turl: this._createLogoutUrl(),\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({}),\n\t\t\t\tcancellationToken,\n\t\t\t});\n\n\t\t\tif (response.status < 200 || response.status >= 300) {\n\t\t\t\tthrow ClientError.fromHttpResponse({\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\tbody: response.body,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tcancellationToken.throwIfCancellationRequested();\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Resolve,\n\t\t\t\t\tvalue: null,\n\t\t\t\t}),\n\t\t\t);\n\t\t\toperationSpan?.setTraceAttributes({ authenticated: false });\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionLogoutSucceeded,\n\t\t\t\tsession: null,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconst clientError = clientErrorFromSessionError(error, {\n\t\t\t\tspan: operationSpan?.span,\n\t\t\t});\n\t\t\tthis._sessionSnapshotSignal.set(\n\t\t\t\treduceResourceSnapshot(loadingSnapshot, {\n\t\t\t\t\tkind: ResourceSnapshotUpdateKind.Fail,\n\t\t\t\t\terror: clientError,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis._emitSessionEvent({\n\t\t\t\ttype: SessionContextEventType.SessionLogoutFailed,\n\t\t\t\tsession: this._readCurrentSession(),\n\t\t\t\terror: clientError,\n\t\t\t});\n\t\t\tthrow clientError;\n\t\t} finally {\n\t\t\tthis._operationSignals.logoutPending.set(false);\n\t\t}\n\t}\n\n\tprivate async _fetchSessionInfo(\n\t\tcancellationToken: CancellationTokenTrait,\n\t): Promise<SessionInfo | null> {\n\t\tcancellationToken.throwIfCancellationRequested();\n\t\tconst response = await this._environment.transport.execute({\n\t\t\turl: this._config.baseUrl + this._config.userInfoPath,\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {},\n\t\t\tcancellationToken,\n\t\t});\n\t\tcancellationToken.throwIfCancellationRequested();\n\n\t\tif (response.status === 401 || response.status === 403) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (response.status >= 200 && response.status < 300) {\n\t\t\treturn parseSessionInfoPayload(response.body);\n\t\t}\n\n\t\tthrow ClientError.fromHttpResponse({\n\t\t\tstatus: response.status,\n\t\t\tbody: response.body,\n\t\t});\n\t}\n\n\tprivate _createLoginRedirectUrl(postAuthRedirectUri?: string): string {\n\t\tconst base = this._config.baseUrl + this._config.loginPath;\n\t\tif (postAuthRedirectUri) {\n\t\t\tconst params = new URLSearchParams({\n\t\t\t\t[POST_AUTH_REDIRECT_PARAM]: postAuthRedirectUri,\n\t\t\t});\n\t\t\treturn `${base}?${params.toString()}`;\n\t\t}\n\t\treturn base;\n\t}\n\n\tprivate _createLogoutUrl(): string {\n\t\treturn this._config.baseUrl + this._config.logoutPath;\n\t}\n\n\tprivate _readCurrentSession(): SessionInfo | null {\n\t\tconst snapshot = this._sessionSnapshotSignal.get();\n\t\treturn snapshot.status === ResourceStatus.Reloading ||\n\t\t\tsnapshot.status === ResourceStatus.Resolved ||\n\t\t\tsnapshot.status === ResourceStatus.Error\n\t\t\t? snapshot.value\n\t\t\t: null;\n\t}\n\n\tprivate _emitSessionEvent(input: SessionContextEventInput): void {\n\t\tthis._eventSubject.next({\n\t\t\t...input,\n\t\t\tat: this._environment.time.now(),\n\t\t\tclient: {\n\t\t\t\tid: this.id,\n\t\t\t},\n\t\t});\n\t}\n}\n","import {\n\tINJECTOR_TOKEN,\n\ttype SecuritydeptInjectorTrait,\n\ttype SecuritydeptProvider,\n} from \"@securitydept/client\";\nimport { SessionContextClient } from \"./client\";\nimport {\n\tSESSION_CONTEXT_CLIENT,\n\tSESSION_CONTEXT_CLIENT_CONFIG,\n} from \"./tokens\";\nimport { type SessionContextClientConfig } from \"./types\";\n\nexport interface ProvideSessionContextOptions {\n\treadonly config: SessionContextClientConfig;\n}\n\nexport function provideSessionContext(\n\toptions: ProvideSessionContextOptions,\n): readonly SecuritydeptProvider[] {\n\treturn [\n\t\t{\n\t\t\tprovide: SESSION_CONTEXT_CLIENT_CONFIG,\n\t\t\tuseValue: options.config,\n\t\t},\n\t\t{\n\t\t\tprovide: SESSION_CONTEXT_CLIENT,\n\t\t\tuseFactory: (injector: SecuritydeptInjectorTrait) =>\n\t\t\t\tSessionContextClient.fromInjector(injector),\n\t\t\tdeps: [INJECTOR_TOKEN],\n\t\t},\n\t];\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@securitydept/session-context-client",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.7",
|
|
4
4
|
"description": "Session Context Client of the SecurityDept TypeScript SDK, a layered authentication and authorization toolkit built as reusable Rust crates, a TypeScript client SDK workspace, and reference server/web apps.",
|
|
5
5
|
"author": "Zhou Yeheng <root@aitiotekt.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"dist"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"arktype": "^2.2.
|
|
40
|
+
"arktype": "^2.2.3",
|
|
41
41
|
"rxjs": "^7.8.2",
|
|
42
42
|
"uuid": "^14.0.1",
|
|
43
|
-
"@securitydept/client": "0.3.0-beta.
|
|
43
|
+
"@securitydept/client": "0.3.0-beta.7"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"vitest": "^4.1.
|
|
46
|
+
"vitest": "^4.1.10"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsdown",
|