@feelflow/ffid-sdk 5.19.0 → 5.21.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.
@@ -1649,6 +1649,19 @@ interface FFIDSessionResponse {
1649
1649
  organizations: FFIDOrganization[];
1650
1650
  subscriptions: FFIDSubscription[];
1651
1651
  }
1652
+ /**
1653
+ * Optional metadata on successful {@link FFIDApiResponse} values (#4136).
1654
+ *
1655
+ * Present only on the success branch — error responses never carry `meta`.
1656
+ */
1657
+ interface FFIDApiResponseMeta {
1658
+ /**
1659
+ * Set when introspect-strategy verification could not use the configured
1660
+ * cache (adapter read/write failure or `crypto.subtle` unavailable).
1661
+ * Visible without a custom logger; absent when cache operated normally.
1662
+ */
1663
+ verificationCacheDegraded?: true;
1664
+ }
1652
1665
  /**
1653
1666
  * API response wrapper (discriminated union for type safety)
1654
1667
  *
@@ -1658,10 +1671,33 @@ interface FFIDSessionResponse {
1658
1671
  type FFIDApiResponse<T> = {
1659
1672
  data: T;
1660
1673
  error?: undefined;
1674
+ meta?: FFIDApiResponseMeta;
1661
1675
  } | {
1662
1676
  data?: undefined;
1663
1677
  error: FFIDError;
1664
1678
  };
1679
+ /**
1680
+ * Result of `signOut()` (#4119, extended #4136).
1681
+ *
1682
+ * Local credentials (tokens / local state) are always cleared when `signOut()`
1683
+ * resolves without `error`. `revoked` additionally indicates whether the
1684
+ * server-side revocation/sign-out actually succeeded:
1685
+ *
1686
+ * - `revoked: true` — no server-side session/token remains active.
1687
+ * - `revoked: false` — server-side revocation failed (network error or non-2xx
1688
+ * response). The access token may remain valid server-side until natural
1689
+ * expiry. Non-fatal: the local sign-out still completed, but callers that
1690
+ * need guaranteed revocation (e.g. shared-device flows) should surface this.
1691
+ *
1692
+ * Token mode (#4136): `accessTokenRevoked` / `refreshTokenRevoked` report each
1693
+ * RFC 7009 revoke call. `revoked` is `true` only when every applicable token
1694
+ * was revoked successfully. Cookie mode omits the per-token fields.
1695
+ */
1696
+ interface FFIDSignOutResult {
1697
+ revoked: boolean;
1698
+ accessTokenRevoked?: boolean;
1699
+ refreshTokenRevoked?: boolean;
1700
+ }
1665
1701
 
1666
1702
  /**
1667
1703
  * Response shape from `GET /api/v1/ext/analytics/config?service=<code>`.
@@ -1695,23 +1731,33 @@ interface FFIDAnalyticsConfig {
1695
1731
  * has been fired **3 times within 60 seconds**. Caller should surface a
1696
1732
  * manual "再度ログインする" UI rather than retry automatically (#2406 / #2411).
1697
1733
  *
1698
- * SDK 2.18.0 only ships `'redirect_loop_detected'`. Other failure paths
1699
- * (SSR environment, PKCE generation failure, empty organizationId) currently
1700
- * return `error` without a `code`. New codes will be added in future minor
1701
- * versions — treat this union as forward-extensible and do NOT exhaustively
1702
- * `switch` over it without a `default` branch for consumer code that must
1703
- * stay compatible across SDK upgrades.
1734
+ * - `'state_persistence_failed'`: `redirectToAuthorize()` could not persist
1735
+ * the OAuth CSRF `state` (storage unavailable / quota). Redirect is aborted
1736
+ * fail-closed (#4136) callers should surface a manual retry UI.
1737
+ *
1738
+ * Other failure paths (SSR environment, PKCE generation failure, empty
1739
+ * organizationId) currently return `error` without a `code`. Treat this union
1740
+ * as forward-extensible and do NOT exhaustively `switch` over it without a
1741
+ * `default` branch for consumer code that must stay compatible across SDK
1742
+ * upgrades.
1704
1743
  */
1705
- type FFIDRedirectErrorCode = 'redirect_loop_detected';
1744
+ type FFIDRedirectErrorCode = 'redirect_loop_detected' | 'state_persistence_failed';
1706
1745
  /**
1707
1746
  * Result of a redirect operation (redirectToLogin / redirectToAuthorize / redirectToLogout)
1708
1747
  *
1709
1748
  * Structured return type so callers can inspect failure reasons
1710
1749
  * instead of receiving a bare `false`. When `code` is set, branch on it
1711
1750
  * for programmatic handling; otherwise log `error` for humans.
1751
+ *
1752
+ * `loopDetectionDisabled` (#4119): set to `true` when sessionStorage is
1753
+ * unavailable (iOS WebKit private mode / eviction) so redirect-loop detection
1754
+ * ran **fail-open** — the redirect fired, but repeated-redirect protection is
1755
+ * disabled for this browser session. Callers that need loop protection on
1756
+ * such browsers should add their own max-retry guard.
1712
1757
  */
