@trymellon/js 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -32,9 +32,14 @@ interface TelemetrySender {
32
32
  send(payload: TelemetryPayload): Promise<void>;
33
33
  }
34
34
 
35
+ type Branded<T, B> = T & {
36
+ __brand: B;
37
+ };
38
+ type AppId = Branded<string, 'AppId'>;
39
+ type ExternalUserId = Branded<string, 'ExternalUserId'>;
35
40
  type TryMellonConfig = {
36
41
  /** Application identifier (tenant). Required for API requests. */
37
- appId: string;
42
+ appId: string | AppId;
38
43
  /** API key for authentication. Required for API requests. */
39
44
  publishableKey: string;
40
45
  apiBaseUrl?: string;
@@ -49,16 +54,26 @@ type TryMellonConfig = {
49
54
  telemetrySender?: TelemetrySender;
50
55
  /** Endpoint for default telemetry sender when enableTelemetry is true and telemetrySender not set. */
51
56
  telemetryEndpoint?: string;
57
+ /**
58
+ * When true, register() and authenticate() return immediately with a fixed sandbox token (no API or WebAuthn).
59
+ * For local development only. Your backend must NOT accept the sandbox token in production.
60
+ */
61
+ sandbox?: boolean;
62
+ /**
63
+ * Custom token to return in sandbox mode. If not set, SANDBOX_SESSION_TOKEN is used.
64
+ * Only used when sandbox is true.
65
+ */
66
+ sandboxToken?: string;
52
67
  };
53
68
  interface RegisterOptions {
54
69
  /**
55
70
  * Impacto en Analytics y Dashboard.
56
71
  */
57
- externalUserId?: string;
72
+ externalUserId?: string | ExternalUserId;
58
73
  /**
59
74
  * @deprecated Use `externalUserId` instead.
60
75
  */
61
- external_user_id?: string;
76
+ external_user_id?: string | ExternalUserId;
62
77
  authenticatorType?: 'platform' | 'cross-platform';
63
78
  signal?: AbortSignal;
64
79
  }
@@ -66,11 +81,11 @@ interface AuthenticateOptions {
66
81
  /**
67
82
  * Impacto en Analytics y Dashboard.
68
83
  */
69
- externalUserId?: string;
84
+ externalUserId?: string | ExternalUserId;
70
85
  /**
71
86
  * @deprecated Use `externalUserId` instead.
72
87
  */
73
- external_user_id?: string;
88
+ external_user_id?: string | ExternalUserId;
74
89
  hint?: string;
75
90
  signal?: AbortSignal;
76
91
  /** Conditional UI mediation for passkey autofill / conditional UI. */
@@ -425,11 +440,23 @@ declare class OnboardingManager {
425
440
  }
426
441
 
427
442
  declare class TryMellon {
443
+ private readonly sandbox;
444
+ private readonly sandboxToken;
428
445
  private apiClient;
429
446
  private eventEmitter;
430
447
  private telemetrySender;
431
448
  private crossDeviceManager;
432
449
  onboarding: OnboardingManager;
450
+ /**
451
+ * Configura una nueva instancia de TryMellon.
452
+ * Valida la configuración y retorna un Result.
453
+ * @param config Configuración del SDK
454
+ */
455
+ static create(config: TryMellonConfig): Result<TryMellon, TryMellonError>;
456
+ /**
457
+ * @deprecated Use `TryMellon.create(config)` instead to handle validation errors safely.
458
+ * This constructor will throw errors if configuration is invalid.
459
+ */
433
460
  constructor(config: TryMellonConfig);
434
461
  static isSupported(): boolean;
435
462
  register(options: RegisterOptions): Promise<Result<RegisterResult, TryMellonError>>;
@@ -456,6 +483,12 @@ declare class TryMellon {
456
483
  };
457
484
  }
458
485
 
486
+ /**
487
+ * Fixed session token returned by register() and authenticate() when sandbox mode is enabled.
488
+ * Backends MUST NOT accept this token in production; only in development for testing the integration flow.
489
+ */
490
+ declare const SANDBOX_SESSION_TOKEN = "trymellon_sandbox_session_token_v1";
491
+
459
492
  declare class ConsoleLogger implements Logger {
460
493
  debug(message: string, meta?: Record<string, unknown>): void;
461
494
  info(message: string, meta?: Record<string, unknown>): void;
@@ -463,4 +496,4 @@ declare class ConsoleLogger implements Logger {
463
496
  error(message: string, meta?: Record<string, unknown>): void;
464
497
  }
465
498
 
466
- export { type AuthenticateOptions, type AuthenticateResult, type ClientStatus, ConsoleLogger, type EmailFallbackStartOptions, type EmailFallbackVerifyOptions, type EmailFallbackVerifyResult, type EventHandler, type EventPayload, type LogLevel, type Logger, type OnboardingCompleteOptions, type OnboardingCompleteResult, type OnboardingRegisterPasskeyOptions, type OnboardingRegisterPasskeyResult, type OnboardingRegisterResult, type OnboardingStartOptions, type OnboardingStartResult, type OnboardingStatusResult, type RegisterOptions, type RegisterResult, type Result, type SessionValidateResponse, TryMellon, type TryMellonConfig, TryMellonError, type TryMellonErrorCode, type TryMellonEvent, createError, createInvalidArgumentError, createNetworkError, createNotSupportedError, createTimeoutError, createUserCancelledError, err, isTryMellonError, mapWebAuthnError, ok };
499
+ export { type AuthenticateOptions, type AuthenticateResult, type ClientStatus, ConsoleLogger, type EmailFallbackStartOptions, type EmailFallbackVerifyOptions, type EmailFallbackVerifyResult, type EventHandler, type EventPayload, type LogLevel, type Logger, type OnboardingCompleteOptions, type OnboardingCompleteResult, type OnboardingRegisterPasskeyOptions, type OnboardingRegisterPasskeyResult, type OnboardingRegisterResult, type OnboardingStartOptions, type OnboardingStartResult, type OnboardingStatusResult, type RegisterOptions, type RegisterResult, type Result, SANDBOX_SESSION_TOKEN, type SessionValidateResponse, TryMellon, type TryMellonConfig, TryMellonError, type TryMellonErrorCode, type TryMellonEvent, createError, createInvalidArgumentError, createNetworkError, createNotSupportedError, createTimeoutError, createUserCancelledError, err, isTryMellonError, mapWebAuthnError, ok };
package/dist/index.d.ts CHANGED
@@ -32,9 +32,14 @@ interface TelemetrySender {
32
32
  send(payload: TelemetryPayload): Promise<void>;
33
33
  }
34
34
 
35
+ type Branded<T, B> = T & {
36
+ __brand: B;
37
+ };
38
+ type AppId = Branded<string, 'AppId'>;
39
+ type ExternalUserId = Branded<string, 'ExternalUserId'>;
35
40
  type TryMellonConfig = {
36
41
  /** Application identifier (tenant). Required for API requests. */
37
- appId: string;
42
+ appId: string | AppId;
38
43
  /** API key for authentication. Required for API requests. */
39
44
  publishableKey: string;
40
45
  apiBaseUrl?: string;
@@ -49,16 +54,26 @@ type TryMellonConfig = {
49
54
  telemetrySender?: TelemetrySender;
50
55
  /** Endpoint for default telemetry sender when enableTelemetry is true and telemetrySender not set. */
51
56
  telemetryEndpoint?: string;
57
+ /**
58
+ * When true, register() and authenticate() return immediately with a fixed sandbox token (no API or WebAuthn).
59
+ * For local development only. Your backend must NOT accept the sandbox token in production.
60
+ */
61
+ sandbox?: boolean;
62
+ /**
63
+ * Custom token to return in sandbox mode. If not set, SANDBOX_SESSION_TOKEN is used.
64
+ * Only used when sandbox is true.
65
+ */
66
+ sandboxToken?: string;
52
67
  };
53
68
  interface RegisterOptions {
54
69
  /**
55
70
  * Impacto en Analytics y Dashboard.
56
71
  */
57
- externalUserId?: string;
72
+ externalUserId?: string | ExternalUserId;
58
73
  /**
59
74
  * @deprecated Use `externalUserId` instead.
60
75
  */
61
- external_user_id?: string;
76
+ external_user_id?: string | ExternalUserId;
62
77
  authenticatorType?: 'platform' | 'cross-platform';
63
78
  signal?: AbortSignal;
64
79
  }
@@ -66,11 +81,11 @@ interface AuthenticateOptions {
66
81
  /**
67
82
  * Impacto en Analytics y Dashboard.
68
83
  */
69
- externalUserId?: string;
84
+ externalUserId?: string | ExternalUserId;
70
85
  /**
71
86
  * @deprecated Use `externalUserId` instead.
72
87
  */
73
- external_user_id?: string;
88
+ external_user_id?: string | ExternalUserId;
74
89
  hint?: string;
75
90
  signal?: AbortSignal;
76
91
  /** Conditional UI mediation for passkey autofill / conditional UI. */
@@ -425,11 +440,23 @@ declare class OnboardingManager {
425
440
  }
426
441
 
427
442
  declare class TryMellon {
443
+ private readonly sandbox;
444
+ private readonly sandboxToken;
428
445
  private apiClient;
429
446
  private eventEmitter;
430
447
  private telemetrySender;
431
448
  private crossDeviceManager;
432
449
  onboarding: OnboardingManager;
450
+ /**
451
+ * Configura una nueva instancia de TryMellon.
452
+ * Valida la configuración y retorna un Result.
453
+ * @param config Configuración del SDK
454
+ */
455
+ static create(config: TryMellonConfig): Result<TryMellon, TryMellonError>;
456
+ /**
457
+ * @deprecated Use `TryMellon.create(config)` instead to handle validation errors safely.
458
+ * This constructor will throw errors if configuration is invalid.
459
+ */
433
460
  constructor(config: TryMellonConfig);
434
461
  static isSupported(): boolean;
435
462
  register(options: RegisterOptions): Promise<Result<RegisterResult, TryMellonError>>;
@@ -456,6 +483,12 @@ declare class TryMellon {
456
483
  };
457
484
  }
458
485
 
486
+ /**
487
+ * Fixed session token returned by register() and authenticate() when sandbox mode is enabled.
488
+ * Backends MUST NOT accept this token in production; only in development for testing the integration flow.
489
+ */
490
+ declare const SANDBOX_SESSION_TOKEN = "trymellon_sandbox_session_token_v1";
491
+
459
492
  declare class ConsoleLogger implements Logger {
460
493
  debug(message: string, meta?: Record<string, unknown>): void;
461
494
  info(message: string, meta?: Record<string, unknown>): void;
@@ -463,4 +496,4 @@ declare class ConsoleLogger implements Logger {
463
496
  error(message: string, meta?: Record<string, unknown>): void;
464
497
  }
465
498
 
466
- export { type AuthenticateOptions, type AuthenticateResult, type ClientStatus, ConsoleLogger, type EmailFallbackStartOptions, type EmailFallbackVerifyOptions, type EmailFallbackVerifyResult, type EventHandler, type EventPayload, type LogLevel, type Logger, type OnboardingCompleteOptions, type OnboardingCompleteResult, type OnboardingRegisterPasskeyOptions, type OnboardingRegisterPasskeyResult, type OnboardingRegisterResult, type OnboardingStartOptions, type OnboardingStartResult, type OnboardingStatusResult, type RegisterOptions, type RegisterResult, type Result, type SessionValidateResponse, TryMellon, type TryMellonConfig, TryMellonError, type TryMellonErrorCode, type TryMellonEvent, createError, createInvalidArgumentError, createNetworkError, createNotSupportedError, createTimeoutError, createUserCancelledError, err, isTryMellonError, mapWebAuthnError, ok };
499
+ export { type AuthenticateOptions, type AuthenticateResult, type ClientStatus, ConsoleLogger, type EmailFallbackStartOptions, type EmailFallbackVerifyOptions, type EmailFallbackVerifyResult, type EventHandler, type EventPayload, type LogLevel, type Logger, type OnboardingCompleteOptions, type OnboardingCompleteResult, type OnboardingRegisterPasskeyOptions, type OnboardingRegisterPasskeyResult, type OnboardingRegisterResult, type OnboardingStartOptions, type OnboardingStartResult, type OnboardingStatusResult, type RegisterOptions, type RegisterResult, type Result, SANDBOX_SESSION_TOKEN, type SessionValidateResponse, TryMellon, type TryMellonConfig, TryMellonError, type TryMellonErrorCode, type TryMellonEvent, createError, createInvalidArgumentError, createNetworkError, createNotSupportedError, createTimeoutError, createUserCancelledError, err, isTryMellonError, mapWebAuthnError, ok };
@@ -1,3 +1,3 @@
1
- var TryMellon=(function(exports){'use strict';var f=e=>({ok:true,value:e}),p=e=>({ok:false,error:e});var k=class e extends Error{code;details;isTryMellonError=true;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e);}},_e={NOT_SUPPORTED:"WebAuthn is not supported in this environment",USER_CANCELLED:"User cancelled the operation",PASSKEY_NOT_FOUND:"Passkey not found",SESSION_EXPIRED:"Session has expired",NETWORK_FAILURE:"Network request failed",INVALID_ARGUMENT:"Invalid argument provided",TIMEOUT:"Operation timed out",ABORTED:"Operation was aborted",ABORT_ERROR:"Operation aborted by user or timeout",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new k(e,r??_e[e],t)}function pe(e){return e instanceof k||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function D(){return R("NOT_SUPPORTED")}function Te(){return R("USER_CANCELLED")}function Ae(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Ie(){return R("TIMEOUT")}function E(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function ce(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function V(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function de(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw E(r,"must use http or https protocol")}catch(t){throw pe(t)?t:E(r,"must be a valid URL")}}function M(e,r,t,n){if(e<t||e>n)throw E(r,`must be between ${t} and ${n}`)}function x(e,r){if(typeof e!="string"||e.length===0)throw E(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw E(r,"must be a valid base64url string")}var Se={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function h(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=Se[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function a(e){return typeof e=="string"}function _(e){return typeof e=="number"&&Number.isFinite(e)}function w(e){return typeof e=="boolean"}function O(e){return Array.isArray(e)}function i(e,r){return p(R("NETWORK_FAILURE",e,{...r,originalData:r?.originalData}))}function l(e,r){return e[r]}function W(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"session_id");if(!a(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=l(e,"challenge");if(!m(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=l(t,"rp");if(!m(n)||!a(n.name)||!a(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=l(t,"user");if(!m(s)||!a(s.id)||!a(s.name)||!a(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=l(t,"challenge");if(!a(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let c=l(t,"pubKeyCredParams");if(!O(c))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let d of c)if(!m(d)||d.type!=="public-key"||!_(d.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let g=t.timeout;if(g!==void 0&&!_(g))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let u=t.excludeCredentials;if(u!==void 0){if(!O(u))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let d of u)if(!m(d)||d.type!=="public-key"||!a(d.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let y=t.authenticatorSelection;return y!==void 0&&!m(y)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):f({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:c,...g!==void 0&&{timeout:g},...u!==void 0&&{excludeCredentials:u},...y!==void 0&&{authenticatorSelection:y}}})}function B(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"session_id");if(!a(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=l(e,"challenge");if(!m(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=l(t,"challenge"),s=l(t,"rpId"),o=t.allowCredentials;if(!a(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!a(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!O(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let u of o)if(!m(u)||u.type!=="public-key"||!a(u.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let c=t.timeout;if(c!==void 0&&!_(c))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let g=t.userVerification;return g!==void 0&&!["required","preferred","discouraged"].includes(String(g))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):f({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...c!==void 0&&{timeout:c},...g!==void 0&&{userVerification:g}}})}function $(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"credential_id"),t=l(e,"status"),n=l(e,"session_token"),s=l(e,"user");if(!a(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!a(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!a(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!m(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=l(s,"user_id"),c=l(s,"external_user_id");if(!a(o)||!a(c))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let g=s.email,u=s.metadata;return g!==void 0&&!a(g)?i("Invalid API response: user.email must be string",{originalData:e}):u!==void 0&&(typeof u!="object"||u===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):f({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:c,...g!==void 0&&{email:g},...u!==void 0&&{metadata:u}}})}function H(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"authenticated"),t=l(e,"session_token"),n=l(e,"user"),s=l(e,"signals");if(!w(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!a(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!m(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=l(n,"user_id"),c=l(n,"external_user_id");return !a(o)||!a(c)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!m(s)?i("Invalid API response: signals must be object",{originalData:e}):f({authenticated:r,session_token:t,user:{user_id:o,external_user_id:c,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function Y(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"valid"),t=l(e,"user_id"),n=l(e,"external_user_id"),s=l(e,"tenant_id"),o=l(e,"app_id");return w(r)?a(t)?a(n)?a(s)?a(o)?f({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function X(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"sessionToken");return a(r)?f({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Oe=["pending_passkey","pending_data","completed"],Ce=["pending_data","completed"];function z(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"session_id"),t=l(e,"onboarding_url"),n=l(e,"expires_in");return a(r)?a(t)?_(n)?f({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function G(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"status"),t=l(e,"onboarding_url"),n=l(e,"expires_in");return !a(r)||!Oe.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):a(t)?_(n)?f({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function J(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"session_id"),t=l(e,"status"),n=l(e,"onboarding_url");if(!a(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!a(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let c=Pe(s);if(!c.ok)return c;o=c.value;}return f({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Pe(e){if(!m(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=l(e,"rp"),t=l(e,"user"),n=l(e,"challenge"),s=l(e,"pubKeyCredParams");if(!m(r)||!a(r.name)||!a(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!m(t)||!a(t.id)||!a(t.name)||!a(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!a(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!O(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!m(o)||o.type!=="public-key"||!_(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return f({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function Z(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"session_id"),t=l(e,"status"),n=l(e,"user_id"),s=l(e,"tenant_id");return a(r)?!a(t)||!Ce.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):a(n)?a(s)?f({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function Q(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=l(e,"session_id"),t=l(e,"status"),n=l(e,"user_id"),s=l(e,"tenant_id"),o=l(e,"session_token");return a(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!a(n)||!a(s)||!a(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):f({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function ee(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !a(r)||!a(t)||!a(n)?i("Invalid API response: missing required fields",{originalData:e}):f({session_id:r,qr_url:t,expires_at:n})}function re(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !a(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):f({status:r,user_id:e.user_id,session_token:e.session_token})}function te(e){if(!m(e))return i("Invalid API response: expected object",{originalData:e});let r=e.options;return m(r)?f({options:r}):i("Invalid API response: options are required",{originalData:e})}var N=class{constructor(r,t,n={}){this.httpClient=r;this.baseUrl=t;this.defaultHeaders=n;}mergeHeaders(r){return {...this.defaultHeaders,...r}}async post(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):p(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):p(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,W)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,B)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,$)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,H)}async validateSession(r){return this.get("/v1/sessions/validate",Y,{Authorization:`Bearer ${r}`})}async startEmailFallback(r){let t=`${this.baseUrl}/v1/fallback/email/start`,n=await this.httpClient.post(t,{userId:r},this.mergeHeaders());return n.ok?f(void 0):p(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},X)}async startOnboarding(r){return this.post("/onboarding/start",r,z)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,G)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,J)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,Z)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,Q)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},ee)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,re)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,te)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):p(n.error)}};var ke=3e4;function De(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ge(e,r){let t=r*Math.pow(2,e);return Math.min(t,ke)}function Me(e,r){return e!=="GET"?false:r>=500||r===429}var U=class{constructor(r,t=0,n=1e3,s){this.timeoutMs=r;this.maxRetries=t;this.retryDelayMs=n;this.logger=s;}async get(r,t){return this.request(r,{method:"GET",headers:t})}async post(r,t,n){return this.request(r,{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",...n}})}async request(r,t){let n=(t.method??"GET").toUpperCase(),s=De(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let c;for(let g=0;g<=this.maxRetries;g++)try{let u=new AbortController,y=setTimeout(()=>u.abort(),this.timeoutMs),d=await fetch(r,{...t,headers:o,signal:u.signal});if(clearTimeout(y),!d.ok){let S;try{S=await d.json();}catch{}let P=S,le=P?.message??d.statusText,T=P?.error??"NETWORK_FAILURE",ue=R(T,le,{requestId:s,status:d.status,statusText:d.statusText,data:S});if(Me(n,d.status)&&g<this.maxRetries){c=ue,await new Promise(ve=>setTimeout(ve,ge(g,this.retryDelayMs)));continue}return p(ue)}let b=await d.json();return f(b)}catch(u){if(c=u,n==="GET"&&g<this.maxRetries)await new Promise(d=>setTimeout(d,ge(g,this.retryDelayMs)));else break}return c instanceof Error&&c.name==="AbortError"?p(R("TIMEOUT","Request timed out",{requestId:s})):p(R("NETWORK_FAILURE",c instanceof Error?c.message:"Request failed",{requestId:s,cause:c}))}};function A(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function xe(){try{return !A()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function me(){let e=A(),r=await xe();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function v(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw V("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function we(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw V("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function C(e){let r=we(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function I(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw ce(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function F(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("UNKNOWN_ERROR","Invalid credential response structure for register: attestationObject is missing",{response:r});let t=r.clientDataJSON,n=r.attestationObject;return {id:e.id,rawId:v(e.rawId),response:{clientDataJSON:v(t),attestationObject:v(n)},type:"public-key"}}function L(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("UNKNOWN_ERROR","Invalid credential response structure for auth: authenticatorData or signature is missing",{response:r});let t=r.clientDataJSON,n=r.authenticatorData,s=r.signature,o=r.userHandle;return {id:e.id,rawId:v(e.rawId),response:{authenticatorData:v(n),clientDataJSON:v(t),signature:v(s),...o&&{userHandle:v(o)}},type:"public-key"}}function ne(e,r){try{x(e.challenge,"challenge"),x(e.user.id,"user.id");let t=C(e.challenge),n=C(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={rp:{id:e.rp.id,name:e.rp.name},user:{id:n,name:e.user.name,displayName:e.user.displayName},challenge:t,pubKeyCredParams:e.pubKeyCredParams,...e.timeout!==void 0&&{timeout:e.timeout},attestation:"none",authenticatorSelection:s,...e.excludeCredentials&&{excludeCredentials:e.excludeCredentials.map(c=>({id:C(c.id),type:c.type,...c.transports&&{transports:c.transports}}))}};return f({publicKey:o})}catch(t){return p(h(t))}}function se(e,r){try{x(e.challenge,"challenge");let t=C(e.challenge);return f({publicKey:{challenge:t,rpId:e.rpId,...e.timeout!==void 0&&{timeout:e.timeout},userVerification:e.userVerification??"preferred",...e.allowCredentials&&{allowCredentials:e.allowCredentials.map(n=>({id:C(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return p(h(t))}}async function Re(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!A()){let d=D();return t.emit("error",{type:"error",error:d}),p(d)}let n=e.externalUserId??e.external_user_id;if(!n)throw new Error("externalUserId is required");let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),p(s.error);let o=ne(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),p(o.error);let c=o.value;e.signal&&(c.signal=e.signal);let g=await navigator.credentials.create(c);if(!g){let d=E("credential","creation failed");return t.emit("error",{type:"error",error:d}),p(d)}try{I(g);}catch(d){let b=h(d);return t.emit("error",{type:"error",error:b}),p(b)}let u=await r.finishRegister({session_id:s.value.session_id,credential:F(g)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),p(u.error);let y={success:true,credentialId:u.value.credential_id,credential_id:u.value.credential_id,status:u.value.status,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),f(y)}catch(n){let s=h(n);return t.emit("error",{type:"error",error:s}),p(s)}}async function ye(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!A()){let d=D();return t.emit("error",{type:"error",error:d}),p(d)}let n=e.externalUserId??e.external_user_id;if(!n)throw new Error("externalUserId is required");let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),p(s.error);let o=se(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),p(o.error);let c=o.value;e.signal&&(c.signal=e.signal);let g=await navigator.credentials.get(c);if(!g){let d=E("credential","retrieval failed");return t.emit("error",{type:"error",error:d}),p(d)}try{I(g);}catch(d){let b=h(d);return t.emit("error",{type:"error",error:b}),p(b)}let u=await r.finishAuthentication({session_id:s.value.session_id,credential:L(g)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),p(u.error);let y={authenticated:u.value.authenticated,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata},signals:u.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),f(y)}catch(n){let s=h(n);return t.emit("error",{type:"error",error:s}),p(s)}}var Ne=2e3,Ue=60,K=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return p(t.error);let{session_id:n}=t.value;for(let s=0;s<Ue;s++){await new Promise(u=>setTimeout(u,Ne));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return p(o.error);let c=o.value.status,g=o.value.onboarding_url;if(c==="pending_passkey"){let u=await this.apiClient.getOnboardingRegister(n);if(!u.ok)return p(u.error);let y=u.value;if(!y.challenge)return p(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:g}));let d=ne(y.challenge);if(!d.ok)return p(d.error);let b;try{b=await navigator.credentials.create(d.value);}catch(T){return p(h(T))}try{I(b,"create");}catch(T){return p(h(T))}let S;try{S=F(b);}catch(T){return p(h(T))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:S,challenge:y.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):p(P.error)}if(c==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return p(R("TIMEOUT","Onboarding timed out"))}};var Fe=2e3,Le=60,q=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async waitForSession(r,t){for(let n=0;n<Le;n++){if(t?.aborted)return p(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return p(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?p(R("UNKNOWN_ERROR","Missing data in completed session")):f({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return p(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let c=setTimeout(()=>{o(null),t?.removeEventListener("abort",g);},Fe),g=()=>{clearTimeout(c),o(null);};t?.addEventListener("abort",g);}),t?.aborted)return p(R("ABORT_ERROR","Operation aborted by user or timeout"))}return p(R("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return p(t.error);let n=se(t.value.options);if(!n.ok)return p(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(c){return p(h(c))}try{I(s,"get");}catch(c){return p(h(c))}let o;try{o=L(s);}catch(c){return p(h(c))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var j=class{handlers;constructor(){this.handlers=new Map;}on(r,t){let n=this.handlers.get(r);return n||(n=new Set,this.handlers.set(r,n)),n.add(t),()=>{this.off(r,t);}}off(r,t){let n=this.handlers.get(r);n&&(n.delete(t),n.size===0&&this.handlers.delete(r));}emit(r,t){let n=this.handlers.get(r);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var he="https://api.trymellonauth.com",Ee="https://api.trymellonauth.com/v1/telemetry";function be(e){return {async send(r){let t=JSON.stringify(r);if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"){navigator.sendBeacon(e,t);return}typeof fetch<"u"&&await fetch(e,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:true});}}}function ie(e,r){return {event:e,latencyMs:r,ok:true}}var oe=class{apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;constructor(r){let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw E("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw E("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??he;de(s,"apiBaseUrl");let o=r.timeoutMs??3e4;M(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&M(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&M(r.retryDelayMs,"retryDelayMs",100,1e4);let c=r.maxRetries??3,g=r.retryDelayMs??1e3,u=new U(o,c,g,r.logger),y={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`};this.apiClient=new N(u,s,y),this.onboarding=new K(this.apiClient),this.crossDeviceManager=new q(this.apiClient),this.eventEmitter=new j,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??be(r.telemetryEndpoint??Ee));}static isSupported(){return A()}async register(r){let t=Date.now(),n=await Re(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ie("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){let t=Date.now(),n=await ye(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ie("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.apiClient.validateSession(r)}async getStatus(){return me()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.2.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r.userId),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var ae=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
2
- exports.ConsoleLogger=ae;exports.TryMellon=oe;exports.TryMellonError=k;exports.createError=R;exports.createInvalidArgumentError=E;exports.createNetworkError=Ae;exports.createNotSupportedError=D;exports.createTimeoutError=Ie;exports.createUserCancelledError=Te;exports.err=p;exports.isTryMellonError=pe;exports.mapWebAuthnError=h;exports.ok=f;return exports;})({});//# sourceMappingURL=index.global.js.map
1
+ var TryMellon=(function(exports){'use strict';var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var P=class e extends Error{code;details;isTryMellonError=true;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e);}},ke={NOT_SUPPORTED:"WebAuthn is not supported in this environment",USER_CANCELLED:"User cancelled the operation",PASSKEY_NOT_FOUND:"Passkey not found",SESSION_EXPIRED:"Session has expired",NETWORK_FAILURE:"Network request failed",INVALID_ARGUMENT:"Invalid argument provided",TIMEOUT:"Operation timed out",ABORTED:"Operation was aborted",ABORT_ERROR:"Operation aborted by user or timeout",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new P(e,r??ke[e],t)}function M(e){return e instanceof P||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function D(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function Me(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function De(){return R("TIMEOUT")}function y(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function V(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function W(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw y(r,"must use http or https protocol")}catch(t){throw M(t)?t:y(r,"must be a valid URL")}}function A(e,r,t,n){if(!Number.isFinite(e))throw y(r,"must be a finite number");if(e<t||e>n)throw y(r,`must be between ${t} and ${n}`)}function w(e,r){if(typeof e!="string"||e.length===0)throw y(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw y(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function b(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function f(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function _(e){return typeof e=="number"&&Number.isFinite(e)}function N(e){return typeof e=="boolean"}function x(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function u(e,r){return e[r]}function $(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=u(e,"challenge");if(!f(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=u(t,"rp");if(!f(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=u(t,"user");if(!f(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=u(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let d=u(t,"pubKeyCredParams");if(!x(d))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of d)if(!f(c)||c.type!=="public-key"||!_(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!_(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let p=t.excludeCredentials;if(p!==void 0){if(!x(p))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of p)if(!f(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!f(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:d,...m!==void 0&&{timeout:m},...p!==void 0&&{excludeCredentials:p},...h!==void 0&&{authenticatorSelection:h}}})}function H(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=u(e,"challenge");if(!f(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=u(t,"challenge"),s=u(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!x(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let p of o)if(!f(p)||p.type!=="public-key"||!l(p.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let d=t.timeout;if(d!==void 0&&!_(d))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...d!==void 0&&{timeout:d},...m!==void 0&&{userVerification:m}}})}function X(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"credential_id"),t=u(e,"status"),n=u(e,"session_token"),s=u(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!f(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=u(s,"user_id"),d=u(s,"external_user_id");if(!l(o)||!l(d))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,p=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):p!==void 0&&(typeof p!="object"||p===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:d,...m!==void 0&&{email:m},...p!==void 0&&{metadata:p}}})}function Y(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"authenticated"),t=u(e,"session_token"),n=u(e,"user"),s=u(e,"signals");if(!N(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!f(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=u(n,"user_id"),d=u(n,"external_user_id");return !l(o)||!l(d)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!f(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:d,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function z(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"valid"),t=u(e,"user_id"),n=u(e,"external_user_id"),s=u(e,"tenant_id"),o=u(e,"app_id");return N(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function G(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function J(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"session_id"),t=u(e,"onboarding_url"),n=u(e,"expires_in");return l(r)?l(t)?_(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function Z(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"status"),t=u(e,"onboarding_url"),n=u(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?_(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function Q(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"session_id"),t=u(e,"status"),n=u(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let d=Fe(s);if(!d.ok)return d;o=d.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!f(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=u(e,"rp"),t=u(e,"user"),n=u(e,"challenge"),s=u(e,"pubKeyCredParams");if(!f(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!f(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!x(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!f(o)||o.type!=="public-key"||!_(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function ee(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"session_id"),t=u(e,"status"),n=u(e,"user_id"),s=u(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function re(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=u(e,"session_id"),t=u(e,"status"),n=u(e,"user_id"),s=u(e,"tenant_id"),o=u(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function te(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function ne(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function se(e){if(!f(e))return i("Invalid API response: expected object",{originalData:e});let r=e.options;return f(r)?g({options:r}):i("Invalid API response: options are required",{originalData:e})}var U=class{constructor(r,t,n={}){this.httpClient=r;this.baseUrl=t;this.defaultHeaders=n;}mergeHeaders(r){return {...this.defaultHeaders,...r}}async post(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,$)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,H)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,X)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,Y)}async validateSession(r){return this.get("/v1/sessions/validate",z,{Authorization:`Bearer ${r}`})}async startEmailFallback(r){let t=`${this.baseUrl}/v1/fallback/email/start`,n=await this.httpClient.post(t,{userId:r},this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},G)}async startOnboarding(r){return this.post("/onboarding/start",r,J)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,Z)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,Q)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,ee)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,re)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},te)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,ne)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,se)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var Le=3e4;function Ke(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function fe(e,r){let t=r*Math.pow(2,e);return Math.min(t,Le)}function qe(e,r){return e!=="GET"?false:r>=500||r===429}var F=class{constructor(r,t=0,n=1e3,s){this.timeoutMs=r;this.maxRetries=t;this.retryDelayMs=n;this.logger=s;}async get(r,t){return this.request(r,{method:"GET",headers:t})}async post(r,t,n){return this.request(r,{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",...n}})}async request(r,t){let n=(t.method??"GET").toUpperCase(),s=Ke(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let d;for(let m=0;m<=this.maxRetries;m++)try{let p=new AbortController,h=setTimeout(()=>p.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:p.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let k=O,ce=k?.message??c.statusText,T=k?.error??"NETWORK_FAILURE",ge=R(T,ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(qe(n,c.status)&&m<this.maxRetries){d=ge,await new Promise(Ce=>setTimeout(Ce,fe(m,this.retryDelayMs)));continue}return a(ge)}let E=await c.json();return g(E)}finally{clearTimeout(h);}}catch(p){if(d=p,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,fe(m,this.retryDelayMs)));else break}return d instanceof Error&&d.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",d instanceof Error?d.message:"Request failed",{requestId:s,cause:d}))}};function I(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function je(){try{return !I()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=I(),r=await je();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function v(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw V("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function Be(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw V("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function C(e){let r=Be(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function S(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function ye(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function L(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!ye(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("UNKNOWN_ERROR","Invalid credential response structure for register: attestationObject is missing",{response:r});let t=r.clientDataJSON,n=r.attestationObject;return {id:e.id,rawId:v(e.rawId),response:{clientDataJSON:v(t),attestationObject:v(n)},type:"public-key"}}function K(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!ye(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("UNKNOWN_ERROR","Invalid credential response structure for auth: authenticatorData or signature is missing",{response:r});let t=r.clientDataJSON,n=r.authenticatorData,s=r.signature,o=r.userHandle;return {id:e.id,rawId:v(e.rawId),response:{authenticatorData:v(n),clientDataJSON:v(t),signature:v(s),...o&&{userHandle:v(o)}},type:"public-key"}}function ie(e,r){try{w(e.challenge,"challenge"),w(e.user.id,"user.id");let t=C(e.challenge),n=C(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={rp:{id:e.rp.id,name:e.rp.name},user:{id:n,name:e.user.name,displayName:e.user.displayName},challenge:t,pubKeyCredParams:e.pubKeyCredParams,...e.timeout!==void 0&&{timeout:e.timeout},attestation:"none",authenticatorSelection:s,...e.excludeCredentials&&{excludeCredentials:e.excludeCredentials.map(d=>({id:C(d.id),type:d.type,...d.transports&&{transports:d.transports}}))}};return g({publicKey:o})}catch(t){return a(b(t))}}function oe(e,r){try{w(e.challenge,"challenge");let t=C(e.challenge);return g({publicKey:{challenge:t,rpId:e.rpId,...e.timeout!==void 0&&{timeout:e.timeout},userVerification:e.userVerification??"preferred",...e.allowCredentials&&{allowCredentials:e.allowCredentials.map(n=>({id:C(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(b(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!I()){let c=D();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=y("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=ie(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let d={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(d);if(!m){let c=y("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{S(m);}catch(c){let E=b(c);return t.emit("error",{type:"error",error:E}),a(E)}let p=await r.finishRegister({session_id:s.value.session_id,credential:L(m)});if(!p.ok)return t.emit("error",{type:"error",error:p.error}),a(p.error);let h={success:true,credentialId:p.value.credential_id,credential_id:p.value.credential_id,status:p.value.status,sessionToken:p.value.session_token,user:{userId:p.value.user.user_id,externalUserId:p.value.user.external_user_id,email:p.value.user.email,metadata:p.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=b(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!I()){let c=D();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=y("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let d={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(d);if(!m){let c=y("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{S(m);}catch(c){let E=b(c);return t.emit("error",{type:"error",error:E}),a(E)}let p=await r.finishAuthentication({session_id:s.value.session_id,credential:K(m)});if(!p.ok)return t.emit("error",{type:"error",error:p.error}),a(p.error);let h={authenticated:p.value.authenticated,sessionToken:p.value.session_token,user:{userId:p.value.user.user_id,externalUserId:p.value.user.external_user_id,email:p.value.user.email,metadata:p.value.user.metadata},signals:p.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=b(n);return t.emit("error",{type:"error",error:s}),a(s)}}var Ve=2e3,We=60,q=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<We;s++){await new Promise(p=>setTimeout(p,Ve));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let d=o.value.status,m=o.value.onboarding_url;if(d==="pending_passkey"){let p=await this.apiClient.getOnboardingRegister(n);if(!p.ok)return a(p.error);let h=p.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=ie(h.challenge);if(!c.ok)return a(c.error);let E;try{E=await navigator.credentials.create(c.value);}catch(T){return a(b(T))}try{S(E,"create");}catch(T){return a(b(T))}let O;try{O=L(E);}catch(T){return a(b(T))}let k=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return k.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(k.error)}if(d==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var $e=2e3,He=60,j=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async waitForSession(r,t){for(let n=0;n<He;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let d=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},$e),m=()=>{clearTimeout(d),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return a(t.error);let n=oe(t.value.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(d){return a(b(d))}try{S(s,"get");}catch(d){return a(b(d))}let o;try{o=K(s);}catch(d){return a(b(d))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var B=class{handlers;constructor(){this.handlers=new Map;}on(r,t){let n=this.handlers.get(r);return n||(n=new Set,this.handlers.set(r,n)),n.add(t),()=>{this.off(r,t);}}off(r,t){let n=this.handlers.get(r);n&&(n.delete(t),n.size===0&&this.handlers.delete(r));}emit(r,t){let n=this.handlers.get(r);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",Ee="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function ve(e){return {async send(r){let t=JSON.stringify(r);if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"){navigator.sendBeacon(e,t);return}typeof fetch<"u"&&await fetch(e,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:true});}}}function ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(y("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(y("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;W(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return A(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&A(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&A(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return M(t)?a(t):a(y("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw y("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw y("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;W(s,"apiBaseUrl");let o=r.timeoutMs??3e4;A(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&A(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&A(r.retryDelayMs,"retryDelayMs",100,1e4);let d=r.maxRetries??3,m=r.retryDelayMs??1e3,p=new F(o,d,m,r.logger),h={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`};this.apiClient=new U(p,s,h),this.onboarding=new q(this.apiClient),this.crossDeviceManager=new j(this.apiClient),this.eventEmitter=new B,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??ve(r.telemetryEndpoint??Ee));}static isSupported(){return I()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.3.0"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r.userId),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
2
+ exports.ConsoleLogger=de;exports.SANDBOX_SESSION_TOKEN=le;exports.TryMellon=pe;exports.TryMellonError=P;exports.createError=R;exports.createInvalidArgumentError=y;exports.createNetworkError=Me;exports.createNotSupportedError=D;exports.createTimeoutError=De;exports.createUserCancelledError=Pe;exports.err=a;exports.isTryMellonError=M;exports.mapWebAuthnError=b;exports.ok=g;return exports;})({});//# sourceMappingURL=index.global.js.map
3
3
  //# sourceMappingURL=index.global.js.map