@corbado/autocapture 0.1.0-next.2-dd9eb36 → 0.1.0-next.3-b8e8889

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 CHANGED
@@ -37,15 +37,10 @@ Every observer follows the platform observer pattern (`MutationObserver`, `Resiz
37
37
  it with a callback, receive events, and call `disconnect()` when finished.
38
38
 
39
39
  ```ts
40
- import {
41
- captureWebAuthn,
42
- captureNetwork,
43
- captureNavigation,
44
- captureShadowRoots,
45
- } from "@corbado/autocapture";
40
+ import { captureWebAuthn, captureNetwork, captureNavigation, captureShadowRoots } from "@corbado/autocapture";
46
41
 
47
42
  const webauthn = captureWebAuthn({
48
- onEvent: (event) => console.log(event.kind, event.phase, event.ceremonyId),
43
+ onEvent: (event) => console.log(event.kind, event.mediation, event.phase, event.ceremonyId),
49
44
  });
50
45
 
51
46
  const network = captureNetwork({
@@ -85,6 +80,13 @@ throwing; a misconfigured `captureNetwork` call (missing `match` or `onExchange`
85
80
  `TypeError` instead, since that is a programming error, not a degraded environment. Full event and
86
81
  option types ship with the package.
87
82
 
83
+ WebAuthn events use a protocol-native discriminated union. Authentication phases carry normalized
84
+ `mediation`, `uiMode`, and `credentialSet` (`"allowlisted"` or `"discoverable"`); registration
85
+ phases carry normalized `mediation`. The same profile is present on every phase of one ceremony.
86
+ Autocapture deliberately does not infer product concepts such as conditional-UI spec types,
87
+ known-identifier state, enrollment intent, or the user/system actor. Integrations map those facts in
88
+ their own state context.
89
+
88
90
  ## Safety invariants
89
91
 
90
92
  The observers run inside application call paths, so their behaviour is defined by what they promise
@@ -130,13 +132,12 @@ Network observation is designed for minimal data exposure:
130
132
  only on `onExchange`; string bodies passed through `RequestInit` are available synchronously.
131
133
  - Autocapture performs no generic body parsing or redaction. The endpoint-specific projector is the
132
134
  privacy boundary: it receives the matched raw body and must return only the fields the consumer is
133
- allowed to observe. Only that projected value is attached to the exchange. Projector failures,
134
- promises, `undefined`, oversized output, and non-JSON output fail closed by omitting the body.
135
- - Projected outputs are size-bounded (`maxBodyChars`, on the JSON-serialized projection); raw bodies
136
- are not size-checked, since matched traffic is first-party. Readable bodies come from isolated
137
- clones read within a 500 ms window; the source body is never directly consumed, and streaming and
138
- binary payloads are never read. Body cloning still has inherent stream tee/backpressure costs, so
139
- enabling it is a security and performance decision.
135
+ allowed to observe. The exact projected value is attached to the exchange without generic
136
+ serialization, cloning, or size limiting. Projector failures, promises, and `undefined` fail closed
137
+ by omitting the body.
138
+ - Readable bodies come from isolated clones read within a 500 ms window; the source body is never
139
+ directly consumed, and streaming and binary payloads are never read. Body cloning still has
140
+ inherent stream tee/backpressure costs, so enabling it is a security and performance decision.
140
141
 
141
142
  Network metadata currently includes the resolved full URL and final response URL. Query strings can
142
143
  contain secrets or PII; callers should restrict `match` accordingly until a URL-redaction policy is
package/dist/index.d.mts CHANGED
@@ -15,55 +15,62 @@ type CaptureHandle = {
15
15
  /** Stops future event delivery. Safe to call more than once. */
16
16
  disconnect(): void;
17
17
  };
18
- /** WebAuthn operation that initiated a ceremony. */
19
- type WebAuthnCeremonyKind = "get" | "create";
20
- /**
21
- * A lifecycle event for a WebAuthn ceremony initiated through
22
- * `navigator.credentials.get()` or `navigator.credentials.create()`.
23
- */
24
- type WebAuthnCeremonyEvent = {
25
- /** WebAuthn operation that initiated the ceremony. */
26
- kind: WebAuthnCeremonyKind;
18
+ /** Normalized Credential Management mediation. Missing mediation defaults to `optional`. */
19
+ type WebAuthnMediation = "silent" | "optional" | "conditional" | "required" | "unknown";
20
+ /** Normalized Credential Management UI mode for authentication ceremonies. */
21
+ type WebAuthnUiMode = "default" | "immediate" | "unknown";
22
+ /** Browser-native facts that remain stable for one ceremony. */
23
+ type WebAuthnCeremonyContext = {
24
+ kind: "authentication";
25
+ mediation: WebAuthnMediation;
26
+ uiMode: WebAuthnUiMode;
27
+ /** Whether the RP supplied a non-empty allow list or requested discoverable credentials. */
28
+ credentialSet: "allowlisted" | "discoverable";
29
+ } | {
30
+ kind: "registration";
31
+ mediation: WebAuthnMediation;
32
+ };
33
+ type WebAuthnCeremonyBase = WebAuthnCeremonyContext & {
27
34
  /** Identifier shared by all events belonging to the same ceremony. */
28
35
  ceremonyId: string;
29
- /** Current ceremony lifecycle phase. */
30
- phase: "started" | "completed" | "failed";
31
- /** Requested mediation mode, when available. */
32
- mediation?: string;
33
- /** Whether transient user activation was active when the ceremony started. Present on `started` events when exposed by the browser. */
34
- userActivation?: boolean;
35
- /**
36
- * JSON-encoded request metadata for a `get` ceremony: `rpId`, `timeout`,
37
- * `userVerification`, `hints`, `challenge`, and `allowCredentials`
38
- * (`type`, `id`, and `transports`). Binary values are base64url-encoded.
39
- * Unavailable fields are omitted. Present on `started` events when
40
- * serialization succeeds. Treat this value as sensitive telemetry.
41
- */
36
+ /** Authentication request metadata; present only when applicable and serializable. */
42
37
  requestOptionsJson?: string;
43
- /** Whether a `get` request included at least one allowed credential. Present on `started` events. */
44
- hasAllowCredentials?: boolean;
45
- /**
46
- * JSON-encoded, allowlisted credential returned by a completed ceremony.
47
- * Common fields are `id`, `rawId`, `type`, and `authenticatorAttachment`.
48
- * Assertion responses include `clientDataJSON`, `authenticatorData`,
49
- * `signature`, and `userHandle`; attestation responses include
50
- * `clientDataJSON`, `attestationObject`, and `transports`. Binary values are
51
- * base64url-encoded. Of the client-extension results, only `credProps.rk` may
52
- * be included. Present when serialization succeeds. Treat this value as
53
- * sensitive telemetry.
54
- */
38
+ /** Completed credential metadata; present only when applicable and serializable. */
55
39
  credentialJson?: string;
56
- /** Rejection value from a failed ceremony. This may contain application-specific data. */
40
+ /** Failure details; present only for failed ceremonies. */
57
41
  error?: unknown;
58
- /** Error name for a failed ceremony, or `UnknownError` when no DOM exception name is available. */
59
42
  errorName?: string;
43
+ /** Present when the request signal was aborted before settlement. */
44
+ aborted?: true;
45
+ };
46
+ type WebAuthnCeremonyStartedEvent = WebAuthnCeremonyBase & {
47
+ phase: "started";
48
+ /** Whether transient user activation was active when the ceremony started, when exposed by the browser. */
49
+ userActivation?: boolean;
60
50
  /**
61
- * `true` when the request signal was observed as aborted before settlement.
62
- * A credential manager may still complete such a ceremony, so this can be
63
- * present on either a `completed` or `failed` event.
51
+ * JSON-encoded request metadata for authentication: `rpId`, `timeout`,
52
+ * `userVerification`, `hints`, `challenge`, and `allowCredentials`.
53
+ * Binary values are base64url-encoded. Treat this value as sensitive telemetry.
64
54
  */
65
- aborted?: boolean;
55
+ requestOptionsJson?: string;
56
+ };
57
+ type WebAuthnCeremonyCompletedEvent = WebAuthnCeremonyBase & {
58
+ phase: "completed";
59
+ /** JSON-encoded allowlisted credential. Treat this value as sensitive telemetry. */
60
+ credentialJson?: string;
61
+ /** A credential manager may complete even after the ceremony signal was aborted. */
62
+ aborted?: true;
63
+ };
64
+ type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
65
+ phase: "failed";
66
+ /** Rejection value from the failed ceremony. This may contain application-specific data. */
67
+ error: unknown;
68
+ /** DOM exception name, or `UnknownError` when no name is available. */
69
+ errorName: string;
70
+ aborted?: true;
66
71
  };
72
+ /** A protocol-native lifecycle event for WebAuthn authentication or registration. */
73
+ type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
67
74
  /** Options for {@link captureWebAuthn}. */
68
75
  type WebAuthnCaptureOptions = {
69
76
  /** Receives WebAuthn lifecycle events. Return values are not awaited. */
@@ -73,8 +80,10 @@ type WebAuthnCaptureOptions = {
73
80
  };
74
81
  /** Network API used for an observed exchange. */
75
82
  type NetworkTransport = "xhr" | "fetch";
83
+ /** Direction of a projected body within an observed network exchange. */
84
+ type NetworkBodyDirection = "request" | "response";
76
85
  /** A matched network request immediately after the platform accepted it. */
77
- type HttpRequestStarted = {
86
+ type HttpRequestStarted<RequestBody = unknown> = {
78
87
  /** Identifier shared with the eventual {@link HttpExchange}. */
79
88
  requestId: string;
80
89
  /** Network API used for the request. */
@@ -88,10 +97,10 @@ type HttpRequestStarted = {
88
97
  /** Timestamp captured at the request boundary. */
89
98
  startedAt: number;
90
99
  /** Request-body value returned by the configured projector, when synchronously available. */
91
- requestBody?: unknown;
100
+ requestBody?: RequestBody;
92
101
  };
93
102
  /** An observed network request and its outcome. */
94
- type HttpExchange = {
103
+ type HttpExchange<RequestBody = unknown, ResponseBody = unknown> = {
95
104
  /** Identifier shared with the corresponding {@link HttpRequestStarted}. */
96
105
  requestId: string;
97
106
  /** Network API used for the request. */
@@ -122,14 +131,14 @@ type HttpExchange = {
122
131
  */
123
132
  responseUrl?: string;
124
133
  /** Request-body value returned by the configured projector, when available. */
125
- requestBody?: unknown;
134
+ requestBody?: RequestBody;
126
135
  /** Response-body value returned by the configured projector, when available. */
127
- responseBody?: unknown;
136
+ responseBody?: ResponseBody;
128
137
  };
129
138
  /** Metadata supplied to a body projector for one matched exchange. */
130
- type NetworkBodyProjectionContext = {
139
+ type NetworkBodyProjectionContext<Direction extends NetworkBodyDirection = NetworkBodyDirection> = {
131
140
  /** Whether the observed body belongs to the request or response. */
132
- direction: "request" | "response";
141
+ direction: Direction;
133
142
  /** Network API used by the application. */
134
143
  transport: NetworkTransport;
135
144
  /** Uppercase HTTP method. */
@@ -144,10 +153,14 @@ type NetworkBodyProjectionContext = {
144
153
  * Textual bodies are supplied as strings; an XHR with `responseType="json"`
145
154
  * supplies the browser-parsed value. Returning `undefined`, throwing, or
146
155
  * returning a Promise omits the body without affecting the application.
156
+ * `ProjectedBody` describes the exact value delivered to callbacks.
147
157
  */
148
- type NetworkBodyProjector = (body: unknown, context: NetworkBodyProjectionContext) => unknown;
149
- /** Options for {@link captureNetwork}. */
150
- type NetworkCaptureOptions = {
158
+ type NetworkBodyProjector<ProjectedBody = unknown, Direction extends NetworkBodyDirection = NetworkBodyDirection> = (body: unknown, context: NetworkBodyProjectionContext<Direction>) => ProjectedBody | undefined;
159
+ /**
160
+ * Options for {@link captureNetwork}. Request and response body types are
161
+ * inferred from their projectors and propagated to the corresponding callbacks.
162
+ */
163
+ type NetworkCaptureOptions<RequestBody = unknown, ResponseBody = unknown> = {
151
164
  /**
152
165
  * Selects requests to observe. The URL is resolved against the document base
153
166
  * URL and the method is uppercase. Return `true` to observe the request. The
@@ -156,12 +169,12 @@ type NetworkCaptureOptions = {
156
169
  */
157
170
  match: (url: URL, method: string) => boolean;
158
171
  /** Receives completed network exchanges. Return values are not awaited. */
159
- onExchange: (exchange: HttpExchange) => void;
172
+ onExchange: (exchange: HttpExchange<NoInfer<RequestBody>, NoInfer<ResponseBody>>) => void;
160
173
  /**
161
174
  * Receives matched requests after the platform call succeeds. The request ID
162
175
  * matches the eventual exchange. Return values are not awaited.
163
176
  */
164
- onRequest?: (request: HttpRequestStarted) => void;
177
+ onRequest?: (request: HttpRequestStarted<NoInfer<RequestBody>>) => void;
165
178
  /**
166
179
  * Network APIs to observe. Defaults to both `xhr` and `fetch`. Unavailable
167
180
  * transports are skipped if at least one requested transport can be observed.
@@ -174,19 +187,11 @@ type NetworkCaptureOptions = {
174
187
  * data minimization and its return value is the only body data reported.
175
188
  */
176
189
  bodyCapture?: {
177
- /** Projects a bounded request body. */
178
- request?: NetworkBodyProjector;
179
- /** Projects a bounded response body. */
180
- response?: NetworkBodyProjector;
190
+ /** Projects a request body. */
191
+ request?: NetworkBodyProjector<RequestBody, "request">;
192
+ /** Projects a response body. */
193
+ response?: NetworkBodyProjector<ResponseBody, "response">;
181
194
  };
182
- /**
183
- * Maximum size of a projected body attached to a request or exchange,
184
- * measured on its JSON-serialized form; larger projections are omitted.
185
- * Raw bodies are not size-checked before projection — matched traffic is
186
- * first-party and assumed well-behaved. Must be a finite, non-negative
187
- * number when provided. Defaults to 65,536.
188
- */
189
- maxBodyChars?: number;
190
195
  /** Optional diagnostic logger. */
191
196
  logger?: Logger;
192
197
  };
@@ -312,7 +317,7 @@ declare function captureWebAuthn(options: WebAuthnCaptureOptions): CaptureHandle
312
317
  * @throws TypeError when `onExchange` or `match` is not a function — a
313
318
  * misconfigured integration is a programming error, not a degraded mode.
314
319
  */
315
- declare function captureNetwork(options: NetworkCaptureOptions): CaptureHandle;
320
+ declare function captureNetwork<RequestBody = unknown, ResponseBody = unknown>(options: NetworkCaptureOptions<RequestBody, ResponseBody>): CaptureHandle;
316
321
 
317
322
  /**
318
323
  * Observes same-document navigations produced by `history.pushState()`,
@@ -375,4 +380,4 @@ declare function createConsoleLogger(prefix?: string): Logger;
375
380
  /** Version identifier embedded in the current build. */
376
381
  declare const VERSION: string;
377
382
 
378
- export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyEvent, type WebAuthnCeremonyKind, captureNavigation, captureNetwork, captureShadowRoots, captureUiState, captureWebAuthn, composedPath, composedTarget, createConsoleLogger };
383
+ export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureShadowRoots, captureUiState, captureWebAuthn, composedPath, composedTarget, createConsoleLogger };
package/dist/index.d.ts CHANGED
@@ -15,55 +15,62 @@ type CaptureHandle = {
15
15
  /** Stops future event delivery. Safe to call more than once. */
16
16
  disconnect(): void;
17
17
  };
18
- /** WebAuthn operation that initiated a ceremony. */
19
- type WebAuthnCeremonyKind = "get" | "create";
20
- /**
21
- * A lifecycle event for a WebAuthn ceremony initiated through
22
- * `navigator.credentials.get()` or `navigator.credentials.create()`.
23
- */
24
- type WebAuthnCeremonyEvent = {
25
- /** WebAuthn operation that initiated the ceremony. */
26
- kind: WebAuthnCeremonyKind;
18
+ /** Normalized Credential Management mediation. Missing mediation defaults to `optional`. */
19
+ type WebAuthnMediation = "silent" | "optional" | "conditional" | "required" | "unknown";
20
+ /** Normalized Credential Management UI mode for authentication ceremonies. */
21
+ type WebAuthnUiMode = "default" | "immediate" | "unknown";
22
+ /** Browser-native facts that remain stable for one ceremony. */
23
+ type WebAuthnCeremonyContext = {
24
+ kind: "authentication";
25
+ mediation: WebAuthnMediation;
26
+ uiMode: WebAuthnUiMode;
27
+ /** Whether the RP supplied a non-empty allow list or requested discoverable credentials. */
28
+ credentialSet: "allowlisted" | "discoverable";
29
+ } | {
30
+ kind: "registration";
31
+ mediation: WebAuthnMediation;
32
+ };
33
+ type WebAuthnCeremonyBase = WebAuthnCeremonyContext & {
27
34
  /** Identifier shared by all events belonging to the same ceremony. */
28
35
  ceremonyId: string;
29
- /** Current ceremony lifecycle phase. */
30
- phase: "started" | "completed" | "failed";
31
- /** Requested mediation mode, when available. */
32
- mediation?: string;
33
- /** Whether transient user activation was active when the ceremony started. Present on `started` events when exposed by the browser. */
34
- userActivation?: boolean;
35
- /**
36
- * JSON-encoded request metadata for a `get` ceremony: `rpId`, `timeout`,
37
- * `userVerification`, `hints`, `challenge`, and `allowCredentials`
38
- * (`type`, `id`, and `transports`). Binary values are base64url-encoded.
39
- * Unavailable fields are omitted. Present on `started` events when
40
- * serialization succeeds. Treat this value as sensitive telemetry.
41
- */
36
+ /** Authentication request metadata; present only when applicable and serializable. */
42
37
  requestOptionsJson?: string;
43
- /** Whether a `get` request included at least one allowed credential. Present on `started` events. */
44
- hasAllowCredentials?: boolean;
45
- /**
46
- * JSON-encoded, allowlisted credential returned by a completed ceremony.
47
- * Common fields are `id`, `rawId`, `type`, and `authenticatorAttachment`.
48
- * Assertion responses include `clientDataJSON`, `authenticatorData`,
49
- * `signature`, and `userHandle`; attestation responses include
50
- * `clientDataJSON`, `attestationObject`, and `transports`. Binary values are
51
- * base64url-encoded. Of the client-extension results, only `credProps.rk` may
52
- * be included. Present when serialization succeeds. Treat this value as
53
- * sensitive telemetry.
54
- */
38
+ /** Completed credential metadata; present only when applicable and serializable. */
55
39
  credentialJson?: string;
56
- /** Rejection value from a failed ceremony. This may contain application-specific data. */
40
+ /** Failure details; present only for failed ceremonies. */
57
41
  error?: unknown;
58
- /** Error name for a failed ceremony, or `UnknownError` when no DOM exception name is available. */
59
42
  errorName?: string;
43
+ /** Present when the request signal was aborted before settlement. */
44
+ aborted?: true;
45
+ };
46
+ type WebAuthnCeremonyStartedEvent = WebAuthnCeremonyBase & {
47
+ phase: "started";
48
+ /** Whether transient user activation was active when the ceremony started, when exposed by the browser. */
49
+ userActivation?: boolean;
60
50
  /**
61
- * `true` when the request signal was observed as aborted before settlement.
62
- * A credential manager may still complete such a ceremony, so this can be
63
- * present on either a `completed` or `failed` event.
51
+ * JSON-encoded request metadata for authentication: `rpId`, `timeout`,
52
+ * `userVerification`, `hints`, `challenge`, and `allowCredentials`.
53
+ * Binary values are base64url-encoded. Treat this value as sensitive telemetry.
64
54
  */
65
- aborted?: boolean;
55
+ requestOptionsJson?: string;
56
+ };
57
+ type WebAuthnCeremonyCompletedEvent = WebAuthnCeremonyBase & {
58
+ phase: "completed";
59
+ /** JSON-encoded allowlisted credential. Treat this value as sensitive telemetry. */
60
+ credentialJson?: string;
61
+ /** A credential manager may complete even after the ceremony signal was aborted. */
62
+ aborted?: true;
63
+ };
64
+ type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
65
+ phase: "failed";
66
+ /** Rejection value from the failed ceremony. This may contain application-specific data. */
67
+ error: unknown;
68
+ /** DOM exception name, or `UnknownError` when no name is available. */
69
+ errorName: string;
70
+ aborted?: true;
66
71
  };
72
+ /** A protocol-native lifecycle event for WebAuthn authentication or registration. */
73
+ type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
67
74
  /** Options for {@link captureWebAuthn}. */
68
75
  type WebAuthnCaptureOptions = {
69
76
  /** Receives WebAuthn lifecycle events. Return values are not awaited. */
@@ -73,8 +80,10 @@ type WebAuthnCaptureOptions = {
73
80
  };
74
81
  /** Network API used for an observed exchange. */
75
82
  type NetworkTransport = "xhr" | "fetch";
83
+ /** Direction of a projected body within an observed network exchange. */
84
+ type NetworkBodyDirection = "request" | "response";
76
85
  /** A matched network request immediately after the platform accepted it. */
77
- type HttpRequestStarted = {
86
+ type HttpRequestStarted<RequestBody = unknown> = {
78
87
  /** Identifier shared with the eventual {@link HttpExchange}. */
79
88
  requestId: string;
80
89
  /** Network API used for the request. */
@@ -88,10 +97,10 @@ type HttpRequestStarted = {
88
97
  /** Timestamp captured at the request boundary. */
89
98
  startedAt: number;
90
99
  /** Request-body value returned by the configured projector, when synchronously available. */
91
- requestBody?: unknown;
100
+ requestBody?: RequestBody;
92
101
  };
93
102
  /** An observed network request and its outcome. */
94
- type HttpExchange = {
103
+ type HttpExchange<RequestBody = unknown, ResponseBody = unknown> = {
95
104
  /** Identifier shared with the corresponding {@link HttpRequestStarted}. */
96
105
  requestId: string;
97
106
  /** Network API used for the request. */
@@ -122,14 +131,14 @@ type HttpExchange = {
122
131
  */
123
132
  responseUrl?: string;
124
133
  /** Request-body value returned by the configured projector, when available. */
125
- requestBody?: unknown;
134
+ requestBody?: RequestBody;
126
135
  /** Response-body value returned by the configured projector, when available. */
127
- responseBody?: unknown;
136
+ responseBody?: ResponseBody;
128
137
  };
129
138
  /** Metadata supplied to a body projector for one matched exchange. */
130
- type NetworkBodyProjectionContext = {
139
+ type NetworkBodyProjectionContext<Direction extends NetworkBodyDirection = NetworkBodyDirection> = {
131
140
  /** Whether the observed body belongs to the request or response. */
132
- direction: "request" | "response";
141
+ direction: Direction;
133
142
  /** Network API used by the application. */
134
143
  transport: NetworkTransport;
135
144
  /** Uppercase HTTP method. */
@@ -144,10 +153,14 @@ type NetworkBodyProjectionContext = {
144
153
  * Textual bodies are supplied as strings; an XHR with `responseType="json"`
145
154
  * supplies the browser-parsed value. Returning `undefined`, throwing, or
146
155
  * returning a Promise omits the body without affecting the application.
156
+ * `ProjectedBody` describes the exact value delivered to callbacks.
147
157
  */
148
- type NetworkBodyProjector = (body: unknown, context: NetworkBodyProjectionContext) => unknown;
149
- /** Options for {@link captureNetwork}. */
150
- type NetworkCaptureOptions = {
158
+ type NetworkBodyProjector<ProjectedBody = unknown, Direction extends NetworkBodyDirection = NetworkBodyDirection> = (body: unknown, context: NetworkBodyProjectionContext<Direction>) => ProjectedBody | undefined;
159
+ /**
160
+ * Options for {@link captureNetwork}. Request and response body types are
161
+ * inferred from their projectors and propagated to the corresponding callbacks.
162
+ */
163
+ type NetworkCaptureOptions<RequestBody = unknown, ResponseBody = unknown> = {
151
164
  /**
152
165
  * Selects requests to observe. The URL is resolved against the document base
153
166
  * URL and the method is uppercase. Return `true` to observe the request. The
@@ -156,12 +169,12 @@ type NetworkCaptureOptions = {
156
169
  */
157
170
  match: (url: URL, method: string) => boolean;
158
171
  /** Receives completed network exchanges. Return values are not awaited. */
159
- onExchange: (exchange: HttpExchange) => void;
172
+ onExchange: (exchange: HttpExchange<NoInfer<RequestBody>, NoInfer<ResponseBody>>) => void;
160
173
  /**
161
174
  * Receives matched requests after the platform call succeeds. The request ID
162
175
  * matches the eventual exchange. Return values are not awaited.
163
176
  */
164
- onRequest?: (request: HttpRequestStarted) => void;
177
+ onRequest?: (request: HttpRequestStarted<NoInfer<RequestBody>>) => void;
165
178
  /**
166
179
  * Network APIs to observe. Defaults to both `xhr` and `fetch`. Unavailable
167
180
  * transports are skipped if at least one requested transport can be observed.
@@ -174,19 +187,11 @@ type NetworkCaptureOptions = {
174
187
  * data minimization and its return value is the only body data reported.
175
188
  */
176
189
  bodyCapture?: {
177
- /** Projects a bounded request body. */
178
- request?: NetworkBodyProjector;
179
- /** Projects a bounded response body. */
180
- response?: NetworkBodyProjector;
190
+ /** Projects a request body. */
191
+ request?: NetworkBodyProjector<RequestBody, "request">;
192
+ /** Projects a response body. */
193
+ response?: NetworkBodyProjector<ResponseBody, "response">;
181
194
  };
182
- /**
183
- * Maximum size of a projected body attached to a request or exchange,
184
- * measured on its JSON-serialized form; larger projections are omitted.
185
- * Raw bodies are not size-checked before projection — matched traffic is
186
- * first-party and assumed well-behaved. Must be a finite, non-negative
187
- * number when provided. Defaults to 65,536.
188
- */
189
- maxBodyChars?: number;
190
195
  /** Optional diagnostic logger. */
191
196
  logger?: Logger;
192
197
  };
@@ -312,7 +317,7 @@ declare function captureWebAuthn(options: WebAuthnCaptureOptions): CaptureHandle
312
317
  * @throws TypeError when `onExchange` or `match` is not a function — a
313
318
  * misconfigured integration is a programming error, not a degraded mode.
314
319
  */
315
- declare function captureNetwork(options: NetworkCaptureOptions): CaptureHandle;
320
+ declare function captureNetwork<RequestBody = unknown, ResponseBody = unknown>(options: NetworkCaptureOptions<RequestBody, ResponseBody>): CaptureHandle;
316
321
 
317
322
  /**
318
323
  * Observes same-document navigations produced by `history.pushState()`,
@@ -375,4 +380,4 @@ declare function createConsoleLogger(prefix?: string): Logger;
375
380
  /** Version identifier embedded in the current build. */
376
381
  declare const VERSION: string;
377
382
 
378
- export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyEvent, type WebAuthnCeremonyKind, captureNavigation, captureNetwork, captureShadowRoots, captureUiState, captureWebAuthn, composedPath, composedTarget, createConsoleLogger };
383
+ export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, type ShadowRootAttachedEvent, type ShadowRootCaptureOptions, type UiStateCaptureHandle, type UiStateCaptureOptions, type UiStateTrigger, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureShadowRoots, captureUiState, captureWebAuthn, composedPath, composedTarget, createConsoleLogger };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var oe=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var De=(e,t)=>{for(var n in t)oe(e,n,{get:t[n],enumerable:!0})},Te=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Le(t))!Ne.call(e,o)&&o!==n&&oe(e,o,{get:()=>t[o],enumerable:!(r=xe(t,o))||r.enumerable});return e};var He=e=>Te(oe({},"__esModule",{value:!0}),e);var Ke={};De(Ke,{VERSION:()=>Pe,captureNavigation:()=>Re,captureNetwork:()=>ve,captureShadowRoots:()=>Oe,captureUiState:()=>Ae,captureWebAuthn:()=>pe,composedPath:()=>ce,composedTarget:()=>Ce,createConsoleLogger:()=>ke});module.exports=He(Ke);var ae={log:()=>{}};function j(e){return e?{log:(...t)=>{try{let n=e.log(...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}:ae}var le=Symbol.for("corbado.autocapture.installed");function B(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,le)}catch{return!1}}function M(e,t){var r,o;let n=t;try{Object.defineProperty(e,le,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(r=n.name)!=null?r:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=n.length)!=null?o:0,configurable:!0})}catch{}return e}function w(){return{mode:"unavailable",disconnect:()=>{}}}function _(e,t,n){let r=j(e);return o=>{try{let a=n(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(d=>r.log(`${t} listener failed`,d))}catch(d){r.log(`${t} listener failed`,d)}}catch(a){r.log(`${t} listener failed`,a)}}}function pe(e){let t=j(e.logger),n=e.onEvent;if(typeof n!="function")return w();let r=typeof navigator=="undefined"?void 0:navigator,o=r==null?void 0:r.credentials;if(!r||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),w();let a=o.get,d=o.create;if(typeof a!="function"||typeof d!="function")return t.log("webauthn capture unavailable: credentials methods missing"),w();if(B(a)||B(d))return t.log("webauthn capture unavailable: an equivalent capture is already active"),w();let p=!1,v=0,k=_(t,"webauthn",s=>{if(p)return n(s)}),D=(s,b)=>{let L={invoke(...q){let O=this,R=q[0];if(!p||!Q(R)||!Q(R.publicKey))return Reflect.apply(b,O,q);let Z=R.publicKey,V=`wa-${++v}`,ee=Reflect.apply(b,O,q),f=typeof R.mediation=="string"?R.mediation:void 0,m=Q(R.signal)?R.signal:void 0,C={kind:s,ceremonyId:V,phase:"started",mediation:f,userActivation:je(r)};if(s==="get"){let c=Z;C.requestOptionsJson=Ie(c,t),C.hasAllowCredentials=Array.isArray(c.allowCredentials)&&c.allowCredentials.length>0}return k(C),Promise.resolve(ee).then(c=>(p&&k({kind:s,ceremonyId:V,phase:"completed",mediation:f,credentialJson:Be(c,s,t),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c),c=>{throw p&&k({kind:s,ceremonyId:V,phase:"failed",mediation:f,error:c,errorName:_e(c),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c})}}.invoke;return M(L,{name:s,length:0})},h=(s,b)=>{let L=D(s,b),q=Object.getOwnPropertyDescriptor(o,s);if(q&&(!("value"in q)||q.writable!==!0))return null;try{o[s]=L}catch{return null}return()=>{o[s]===L&&(q?o[s]=q.value:delete o[s])}},S=h("get",a),u=S?h("create",d):null;return!S||!u?(S==null||S(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),w()):(p=!0,{mode:"standard",disconnect:()=>{p=!1,S(),u()}})}function je(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Be(e,t,n){var r;if(e)try{let o=e,a=o.response,d={id:z(o.id),rawId:$(o.rawId),type:z(o.type),authenticatorAttachment:z(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:$(a==null?void 0:a.clientDataJSON),attestationObject:$(a==null?void 0:a.attestationObject),transports:ie((r=a==null?void 0:a.getTransports)==null?void 0:r.call(a))}:{clientDataJSON:$(a==null?void 0:a.clientDataJSON),authenticatorData:$(a==null?void 0:a.authenticatorData),signature:$(a==null?void 0:a.signature),userHandle:$(a==null?void 0:a.userHandle)},...t==="create"?Me(o):{}};return JSON.stringify(d)}catch(o){n.log("credential serialization failed",o);return}}function Ie(e,t){try{let n={},r=z(e.rpId),o=z(e.userVerification),a=ie(e.hints);return r!==void 0&&(n.rpId=r),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(n.timeout=e.timeout),o!==void 0&&(n.userVerification=o),a!==void 0&&(n.hints=a),n.challenge=$(e.challenge),Array.isArray(e.allowCredentials)&&(n.allowCredentials=Ue(e.allowCredentials)),JSON.stringify(n)}catch(n){t.log("request options serialization failed",n);return}}function Ue(e){let t=[];for(let n of e){if(!Q(n))continue;let r=n;t.push({type:z(r.type),id:$(r.id),transports:ie(r.transports)})}return t}function ie(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function z(e){return typeof e=="string"?e:void 0}function Me(e){var r;let t=(r=e.getClientExtensionResults)==null?void 0:r.call(e);if(!Q(t))return{};let n=t.credProps;return!n||typeof n.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:n.rk}}}}function $(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let n="";for(let r of t)n+=String.fromCharCode(r);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function _e(e){return e instanceof DOMException?e.name:"UnknownError"}var fe=0;function he(){return fe+=1,`network-${fe}`}function Fe(e,t){let n=e.responseType;if(n===""||n==="text")return t(e.responseText);if(n==="json"){let r=e.response;return r==null?void 0:t(r)}}var Xe=500,We=65536,ge=Symbol("body-read-timeout");function ye(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function me(e,t){let n=e.body;if(!n)return;let r=n.getReader(),o;try{let a=new Promise(v=>{o=setTimeout(()=>v(ge),Xe)}),d=new TextDecoder,p=[];for(;;){let v=await Promise.race([r.read(),a]);if(v===ge){t.log("body omitted: read timed out"),r.cancel().catch(()=>{});return}if(v.done)break;p.push(d.decode(v.value,{stream:!0}))}return p.push(d.decode()),p.join("")}catch{r.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function se(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function ue(e,t,n,r,o){try{let a=Object.getOwnPropertyDescriptor(e,t);Je(a,{...r,value:n})&&Object.defineProperty(e,t,r)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function Je(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function ve(e){var R,Z,V,ee;let{onExchange:t,onRequest:n,match:r}=e;if(typeof t!="function"||typeof r!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=j(e.logger),a=(R=e.transports)!=null?R:["xhr","fetch"],d=(Z=e.bodyCapture)==null?void 0:Z.request,p=(V=e.bodyCapture)==null?void 0:V.response,v=typeof d=="function",k=typeof p=="function",D=(ee=e.maxBodyChars)!=null?ee:We,h=!1,S=_(o,"network",f=>{if(h)return t(f)}),u=_(o,"network request",f=>{if(h)return n==null?void 0:n(f)}),s=(f,m)=>{let C=m.direction==="request"?d:p;if(typeof C=="function")try{let c=C(f,m);if(c===void 0||typeof(c==null?void 0:c.then)=="function")return;let F=JSON.stringify(c);return F===void 0||F.length>D?void 0:JSON.parse(F)}catch(c){o.log("body projection failed",c);return}},b=(f,m)=>{try{let C=typeof document!="undefined"?document.baseURI:void 0,c=new URL(String(f),C);return/\/observe\/events\/[^/]+\/?$/.test(c.pathname)?void 0:r(c,m)===!0?{url:c.href,path:c.pathname}:void 0}catch{return}},L=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let f=XMLHttpRequest.prototype,m=Object.getOwnPropertyDescriptor(f,"open"),C=Object.getOwnPropertyDescriptor(f,"send");if(!m||!("value"in m)||typeof m.value!="function"||!C||!("value"in C)||typeof C.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let c=m.value,F=C.value;if(B(c)||B(F))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let X=new WeakMap,A=new Set,x=!1,T={open(...E){var g;let i=Reflect.apply(c,this,E);if(!h||!x)return i;try{let N=X.get(this);N&&(N.reported=!0,(g=N.cleanupListeners)==null||g.call(N));let H=String(E[0]).toUpperCase(),P=b(E[1],H);P?X.set(this,{method:H,url:P.url,path:P.path,reported:!1}):X.delete(this)}catch(N){o.log("xhr open observation failed",N)}return i}}.open,J={send(...E){let i=h&&x?X.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(F,this,E);let g=()=>{},N=!1;try{i.requestId=he();let P={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=v&&typeof E[0]=="string"?s(E[0],P):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},y=()=>{var K;g();try{if(!h||!x||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},re=this.status,de={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:re,ok:re>=200&&re<300,outcome:(K=i.outcome)!=null?K:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:k?Fe(this,qe=>s(qe,U)):void 0};i.requestEmitted?S(de):i.pendingExchange=de}catch(U){o.log("xhr exchange observation failed",U)}finally{X.get(this)===i&&X.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&y()}catch(K){o.log("xhr ready-state observation failed",K)}},W=()=>y();g=()=>{for(let[K,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",W]])this.removeEventListener(K,U);i.cleanupListeners===g&&(i.cleanupListeners=void 0),A.delete(g)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",W),i.cleanupListeners=g,A.add(g),i.startedAt=Date.now(),N=!0}catch(P){o.log("xhr send observation failed",P),g()}let H;try{H=Reflect.apply(F,this,E)}catch(P){throw g(),P}if(N&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,u({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let P=i.pendingExchange;i.pendingExchange=void 0,P&&S(P)}return H}}.send;return M(T,c),M(J,F),m.writable!==!0||C.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(f,"open",{...m,value:T}),Object.defineProperty(f,"send",{...C,value:J}),x=!0,()=>{x=!1;for(let E of[...A])E();ue(f,"open",T,m,o),ue(f,"send",J,C,o)})},q=()=>{let f=globalThis,m=Object.getOwnPropertyDescriptor(f,"fetch");if(!m||!("value"in m))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let C=m.value;if(typeof C!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(B(C))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let c=!1,F=async(A,x,T,J)=>{try{if(!h||!c){se(T);return}let[E,i]=await Promise.all([J!=null?J:Promise.resolve(void 0),T?me(T,o):Promise.resolve(void 0)]);if(!h||!c)return;let g={direction:"request",transport:"fetch",method:A.method,url:A.url,path:A.path},N={...g,direction:"response"},H=A.requestBody;H===void 0&&E!==void 0&&(H=s(E,g));let P=i!==void 0?s(i,N):void 0;S({requestId:A.requestId,transport:"fetch",method:A.method,url:A.url,path:A.path,status:x.status,ok:x.ok,outcome:"load",durationMs:Date.now()-A.startedAt,responseUrl:x.url||void 0,requestBody:H,responseBody:P})}catch(E){o.log("fetch exchange observation failed",E)}},X={fetch(...A){var H,P,G,Y;let x;try{let l=A[0],y=A[1];if(h&&c&&v&&typeof Request!="undefined"&&l instanceof Request&&(y==null?void 0:y.body)===void 0&&l.body){let I=String((H=y==null?void 0:y.method)!=null?H:l.method).toUpperCase(),W=(P=l.headers.get("content-type"))!=null?P:"";b(l.url,I)&&ye(W)&&(x=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,J=Date.now();try{T=Reflect.apply(C,this,A)}catch(l){throw se(x),l}let E,i;try{if(h&&c){let l=A[0],y=A[1],I=typeof Request!="undefined"&&l instanceof Request,W=String((G=y==null?void 0:y.method)!=null?G:I?l.method:"GET").toUpperCase(),K=I?l.url:l,U=b(K,W);U&&(E={requestId:he(),method:W,url:U.url,path:U.path,startedAt:J},i=(Y=y==null?void 0:y.signal)!=null?Y:I?l.signal:void 0,v&&typeof(y==null?void 0:y.body)=="string"&&(E.requestBody=s(y.body,{direction:"request",transport:"fetch",method:W,url:U.url,path:U.path})))}}catch(l){o.log("fetch observation failed",l)}if(!E)return se(x),T;let g=E;u({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,startedAt:g.startedAt,requestBody:g.requestBody});let N=x?me(x,o):void 0;return T.then(l=>{var I;let y;try{if(h&&c&&k){let W=(I=l.headers.get("content-type"))!=null?I:"";ye(W)&&l.body&&(y=l.clone())}}catch{}F(g,l,y,N)},l=>{try{if(!h||!c)return;let y=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;S({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,status:0,ok:!1,outcome:y?"abort":"error",durationMs:Date.now()-g.startedAt})}catch(y){o.log("fetch failure observation failed",y)}}),T}}.fetch;return M(X,C),m.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(f,"fetch",{...m,value:X}),c=!0,()=>{c=!1,ue(f,"fetch",X,m,o)})},O=[];if(a.includes("xhr")){let f=L();f&&O.push(f)}if(a.includes("fetch")){let f=q();f&&O.push(f)}return O.length===0?w():(h=!0,{mode:"standard",disconnect:()=>{h=!1;for(let f of O.splice(0))f()}})}function Re(e){let t=j(),n;try{if(t=j(e.logger),n=e.onNavigate,typeof n!="function")return w()}catch{return w()}let r,o,a,d,p,v;try{if(r=window,o=r==null?void 0:r.history,!r||!o)return t.log("navigation capture unavailable: window/history missing"),w();if(p=we(o,"pushState"),v=we(o,"replaceState"),!p||!v)return t.log("navigation capture unavailable: history method descriptors missing"),w();if(a=p.descriptor.value,d=v.descriptor.value,typeof a!="function"||typeof d!="function")return t.log("navigation capture unavailable: history methods missing"),w();if(typeof r.addEventListener!="function"||typeof r.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),w()}catch(O){return t.log("navigation capture unavailable: history inspection failed",O),w()}if(B(a)||B(d))return t.log("navigation capture unavailable: an equivalent capture is already active"),w();let k=!1,D=()=>({path:r.location.pathname,search:r.location.search,hash:r.location.hash}),h;try{h=D()}catch(O){return t.log("navigation capture unavailable: location inspection failed",O),w()}let S=_(t,"navigation",O=>{if(k)return n(O)}),u=O=>{if(k)try{let R=D();if(R.path===h.path&&R.search===h.search&&R.hash===h.hash)return;h=R,S({...R,source:O})}catch(R){t.log("navigation observation failed",R)}},s={pushState(...O){let R=Reflect.apply(a,this,O);return u("push"),R}}.pushState,b={replaceState(...O){let R=Reflect.apply(d,this,O);return u("replace"),R}}.replaceState;M(s,a),M(b,d);let L=()=>u("pop"),q=()=>u("hash");try{if(be(p,s),be(v,b),o.pushState!==s||o.replaceState!==b)throw new Error("history method replacement did not take effect");r.addEventListener("popstate",L),r.addEventListener("hashchange",q),k=!0}catch(O){return k=!1,ne(r,"popstate",L,t),ne(r,"hashchange",q,t),te(v,b,t),te(p,s,t),t.log("navigation capture unavailable: history methods are not writable",O),n=()=>{},S=()=>{},t=j(),w()}return{mode:"standard",disconnect:()=>{k=!1,n=()=>{},ne(r,"popstate",L,t),ne(r,"hashchange",q,t),te(p,s,t),te(v,b,t),S=()=>{},t=j()}}}function we(e,t){let n=e;for(;n;){let r=Object.getOwnPropertyDescriptor(n,t);if(r)return!("value"in r)||typeof r.value!="function"?null:{owner:n,key:t,descriptor:r};n=Object.getPrototypeOf(n)}return null}function be(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let n=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!Se(n,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function Se(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function te(e,t,n){try{let r=Object.getOwnPropertyDescriptor(e.owner,e.key);Se(r,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(r){n.log(`navigation ${e.key} restoration skipped`,r)}}function ne(e,t,n,r){try{e.removeEventListener(t,n)}catch(o){r.log(`navigation ${t} listener removal skipped`,o)}}function Oe(e){var S;let t=(S=e.logger)!=null?S:ae,n=e.onAttached;if(typeof n!="function")return w();let r=Element.prototype,o=Object.getOwnPropertyDescriptor(r,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),w();let a=o.value;if(B(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),w();let d=!1,p=new WeakSet,v=_(t,"shadow-root",n),k=(u,s)=>{!d||p.has(s)||(p.add(s),v({host:u,shadowRoot:s,mode:s.mode==="closed"?"closed":"open"}))},D={attachShadow(...u){let s=Reflect.apply(a,this,u);return k(this,s),s}}.attachShadow;M(D,a);try{Object.defineProperty(r,"attachShadow",{...o,value:D})}catch(u){return t.log("shadow-root capture unavailable: attachShadow is locked",u),w()}d=!0;let h=u=>{let s=u.querySelectorAll("*");for(let b=0;b<s.length&&d;b++){let L=s[b].shadowRoot;L&&(k(s[b],L),h(L))}};return e.includeExisting&&h(document),{mode:"standard",disconnect:()=>{d=!1;let u=Object.getOwnPropertyDescriptor(r,"attachShadow");$e(u,{...o,value:D})&&Object.defineProperty(r,"attachShadow",o)}}}function Ce(e){var t;return(t=ce(e)[0])!=null?t:null}function ce(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function $e(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Ae(e){var D,h,S;let t=j(e==null?void 0:e.logger),n=e==null?void 0:e.read,r=e==null?void 0:e.onState;if(typeof n!="function"||typeof r!="function")return Ee();let o=Number.isFinite(e.delayMs)&&((D=e.delayMs)!=null?D:0)>=0&&(h=e.delayMs)!=null?h:0,a=_(t,"ui-state",r),d=!0,p,v=[],k=()=>{d&&(p!==void 0&&clearTimeout(p),p=setTimeout(()=>{if(p=void 0,!!d)try{let u=n();u!==void 0&&a(u)}catch(u){t.log("ui-state read failed",u)}},o))};try{for(let u of(S=e.triggers)!=null?S:[]){if(!(u!=null&&u.target)||typeof u.target.addEventListener!="function")continue;let s=k;u.target.addEventListener(u.type,s,u.capture===!0),v.push({trigger:u,listener:s})}}catch(u){t.log("ui-state trigger installation failed",u);for(let{trigger:s,listener:b}of v)try{s.target.removeEventListener(s.type,b,s.capture===!0)}catch{}return d=!1,Ee()}return{mode:"standard",schedule:k,disconnect:()=>{if(d){d=!1,p!==void 0&&clearTimeout(p),p=void 0;for(let{trigger:u,listener:s}of v)try{u.target.removeEventListener(u.type,s,u.capture===!0)}catch(b){t.log("ui-state trigger removal failed",b)}v.length=0}}}}function Ee(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function ke(e="[autocapture]"){return{log:(...t)=>{try{let n=console.log(e,...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}}var Pe="0.1.0-next.2-dd9eb36";0&&(module.exports={VERSION,captureNavigation,captureNetwork,captureShadowRoots,captureUiState,captureWebAuthn,composedPath,composedTarget,createConsoleLogger});
1
+ "use strict";var ne=Object.defineProperty;var qe=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var xe=Object.prototype.hasOwnProperty;var De=(e,t)=>{for(var n in t)ne(e,n,{get:t[n],enumerable:!0})},Le=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Pe(t))!xe.call(e,o)&&o!==n&&ne(e,o,{get:()=>t[o],enumerable:!(r=qe(t,o))||r.enumerable});return e};var Ne=e=>Le(ne({},"__esModule",{value:!0}),e);var Ve={};De(Ve,{VERSION:()=>ke,captureNavigation:()=>be,captureNetwork:()=>ge,captureShadowRoots:()=>Re,captureUiState:()=>Oe,captureWebAuthn:()=>de,composedPath:()=>se,composedTarget:()=>Ce,createConsoleLogger:()=>Ee});module.exports=Ne(Ve);var re={log:()=>{}};function j(e){return e?{log:(...t)=>{try{let n=e.log(...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}:re}var ce=Symbol.for("corbado.autocapture.installed");function M(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,ce)}catch{return!1}}function _(e,t){var r,o;let n=t;try{Object.defineProperty(e,ce,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(r=n.name)!=null?r:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=n.length)!=null?o:0,configurable:!0})}catch{}return e}function b(){return{mode:"unavailable",disconnect:()=>{}}}function W(e,t,n){let r=j(e);return o=>{try{let a=n(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(c=>r.log(`${t} listener failed`,c))}catch(c){r.log(`${t} listener failed`,c)}}catch(a){r.log(`${t} listener failed`,a)}}}function de(e){let t=j(e.logger),n=e.onEvent;if(typeof n!="function")return b();let r=typeof navigator=="undefined"?void 0:navigator,o=r==null?void 0:r.credentials;if(!r||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),b();let a=o.get,c=o.create;if(typeof a!="function"||typeof c!="function")return t.log("webauthn capture unavailable: credentials methods missing"),b();if(M(a)||M(c))return t.log("webauthn capture unavailable: an equivalent capture is already active"),b();let d=!1,g=0,P=W(t,"webauthn",u=>{if(d)return n(u)}),m=(u,w)=>{let N={invoke(...x){let k=this,R=x[0];if(!d||!Q(R)||!Q(R.publicKey))return Reflect.apply(w,k,x);let z=R.publicKey,p=`wa-${++g}`,C=Reflect.apply(w,k,x),v=Q(R.signal)?R.signal:void 0,f=Be(u,R,z),X={...f,ceremonyId:p,phase:"started",userActivation:je(r)};if(f.kind==="authentication"){let A=z;X.requestOptionsJson=Ie(A,t)}return P(X),Promise.resolve(C).then(A=>(d&&P({...f,ceremonyId:p,phase:"completed",credentialJson:Me(A,u,t),...(v==null?void 0:v.aborted)===!0?{aborted:!0}:{}}),A),A=>{throw d&&P({...f,ceremonyId:p,phase:"failed",error:A,errorName:We(A),...(v==null?void 0:v.aborted)===!0?{aborted:!0}:{}}),A})}}.invoke;return _(N,{name:u,length:0})},O=(u,w)=>{let N=m(u,w),x=Object.getOwnPropertyDescriptor(o,u);if(x&&(!("value"in x)||x.writable!==!0))return null;try{o[u]=N}catch{return null}return()=>{o[u]===N&&(x?o[u]=x.value:delete o[u])}},E=O("get",a),s=E?O("create",c):null;return!E||!s?(E==null||E(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),b()):(d=!0,{mode:"standard",disconnect:()=>{d=!1,E(),s()}})}function Be(e,t,n){let r=Te(t.mediation);if(e==="create")return{kind:"registration",mediation:r};let o=n;return{kind:"authentication",mediation:r,uiMode:He(t.uiMode),credentialSet:Array.isArray(o.allowCredentials)&&o.allowCredentials.length>0?"allowlisted":"discoverable"}}function Te(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function He(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function je(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Me(e,t,n){var r;if(e)try{let o=e,a=o.response,c={id:J(o.id),rawId:$(o.rawId),type:J(o.type),authenticatorAttachment:J(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:$(a==null?void 0:a.clientDataJSON),attestationObject:$(a==null?void 0:a.attestationObject),transports:oe((r=a==null?void 0:a.getTransports)==null?void 0:r.call(a))}:{clientDataJSON:$(a==null?void 0:a.clientDataJSON),authenticatorData:$(a==null?void 0:a.authenticatorData),signature:$(a==null?void 0:a.signature),userHandle:$(a==null?void 0:a.userHandle)},...t==="create"?_e(o):{}};return JSON.stringify(c)}catch(o){n.log("credential serialization failed",o);return}}function Ie(e,t){try{let n={},r=J(e.rpId),o=J(e.userVerification),a=oe(e.hints);return r!==void 0&&(n.rpId=r),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(n.timeout=e.timeout),o!==void 0&&(n.userVerification=o),a!==void 0&&(n.hints=a),n.challenge=$(e.challenge),Array.isArray(e.allowCredentials)&&(n.allowCredentials=Ue(e.allowCredentials)),JSON.stringify(n)}catch(n){t.log("request options serialization failed",n);return}}function Ue(e){let t=[];for(let n of e){if(!Q(n))continue;let r=n;t.push({type:J(r.type),id:$(r.id),transports:oe(r.transports)})}return t}function oe(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function J(e){return typeof e=="string"?e:void 0}function _e(e){var r;let t=(r=e.getClientExtensionResults)==null?void 0:r.call(e);if(!Q(t))return{};let n=t.credProps;return!n||typeof n.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:n.rk}}}}function $(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let n="";for(let r of t)n+=String.fromCharCode(r);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function We(e){return e instanceof DOMException?e.name:"UnknownError"}var le=0;function pe(){return le+=1,`network-${le}`}function Fe(e,t){let n=e.responseType;if(n===""||n==="text")return t(e.responseText);if(n==="json"){let r=e.response;return r==null?void 0:t(r)}}var Xe=500,fe=Symbol("body-read-timeout");function he(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function ye(e,t){let n=e.body;if(!n)return;let r=n.getReader(),o;try{let a=new Promise(g=>{o=setTimeout(()=>g(fe),Xe)}),c=new TextDecoder,d=[];for(;;){let g=await Promise.race([r.read(),a]);if(g===fe){t.log("body omitted: read timed out"),r.cancel().catch(()=>{});return}if(g.done)break;d.push(c.decode(g.value,{stream:!0}))}return d.push(c.decode()),d.join("")}catch{r.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function ae(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function ie(e,t,n,r,o){try{let a=Object.getOwnPropertyDescriptor(e,t);Ke(a,{...r,value:n})&&Object.defineProperty(e,t,r)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function Ke(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function ge(e){var k,R,z;let{onExchange:t,onRequest:n,match:r}=e;if(typeof t!="function"||typeof r!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=j(e.logger),a=(k=e.transports)!=null?k:["xhr","fetch"],c=(R=e.bodyCapture)==null?void 0:R.request,d=(z=e.bodyCapture)==null?void 0:z.response,g=typeof c=="function",P=typeof d=="function",m=!1,O=W(o,"network",p=>{if(m)return t(p)}),E=W(o,"network request",p=>{if(m)return n==null?void 0:n(p)}),s=(p,C,v)=>{if(typeof v=="function")try{let f=v(p,C);return f===void 0||typeof(f==null?void 0:f.then)=="function"?void 0:f}catch(f){o.log("body projection failed",f);return}},u=(p,C)=>{try{let v=typeof document!="undefined"?document.baseURI:void 0,f=new URL(String(p),v);return/\/observe\/events\/[^/]+\/?$/.test(f.pathname)?void 0:r(f,C)===!0?{url:f.href,path:f.pathname}:void 0}catch{return}},w=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let p=XMLHttpRequest.prototype,C=Object.getOwnPropertyDescriptor(p,"open"),v=Object.getOwnPropertyDescriptor(p,"send");if(!C||!("value"in C)||typeof C.value!="function"||!v||!("value"in v)||typeof v.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let f=C.value,X=v.value;if(M(f)||M(X))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let A=new WeakMap,q=new Set,L=!1,T={open(...S){var h;let i=Reflect.apply(f,this,S);if(!m||!L)return i;try{let B=A.get(this);B&&(B.reported=!0,(h=B.cleanupListeners)==null||h.call(B));let H=String(S[0]).toUpperCase(),D=u(S[1],H);D?A.set(this,{method:H,url:D.url,path:D.path,reported:!1}):A.delete(this)}catch(B){o.log("xhr open observation failed",B)}return i}}.open,K={send(...S){let i=m&&L?A.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(X,this,S);let h=()=>{},B=!1;try{i.requestId=pe();let D={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=g&&typeof S[0]=="string"?s(S[0],D,c):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},y=()=>{var V;h();try{if(!m||!L||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},te=this.status,ue={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:te,ok:te>=200&&te<300,outcome:(V=i.outcome)!=null?V:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:P?Fe(this,Ae=>s(Ae,U,d)):void 0};i.requestEmitted?O(ue):i.pendingExchange=ue}catch(U){o.log("xhr exchange observation failed",U)}finally{A.get(this)===i&&A.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&y()}catch(V){o.log("xhr ready-state observation failed",V)}},F=()=>y();h=()=>{for(let[V,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",F]])this.removeEventListener(V,U);i.cleanupListeners===h&&(i.cleanupListeners=void 0),q.delete(h)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",F),i.cleanupListeners=h,q.add(h),i.startedAt=Date.now(),B=!0}catch(D){o.log("xhr send observation failed",D),h()}let H;try{H=Reflect.apply(X,this,S)}catch(D){throw h(),D}if(B&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,E({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let D=i.pendingExchange;i.pendingExchange=void 0,D&&O(D)}return H}}.send;return _(T,f),_(K,X),C.writable!==!0||v.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(p,"open",{...C,value:T}),Object.defineProperty(p,"send",{...v,value:K}),L=!0,()=>{L=!1;for(let S of[...q])S();ie(p,"open",T,C,o),ie(p,"send",K,v,o)})},N=()=>{let p=globalThis,C=Object.getOwnPropertyDescriptor(p,"fetch");if(!C||!("value"in C))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let v=C.value;if(typeof v!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(M(v))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let f=!1,X=async(q,L,T,K)=>{try{if(!m||!f){ae(T);return}let[S,i]=await Promise.all([K!=null?K:Promise.resolve(void 0),T?ye(T,o):Promise.resolve(void 0)]);if(!m||!f)return;let h={direction:"request",transport:"fetch",method:q.method,url:q.url,path:q.path},B={...h,direction:"response"},H=q.requestBody;H===void 0&&S!==void 0&&(H=s(S,h,c));let D=i!==void 0?s(i,B,d):void 0;O({requestId:q.requestId,transport:"fetch",method:q.method,url:q.url,path:q.path,status:L.status,ok:L.ok,outcome:"load",durationMs:Date.now()-q.startedAt,responseUrl:L.url||void 0,requestBody:H,responseBody:D})}catch(S){o.log("fetch exchange observation failed",S)}},A={fetch(...q){var H,D,G,Y;let L;try{let l=q[0],y=q[1];if(m&&f&&g&&typeof Request!="undefined"&&l instanceof Request&&(y==null?void 0:y.body)===void 0&&l.body){let I=String((H=y==null?void 0:y.method)!=null?H:l.method).toUpperCase(),F=(D=l.headers.get("content-type"))!=null?D:"";u(l.url,I)&&he(F)&&(L=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,K=Date.now();try{T=Reflect.apply(v,this,q)}catch(l){throw ae(L),l}let S,i;try{if(m&&f){let l=q[0],y=q[1],I=typeof Request!="undefined"&&l instanceof Request,F=String((G=y==null?void 0:y.method)!=null?G:I?l.method:"GET").toUpperCase(),V=I?l.url:l,U=u(V,F);U&&(S={requestId:pe(),method:F,url:U.url,path:U.path,startedAt:K},i=(Y=y==null?void 0:y.signal)!=null?Y:I?l.signal:void 0,g&&typeof(y==null?void 0:y.body)=="string"&&(S.requestBody=s(y.body,{direction:"request",transport:"fetch",method:F,url:U.url,path:U.path},c)))}}catch(l){o.log("fetch observation failed",l)}if(!S)return ae(L),T;let h=S;E({requestId:h.requestId,transport:"fetch",method:h.method,url:h.url,path:h.path,startedAt:h.startedAt,requestBody:h.requestBody});let B=L?ye(L,o):void 0;return T.then(l=>{var I;let y;try{if(m&&f&&P){let F=(I=l.headers.get("content-type"))!=null?I:"";he(F)&&l.body&&(y=l.clone())}}catch{}X(h,l,y,B)},l=>{try{if(!m||!f)return;let y=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;O({requestId:h.requestId,transport:"fetch",method:h.method,url:h.url,path:h.path,status:0,ok:!1,outcome:y?"abort":"error",durationMs:Date.now()-h.startedAt})}catch(y){o.log("fetch failure observation failed",y)}}),T}}.fetch;return _(A,v),C.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(p,"fetch",{...C,value:A}),f=!0,()=>{f=!1,ie(p,"fetch",A,C,o)})},x=[];if(a.includes("xhr")){let p=w();p&&x.push(p)}if(a.includes("fetch")){let p=N();p&&x.push(p)}return x.length===0?b():(m=!0,{mode:"standard",disconnect:()=>{m=!1;for(let p of x.splice(0))p()}})}function be(e){let t=j(),n;try{if(t=j(e.logger),n=e.onNavigate,typeof n!="function")return b()}catch{return b()}let r,o,a,c,d,g;try{if(r=window,o=r==null?void 0:r.history,!r||!o)return t.log("navigation capture unavailable: window/history missing"),b();if(d=me(o,"pushState"),g=me(o,"replaceState"),!d||!g)return t.log("navigation capture unavailable: history method descriptors missing"),b();if(a=d.descriptor.value,c=g.descriptor.value,typeof a!="function"||typeof c!="function")return t.log("navigation capture unavailable: history methods missing"),b();if(typeof r.addEventListener!="function"||typeof r.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),b()}catch(k){return t.log("navigation capture unavailable: history inspection failed",k),b()}if(M(a)||M(c))return t.log("navigation capture unavailable: an equivalent capture is already active"),b();let P=!1,m=()=>({path:r.location.pathname,search:r.location.search,hash:r.location.hash}),O;try{O=m()}catch(k){return t.log("navigation capture unavailable: location inspection failed",k),b()}let E=W(t,"navigation",k=>{if(P)return n(k)}),s=k=>{if(P)try{let R=m();if(R.path===O.path&&R.search===O.search&&R.hash===O.hash)return;O=R,E({...R,source:k})}catch(R){t.log("navigation observation failed",R)}},u={pushState(...k){let R=Reflect.apply(a,this,k);return s("push"),R}}.pushState,w={replaceState(...k){let R=Reflect.apply(c,this,k);return s("replace"),R}}.replaceState;_(u,a),_(w,c);let N=()=>s("pop"),x=()=>s("hash");try{if(ve(d,u),ve(g,w),o.pushState!==u||o.replaceState!==w)throw new Error("history method replacement did not take effect");r.addEventListener("popstate",N),r.addEventListener("hashchange",x),P=!0}catch(k){return P=!1,ee(r,"popstate",N,t),ee(r,"hashchange",x,t),Z(g,w,t),Z(d,u,t),t.log("navigation capture unavailable: history methods are not writable",k),n=()=>{},E=()=>{},t=j(),b()}return{mode:"standard",disconnect:()=>{P=!1,n=()=>{},ee(r,"popstate",N,t),ee(r,"hashchange",x,t),Z(d,u,t),Z(g,w,t),E=()=>{},t=j()}}}function me(e,t){let n=e;for(;n;){let r=Object.getOwnPropertyDescriptor(n,t);if(r)return!("value"in r)||typeof r.value!="function"?null:{owner:n,key:t,descriptor:r};n=Object.getPrototypeOf(n)}return null}function ve(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let n=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!we(n,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function we(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Z(e,t,n){try{let r=Object.getOwnPropertyDescriptor(e.owner,e.key);we(r,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(r){n.log(`navigation ${e.key} restoration skipped`,r)}}function ee(e,t,n,r){try{e.removeEventListener(t,n)}catch(o){r.log(`navigation ${t} listener removal skipped`,o)}}function Re(e){var E;let t=(E=e.logger)!=null?E:re,n=e.onAttached;if(typeof n!="function")return b();let r=Element.prototype,o=Object.getOwnPropertyDescriptor(r,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),b();let a=o.value;if(M(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),b();let c=!1,d=new WeakSet,g=W(t,"shadow-root",n),P=(s,u)=>{!c||d.has(u)||(d.add(u),g({host:s,shadowRoot:u,mode:u.mode==="closed"?"closed":"open"}))},m={attachShadow(...s){let u=Reflect.apply(a,this,s);return P(this,u),u}}.attachShadow;_(m,a);try{Object.defineProperty(r,"attachShadow",{...o,value:m})}catch(s){return t.log("shadow-root capture unavailable: attachShadow is locked",s),b()}c=!0;let O=s=>{let u=s.querySelectorAll("*");for(let w=0;w<u.length&&c;w++){let N=u[w].shadowRoot;N&&(P(u[w],N),O(N))}};return e.includeExisting&&O(document),{mode:"standard",disconnect:()=>{c=!1;let s=Object.getOwnPropertyDescriptor(r,"attachShadow");$e(s,{...o,value:m})&&Object.defineProperty(r,"attachShadow",o)}}}function Ce(e){var t;return(t=se(e)[0])!=null?t:null}function se(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function $e(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Oe(e){var m,O,E;let t=j(e==null?void 0:e.logger),n=e==null?void 0:e.read,r=e==null?void 0:e.onState;if(typeof n!="function"||typeof r!="function")return Se();let o=Number.isFinite(e.delayMs)&&((m=e.delayMs)!=null?m:0)>=0&&(O=e.delayMs)!=null?O:0,a=W(t,"ui-state",r),c=!0,d,g=[],P=()=>{c&&(d!==void 0&&clearTimeout(d),d=setTimeout(()=>{if(d=void 0,!!c)try{let s=n();s!==void 0&&a(s)}catch(s){t.log("ui-state read failed",s)}},o))};try{for(let s of(E=e.triggers)!=null?E:[]){if(!(s!=null&&s.target)||typeof s.target.addEventListener!="function")continue;let u=P;s.target.addEventListener(s.type,u,s.capture===!0),g.push({trigger:s,listener:u})}}catch(s){t.log("ui-state trigger installation failed",s);for(let{trigger:u,listener:w}of g)try{u.target.removeEventListener(u.type,w,u.capture===!0)}catch{}return c=!1,Se()}return{mode:"standard",schedule:P,disconnect:()=>{if(c){c=!1,d!==void 0&&clearTimeout(d),d=void 0;for(let{trigger:s,listener:u}of g)try{s.target.removeEventListener(s.type,u,s.capture===!0)}catch(w){t.log("ui-state trigger removal failed",w)}g.length=0}}}}function Se(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function Ee(e="[autocapture]"){return{log:(...t)=>{try{let n=console.log(e,...t);if(n&&(typeof n=="object"||typeof n=="function"))try{Promise.resolve(n).catch(()=>{})}catch{}}catch{}}}}var ke="0.1.0-next.3-b8e8889";0&&(module.exports={VERSION,captureNavigation,captureNetwork,captureShadowRoots,captureUiState,captureWebAuthn,composedPath,composedTarget,createConsoleLogger});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var oe={log:()=>{}};function j(e){return e?{log:(...t)=>{try{let r=e.log(...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}:oe}var ce=Symbol.for("corbado.autocapture.installed");function B(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,ce)}catch{return!1}}function M(e,t){var n,o;let r=t;try{Object.defineProperty(e,ce,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(n=r.name)!=null?n:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=r.length)!=null?o:0,configurable:!0})}catch{}return e}function w(){return{mode:"unavailable",disconnect:()=>{}}}function _(e,t,r){let n=j(e);return o=>{try{let a=r(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(d=>n.log(`${t} listener failed`,d))}catch(d){n.log(`${t} listener failed`,d)}}catch(a){n.log(`${t} listener failed`,a)}}}function Re(e){let t=j(e.logger),r=e.onEvent;if(typeof r!="function")return w();let n=typeof navigator=="undefined"?void 0:navigator,o=n==null?void 0:n.credentials;if(!n||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),w();let a=o.get,d=o.create;if(typeof a!="function"||typeof d!="function")return t.log("webauthn capture unavailable: credentials methods missing"),w();if(B(a)||B(d))return t.log("webauthn capture unavailable: an equivalent capture is already active"),w();let p=!1,v=0,k=_(t,"webauthn",s=>{if(p)return r(s)}),D=(s,b)=>{let L={invoke(...q){let O=this,R=q[0];if(!p||!Q(R)||!Q(R.publicKey))return Reflect.apply(b,O,q);let Z=R.publicKey,V=`wa-${++v}`,ee=Reflect.apply(b,O,q),f=typeof R.mediation=="string"?R.mediation:void 0,m=Q(R.signal)?R.signal:void 0,C={kind:s,ceremonyId:V,phase:"started",mediation:f,userActivation:Se(n)};if(s==="get"){let c=Z;C.requestOptionsJson=Ce(c,t),C.hasAllowCredentials=Array.isArray(c.allowCredentials)&&c.allowCredentials.length>0}return k(C),Promise.resolve(ee).then(c=>(p&&k({kind:s,ceremonyId:V,phase:"completed",mediation:f,credentialJson:Oe(c,s,t),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c),c=>{throw p&&k({kind:s,ceremonyId:V,phase:"failed",mediation:f,error:c,errorName:ke(c),...(m==null?void 0:m.aborted)===!0?{aborted:!0}:{}}),c})}}.invoke;return M(L,{name:s,length:0})},h=(s,b)=>{let L=D(s,b),q=Object.getOwnPropertyDescriptor(o,s);if(q&&(!("value"in q)||q.writable!==!0))return null;try{o[s]=L}catch{return null}return()=>{o[s]===L&&(q?o[s]=q.value:delete o[s])}},S=h("get",a),u=S?h("create",d):null;return!S||!u?(S==null||S(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),w()):(p=!0,{mode:"standard",disconnect:()=>{p=!1,S(),u()}})}function Se(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Oe(e,t,r){var n;if(e)try{let o=e,a=o.response,d={id:z(o.id),rawId:$(o.rawId),type:z(o.type),authenticatorAttachment:z(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:$(a==null?void 0:a.clientDataJSON),attestationObject:$(a==null?void 0:a.attestationObject),transports:ae((n=a==null?void 0:a.getTransports)==null?void 0:n.call(a))}:{clientDataJSON:$(a==null?void 0:a.clientDataJSON),authenticatorData:$(a==null?void 0:a.authenticatorData),signature:$(a==null?void 0:a.signature),userHandle:$(a==null?void 0:a.userHandle)},...t==="create"?Ae(o):{}};return JSON.stringify(d)}catch(o){r.log("credential serialization failed",o);return}}function Ce(e,t){try{let r={},n=z(e.rpId),o=z(e.userVerification),a=ae(e.hints);return n!==void 0&&(r.rpId=n),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(r.timeout=e.timeout),o!==void 0&&(r.userVerification=o),a!==void 0&&(r.hints=a),r.challenge=$(e.challenge),Array.isArray(e.allowCredentials)&&(r.allowCredentials=Ee(e.allowCredentials)),JSON.stringify(r)}catch(r){t.log("request options serialization failed",r);return}}function Ee(e){let t=[];for(let r of e){if(!Q(r))continue;let n=r;t.push({type:z(n.type),id:$(n.id),transports:ae(n.transports)})}return t}function ae(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function z(e){return typeof e=="string"?e:void 0}function Ae(e){var n;let t=(n=e.getClientExtensionResults)==null?void 0:n.call(e);if(!Q(t))return{};let r=t.credProps;return!r||typeof r.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:r.rk}}}}function $(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let r="";for(let n of t)r+=String.fromCharCode(n);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function ke(e){return e instanceof DOMException?e.name:"UnknownError"}var de=0;function le(){return de+=1,`network-${de}`}function Pe(e,t){let r=e.responseType;if(r===""||r==="text")return t(e.responseText);if(r==="json"){let n=e.response;return n==null?void 0:t(n)}}var qe=500,xe=65536,pe=Symbol("body-read-timeout");function fe(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function he(e,t){let r=e.body;if(!r)return;let n=r.getReader(),o;try{let a=new Promise(v=>{o=setTimeout(()=>v(pe),qe)}),d=new TextDecoder,p=[];for(;;){let v=await Promise.race([n.read(),a]);if(v===pe){t.log("body omitted: read timed out"),n.cancel().catch(()=>{});return}if(v.done)break;p.push(d.decode(v.value,{stream:!0}))}return p.push(d.decode()),p.join("")}catch{n.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function ie(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function se(e,t,r,n,o){try{let a=Object.getOwnPropertyDescriptor(e,t);Le(a,{...n,value:r})&&Object.defineProperty(e,t,n)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function Le(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Ne(e){var R,Z,V,ee;let{onExchange:t,onRequest:r,match:n}=e;if(typeof t!="function"||typeof n!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=j(e.logger),a=(R=e.transports)!=null?R:["xhr","fetch"],d=(Z=e.bodyCapture)==null?void 0:Z.request,p=(V=e.bodyCapture)==null?void 0:V.response,v=typeof d=="function",k=typeof p=="function",D=(ee=e.maxBodyChars)!=null?ee:xe,h=!1,S=_(o,"network",f=>{if(h)return t(f)}),u=_(o,"network request",f=>{if(h)return r==null?void 0:r(f)}),s=(f,m)=>{let C=m.direction==="request"?d:p;if(typeof C=="function")try{let c=C(f,m);if(c===void 0||typeof(c==null?void 0:c.then)=="function")return;let F=JSON.stringify(c);return F===void 0||F.length>D?void 0:JSON.parse(F)}catch(c){o.log("body projection failed",c);return}},b=(f,m)=>{try{let C=typeof document!="undefined"?document.baseURI:void 0,c=new URL(String(f),C);return/\/observe\/events\/[^/]+\/?$/.test(c.pathname)?void 0:n(c,m)===!0?{url:c.href,path:c.pathname}:void 0}catch{return}},L=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let f=XMLHttpRequest.prototype,m=Object.getOwnPropertyDescriptor(f,"open"),C=Object.getOwnPropertyDescriptor(f,"send");if(!m||!("value"in m)||typeof m.value!="function"||!C||!("value"in C)||typeof C.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let c=m.value,F=C.value;if(B(c)||B(F))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let X=new WeakMap,A=new Set,x=!1,T={open(...E){var g;let i=Reflect.apply(c,this,E);if(!h||!x)return i;try{let N=X.get(this);N&&(N.reported=!0,(g=N.cleanupListeners)==null||g.call(N));let H=String(E[0]).toUpperCase(),P=b(E[1],H);P?X.set(this,{method:H,url:P.url,path:P.path,reported:!1}):X.delete(this)}catch(N){o.log("xhr open observation failed",N)}return i}}.open,J={send(...E){let i=h&&x?X.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(F,this,E);let g=()=>{},N=!1;try{i.requestId=le();let P={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=v&&typeof E[0]=="string"?s(E[0],P):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},y=()=>{var K;g();try{if(!h||!x||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},re=this.status,ue={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:re,ok:re>=200&&re<300,outcome:(K=i.outcome)!=null?K:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:k?Pe(this,be=>s(be,U)):void 0};i.requestEmitted?S(ue):i.pendingExchange=ue}catch(U){o.log("xhr exchange observation failed",U)}finally{X.get(this)===i&&X.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&y()}catch(K){o.log("xhr ready-state observation failed",K)}},W=()=>y();g=()=>{for(let[K,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",W]])this.removeEventListener(K,U);i.cleanupListeners===g&&(i.cleanupListeners=void 0),A.delete(g)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",W),i.cleanupListeners=g,A.add(g),i.startedAt=Date.now(),N=!0}catch(P){o.log("xhr send observation failed",P),g()}let H;try{H=Reflect.apply(F,this,E)}catch(P){throw g(),P}if(N&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,u({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let P=i.pendingExchange;i.pendingExchange=void 0,P&&S(P)}return H}}.send;return M(T,c),M(J,F),m.writable!==!0||C.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(f,"open",{...m,value:T}),Object.defineProperty(f,"send",{...C,value:J}),x=!0,()=>{x=!1;for(let E of[...A])E();se(f,"open",T,m,o),se(f,"send",J,C,o)})},q=()=>{let f=globalThis,m=Object.getOwnPropertyDescriptor(f,"fetch");if(!m||!("value"in m))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let C=m.value;if(typeof C!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(B(C))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let c=!1,F=async(A,x,T,J)=>{try{if(!h||!c){ie(T);return}let[E,i]=await Promise.all([J!=null?J:Promise.resolve(void 0),T?he(T,o):Promise.resolve(void 0)]);if(!h||!c)return;let g={direction:"request",transport:"fetch",method:A.method,url:A.url,path:A.path},N={...g,direction:"response"},H=A.requestBody;H===void 0&&E!==void 0&&(H=s(E,g));let P=i!==void 0?s(i,N):void 0;S({requestId:A.requestId,transport:"fetch",method:A.method,url:A.url,path:A.path,status:x.status,ok:x.ok,outcome:"load",durationMs:Date.now()-A.startedAt,responseUrl:x.url||void 0,requestBody:H,responseBody:P})}catch(E){o.log("fetch exchange observation failed",E)}},X={fetch(...A){var H,P,G,Y;let x;try{let l=A[0],y=A[1];if(h&&c&&v&&typeof Request!="undefined"&&l instanceof Request&&(y==null?void 0:y.body)===void 0&&l.body){let I=String((H=y==null?void 0:y.method)!=null?H:l.method).toUpperCase(),W=(P=l.headers.get("content-type"))!=null?P:"";b(l.url,I)&&fe(W)&&(x=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,J=Date.now();try{T=Reflect.apply(C,this,A)}catch(l){throw ie(x),l}let E,i;try{if(h&&c){let l=A[0],y=A[1],I=typeof Request!="undefined"&&l instanceof Request,W=String((G=y==null?void 0:y.method)!=null?G:I?l.method:"GET").toUpperCase(),K=I?l.url:l,U=b(K,W);U&&(E={requestId:le(),method:W,url:U.url,path:U.path,startedAt:J},i=(Y=y==null?void 0:y.signal)!=null?Y:I?l.signal:void 0,v&&typeof(y==null?void 0:y.body)=="string"&&(E.requestBody=s(y.body,{direction:"request",transport:"fetch",method:W,url:U.url,path:U.path})))}}catch(l){o.log("fetch observation failed",l)}if(!E)return ie(x),T;let g=E;u({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,startedAt:g.startedAt,requestBody:g.requestBody});let N=x?he(x,o):void 0;return T.then(l=>{var I;let y;try{if(h&&c&&k){let W=(I=l.headers.get("content-type"))!=null?I:"";fe(W)&&l.body&&(y=l.clone())}}catch{}F(g,l,y,N)},l=>{try{if(!h||!c)return;let y=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;S({requestId:g.requestId,transport:"fetch",method:g.method,url:g.url,path:g.path,status:0,ok:!1,outcome:y?"abort":"error",durationMs:Date.now()-g.startedAt})}catch(y){o.log("fetch failure observation failed",y)}}),T}}.fetch;return M(X,C),m.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(f,"fetch",{...m,value:X}),c=!0,()=>{c=!1,se(f,"fetch",X,m,o)})},O=[];if(a.includes("xhr")){let f=L();f&&O.push(f)}if(a.includes("fetch")){let f=q();f&&O.push(f)}return O.length===0?w():(h=!0,{mode:"standard",disconnect:()=>{h=!1;for(let f of O.splice(0))f()}})}function De(e){let t=j(),r;try{if(t=j(e.logger),r=e.onNavigate,typeof r!="function")return w()}catch{return w()}let n,o,a,d,p,v;try{if(n=window,o=n==null?void 0:n.history,!n||!o)return t.log("navigation capture unavailable: window/history missing"),w();if(p=ge(o,"pushState"),v=ge(o,"replaceState"),!p||!v)return t.log("navigation capture unavailable: history method descriptors missing"),w();if(a=p.descriptor.value,d=v.descriptor.value,typeof a!="function"||typeof d!="function")return t.log("navigation capture unavailable: history methods missing"),w();if(typeof n.addEventListener!="function"||typeof n.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),w()}catch(O){return t.log("navigation capture unavailable: history inspection failed",O),w()}if(B(a)||B(d))return t.log("navigation capture unavailable: an equivalent capture is already active"),w();let k=!1,D=()=>({path:n.location.pathname,search:n.location.search,hash:n.location.hash}),h;try{h=D()}catch(O){return t.log("navigation capture unavailable: location inspection failed",O),w()}let S=_(t,"navigation",O=>{if(k)return r(O)}),u=O=>{if(k)try{let R=D();if(R.path===h.path&&R.search===h.search&&R.hash===h.hash)return;h=R,S({...R,source:O})}catch(R){t.log("navigation observation failed",R)}},s={pushState(...O){let R=Reflect.apply(a,this,O);return u("push"),R}}.pushState,b={replaceState(...O){let R=Reflect.apply(d,this,O);return u("replace"),R}}.replaceState;M(s,a),M(b,d);let L=()=>u("pop"),q=()=>u("hash");try{if(ye(p,s),ye(v,b),o.pushState!==s||o.replaceState!==b)throw new Error("history method replacement did not take effect");n.addEventListener("popstate",L),n.addEventListener("hashchange",q),k=!0}catch(O){return k=!1,ne(n,"popstate",L,t),ne(n,"hashchange",q,t),te(v,b,t),te(p,s,t),t.log("navigation capture unavailable: history methods are not writable",O),r=()=>{},S=()=>{},t=j(),w()}return{mode:"standard",disconnect:()=>{k=!1,r=()=>{},ne(n,"popstate",L,t),ne(n,"hashchange",q,t),te(p,s,t),te(v,b,t),S=()=>{},t=j()}}}function ge(e,t){let r=e;for(;r;){let n=Object.getOwnPropertyDescriptor(r,t);if(n)return!("value"in n)||typeof n.value!="function"?null:{owner:r,key:t,descriptor:n};r=Object.getPrototypeOf(r)}return null}function ye(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let r=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!me(r,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function me(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function te(e,t,r){try{let n=Object.getOwnPropertyDescriptor(e.owner,e.key);me(n,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(n){r.log(`navigation ${e.key} restoration skipped`,n)}}function ne(e,t,r,n){try{e.removeEventListener(t,r)}catch(o){n.log(`navigation ${t} listener removal skipped`,o)}}function Te(e){var S;let t=(S=e.logger)!=null?S:oe,r=e.onAttached;if(typeof r!="function")return w();let n=Element.prototype,o=Object.getOwnPropertyDescriptor(n,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),w();let a=o.value;if(B(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),w();let d=!1,p=new WeakSet,v=_(t,"shadow-root",r),k=(u,s)=>{!d||p.has(s)||(p.add(s),v({host:u,shadowRoot:s,mode:s.mode==="closed"?"closed":"open"}))},D={attachShadow(...u){let s=Reflect.apply(a,this,u);return k(this,s),s}}.attachShadow;M(D,a);try{Object.defineProperty(n,"attachShadow",{...o,value:D})}catch(u){return t.log("shadow-root capture unavailable: attachShadow is locked",u),w()}d=!0;let h=u=>{let s=u.querySelectorAll("*");for(let b=0;b<s.length&&d;b++){let L=s[b].shadowRoot;L&&(k(s[b],L),h(L))}};return e.includeExisting&&h(document),{mode:"standard",disconnect:()=>{d=!1;let u=Object.getOwnPropertyDescriptor(n,"attachShadow");je(u,{...o,value:D})&&Object.defineProperty(n,"attachShadow",o)}}}function He(e){var t;return(t=ve(e)[0])!=null?t:null}function ve(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function je(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Be(e){var D,h,S;let t=j(e==null?void 0:e.logger),r=e==null?void 0:e.read,n=e==null?void 0:e.onState;if(typeof r!="function"||typeof n!="function")return we();let o=Number.isFinite(e.delayMs)&&((D=e.delayMs)!=null?D:0)>=0&&(h=e.delayMs)!=null?h:0,a=_(t,"ui-state",n),d=!0,p,v=[],k=()=>{d&&(p!==void 0&&clearTimeout(p),p=setTimeout(()=>{if(p=void 0,!!d)try{let u=r();u!==void 0&&a(u)}catch(u){t.log("ui-state read failed",u)}},o))};try{for(let u of(S=e.triggers)!=null?S:[]){if(!(u!=null&&u.target)||typeof u.target.addEventListener!="function")continue;let s=k;u.target.addEventListener(u.type,s,u.capture===!0),v.push({trigger:u,listener:s})}}catch(u){t.log("ui-state trigger installation failed",u);for(let{trigger:s,listener:b}of v)try{s.target.removeEventListener(s.type,b,s.capture===!0)}catch{}return d=!1,we()}return{mode:"standard",schedule:k,disconnect:()=>{if(d){d=!1,p!==void 0&&clearTimeout(p),p=void 0;for(let{trigger:u,listener:s}of v)try{u.target.removeEventListener(u.type,s,u.capture===!0)}catch(b){t.log("ui-state trigger removal failed",b)}v.length=0}}}}function we(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function Ie(e="[autocapture]"){return{log:(...t)=>{try{let r=console.log(e,...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}}var Ue="0.1.0-next.2-dd9eb36";export{Ue as VERSION,De as captureNavigation,Ne as captureNetwork,Te as captureShadowRoots,Be as captureUiState,Re as captureWebAuthn,ve as composedPath,He as composedTarget,Ie as createConsoleLogger};
1
+ var ne={log:()=>{}};function j(e){return e?{log:(...t)=>{try{let r=e.log(...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}:ne}var se=Symbol.for("corbado.autocapture.installed");function M(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,se)}catch{return!1}}function _(e,t){var n,o;let r=t;try{Object.defineProperty(e,se,{value:t,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(n=r.name)!=null?n:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=r.length)!=null?o:0,configurable:!0})}catch{}return e}function b(){return{mode:"unavailable",disconnect:()=>{}}}function W(e,t,r){let n=j(e);return o=>{try{let a=r(o);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(c=>n.log(`${t} listener failed`,c))}catch(c){n.log(`${t} listener failed`,c)}}catch(a){n.log(`${t} listener failed`,a)}}}function be(e){let t=j(e.logger),r=e.onEvent;if(typeof r!="function")return b();let n=typeof navigator=="undefined"?void 0:navigator,o=n==null?void 0:n.credentials;if(!n||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),b();let a=o.get,c=o.create;if(typeof a!="function"||typeof c!="function")return t.log("webauthn capture unavailable: credentials methods missing"),b();if(M(a)||M(c))return t.log("webauthn capture unavailable: an equivalent capture is already active"),b();let d=!1,g=0,P=W(t,"webauthn",u=>{if(d)return r(u)}),m=(u,w)=>{let N={invoke(...x){let k=this,R=x[0];if(!d||!Q(R)||!Q(R.publicKey))return Reflect.apply(w,k,x);let z=R.publicKey,p=`wa-${++g}`,C=Reflect.apply(w,k,x),v=Q(R.signal)?R.signal:void 0,f=we(u,R,z),X={...f,ceremonyId:p,phase:"started",userActivation:Se(n)};if(f.kind==="authentication"){let A=z;X.requestOptionsJson=Ee(A,t)}return P(X),Promise.resolve(C).then(A=>(d&&P({...f,ceremonyId:p,phase:"completed",credentialJson:Oe(A,u,t),...(v==null?void 0:v.aborted)===!0?{aborted:!0}:{}}),A),A=>{throw d&&P({...f,ceremonyId:p,phase:"failed",error:A,errorName:qe(A),...(v==null?void 0:v.aborted)===!0?{aborted:!0}:{}}),A})}}.invoke;return _(N,{name:u,length:0})},O=(u,w)=>{let N=m(u,w),x=Object.getOwnPropertyDescriptor(o,u);if(x&&(!("value"in x)||x.writable!==!0))return null;try{o[u]=N}catch{return null}return()=>{o[u]===N&&(x?o[u]=x.value:delete o[u])}},E=O("get",a),s=E?O("create",c):null;return!E||!s?(E==null||E(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),b()):(d=!0,{mode:"standard",disconnect:()=>{d=!1,E(),s()}})}function we(e,t,r){let n=Re(t.mediation);if(e==="create")return{kind:"registration",mediation:n};let o=r;return{kind:"authentication",mediation:n,uiMode:Ce(t.uiMode),credentialSet:Array.isArray(o.allowCredentials)&&o.allowCredentials.length>0?"allowlisted":"discoverable"}}function Re(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function Ce(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function Se(e){let t=e.userActivation;return typeof(t==null?void 0:t.isActive)=="boolean"?t.isActive:void 0}function Oe(e,t,r){var n;if(e)try{let o=e,a=o.response,c={id:J(o.id),rawId:$(o.rawId),type:J(o.type),authenticatorAttachment:J(o.authenticatorAttachment),response:t==="create"?{clientDataJSON:$(a==null?void 0:a.clientDataJSON),attestationObject:$(a==null?void 0:a.attestationObject),transports:re((n=a==null?void 0:a.getTransports)==null?void 0:n.call(a))}:{clientDataJSON:$(a==null?void 0:a.clientDataJSON),authenticatorData:$(a==null?void 0:a.authenticatorData),signature:$(a==null?void 0:a.signature),userHandle:$(a==null?void 0:a.userHandle)},...t==="create"?Ae(o):{}};return JSON.stringify(c)}catch(o){r.log("credential serialization failed",o);return}}function Ee(e,t){try{let r={},n=J(e.rpId),o=J(e.userVerification),a=re(e.hints);return n!==void 0&&(r.rpId=n),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(r.timeout=e.timeout),o!==void 0&&(r.userVerification=o),a!==void 0&&(r.hints=a),r.challenge=$(e.challenge),Array.isArray(e.allowCredentials)&&(r.allowCredentials=ke(e.allowCredentials)),JSON.stringify(r)}catch(r){t.log("request options serialization failed",r);return}}function ke(e){let t=[];for(let r of e){if(!Q(r))continue;let n=r;t.push({type:J(n.type),id:$(n.id),transports:re(n.transports)})}return t}function re(e){if(Array.isArray(e))return e.filter(t=>typeof t=="string")}function J(e){return typeof e=="string"?e:void 0}function Ae(e){var n;let t=(n=e.getClientExtensionResults)==null?void 0:n.call(e);if(!Q(t))return{};let r=t.credProps;return!r||typeof r.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:r.rk}}}}function $(e){let t;if(e instanceof ArrayBuffer)t=new Uint8Array(e);else if(ArrayBuffer.isView(e))t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let r="";for(let n of t)r+=String.fromCharCode(n);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Q(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function qe(e){return e instanceof DOMException?e.name:"UnknownError"}var ue=0;function ce(){return ue+=1,`network-${ue}`}function Pe(e,t){let r=e.responseType;if(r===""||r==="text")return t(e.responseText);if(r==="json"){let n=e.response;return n==null?void 0:t(n)}}var xe=500,de=Symbol("body-read-timeout");function le(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function pe(e,t){let r=e.body;if(!r)return;let n=r.getReader(),o;try{let a=new Promise(g=>{o=setTimeout(()=>g(de),xe)}),c=new TextDecoder,d=[];for(;;){let g=await Promise.race([n.read(),a]);if(g===de){t.log("body omitted: read timed out"),n.cancel().catch(()=>{});return}if(g.done)break;d.push(c.decode(g.value,{stream:!0}))}return d.push(c.decode()),d.join("")}catch{n.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function oe(e){var t;(t=e==null?void 0:e.body)==null||t.cancel().catch(()=>{})}function ae(e,t,r,n,o){try{let a=Object.getOwnPropertyDescriptor(e,t);De(a,{...n,value:r})&&Object.defineProperty(e,t,n)}catch(a){o.log(`${String(t)} restoration skipped`,a)}}function De(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Le(e){var k,R,z;let{onExchange:t,onRequest:r,match:n}=e;if(typeof t!="function"||typeof n!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=j(e.logger),a=(k=e.transports)!=null?k:["xhr","fetch"],c=(R=e.bodyCapture)==null?void 0:R.request,d=(z=e.bodyCapture)==null?void 0:z.response,g=typeof c=="function",P=typeof d=="function",m=!1,O=W(o,"network",p=>{if(m)return t(p)}),E=W(o,"network request",p=>{if(m)return r==null?void 0:r(p)}),s=(p,C,v)=>{if(typeof v=="function")try{let f=v(p,C);return f===void 0||typeof(f==null?void 0:f.then)=="function"?void 0:f}catch(f){o.log("body projection failed",f);return}},u=(p,C)=>{try{let v=typeof document!="undefined"?document.baseURI:void 0,f=new URL(String(p),v);return/\/observe\/events\/[^/]+\/?$/.test(f.pathname)?void 0:n(f,C)===!0?{url:f.href,path:f.pathname}:void 0}catch{return}},w=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let p=XMLHttpRequest.prototype,C=Object.getOwnPropertyDescriptor(p,"open"),v=Object.getOwnPropertyDescriptor(p,"send");if(!C||!("value"in C)||typeof C.value!="function"||!v||!("value"in v)||typeof v.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let f=C.value,X=v.value;if(M(f)||M(X))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let A=new WeakMap,q=new Set,L=!1,T={open(...S){var h;let i=Reflect.apply(f,this,S);if(!m||!L)return i;try{let B=A.get(this);B&&(B.reported=!0,(h=B.cleanupListeners)==null||h.call(B));let H=String(S[0]).toUpperCase(),D=u(S[1],H);D?A.set(this,{method:H,url:D.url,path:D.path,reported:!1}):A.delete(this)}catch(B){o.log("xhr open observation failed",B)}return i}}.open,K={send(...S){let i=m&&L?A.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(X,this,S);let h=()=>{},B=!1;try{i.requestId=ce();let D={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=g&&typeof S[0]=="string"?s(S[0],D,c):void 0;let G=()=>{i.outcome===void 0&&(i.outcome="abort")},Y=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},y=()=>{var V;h();try{if(!m||!L||i.reported||!i.requestId)return;i.reported=!0;let U={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},te=this.status,ie={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:te,ok:te>=200&&te<300,outcome:(V=i.outcome)!=null?V:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:P?Pe(this,ve=>s(ve,U,d)):void 0};i.requestEmitted?O(ie):i.pendingExchange=ie}catch(U){o.log("xhr exchange observation failed",U)}finally{A.get(this)===i&&A.delete(this)}},I=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&y()}catch(V){o.log("xhr ready-state observation failed",V)}},F=()=>y();h=()=>{for(let[V,U]of[["readystatechange",I],["abort",G],["timeout",Y],["error",l],["loadend",F]])this.removeEventListener(V,U);i.cleanupListeners===h&&(i.cleanupListeners=void 0),q.delete(h)},this.addEventListener("readystatechange",I),this.addEventListener("abort",G),this.addEventListener("timeout",Y),this.addEventListener("error",l),this.addEventListener("loadend",F),i.cleanupListeners=h,q.add(h),i.startedAt=Date.now(),B=!0}catch(D){o.log("xhr send observation failed",D),h()}let H;try{H=Reflect.apply(X,this,S)}catch(D){throw h(),D}if(B&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,E({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let D=i.pendingExchange;i.pendingExchange=void 0,D&&O(D)}return H}}.send;return _(T,f),_(K,X),C.writable!==!0||v.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(p,"open",{...C,value:T}),Object.defineProperty(p,"send",{...v,value:K}),L=!0,()=>{L=!1;for(let S of[...q])S();ae(p,"open",T,C,o),ae(p,"send",K,v,o)})},N=()=>{let p=globalThis,C=Object.getOwnPropertyDescriptor(p,"fetch");if(!C||!("value"in C))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let v=C.value;if(typeof v!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(M(v))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let f=!1,X=async(q,L,T,K)=>{try{if(!m||!f){oe(T);return}let[S,i]=await Promise.all([K!=null?K:Promise.resolve(void 0),T?pe(T,o):Promise.resolve(void 0)]);if(!m||!f)return;let h={direction:"request",transport:"fetch",method:q.method,url:q.url,path:q.path},B={...h,direction:"response"},H=q.requestBody;H===void 0&&S!==void 0&&(H=s(S,h,c));let D=i!==void 0?s(i,B,d):void 0;O({requestId:q.requestId,transport:"fetch",method:q.method,url:q.url,path:q.path,status:L.status,ok:L.ok,outcome:"load",durationMs:Date.now()-q.startedAt,responseUrl:L.url||void 0,requestBody:H,responseBody:D})}catch(S){o.log("fetch exchange observation failed",S)}},A={fetch(...q){var H,D,G,Y;let L;try{let l=q[0],y=q[1];if(m&&f&&g&&typeof Request!="undefined"&&l instanceof Request&&(y==null?void 0:y.body)===void 0&&l.body){let I=String((H=y==null?void 0:y.method)!=null?H:l.method).toUpperCase(),F=(D=l.headers.get("content-type"))!=null?D:"";u(l.url,I)&&le(F)&&(L=l.clone())}}catch(l){o.log("fetch observation failed",l)}let T,K=Date.now();try{T=Reflect.apply(v,this,q)}catch(l){throw oe(L),l}let S,i;try{if(m&&f){let l=q[0],y=q[1],I=typeof Request!="undefined"&&l instanceof Request,F=String((G=y==null?void 0:y.method)!=null?G:I?l.method:"GET").toUpperCase(),V=I?l.url:l,U=u(V,F);U&&(S={requestId:ce(),method:F,url:U.url,path:U.path,startedAt:K},i=(Y=y==null?void 0:y.signal)!=null?Y:I?l.signal:void 0,g&&typeof(y==null?void 0:y.body)=="string"&&(S.requestBody=s(y.body,{direction:"request",transport:"fetch",method:F,url:U.url,path:U.path},c)))}}catch(l){o.log("fetch observation failed",l)}if(!S)return oe(L),T;let h=S;E({requestId:h.requestId,transport:"fetch",method:h.method,url:h.url,path:h.path,startedAt:h.startedAt,requestBody:h.requestBody});let B=L?pe(L,o):void 0;return T.then(l=>{var I;let y;try{if(m&&f&&P){let F=(I=l.headers.get("content-type"))!=null?I:"";le(F)&&l.body&&(y=l.clone())}}catch{}X(h,l,y,B)},l=>{try{if(!m||!f)return;let y=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;O({requestId:h.requestId,transport:"fetch",method:h.method,url:h.url,path:h.path,status:0,ok:!1,outcome:y?"abort":"error",durationMs:Date.now()-h.startedAt})}catch(y){o.log("fetch failure observation failed",y)}}),T}}.fetch;return _(A,v),C.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(p,"fetch",{...C,value:A}),f=!0,()=>{f=!1,ae(p,"fetch",A,C,o)})},x=[];if(a.includes("xhr")){let p=w();p&&x.push(p)}if(a.includes("fetch")){let p=N();p&&x.push(p)}return x.length===0?b():(m=!0,{mode:"standard",disconnect:()=>{m=!1;for(let p of x.splice(0))p()}})}function Ne(e){let t=j(),r;try{if(t=j(e.logger),r=e.onNavigate,typeof r!="function")return b()}catch{return b()}let n,o,a,c,d,g;try{if(n=window,o=n==null?void 0:n.history,!n||!o)return t.log("navigation capture unavailable: window/history missing"),b();if(d=fe(o,"pushState"),g=fe(o,"replaceState"),!d||!g)return t.log("navigation capture unavailable: history method descriptors missing"),b();if(a=d.descriptor.value,c=g.descriptor.value,typeof a!="function"||typeof c!="function")return t.log("navigation capture unavailable: history methods missing"),b();if(typeof n.addEventListener!="function"||typeof n.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),b()}catch(k){return t.log("navigation capture unavailable: history inspection failed",k),b()}if(M(a)||M(c))return t.log("navigation capture unavailable: an equivalent capture is already active"),b();let P=!1,m=()=>({path:n.location.pathname,search:n.location.search,hash:n.location.hash}),O;try{O=m()}catch(k){return t.log("navigation capture unavailable: location inspection failed",k),b()}let E=W(t,"navigation",k=>{if(P)return r(k)}),s=k=>{if(P)try{let R=m();if(R.path===O.path&&R.search===O.search&&R.hash===O.hash)return;O=R,E({...R,source:k})}catch(R){t.log("navigation observation failed",R)}},u={pushState(...k){let R=Reflect.apply(a,this,k);return s("push"),R}}.pushState,w={replaceState(...k){let R=Reflect.apply(c,this,k);return s("replace"),R}}.replaceState;_(u,a),_(w,c);let N=()=>s("pop"),x=()=>s("hash");try{if(he(d,u),he(g,w),o.pushState!==u||o.replaceState!==w)throw new Error("history method replacement did not take effect");n.addEventListener("popstate",N),n.addEventListener("hashchange",x),P=!0}catch(k){return P=!1,ee(n,"popstate",N,t),ee(n,"hashchange",x,t),Z(g,w,t),Z(d,u,t),t.log("navigation capture unavailable: history methods are not writable",k),r=()=>{},E=()=>{},t=j(),b()}return{mode:"standard",disconnect:()=>{P=!1,r=()=>{},ee(n,"popstate",N,t),ee(n,"hashchange",x,t),Z(d,u,t),Z(g,w,t),E=()=>{},t=j()}}}function fe(e,t){let r=e;for(;r;){let n=Object.getOwnPropertyDescriptor(r,t);if(n)return!("value"in n)||typeof n.value!="function"?null:{owner:r,key:t,descriptor:n};r=Object.getPrototypeOf(r)}return null}function he(e,t){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let r=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!ye(r,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:t})}function ye(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function Z(e,t,r){try{let n=Object.getOwnPropertyDescriptor(e.owner,e.key);ye(n,{...e.descriptor,value:t})&&Object.defineProperty(e.owner,e.key,e.descriptor)}catch(n){r.log(`navigation ${e.key} restoration skipped`,n)}}function ee(e,t,r,n){try{e.removeEventListener(t,r)}catch(o){n.log(`navigation ${t} listener removal skipped`,o)}}function Be(e){var E;let t=(E=e.logger)!=null?E:ne,r=e.onAttached;if(typeof r!="function")return b();let n=Element.prototype,o=Object.getOwnPropertyDescriptor(n,"attachShadow");if(!o||typeof o.value!="function")return t.log("shadow-root capture unavailable: attachShadow not supported"),b();let a=o.value;if(M(a))return t.log("shadow-root capture unavailable: an equivalent capture is already active"),b();let c=!1,d=new WeakSet,g=W(t,"shadow-root",r),P=(s,u)=>{!c||d.has(u)||(d.add(u),g({host:s,shadowRoot:u,mode:u.mode==="closed"?"closed":"open"}))},m={attachShadow(...s){let u=Reflect.apply(a,this,s);return P(this,u),u}}.attachShadow;_(m,a);try{Object.defineProperty(n,"attachShadow",{...o,value:m})}catch(s){return t.log("shadow-root capture unavailable: attachShadow is locked",s),b()}c=!0;let O=s=>{let u=s.querySelectorAll("*");for(let w=0;w<u.length&&c;w++){let N=u[w].shadowRoot;N&&(P(u[w],N),O(N))}};return e.includeExisting&&O(document),{mode:"standard",disconnect:()=>{c=!1;let s=Object.getOwnPropertyDescriptor(n,"attachShadow");He(s,{...o,value:m})&&Object.defineProperty(n,"attachShadow",o)}}}function Te(e){var t;return(t=ge(e)[0])!=null?t:null}function ge(e){let t=e.composedPath();return t.length>0?t:e.target?[e.target]:[]}function He(e,t){return!!e&&"value"in e&&"value"in t&&e.value===t.value&&e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable}function je(e){var m,O,E;let t=j(e==null?void 0:e.logger),r=e==null?void 0:e.read,n=e==null?void 0:e.onState;if(typeof r!="function"||typeof n!="function")return me();let o=Number.isFinite(e.delayMs)&&((m=e.delayMs)!=null?m:0)>=0&&(O=e.delayMs)!=null?O:0,a=W(t,"ui-state",n),c=!0,d,g=[],P=()=>{c&&(d!==void 0&&clearTimeout(d),d=setTimeout(()=>{if(d=void 0,!!c)try{let s=r();s!==void 0&&a(s)}catch(s){t.log("ui-state read failed",s)}},o))};try{for(let s of(E=e.triggers)!=null?E:[]){if(!(s!=null&&s.target)||typeof s.target.addEventListener!="function")continue;let u=P;s.target.addEventListener(s.type,u,s.capture===!0),g.push({trigger:s,listener:u})}}catch(s){t.log("ui-state trigger installation failed",s);for(let{trigger:u,listener:w}of g)try{u.target.removeEventListener(u.type,w,u.capture===!0)}catch{}return c=!1,me()}return{mode:"standard",schedule:P,disconnect:()=>{if(c){c=!1,d!==void 0&&clearTimeout(d),d=void 0;for(let{trigger:s,listener:u}of g)try{s.target.removeEventListener(s.type,u,s.capture===!0)}catch(w){t.log("ui-state trigger removal failed",w)}g.length=0}}}}function me(){return{mode:"unavailable",schedule:()=>{},disconnect:()=>{}}}function Me(e="[autocapture]"){return{log:(...t)=>{try{let r=console.log(e,...t);if(r&&(typeof r=="object"||typeof r=="function"))try{Promise.resolve(r).catch(()=>{})}catch{}}catch{}}}}var Ie="0.1.0-next.3-b8e8889";export{Ie as VERSION,Ne as captureNavigation,Le as captureNetwork,Be as captureShadowRoots,je as captureUiState,be as captureWebAuthn,ge as composedPath,Te as composedTarget,Me as createConsoleLogger};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corbado/autocapture",
3
- "version": "0.1.0-next.2-dd9eb36",
3
+ "version": "0.1.0-next.3-b8e8889",
4
4
  "description": "Observer-style capture helpers for WebAuthn ceremonies, selected network exchanges, in-app navigation, shadow roots, and rendered UI state.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",