1713
1758
  type FFIDRedirectResult = {
1714
1759
  success: true;
1760
+ loopDetectionDisabled?: boolean;
1715
1761
  } | {
1716
1762
  success: false;
1717
1763
  error: string;
@@ -1906,7 +1952,7 @@ interface RedirectToAuthorizeOptions {
1906
1952
  /** Creates an FFID API client instance */
1907
1953
  declare function createFFIDClient(config: FFIDConfig): {
1908
1954
  getSession: () => Promise<FFIDApiResponse<FFIDSessionResponse>>;
1909
- signOut: () => Promise<FFIDApiResponse<void>>;
1955
+ signOut: () => Promise<FFIDApiResponse<FFIDSignOutResult>>;
1910
1956
  redirectToLogin: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1911
1957
  redirectToAuthorize: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1912
1958
  redirectToLogout: (postLogoutRedirectUri?: string) => FFIDRedirectResult;
@@ -1649,6 +1649,19 @@ interface FFIDSessionResponse {
1649
1649
  organizations: FFIDOrganization[];
1650
1650
  subscriptions: FFIDSubscription[];
1651
1651
  }
1652
+ /**
1653
+ * Optional metadata on successful {@link FFIDApiResponse} values (#4136).
1654
+ *
1655
+ * Present only on the success branch — error responses never carry `meta`.
1656
+ */
1657
+ interface FFIDApiResponseMeta {
1658
+ /**
1659
+ * Set when introspect-strategy verification could not use the configured
1660
+ * cache (adapter read/write failure or `crypto.subtle` unavailable).
1661
+ * Visible without a custom logger; absent when cache operated normally.
1662
+ */
1663
+ verificationCacheDegraded?: true;
1664
+ }
1652
1665
  /**
1653
1666
  * API response wrapper (discriminated union for type safety)
1654
1667
  *
@@ -1658,10 +1671,33 @@ interface FFIDSessionResponse {
1658
1671
  type FFIDApiResponse<T> = {
1659
1672
  data: T;
1660
1673
  error?: undefined;
1674
+ meta?: FFIDApiResponseMeta;
1661
1675
  } | {
1662
1676
  data?: undefined;
1663
1677
  error: FFIDError;
1664
1678
  };
1679
+ /**
1680
+ * Result of `signOut()` (#4119, extended #4136).
1681
+ *
1682
+ * Local credentials (tokens / local state) are always cleared when `signOut()`
1683
+ * resolves without `error`. `revoked` additionally indicates whether the
1684
+ * server-side revocation/sign-out actually succeeded:
1685
+ *
1686
+ * - `revoked: true` — no server-side session/token remains active.
1687
+ * - `revoked: false` — server-side revocation failed (network error or non-2xx
1688
+ * response). The access token may remain valid server-side until natural
1689
+ * expiry. Non-fatal: the local sign-out still completed, but callers that
1690
+ * need guaranteed revocation (e.g. shared-device flows) should surface this.
1691
+ *
1692
+ * Token mode (#4136): `accessTokenRevoked` / `refreshTokenRevoked` report each
1693
+ * RFC 7009 revoke call. `revoked` is `true` only when every applicable token
1694
+ * was revoked successfully. Cookie mode omits the per-token fields.
1695
+ */
1696
+ interface FFIDSignOutResult {
1697
+ revoked: boolean;
1698
+ accessTokenRevoked?: boolean;
1699
+ refreshTokenRevoked?: boolean;
1700
+ }
1665
1701
 
1666
1702
  /**
1667
1703
  * Response shape from `GET /api/v1/ext/analytics/config?service=<code>`.
@@ -1695,23 +1731,33 @@ interface FFIDAnalyticsConfig {
1695
1731
  * has been fired **3 times within 60 seconds**. Caller should surface a
1696
1732
  * manual "再度ログインする" UI rather than retry automatically (#2406 / #2411).
1697
1733
  *
1698
- * SDK 2.18.0 only ships `'redirect_loop_detected'`. Other failure paths
1699
- * (SSR environment, PKCE generation failure, empty organizationId) currently
1700
- * return `error` without a `code`. New codes will be added in future minor
1701
- * versions — treat this union as forward-extensible and do NOT exhaustively
1702
- * `switch` over it without a `default` branch for consumer code that must
1703
- * stay compatible across SDK upgrades.
1734
+ * - `'state_persistence_failed'`: `redirectToAuthorize()` could not persist
1735
+ * the OAuth CSRF `state` (storage unavailable / quota). Redirect is aborted
1736
+ * fail-closed (#4136) callers should surface a manual retry UI.
1737
+ *
1738
+ * Other failure paths (SSR environment, PKCE generation failure, empty
1739
+ * organizationId) currently return `error` without a `code`. Treat this union
1740
+ * as forward-extensible and do NOT exhaustively `switch` over it without a
1741
+ * `default` branch for consumer code that must stay compatible across SDK
1742
+ * upgrades.
1704
1743
  */
1705
- type FFIDRedirectErrorCode = 'redirect_loop_detected';
1744
+ type FFIDRedirectErrorCode = 'redirect_loop_detected' | 'state_persistence_failed';
1706
1745
  /**
1707
1746
  * Result of a redirect operation (redirectToLogin / redirectToAuthorize / redirectToLogout)
1708
1747
  *
1709
1748
  * Structured return type so callers can inspect failure reasons
1710
1749
  * instead of receiving a bare `false`. When `code` is set, branch on it
1711
1750
  * for programmatic handling; otherwise log `error` for humans.
1751
+ *
1752
+ * `loopDetectionDisabled` (#4119): set to `true` when sessionStorage is
1753
+ * unavailable (iOS WebKit private mode / eviction) so redirect-loop detection
1754
+ * ran **fail-open** — the redirect fired, but repeated-redirect protection is
1755
+ * disabled for this browser session. Callers that need loop protection on
1756
+ * such browsers should add their own max-retry guard.
1712
1757
  */
1713
1758
  type FFIDRedirectResult = {
1714
1759
  success: true;
1760
+ loopDetectionDisabled?: boolean;
1715
1761
  } | {
1716
1762
  success: false;
1717
1763
  error: string;
@@ -1906,7 +1952,7 @@ interface RedirectToAuthorizeOptions {
1906
1952
  /** Creates an FFID API client instance */
1907
1953
  declare function createFFIDClient(config: FFIDConfig): {
1908
1954
  getSession: () => Promise<FFIDApiResponse<FFIDSessionResponse>>;
1909
- signOut: () => Promise<FFIDApiResponse<void>>;
1955
+ signOut: () => Promise<FFIDApiResponse<FFIDSignOutResult>>;
1910
1956
  redirectToLogin: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1911
1957
  redirectToAuthorize: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1912
1958
  redirectToLogout: (postLogoutRedirectUri?: string) => FFIDRedirectResult;
@@ -658,6 +658,19 @@ interface FFIDSessionResponse {
658
658
  organizations: FFIDOrganization[];
659
659
  subscriptions: FFIDSubscription[];
660
660
  }
661
+ /**
662
+ * Optional metadata on successful {@link FFIDApiResponse} values (#4136).
663
+ *
664
+ * Present only on the success branch — error responses never carry `meta`.
665
+ */
666
+ interface FFIDApiResponseMeta {
667
+ /**
668
+ * Set when introspect-strategy verification could not use the configured
669
+ * cache (adapter read/write failure or `crypto.subtle` unavailable).
670
+ * Visible without a custom logger; absent when cache operated normally.
671
+ */
672
+ verificationCacheDegraded?: true;
673
+ }
661
674
  /**
662
675
  * API response wrapper (discriminated union for type safety)
663
676
  *
@@ -667,10 +680,33 @@ interface FFIDSessionResponse {
667
680
  type FFIDApiResponse<T> = {
668
681
  data: T;
669
682
  error?: undefined;
683
+ meta?: FFIDApiResponseMeta;
670
684
  } | {
671
685
  data?: undefined;
672
686
  error: FFIDError;
673
687
  };
688
+ /**
689
+ * Result of `signOut()` (#4119, extended #4136).
690
+ *
691
+ * Local credentials (tokens / local state) are always cleared when `signOut()`
692
+ * resolves without `error`. `revoked` additionally indicates whether the
693
+ * server-side revocation/sign-out actually succeeded:
694
+ *
695
+ * - `revoked: true` — no server-side session/token remains active.
696
+ * - `revoked: false` — server-side revocation failed (network error or non-2xx
697
+ * response). The access token may remain valid server-side until natural
698
+ * expiry. Non-fatal: the local sign-out still completed, but callers that
699
+ * need guaranteed revocation (e.g. shared-device flows) should surface this.
700
+ *
701
+ * Token mode (#4136): `accessTokenRevoked` / `refreshTokenRevoked` report each
702
+ * RFC 7009 revoke call. `revoked` is `true` only when every applicable token
703
+ * was revoked successfully. Cookie mode omits the per-token fields.
704
+ */
705
+ interface FFIDSignOutResult {
706
+ revoked: boolean;
707
+ accessTokenRevoked?: boolean;
708
+ refreshTokenRevoked?: boolean;
709
+ }
674
710
 
675
711
  /**
676
712
  * Response shape from `GET /api/v1/ext/analytics/config?service=<code>`.
@@ -704,23 +740,33 @@ interface FFIDAnalyticsConfig {
704
740
  * has been fired **3 times within 60 seconds**. Caller should surface a
705
741
  * manual "再度ログインする" UI rather than retry automatically (#2406 / #2411).
706
742
  *
707
- * SDK 2.18.0 only ships `'redirect_loop_detected'`. Other failure paths
708
- * (SSR environment, PKCE generation failure, empty organizationId) currently
709
- * return `error` without a `code`. New codes will be added in future minor
710
- * versions — treat this union as forward-extensible and do NOT exhaustively
711
- * `switch` over it without a `default` branch for consumer code that must
712
- * stay compatible across SDK upgrades.
743
+ * - `'state_persistence_failed'`: `redirectToAuthorize()` could not persist
744
+ * the OAuth CSRF `state` (storage unavailable / quota). Redirect is aborted
745
+ * fail-closed (#4136) callers should surface a manual retry UI.
746
+ *
747
+ * Other failure paths (SSR environment, PKCE generation failure, empty
748
+ * organizationId) currently return `error` without a `code`. Treat this union
749
+ * as forward-extensible and do NOT exhaustively `switch` over it without a
750
+ * `default` branch for consumer code that must stay compatible across SDK
751
+ * upgrades.
713
752
  */
714
- type FFIDRedirectErrorCode = 'redirect_loop_detected';
753
+ type FFIDRedirectErrorCode = 'redirect_loop_detected' | 'state_persistence_failed';
715
754
  /**
716
755
  * Result of a redirect operation (redirectToLogin / redirectToAuthorize / redirectToLogout)
717
756
  *
718
757
  * Structured return type so callers can inspect failure reasons
719
758
  * instead of receiving a bare `false`. When `code` is set, branch on it
720
759
  * for programmatic handling; otherwise log `error` for humans.
760
+ *
761
+ * `loopDetectionDisabled` (#4119): set to `true` when sessionStorage is
762
+ * unavailable (iOS WebKit private mode / eviction) so redirect-loop detection
763
+ * ran **fail-open** — the redirect fired, but repeated-redirect protection is
764
+ * disabled for this browser session. Callers that need loop protection on
765
+ * such browsers should add their own max-retry guard.
721
766
  */
722
767
  type FFIDRedirectResult = {
723
768
  success: true;
769
+ loopDetectionDisabled?: boolean;
724
770
  } | {
725
771
  success: false;
726
772
  error: string;
@@ -1476,4 +1522,4 @@ interface FFIDInquiryFormPlaceholderContext {
1476
1522
  }
1477
1523
  declare function FFIDInquiryForm({ mode, prefill, organizations, preselectedOrganizationId, categories, termsVersion, privacyVersion, termsHref, privacyHref, turnstileToken, turnstileSlot, onSubmit, onChange, legalLayout, messagePlaceholder, requireCategorySelection, unstyled, classNames, locale, className, }: FFIDInquiryFormProps): react_jsx_runtime.JSX.Element;
1478
1524
 
1479
- export { FFIDLoginButton as $, type AnnouncementListResponse as A, type AnnouncementStatus as B, type AnnouncementType as C, EFFECTIVE_SUBSCRIPTION_STATUSES as D, type EffectiveSubscriptionStatus as E, type FFIDSubscriptionStatus as F, FFIDAnnouncementBadge as G, FFIDAnnouncementList as H, type FFIDAnnouncementsError as I, type FFIDAnnouncementsErrorCode as J, type FFIDAnnouncementsServerResponse as K, type ListAnnouncementsOptions as L, type FFIDCacheConfig as M, type FFIDContextValue as N, type FFIDInquiryCategory as O, type FFIDInquiryCategorySite2026 as P, FFIDInquiryForm as Q, type FFIDInquiryFormCategoryItem as R, type FFIDInquiryFormClassNames as S, type FFIDInquiryFormLegalLayout as T, type FFIDInquiryFormOrganization as U, type FFIDInquiryFormPlaceholderContext as V, type FFIDInquiryFormPrefill as W, type FFIDInquiryFormProps as X, type FFIDInquiryFormSubmitData as Y, type FFIDInquiryFormSubmitResult as Z, type FFIDJwtClaims as _, type FFIDPrompt as a, type FFIDOAuthTokenResponse as a0, type FFIDOAuthUserInfoMemberRole as a1, FFIDOrganizationSwitcher as a2, type FFIDRedirectErrorCode as a3, type FFIDSeatModel as a4, type FFIDServiceAccessDenialReason as a5, type FFIDServiceAccessFailPolicy as a6, FFIDSubscriptionBadge as a7, type FFIDTokenIntrospectionResponse as a8, FFIDUserMenu as a9, FFID_INQUIRY_CATEGORIES as aa, FFID_INQUIRY_CATEGORIES_SITE_2026 as ab, type UseFFIDAnnouncementsOptions as ac, type UseFFIDAnnouncementsReturn as ad, isFFIDInquiryCategorySite2026 as ae, useFFIDAnnouncements as af, type FFIDAnnouncementBadgeClassNames as ag, type FFIDAnnouncementBadgeProps as ah, type FFIDAnnouncementListClassNames as ai, type FFIDAnnouncementListProps as aj, type FFIDLoginButtonProps as ak, type FFIDOrganizationSwitcherClassNames as al, type FFIDOrganizationSwitcherProps as am, type FFIDSubscriptionBadgeClassNames as an, type FFIDSubscriptionBadgeProps as ao, type FFIDUserMenuClassNames as ap, type FFIDUserMenuProps as aq, type FFIDConfig as b, type FFIDApiResponse as c, type FFIDSessionResponse as d, type FFIDRedirectResult as e, type FFIDError as f, type FFIDSubscriptionCheckResponse as g, type FFIDCheckServiceAccessParams as h, type FFIDServiceAccessDecision as i, type FFIDAnalyticsConfig as j, type FFIDVerifyAccessTokenOptions as k, type FFIDOAuthUserInfo as l, type FFIDInquiryCreateParams as m, type FFIDInquiryCreateResponse as n, type FFIDAuthMode as o, type FFIDLogger as p, type FFIDCacheAdapter as q, type FFIDUser as r, type FFIDOrganization as s, type FFIDSubscription as t, type FFIDSubscriptionContextValue as u, type FFIDOAuthUserInfoSubscription as v, type FFIDAnnouncementsClientConfig as w, type FFIDAnnouncementsApiResponse as x, type FFIDAnnouncementsLogger as y, type Announcement as z };
1525
+ export { type FFIDInquiryFormSubmitResult as $, type AnnouncementListResponse as A, type Announcement as B, type AnnouncementStatus as C, type AnnouncementType as D, type EffectiveSubscriptionStatus as E, type FFIDSubscriptionStatus as F, EFFECTIVE_SUBSCRIPTION_STATUSES as G, FFIDAnnouncementBadge as H, FFIDAnnouncementList as I, type FFIDAnnouncementsError as J, type FFIDAnnouncementsErrorCode as K, type ListAnnouncementsOptions as L, type FFIDAnnouncementsServerResponse as M, type FFIDApiResponseMeta as N, type FFIDCacheConfig as O, type FFIDContextValue as P, type FFIDInquiryCategory as Q, type FFIDInquiryCategorySite2026 as R, FFIDInquiryForm as S, type FFIDInquiryFormCategoryItem as T, type FFIDInquiryFormClassNames as U, type FFIDInquiryFormLegalLayout as V, type FFIDInquiryFormOrganization as W, type FFIDInquiryFormPlaceholderContext as X, type FFIDInquiryFormPrefill as Y, type FFIDInquiryFormProps as Z, type FFIDInquiryFormSubmitData as _, type FFIDPrompt as a, type FFIDJwtClaims as a0, FFIDLoginButton as a1, type FFIDOAuthTokenResponse as a2, type FFIDOAuthUserInfoMemberRole as a3, FFIDOrganizationSwitcher as a4, type FFIDRedirectErrorCode as a5, type FFIDSeatModel as a6, type FFIDServiceAccessDenialReason as a7, type FFIDServiceAccessFailPolicy as a8, FFIDSubscriptionBadge as a9, type FFIDTokenIntrospectionResponse as aa, FFIDUserMenu as ab, FFID_INQUIRY_CATEGORIES as ac, FFID_INQUIRY_CATEGORIES_SITE_2026 as ad, type UseFFIDAnnouncementsOptions as ae, type UseFFIDAnnouncementsReturn as af, isFFIDInquiryCategorySite2026 as ag, useFFIDAnnouncements as ah, type FFIDAnnouncementBadgeClassNames as ai, type FFIDAnnouncementBadgeProps as aj, type FFIDAnnouncementListClassNames as ak, type FFIDAnnouncementListProps as al, type FFIDLoginButtonProps as am, type FFIDOrganizationSwitcherClassNames as an, type FFIDOrganizationSwitcherProps as ao, type FFIDSubscriptionBadgeClassNames as ap, type FFIDSubscriptionBadgeProps as aq, type FFIDUserMenuClassNames as ar, type FFIDUserMenuProps as as, type FFIDConfig as b, type FFIDApiResponse as c, type FFIDSessionResponse as d, type FFIDSignOutResult as e, type FFIDRedirectResult as f, type FFIDError as g, type FFIDSubscriptionCheckResponse as h, type FFIDCheckServiceAccessParams as i, type FFIDServiceAccessDecision as j, type FFIDAnalyticsConfig as k, type FFIDVerifyAccessTokenOptions as l, type FFIDOAuthUserInfo as m, type FFIDInquiryCreateParams as n, type FFIDInquiryCreateResponse as o, type FFIDAuthMode as p, type FFIDLogger as q, type FFIDCacheAdapter as r, type FFIDUser as s, type FFIDOrganization as t, type FFIDSubscription as u, type FFIDSubscriptionContextValue as v, type FFIDOAuthUserInfoSubscription as w, type FFIDAnnouncementsClientConfig as x, type FFIDAnnouncementsApiResponse as y, type FFIDAnnouncementsLogger as z };
@@ -658,6 +658,19 @@ interface FFIDSessionResponse {
658
658
  organizations: FFIDOrganization[];
659
659
  subscriptions: FFIDSubscription[];
660
660
  }
661
+ /**
662
+ * Optional metadata on successful {@link FFIDApiResponse} values (#4136).
663
+ *
664
+ * Present only on the success branch — error responses never carry `meta`.
665
+ */
666
+ interface FFIDApiResponseMeta {
667
+ /**
668
+ * Set when introspect-strategy verification could not use the configured
669
+ * cache (adapter read/write failure or `crypto.subtle` unavailable).
670
+ * Visible without a custom logger; absent when cache operated normally.
671
+ */
672
+ verificationCacheDegraded?: true;
673
+ }
661
674
  /**
662
675
  * API response wrapper (discriminated union for type safety)
663
676
  *
@@ -667,10 +680,33 @@ interface FFIDSessionResponse {
667
680
  type FFIDApiResponse<T> = {
668
681
  data: T;
669
682
  error?: undefined;
683
+ meta?: FFIDApiResponseMeta;
670
684
  } | {
671
685
  data?: undefined;
672
686
  error: FFIDError;
673
687
  };
688
+ /**
689
+ * Result of `signOut()` (#4119, extended #4136).
690
+ *
691
+ * Local credentials (tokens / local state) are always cleared when `signOut()`
692
+ * resolves without `error`. `revoked` additionally indicates whether the
693
+ * server-side revocation/sign-out actually succeeded:
694
+ *
695
+ * - `revoked: true` — no server-side session/token remains active.
696
+ * - `revoked: false` — server-side revocation failed (network error or non-2xx
697
+ * response). The access token may remain valid server-side until natural
698
+ * expiry. Non-fatal: the local sign-out still completed, but callers that
699
+ * need guaranteed revocation (e.g. shared-device flows) should surface this.
700
+ *
701
+ * Token mode (#4136): `accessTokenRevoked` / `refreshTokenRevoked` report each
702
+ * RFC 7009 revoke call. `revoked` is `true` only when every applicable token
703
+ * was revoked successfully. Cookie mode omits the per-token fields.
704
+ */
705
+ interface FFIDSignOutResult {
706
+ revoked: boolean;
707
+ accessTokenRevoked?: boolean;
708
+ refreshTokenRevoked?: boolean;
709
+ }
674
710
 
675
711
  /**
676
712
  * Response shape from `GET /api/v1/ext/analytics/config?service=<code>`.
@@ -704,23 +740,33 @@ interface FFIDAnalyticsConfig {
704
740
  * has been fired **3 times within 60 seconds**. Caller should surface a
705
741
  * manual "再度ログインする" UI rather than retry automatically (#2406 / #2411).
706
742
  *
707
- * SDK 2.18.0 only ships `'redirect_loop_detected'`. Other failure paths
708
- * (SSR environment, PKCE generation failure, empty organizationId) currently
709
- * return `error` without a `code`. New codes will be added in future minor
710
- * versions — treat this union as forward-extensible and do NOT exhaustively
711
- * `switch` over it without a `default` branch for consumer code that must
712
- * stay compatible across SDK upgrades.
743
+ * - `'state_persistence_failed'`: `redirectToAuthorize()` could not persist
744
+ * the OAuth CSRF `state` (storage unavailable / quota). Redirect is aborted
745
+ * fail-closed (#4136) callers should surface a manual retry UI.
746
+ *
747
+ * Other failure paths (SSR environment, PKCE generation failure, empty
748
+ * organizationId) currently return `error` without a `code`. Treat this union
749
+ * as forward-extensible and do NOT exhaustively `switch` over it without a
750
+ * `default` branch for consumer code that must stay compatible across SDK
751
+ * upgrades.
713
752
  */
714
- type FFIDRedirectErrorCode = 'redirect_loop_detected';
753
+ type FFIDRedirectErrorCode = 'redirect_loop_detected' | 'state_persistence_failed';
715
754
  /**
716
755
  * Result of a redirect operation (redirectToLogin / redirectToAuthorize / redirectToLogout)
717
756
  *
718
757
  * Structured return type so callers can inspect failure reasons
719
758
  * instead of receiving a bare `false`. When `code` is set, branch on it
720
759
  * for programmatic handling; otherwise log `error` for humans.
760
+ *
761
+ * `loopDetectionDisabled` (#4119): set to `true` when sessionStorage is
762
+ * unavailable (iOS WebKit private mode / eviction) so redirect-loop detection
763
+ * ran **fail-open** — the redirect fired, but repeated-redirect protection is
764
+ * disabled for this browser session. Callers that need loop protection on
765
+ * such browsers should add their own max-retry guard.
721
766
  */
722
767
  type FFIDRedirectResult = {
723
768
  success: true;
769
+ loopDetectionDisabled?: boolean;
724
770
  } | {
725
771
  success: false;
726
772
  error: string;
@@ -1476,4 +1522,4 @@ interface FFIDInquiryFormPlaceholderContext {
1476
1522
  }
1477
1523
  declare function FFIDInquiryForm({ mode, prefill, organizations, preselectedOrganizationId, categories, termsVersion, privacyVersion, termsHref, privacyHref, turnstileToken, turnstileSlot, onSubmit, onChange, legalLayout, messagePlaceholder, requireCategorySelection, unstyled, classNames, locale, className, }: FFIDInquiryFormProps): react_jsx_runtime.JSX.Element;
1478
1524
 
1479
- export { FFIDLoginButton as $, type AnnouncementListResponse as A, type AnnouncementStatus as B, type AnnouncementType as C, EFFECTIVE_SUBSCRIPTION_STATUSES as D, type EffectiveSubscriptionStatus as E, type FFIDSubscriptionStatus as F, FFIDAnnouncementBadge as G, FFIDAnnouncementList as H, type FFIDAnnouncementsError as I, type FFIDAnnouncementsErrorCode as J, type FFIDAnnouncementsServerResponse as K, type ListAnnouncementsOptions as L, type FFIDCacheConfig as M, type FFIDContextValue as N, type FFIDInquiryCategory as O, type FFIDInquiryCategorySite2026 as P, FFIDInquiryForm as Q, type FFIDInquiryFormCategoryItem as R, type FFIDInquiryFormClassNames as S, type FFIDInquiryFormLegalLayout as T, type FFIDInquiryFormOrganization as U, type FFIDInquiryFormPlaceholderContext as V, type FFIDInquiryFormPrefill as W, type FFIDInquiryFormProps as X, type FFIDInquiryFormSubmitData as Y, type FFIDInquiryFormSubmitResult as Z, type FFIDJwtClaims as _, type FFIDPrompt as a, type FFIDOAuthTokenResponse as a0, type FFIDOAuthUserInfoMemberRole as a1, FFIDOrganizationSwitcher as a2, type FFIDRedirectErrorCode as a3, type FFIDSeatModel as a4, type FFIDServiceAccessDenialReason as a5, type FFIDServiceAccessFailPolicy as a6, FFIDSubscriptionBadge as a7, type FFIDTokenIntrospectionResponse as a8, FFIDUserMenu as a9, FFID_INQUIRY_CATEGORIES as aa, FFID_INQUIRY_CATEGORIES_SITE_2026 as ab, type UseFFIDAnnouncementsOptions as ac, type UseFFIDAnnouncementsReturn as ad, isFFIDInquiryCategorySite2026 as ae, useFFIDAnnouncements as af, type FFIDAnnouncementBadgeClassNames as ag, type FFIDAnnouncementBadgeProps as ah, type FFIDAnnouncementListClassNames as ai, type FFIDAnnouncementListProps as aj, type FFIDLoginButtonProps as ak, type FFIDOrganizationSwitcherClassNames as al, type FFIDOrganizationSwitcherProps as am, type FFIDSubscriptionBadgeClassNames as an, type FFIDSubscriptionBadgeProps as ao, type FFIDUserMenuClassNames as ap, type FFIDUserMenuProps as aq, type FFIDConfig as b, type FFIDApiResponse as c, type FFIDSessionResponse as d, type FFIDRedirectResult as e, type FFIDError as f, type FFIDSubscriptionCheckResponse as g, type FFIDCheckServiceAccessParams as h, type FFIDServiceAccessDecision as i, type FFIDAnalyticsConfig as j, type FFIDVerifyAccessTokenOptions as k, type FFIDOAuthUserInfo as l, type FFIDInquiryCreateParams as m, type FFIDInquiryCreateResponse as n, type FFIDAuthMode as o, type FFIDLogger as p, type FFIDCacheAdapter as q, type FFIDUser as r, type FFIDOrganization as s, type FFIDSubscription as t, type FFIDSubscriptionContextValue as u, type FFIDOAuthUserInfoSubscription as v, type FFIDAnnouncementsClientConfig as w, type FFIDAnnouncementsApiResponse as x, type FFIDAnnouncementsLogger as y, type Announcement as z };
1525
+ export { type FFIDInquiryFormSubmitResult as $, type AnnouncementListResponse as A, type Announcement as B, type AnnouncementStatus as C, type AnnouncementType as D, type EffectiveSubscriptionStatus as E, type FFIDSubscriptionStatus as F, EFFECTIVE_SUBSCRIPTION_STATUSES as G, FFIDAnnouncementBadge as H, FFIDAnnouncementList as I, type FFIDAnnouncementsError as J, type FFIDAnnouncementsErrorCode as K, type ListAnnouncementsOptions as L, type FFIDAnnouncementsServerResponse as M, type FFIDApiResponseMeta as N, type FFIDCacheConfig as O, type FFIDContextValue as P, type FFIDInquiryCategory as Q, type FFIDInquiryCategorySite2026 as R, FFIDInquiryForm as S, type FFIDInquiryFormCategoryItem as T, type FFIDInquiryFormClassNames as U, type FFIDInquiryFormLegalLayout as V, type FFIDInquiryFormOrganization as W, type FFIDInquiryFormPlaceholderContext as X, type FFIDInquiryFormPrefill as Y, type FFIDInquiryFormProps as Z, type FFIDInquiryFormSubmitData as _, type FFIDPrompt as a, type FFIDJwtClaims as a0, FFIDLoginButton as a1, type FFIDOAuthTokenResponse as a2, type FFIDOAuthUserInfoMemberRole as a3, FFIDOrganizationSwitcher as a4, type FFIDRedirectErrorCode as a5, type FFIDSeatModel as a6, type FFIDServiceAccessDenialReason as a7, type FFIDServiceAccessFailPolicy as a8, FFIDSubscriptionBadge as a9, type FFIDTokenIntrospectionResponse as aa, FFIDUserMenu as ab, FFID_INQUIRY_CATEGORIES as ac, FFID_INQUIRY_CATEGORIES_SITE_2026 as ad, type UseFFIDAnnouncementsOptions as ae, type UseFFIDAnnouncementsReturn as af, isFFIDInquiryCategorySite2026 as ag, useFFIDAnnouncements as ah, type FFIDAnnouncementBadgeClassNames as ai, type FFIDAnnouncementBadgeProps as aj, type FFIDAnnouncementListClassNames as ak, type FFIDAnnouncementListProps as al, type FFIDLoginButtonProps as am, type FFIDOrganizationSwitcherClassNames as an, type FFIDOrganizationSwitcherProps as ao, type FFIDSubscriptionBadgeClassNames as ap, type FFIDSubscriptionBadgeProps as aq, type FFIDUserMenuClassNames as ar, type FFIDUserMenuProps as as, type FFIDConfig as b, type FFIDApiResponse as c, type FFIDSessionResponse as d, type FFIDSignOutResult as e, type FFIDRedirectResult as f, type FFIDError as g, type FFIDSubscriptionCheckResponse as h, type FFIDCheckServiceAccessParams as i, type FFIDServiceAccessDecision as j, type FFIDAnalyticsConfig as k, type FFIDVerifyAccessTokenOptions as l, type FFIDOAuthUserInfo as m, type FFIDInquiryCreateParams as n, type FFIDInquiryCreateResponse as o, type FFIDAuthMode as p, type FFIDLogger as q, type FFIDCacheAdapter as r, type FFIDUser as s, type FFIDOrganization as t, type FFIDSubscription as u, type FFIDSubscriptionContextValue as v, type FFIDOAuthUserInfoSubscription as w, type FFIDAnnouncementsClientConfig as x, type FFIDAnnouncementsApiResponse as y, type FFIDAnnouncementsLogger as z };