@undefineds.co/xpod 0.4.19 → 0.4.20

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.
Files changed (136) hide show
  1. package/dist/api/container/common.js +2 -1
  2. package/dist/api/handlers/AiConfigHandler.js +10 -2
  3. package/dist/runtime/host/node/NodeRuntimeHost.js +7 -3
  4. package/dist/runtime/port-finder.d.ts +0 -5
  5. package/dist/runtime/port-finder.js +24 -12
  6. package/node_modules/@undefineds.co/extension-sdk/dist/react/solid-auth-boundary.d.ts +20 -2
  7. package/node_modules/@undefineds.co/extension-sdk/dist/react/solid-auth-boundary.js +142 -125
  8. package/node_modules/@undefineds.co/shared-ui/dist/focus.d.ts +1 -1
  9. package/node_modules/@undefineds.co/shared-ui/dist/focus.js +1 -1
  10. package/node_modules/@undefineds.co/shared-ui/dist/index.d.ts +1 -0
  11. package/node_modules/@undefineds.co/shared-ui/dist/index.js +1 -0
  12. package/node_modules/@undefineds.co/shared-ui/dist/login/LoginModal.d.ts +2 -0
  13. package/node_modules/@undefineds.co/shared-ui/dist/login/LoginModal.js +2 -0
  14. package/node_modules/@undefineds.co/shared-ui/dist/login/LoginView.d.ts +3 -0
  15. package/node_modules/@undefineds.co/shared-ui/dist/login/LoginView.js +3 -0
  16. package/node_modules/@undefineds.co/shared-ui/dist/login.d.ts +15 -0
  17. package/node_modules/@undefineds.co/shared-ui/dist/login.js +15 -0
  18. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/AccountSections.d.ts +141 -0
  19. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/AccountSections.js +67 -0
  20. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/ConsentView.d.ts +53 -0
  21. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/ConsentView.js +27 -0
  22. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/DeviceDialogs.d.ts +40 -0
  23. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/DeviceDialogs.js +33 -0
  24. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpChrome.d.ts +15 -0
  25. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpChrome.js +8 -0
  26. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpViews.d.ts +93 -0
  27. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpViews.js +88 -0
  28. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/NetworkPanel.d.ts +46 -0
  29. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/NetworkPanel.js +42 -0
  30. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignIn.d.ts +63 -0
  31. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignIn.js +65 -0
  32. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignInFrame.d.ts +31 -0
  33. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignInFrame.js +111 -0
  34. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/StorageBadge.d.ts +8 -0
  35. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/StorageBadge.js +7 -0
  36. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/XpodMark.d.ts +8 -0
  37. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/XpodMark.js +8 -0
  38. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/account-parts.d.ts +37 -0
  39. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/account-parts.js +33 -0
  40. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/copy.d.ts +156 -0
  41. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/copy.js +304 -0
  42. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/index.d.ts +20 -0
  43. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/index.js +18 -0
  44. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/parts.d.ts +69 -0
  45. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/parts.js +65 -0
  46. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/types.d.ts +14 -0
  47. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/types.js +1 -0
  48. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/webid-name.d.ts +5 -0
  49. package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/webid-name.js +14 -0
  50. package/node_modules/@undefineds.co/shared-ui/dist/storage-bootstrap.d.ts +3 -0
  51. package/node_modules/@undefineds.co/shared-ui/dist/storage-bootstrap.js +3 -0
  52. package/node_modules/@undefineds.co/shared-ui/dist/theme.css +168 -83
  53. package/node_modules/@undefineds.co/shared-ui/dist/webid-auth.d.ts +5 -0
  54. package/node_modules/@undefineds.co/shared-ui/dist/webid-auth.js +5 -0
  55. package/package.json +2 -2
  56. package/static/app/assets/main.css +1 -1
  57. package/static/app/assets/main.js +55 -15
  58. package/static/dashboard/assets/{AiConfigContext-B5QP7ow2.js → AiConfigContext-CZEW16so.js} +1 -1
  59. package/static/dashboard/assets/{AiConfigPage-C_TdlUjq.js → AiConfigPage-Cfp0fRX1.js} +1 -1
  60. package/static/dashboard/assets/{DocumentProcessingPanel-CormNOdI.js → DocumentProcessingPanel-DaaRCLp6.js} +1 -1
  61. package/static/dashboard/assets/{IndexLifecyclePanel-S9wNNyHO.js → IndexLifecyclePanel-BCz3jNM8.js} +1 -1
  62. package/static/dashboard/assets/{IndexSubjectPanel-CofZT1oE.js → IndexSubjectPanel-DVCVIt7V.js} +1 -1
  63. package/static/dashboard/assets/ModelAssignmentsPanel-DxauxtEY.js +1 -0
  64. package/static/dashboard/assets/{ModelsPage-DZ46VnUh.js → ModelsPage-B8F3AtZL.js} +3 -3
  65. package/static/dashboard/assets/{NetworkPage-TwbIWASf.js → NetworkPage-Cu7ty71x.js} +2 -2
  66. package/static/dashboard/assets/{PaneListHeader-BtVnyutC.js → PaneListHeader-BEAXSlD9.js} +1 -1
  67. package/static/dashboard/assets/{SearchIndexingPanel-BCq_YMOP.js → SearchIndexingPanel-DEr1EDDC.js} +1 -1
  68. package/static/dashboard/assets/{StatusSubjectPanel-DsUKTysU.js → StatusSubjectPanel-Cg92MGhO.js} +1 -1
  69. package/static/dashboard/assets/{StatusWorkspace-CaVJBRqI.js → StatusWorkspace-BmJSOF3z.js} +1 -1
  70. package/static/dashboard/assets/{SystemSettingsPage-DRWfPjtu.js → SystemSettingsPage-rziu4Q3U.js} +1 -1
  71. package/static/dashboard/assets/SystemSettingsSubjectPanel-D16DGDNW.js +33 -0
  72. package/static/dashboard/assets/{XpodAiConnectionsPodStore-C9tHqutw.js → XpodAiConnectionsPodStore-FlZ0LEn0.js} +1 -1
  73. package/static/dashboard/assets/{activity-tgjewO88.js → activity-D55X-5L5.js} +1 -1
  74. package/static/dashboard/assets/{badge-Czun47II.js → badge-CRf1ISRJ.js} +1 -1
  75. package/static/dashboard/assets/{collection-runtime-DnYlU23-.js → collection-runtime-CfXMuwNc.js} +1 -1
  76. package/static/dashboard/assets/dashboard-B3kGI946.css +1 -0
  77. package/static/dashboard/assets/{dashboard-CF8SbVSR.js → dashboard-D4DWPaAy.js} +122 -122
  78. package/static/dashboard/assets/{dialog-D-Yc_lg-.js → dialog-EVyIyybL.js} +1 -1
  79. package/static/dashboard/assets/{download-vFuOkjCi.js → download-Et4aRDT2.js} +1 -1
  80. package/static/dashboard/assets/{external-link-Cg_VIecD.js → external-link-DT746o7t.js} +1 -1
  81. package/static/dashboard/assets/{index-IXCNeEwi.js → index-D2agcVRx.js} +3 -3
  82. package/static/dashboard/assets/{index-0au0WwkE.js → index-_wC13YGI.js} +1 -1
  83. package/static/dashboard/assets/{index-YDcVky3o.js → index-z6TnJzW6.js} +1 -1
  84. package/static/dashboard/assets/{key-round-9n1xgLbG.js → key-round-CHnogQ1D.js} +1 -1
  85. package/static/dashboard/assets/{rotate-ccw-DJ6s86DW.js → rotate-ccw-BNVDC4Zr.js} +1 -1
  86. package/static/dashboard/assets/{skeleton-Dg9HePtI.js → skeleton-BzsZekVf.js} +1 -1
  87. package/static/dashboard/assets/{waypoints-uxc_qOzk.js → waypoints-CLZA22UN.js} +1 -1
  88. package/static/dashboard/assets/{workspace-layout-BNtAXhPW.js → workspace-layout-urYcwAhS.js} +1 -1
  89. package/static/dashboard/dashboard.html +2 -2
  90. package/static/settings/assets/{AiConfigContext-y6ha7pGs.js → AiConfigContext-B2cVJFNu.js} +1 -1
  91. package/static/settings/assets/AiConfigPage-D_5jSPPF.js +1 -0
  92. package/static/settings/assets/{DocumentProcessingPanel-Oa_cxMcn.js → DocumentProcessingPanel-DodGlYIk.js} +1 -1
  93. package/static/settings/assets/{IndexLifecyclePanel-DlrnI0Kh.js → IndexLifecyclePanel-BtH-0GKv.js} +1 -1
  94. package/static/settings/assets/{IndexSubjectPanel-Dhsl0W32.js → IndexSubjectPanel-CqKhUcw2.js} +1 -1
  95. package/static/settings/assets/ModelAssignmentsPanel-Cam9V9BN.js +1 -0
  96. package/static/settings/assets/{ModelsPage-CuNW1hGX.js → ModelsPage-DWFic09l.js} +3 -3
  97. package/static/settings/assets/{NetworkPage-BBD2Lc_P.js → NetworkPage-CSwHoAWm.js} +2 -2
  98. package/static/settings/assets/{PaneListHeader-C81adSBX.js → PaneListHeader-270Z179Z.js} +1 -1
  99. package/static/settings/assets/{SearchIndexingPanel-Dc4QKWd0.js → SearchIndexingPanel-ATHKMDBQ.js} +1 -1
  100. package/static/settings/assets/{StatusSubjectPanel-DuxOvqzS.js → StatusSubjectPanel-DDWo3v3d.js} +1 -1
  101. package/static/settings/assets/StatusWorkspace-BYgqeCBM.js +1 -0
  102. package/static/settings/assets/SystemSettingsPage-BRaQAFWC.js +1 -0
  103. package/static/settings/assets/SystemSettingsSubjectPanel-Dc0roh9d.js +33 -0
  104. package/static/settings/assets/{XpodAiConnectionsPodStore-G0ClZksP.js → XpodAiConnectionsPodStore-OndzbigX.js} +2 -2
  105. package/static/settings/assets/{activity-DT8pzOea.js → activity-BAZEToJ3.js} +1 -1
  106. package/static/settings/assets/auth-callback-Bd3tvCOa.js +1 -0
  107. package/static/settings/assets/{badge-CvKRjSY2.js → badge-Cpol0LWF.js} +1 -1
  108. package/static/settings/assets/{collection-runtime-C6ZAp2cM.js → collection-runtime-B5vGx3gk.js} +1 -1
  109. package/static/settings/assets/{dialog-LFluK7Nx.js → dialog-_7AVvv5q.js} +1 -1
  110. package/static/settings/assets/{download-CZJeqUm1.js → download-DRAi-dnn.js} +1 -1
  111. package/static/settings/assets/{external-link-BsDft3Oe.js → external-link--Yq8inDb.js} +1 -1
  112. package/static/settings/assets/global-B3kGI946.css +1 -0
  113. package/static/settings/assets/{global-cmKEraT4.js → global-DMtP8ZF4.js} +111 -111
  114. package/static/settings/assets/{index-BiqSFOS1.js → index-C36H49PZ.js} +1 -1
  115. package/static/settings/assets/{index-XRgmPBKw.js → index-CQR3iePj.js} +1 -1
  116. package/static/settings/assets/{index-BMPlaRWG.js → index-DURnCfoQ.js} +1 -1
  117. package/static/settings/assets/{index-browser-B0slhJKc.js → index-browser-kAl2JmYB.js} +1 -1
  118. package/static/settings/assets/{key-round-D1XsWbN_.js → key-round-DzpWBVN9.js} +1 -1
  119. package/static/settings/assets/{rotate-ccw-CEe0P0fY.js → rotate-ccw-CtVsCcAx.js} +1 -1
  120. package/static/settings/assets/settings-DQtt6lql.js +1 -0
  121. package/static/settings/assets/{skeleton-DA404w6m.js → skeleton-R_ACks7d.js} +1 -1
  122. package/static/settings/assets/{waypoints-DJDWc4S9.js → waypoints-D-Qv_sME.js} +1 -1
  123. package/static/settings/assets/{workspace-layout-K38jT4OV.js → workspace-layout-BSMCQq35.js} +1 -1
  124. package/static/settings/auth-callback.html +3 -3
  125. package/static/settings/settings.html +3 -3
  126. package/static/dashboard/assets/ModelAssignmentsPanel-9tgOjj-y.js +0 -1
  127. package/static/dashboard/assets/SystemSettingsSubjectPanel-CgDP7Ii2.js +0 -33
  128. package/static/dashboard/assets/dashboard-DvuM3VTP.css +0 -1
  129. package/static/settings/assets/AiConfigPage-CIcIWdXA.js +0 -1
  130. package/static/settings/assets/ModelAssignmentsPanel-CHoiRZeL.js +0 -1
  131. package/static/settings/assets/StatusWorkspace-DeD3zi3G.js +0 -1
  132. package/static/settings/assets/SystemSettingsPage-8sHOaPb8.js +0 -1
  133. package/static/settings/assets/SystemSettingsSubjectPanel-B1JXut7S.js +0 -33
  134. package/static/settings/assets/auth-callback-1BlsOtMG.js +0 -1
  135. package/static/settings/assets/global-DvuM3VTP.css +0 -1
  136. package/static/settings/assets/settings-DfjkqEJ8.js +0 -1
@@ -176,7 +176,8 @@ function registerCommonServices(container) {
176
176
  solidSessions: (0, awilix_1.asFunction)(({ config }) => {
177
177
  return new SolidSessionFactory_1.SolidSessionFactory({
178
178
  tokenEndpoint: config.cssTokenEndpoint,
179
- publicBaseUrl: config.solidBaseUrl,
179
+ // Managed Local's Pod origin differs from the issuer of its client credentials.
180
+ publicBaseUrl: config.oidcIssuer ?? config.solidBaseUrl,
180
181
  });
181
182
  }).singleton(),
182
183
  ownerPodAccess: (0, awilix_1.asFunction)(({ config, solidSessions, taskCredentialStore }) => {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerAiConfigRoutes = registerAiConfigRoutes;
4
4
  const readBoundedJsonBody_1 = require("../http/readBoundedJsonBody");
5
5
  const GatewayPrincipal_1 = require("../ai-gateway/auth/GatewayPrincipal");
6
+ const PodAccessFailureResponse_1 = require("./PodAccessFailureResponse");
6
7
  const EmbeddingModelPolicy_1 = require("../../ai/service/EmbeddingModelPolicy");
7
8
  function registerAiConfigRoutes(server, options) {
8
9
  server.get('/api/ai/config', async (request, response) => {
@@ -17,7 +18,12 @@ function registerAiConfigRoutes(server, options) {
17
18
  lifecycle: options.lifecycle ? await options.lifecycle.status(owner) : emptyLifecycle(config.updatedAt),
18
19
  });
19
20
  }
20
- catch {
21
+ catch (error) {
22
+ // A caller whose Pod credential cannot be replayed (a DPoP session) is refused, not
23
+ // broken: the session retries with its own client credential only when it sees this
24
+ // stable 403, so reporting it as an internal error would strand the read.
25
+ if ((0, PodAccessFailureResponse_1.sendPodAccessFailure)(response, error))
26
+ return;
21
27
  sendJson(response, 500, { error: 'Failed to read AI Config' });
22
28
  }
23
29
  });
@@ -52,7 +58,9 @@ function registerAiConfigRoutes(server, options) {
52
58
  lifecycle: options.lifecycle ? await options.lifecycle.status(owner) : emptyLifecycle(config.updatedAt),
53
59
  });
54
60
  }
55
- catch {
61
+ catch (error) {
62
+ if ((0, PodAccessFailureResponse_1.sendPodAccessFailure)(response, error))
63
+ return;
56
64
  sendJson(response, 500, { error: 'Failed to update AI Config' });
57
65
  }
58
66
  });
@@ -20,9 +20,13 @@ class NodeRuntimeHost {
20
20
  return process.platform === 'win32' ? 'port' : 'socket';
21
21
  }
22
22
  async allocatePorts(options = {}) {
23
- const gateway = options.gatewayPort ?? await (0, port_finder_1.getFreePort)(options.basePort ?? 5600);
24
- const css = options.cssPort ?? await (0, port_finder_1.getFreePort)(gateway + 1);
25
- const api = options.apiPort ?? await (0, port_finder_1.getFreePort)(css + 1);
23
+ // Defaults have to clear every address a service may bind: `bootstrap` publishes the
24
+ // gateway as `localhost`, which can resolve to `::1`, while CSS/API bind the default
25
+ // `bindHost` 127.0.0.1. An IPv4-only probe reports a port held on `[::]` as free, and the
26
+ // runtime then serves its own localhost traffic to the competitor.
27
+ const gateway = options.gatewayPort ?? await (0, port_finder_1.getFreePortForWildcard)(options.basePort ?? 5600);
28
+ const css = options.cssPort ?? await (0, port_finder_1.getFreePortForWildcard)(gateway + 1);
29
+ const api = options.apiPort ?? await (0, port_finder_1.getFreePortForWildcard)(css + 1);
26
30
  // Tunnels (and the P2P data plane) terminate here, and this listener never treats a
27
31
  // caller as local whatever headers it carries - that is the gate. Its port is the one
28
32
  // number the user copies into a provider console, so it is predictable rather than
@@ -18,11 +18,6 @@ export declare function getFreePort(basePort: number, host?: string, timeoutMs?:
18
18
  * runtime's service.
19
19
  */
20
20
  export declare function getEphemeralLoopbackPort(): Promise<number>;
21
- /**
22
- * Allocates a port for child services that bind wildcard addresses.
23
- * CSS may bind `::` while the API binds `0.0.0.0`, so probing only localhost
24
- * can miss an occupied port on the other address family.
25
- */
26
21
  /**
27
22
  * Takes exactly this port or fails.
28
23
  *
@@ -155,10 +155,26 @@ function hasIpv6Address() {
155
155
  return Object.values(node_os_1.default.networkInterfaces()).some((entries) => entries?.some((entry) => entry.family === 'IPv6'));
156
156
  }
157
157
  /**
158
- * Allocates a port for child services that bind wildcard addresses.
159
- * CSS may bind `::` while the API binds `0.0.0.0`, so probing only localhost
160
- * can miss an occupied port on the other address family.
158
+ * Addresses this allocator clears before handing out a port: the wildcard addresses plus the
159
+ * loopback addresses child services use by default (`bindHost` defaults to `127.0.0.1`).
160
+ * Platforms may allow a wildcard bind and a specific-address bind on the same port (this macOS
161
+ * host does, under Node and Bun), so probing one category can report an unusable port as free.
162
+ * A port held on a non-loopback specific address is outside this guarantee: it is not probed.
161
163
  */
164
+ function serviceProbeHosts(probeIpv6) {
165
+ return probeIpv6
166
+ ? ['0.0.0.0', '::', '127.0.0.1', '::1']
167
+ : ['0.0.0.0', '127.0.0.1'];
168
+ }
169
+ /** The first address a service may bind that is already taken, if any. */
170
+ async function firstOccupiedServiceAddress(port, timeoutMs, probeIpv6) {
171
+ for (const host of serviceProbeHosts(probeIpv6)) {
172
+ if (!await canListen(port, host, timeoutMs)) {
173
+ return host;
174
+ }
175
+ }
176
+ return undefined;
177
+ }
162
178
  /**
163
179
  * Takes exactly this port or fails.
164
180
  *
@@ -169,21 +185,17 @@ async function requireFreePortForWildcard(port, timeoutMs = PORT_PROBE_TIMEOUT_M
169
185
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
170
186
  throw new Error(`ingress port ${port} is not a valid port number`);
171
187
  }
172
- if (!await canListen(port, '0.0.0.0', timeoutMs)) {
173
- throw new Error(`ingress port ${port} is already in use; free it or point the tunnel at another port`);
174
- }
175
- if (hasIpv6Address() && !await canListen(port, '::', timeoutMs)) {
176
- throw new Error(`ingress port ${port} is already in use on IPv6; free it or point the tunnel at another port`);
188
+ const occupied = await firstOccupiedServiceAddress(port, timeoutMs, hasIpv6Address());
189
+ if (occupied) {
190
+ const family = occupied.includes(':') ? ' on IPv6' : '';
191
+ throw new Error(`ingress port ${port} is already in use${family}; free it or point the tunnel at another port`);
177
192
  }
178
193
  return port;
179
194
  }
180
195
  async function getFreePortForWildcard(basePort, timeoutMs = PORT_PROBE_TIMEOUT_MS) {
181
196
  const probeIpv6 = hasIpv6Address();
182
197
  for (let port = basePort; port <= HIGHEST_PORT; port++) {
183
- if (!await canListen(port, '0.0.0.0', timeoutMs)) {
184
- continue;
185
- }
186
- if (probeIpv6 && !await canListen(port, '::', timeoutMs)) {
198
+ if (await firstOccupiedServiceAddress(port, timeoutMs, probeIpv6)) {
187
199
  continue;
188
200
  }
189
201
  return port;
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type AuthSurfaceMode, type StorageBootstrapCopy, type WebIdLoginRouteCopy } from '@undefineds.co/shared-ui';
2
+ import { type AppIdentity, type AuthSurfaceMode, type PodSignInCopy, type PodSignInLocale, type StorageBootstrapCopy, type WebIdLoginRouteCopy } from '@undefineds.co/shared-ui';
3
3
  import type { StorageSelectionState, StorageBinding, WebIdAuthState, WebIdLoginRouteDescriptor } from '@undefineds.co/solid-sdk';
4
4
  export interface SolidAuthBoundaryProps {
5
5
  state: WebIdAuthState;
@@ -9,6 +9,11 @@ export interface SolidAuthBoundaryProps {
9
9
  onCreateStorage?: () => void | Promise<void>;
10
10
  onContinueStorage?: (binding: StorageBinding) => void | Promise<void>;
11
11
  onSelectStorage?: (binding: StorageBinding) => void | Promise<void>;
12
+ /**
13
+ * `storage` still overrides the Pod chooser wording. `route` is retained for
14
+ * source compatibility only: the sign-in wording now ships with `PodSignIn`
15
+ * (`podSignInCopy` overrides it).
16
+ */
12
17
  copy?: {
13
18
  route?: Partial<WebIdLoginRouteCopy>;
14
19
  storage?: Partial<StorageBootstrapCopy>;
@@ -22,6 +27,19 @@ export interface SolidAuthBoundaryProps {
22
27
  /** Optional host-owned close action for modal presentation. */
23
28
  onSurfaceClose?: () => void | Promise<void>;
24
29
  auxiliary?: ReactNode;
30
+ /** The application's own name and icon for the source mark. Nothing is assumed when omitted. */
31
+ app?: AppIdentity;
32
+ /** Sign-in wording language. Defaults to `en`. */
33
+ locale?: PodSignInLocale;
34
+ /** Partial overrides of the shared sign-in wording. */
35
+ podSignInCopy?: Partial<PodSignInCopy>;
36
+ /** Technical detail of a failure becomes expandable. */
37
+ developerMode?: boolean;
25
38
  children: ReactNode;
26
39
  }
27
- export declare function SolidAuthBoundary({ state, storageState, routes, storageRouteId, onCreateStorage, onContinueStorage, onSelectStorage, copy, onLogin, onRetry, onCancel, onSwitchAccount, surfaceMode, onSurfaceClose, auxiliary, children, }: SolidAuthBoundaryProps): import("react").JSX.Element;
40
+ /**
41
+ * The application front door for third-party apps: maps the WebID and Pod
42
+ * selection state onto the shared `PodSignIn` states (A0-A3, plus a one-line
43
+ * C notice). It renders no second login flow; every action calls the host.
44
+ */
45
+ export declare function SolidAuthBoundary({ state, storageState, routes, storageRouteId, onCreateStorage, onContinueStorage, onSelectStorage, copy, onLogin, onRetry, onCancel, onSwitchAccount, surfaceMode, onSurfaceClose, auxiliary, app: appProp, locale, podSignInCopy, developerMode, children, }: SolidAuthBoundaryProps): import("react").JSX.Element;
@@ -1,83 +1,19 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { AuthSurface, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, StorageBootstrapView, WebIdLoginRouteView, } from '@undefineds.co/shared-ui';
4
- const routeCopy = {
5
- title: 'Connect to Solid',
6
- description: 'Choose an identity route to continue.',
7
- startLabel: 'Continue',
8
- restoringLabel: 'Restoring your session…',
9
- connectingLabel: 'Connecting…',
10
- rememberedLabel: 'Remembered identity',
11
- expiredTitle: 'Session expired',
12
- retryLabel: 'Try again',
13
- cancelLabel: 'Cancel',
14
- storageConflictTitle: 'Storage conflict',
15
- failureTitle: 'Could not sign in',
16
- switchAccountLabel: 'Switch account',
17
- };
18
- const storageCopy = {
19
- title: 'Prepare storage',
20
- description: 'The host is preparing the selected storage binding.',
21
- creationMessage: 'Storage is not ready yet.',
22
- waitingMessage: 'Waiting for the storage binding.',
23
- readyMessage: 'Storage is ready.',
24
- conflictMessage: 'The selected storage conflicts with this identity.',
25
- errorMessage: 'Storage could not be prepared.',
26
- createLabel: 'Create storage',
27
- continueLabel: 'Continue',
28
- retryLabel: 'Try again',
29
- cancelLabel: 'Cancel',
30
- };
31
- function presentationState(state, storageState) {
32
- if (storageState?.status === 'conflict') {
33
- return { status: 'storage-conflict', message: storageState.message };
34
- }
35
- if (storageState?.status === 'error') {
36
- return { status: 'error', message: storageState.message };
37
- }
38
- switch (state.status) {
39
- case 'restoring':
40
- return state.remembered
41
- ? { status: 'restoring', remembered: state.remembered }
42
- : { status: 'restoring' };
43
- case 'anonymous':
44
- return state.remembered
45
- ? { status: 'remembered', remembered: state.remembered }
46
- : { status: 'anonymous' };
47
- case 'connecting':
48
- return { status: 'connecting' };
49
- case 'authenticated':
50
- return { status: 'authenticated', webId: state.webId };
51
- case 'expired':
52
- return state.remembered
53
- ? { status: 'expired', remembered: state.remembered }
54
- : { status: 'expired' };
55
- case 'error':
56
- return { status: 'error', message: state.message };
2
+ import { useRef, useState } from 'react';
3
+ import { Button, PodSignIn, PodSignInFrame, SourceMark, formatCopy, resolvePodSignInCopy, webIdShortName, } from '@undefineds.co/shared-ui';
4
+ const DEFAULT_APP_NAME = 'Solid';
5
+ function presentationFor(mode) {
6
+ switch (mode) {
7
+ case 'page': return { presentation: 'page', modal: false };
8
+ case 'modal': return { presentation: 'dialog', modal: true };
9
+ case 'embedded': return { presentation: 'dialog', modal: false };
57
10
  }
58
11
  }
59
- function storageViewState(state) {
60
- switch (state.status) {
61
- case 'loading':
62
- return 'waiting';
63
- case 'empty':
64
- return 'creation';
65
- case 'selecting':
66
- return 'waiting_for_binding';
67
- case 'creating':
68
- return 'creating';
69
- case 'waiting_for_binding':
70
- return 'waiting_for_binding';
71
- case 'ready':
72
- return 'ready';
73
- case 'conflict':
74
- return { status: 'conflict', message: state.message };
75
- case 'error':
76
- return { status: 'error', message: state.message };
77
- }
78
- }
79
- function isStorageReady(state) {
80
- return state === undefined || state.status === 'ready';
12
+ function rememberedIdentity(remembered) {
13
+ return {
14
+ displayName: remembered.displayName,
15
+ ...(remembered.avatarUrl ? { avatarUrl: remembered.avatarUrl } : {}),
16
+ };
81
17
  }
82
18
  function storageBindingLabel(binding) {
83
19
  if (binding.label?.trim())
@@ -87,62 +23,143 @@ function storageBindingLabel(binding) {
87
23
  function storageBindingKey(binding) {
88
24
  return `${binding.storageUrl}\u0000${binding.webId}`;
89
25
  }
90
- function StorageSelectionView({ state, copy, onSelectStorage, onContinueStorage, }) {
26
+ /** The Pod chooser: the same 360px body and tokens as the sign-in states. */
27
+ function StorageSelectionView({ state, app, copy, storageCopy, onSelectStorage, onContinueStorage, }) {
91
28
  const [selectedKey, setSelectedKey] = useState();
92
29
  const selected = state.candidates.find((candidate) => storageBindingKey(candidate) === selectedKey);
93
30
  const canSelect = Boolean(onSelectStorage || onContinueStorage);
94
- return (_jsxs(Card, { className: "w-full rounded-none border-0 bg-transparent text-card-foreground shadow-none", children: [copy.title || copy.description ? (_jsxs(CardHeader, { children: [copy.title ? _jsx(CardTitle, { children: copy.title }) : null, copy.description ? _jsx(CardDescription, { children: copy.description }) : null] })) : null, _jsxs(CardContent, { className: "space-y-4 px-4 pb-4 pt-0", children: [_jsx("p", { role: "status", "aria-live": "polite", className: "text-sm text-foreground", children: "Choose a storage binding to continue." }), _jsx("div", { className: "space-y-2", children: state.candidates.map((candidate) => {
95
- const key = storageBindingKey(candidate);
96
- const label = storageBindingLabel(candidate);
97
- const isSelected = key === selectedKey;
98
- const content = (_jsxs(_Fragment, { children: [_jsx("span", { className: "min-w-0 truncate", children: label }), _jsx("span", { className: "shrink-0 text-xs text-muted-foreground", children: isSelected ? 'Selected' : 'Select' })] }));
99
- return canSelect ? (_jsx(Button, { type: "button", variant: isSelected ? 'secondary' : 'outline', className: "h-auto w-full justify-between gap-3 px-3 py-3 text-left", "aria-label": `${isSelected ? 'Selected' : 'Select'} ${label}`, "aria-pressed": isSelected, onClick: () => {
100
- setSelectedKey(key);
101
- if (onSelectStorage)
102
- void onSelectStorage(candidate);
103
- }, children: content }, key)) : (_jsx("div", { className: "flex items-center justify-between gap-3 rounded-md border border-border/60 px-3 py-3 text-sm", children: content }, key));
104
- }) }), selected && onContinueStorage ? (_jsx(Button, { type: "button", className: "w-full", onClick: () => void onContinueStorage(selected), children: copy.continueLabel })) : null] })] }));
31
+ const title = storageCopy?.title || copy.choosePodTitle;
32
+ const continueLabel = storageCopy?.continueLabel || copy.customSubmit;
33
+ return (_jsxs("div", { "data-pod-sign-in-state": "choose-pod", className: "flex flex-col gap-6", children: [_jsx(SourceMark, { icon: app.icon, name: app.name }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-xl font-semibold text-foreground", children: title }), _jsx("p", { role: "status", "aria-live": "polite", className: "text-sm text-muted-foreground", children: storageCopy?.description || copy.choosePodLead })] }), _jsx("div", { className: "flex flex-col gap-2", children: state.candidates.map((candidate) => {
34
+ const key = storageBindingKey(candidate);
35
+ const label = storageBindingLabel(candidate);
36
+ const isSelected = key === selectedKey;
37
+ const stateLabel = isSelected ? copy.selected : copy.select;
38
+ const content = (_jsxs(_Fragment, { children: [_jsx("span", { className: "min-w-0 truncate text-sm text-foreground", children: label }), _jsx("span", { className: "shrink-0 text-[13px] text-muted-foreground", children: stateLabel })] }));
39
+ return canSelect ? (_jsx("button", { type: "button", "aria-label": `${stateLabel} ${label}`, "aria-pressed": isSelected, className: `flex min-h-11 w-full items-center justify-between gap-3 rounded-lg border px-3 py-2 text-left focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring ${isSelected ? 'border-primary bg-accent' : 'border-border bg-card'}`, onClick: () => {
40
+ setSelectedKey(key);
41
+ if (onSelectStorage)
42
+ void onSelectStorage(candidate);
43
+ }, children: content }, key)) : (_jsx("div", { className: "flex min-h-11 items-center justify-between gap-3 rounded-lg border border-border bg-card px-3 py-2", children: content }, key));
44
+ }) }), selected && onContinueStorage ? (_jsx(Button, { type: "button", className: "h-11 w-full rounded-lg text-sm font-medium", onClick: () => void onContinueStorage(selected), children: continueLabel })) : null] }));
45
+ }
46
+ function isStorageReady(state) {
47
+ return state === undefined || state.status === 'ready';
105
48
  }
106
- export function SolidAuthBoundary({ state, storageState, routes, storageRouteId, onCreateStorage, onContinueStorage, onSelectStorage, copy, onLogin, onRetry, onCancel, onSwitchAccount, surfaceMode = 'page', onSurfaceClose, auxiliary, children, }) {
107
- const visibleRouteCopy = { ...routeCopy, ...copy?.route };
108
- const visibleStorageCopy = { ...storageCopy, ...copy?.storage };
109
- // AuthSurface owns both the accessible heading and the card frame for the
110
- // boundary. The nested views render unframed with presentation-only titles
111
- // so the surface does not show double cards or two equally named headings.
112
- const routeViewCopy = { ...visibleRouteCopy, title: '' };
113
- const storageViewCopy = { ...visibleStorageCopy, title: '' };
114
- const surface = (title, content) => (_jsx(AuthSurface, { mode: surfaceMode, title: title, onClose: onSurfaceClose, closeLabel: "Close", children: content }));
49
+ /**
50
+ * The application front door for third-party apps: maps the WebID and Pod
51
+ * selection state onto the shared `PodSignIn` states (A0-A3, plus a one-line
52
+ * C notice). It renders no second login flow; every action calls the host.
53
+ */
54
+ export function SolidAuthBoundary({ state, storageState, routes, storageRouteId, onCreateStorage, onContinueStorage, onSelectStorage, copy, onLogin, onRetry, onCancel, onSwitchAccount, surfaceMode = 'page', onSurfaceClose, auxiliary, app: appProp, locale = 'en', podSignInCopy, developerMode = false, children, }) {
55
+ const text = resolvePodSignInCopy(locale, podSignInCopy);
56
+ // `connecting` carries only the route, so the screen the user pressed the button on
57
+ // (remembered identity or first visit) is remembered from the states before it.
58
+ const lastRemembered = useRef(undefined);
59
+ if (state.status === 'anonymous' || state.status === 'restoring' || state.status === 'expired') {
60
+ lastRemembered.current = state.remembered;
61
+ }
62
+ const app = appProp ?? { name: DEFAULT_APP_NAME };
63
+ const { presentation, modal } = presentationFor(surfaceMode);
64
+ const frame = (content) => (_jsxs(PodSignInFrame, { presentation: presentation, modal: modal, ariaLabel: text.chooseTitle, onClose: onSurfaceClose ? () => void onSurfaceClose() : undefined, closeLabel: onSurfaceClose ? text.close : undefined, children: [content, auxiliary ? _jsx("div", { className: "mt-4", children: auxiliary }) : null] }));
115
65
  if (state.status === 'authenticated' && isStorageReady(storageState)) {
116
66
  return _jsx(_Fragment, { children: children });
117
67
  }
118
68
  if (state.status === 'authenticated' && storageState?.status === 'selecting') {
119
- return surface(visibleStorageCopy.title, (_jsx(StorageSelectionView, { state: storageState, copy: storageViewCopy, onSelectStorage: onSelectStorage, onContinueStorage: onContinueStorage })));
69
+ return frame(_jsx(StorageSelectionView, { state: storageState, app: app, copy: text, storageCopy: copy?.storage, onSelectStorage: onSelectStorage, onContinueStorage: onContinueStorage }));
70
+ }
71
+ // Route used by "sign in" and "sign in again": the remembered identity's route,
72
+ // else the only route. With several routes and nothing remembered the first is the primary one.
73
+ const rememberedOf = (s) => (s.status === 'anonymous' || s.status === 'restoring' || s.status === 'expired' ? s.remembered : undefined);
74
+ const remembered = rememberedOf(state);
75
+ const primaryRoute = state.status === 'connecting'
76
+ ? state.route
77
+ : routes.find((route) => route.id === remembered?.routeId) ?? routes[0];
78
+ const login = () => { if (primaryRoute)
79
+ void onLogin(primaryRoute.id); };
80
+ const relogin = () => {
81
+ const routeId = state.status === 'error' ? state.retryRouteId : primaryRoute?.id;
82
+ if (routeId && onRetry)
83
+ void onRetry(routeId);
84
+ else
85
+ login();
86
+ };
87
+ const noop = () => undefined;
88
+ const extraRoutes = state.status === 'anonymous' && !remembered ? routes.filter((route) => route !== primaryRoute) : [];
89
+ let podState;
90
+ let notice;
91
+ let onPrimary = login;
92
+ let onUseAnother = onSwitchAccount ? () => void onSwitchAccount() : undefined;
93
+ const serviceLabel = primaryRoute?.label;
94
+ // Route-specific label for the primary button on the first-visit screen.
95
+ const routeCopy = serviceLabel
96
+ ? { useXpod: formatCopy(text.signInWith, { service: serviceLabel }) }
97
+ : undefined;
98
+ if (state.status === 'authenticated') {
99
+ // Valid WebID sessions stay valid while their Pod opens or retries: never
100
+ // turn a Pod problem into a second login.
101
+ const identity = { displayName: webIdShortName(state.webId) };
102
+ const busy = storageState?.status === 'loading'
103
+ || storageState?.status === 'waiting_for_binding'
104
+ || storageState?.status === 'creating';
105
+ podState = { kind: 'remembered', identity, busy };
106
+ onUseAnother = undefined;
107
+ onPrimary = noop;
108
+ if (storageState?.status === 'error') {
109
+ notice = { tone: 'warning', text: text.noticeUnreachable, primaryLabel: text.retry, developerDetail: storageState.message };
110
+ const retryRouteId = storageRouteId;
111
+ onPrimary = retryRouteId && onRetry ? () => void onRetry(retryRouteId) : noop;
112
+ }
113
+ else if (storageState?.status === 'conflict') {
114
+ notice = { tone: 'warning', text: text.noticeIncomplete, primaryLabel: text.useAnother, developerDetail: storageState.message };
115
+ onPrimary = onSwitchAccount
116
+ ? () => void onSwitchAccount()
117
+ : storageRouteId && onRetry ? () => void onRetry(storageRouteId) : noop;
118
+ }
119
+ else if (storageState?.status === 'empty') {
120
+ notice = { tone: 'neutral', text: text.noticeNoWebId, primaryLabel: text.goCreate };
121
+ onPrimary = onCreateStorage ? () => void onCreateStorage() : noop;
122
+ }
123
+ }
124
+ else if (state.status === 'restoring') {
125
+ podState = { kind: 'restoring', ...(remembered ? { identity: rememberedIdentity(remembered) } : {}) };
126
+ }
127
+ else if (state.status === 'connecting') {
128
+ // The screen the user pressed the button on, with the button spinning.
129
+ podState = lastRemembered.current
130
+ ? { kind: 'remembered', identity: rememberedIdentity(lastRemembered.current), busy: true }
131
+ : { kind: 'choose-service', busy: true };
132
+ if (lastRemembered.current)
133
+ onUseAnother = undefined;
134
+ }
135
+ else if (state.status === 'expired') {
136
+ podState = {
137
+ kind: 'expired',
138
+ identity: rememberedIdentity(remembered ?? { displayName: serviceLabel ?? app.name }),
139
+ };
140
+ onPrimary = relogin;
120
141
  }
121
- if (state.status === 'authenticated' && storageState) {
122
- const storageStateView = storageViewState(storageState);
123
- const canRetryStorage = Boolean(onRetry && storageRouteId
124
- && (storageState.status === 'conflict' || storageState.status === 'error'));
125
- const canCancelStorage = Boolean(onCancel
126
- && (storageState.status === 'creating' || storageState.status === 'waiting_for_binding'));
127
- return surface(visibleStorageCopy.title, (_jsx(StorageBootstrapView, { state: storageStateView, copy: storageViewCopy, onCreate: storageState.status === 'empty' ? onCreateStorage : undefined, onRetry: canRetryStorage ? () => void onRetry?.(storageRouteId) : undefined, onCancel: canCancelStorage ? onCancel : undefined, framed: false })));
142
+ else {
143
+ // anonymous, or error (same screens plus a C4 notice)
144
+ podState = remembered
145
+ ? { kind: 'remembered', identity: rememberedIdentity(remembered) }
146
+ : { kind: 'choose-service' };
147
+ if (state.status === 'error') {
148
+ notice = {
149
+ tone: 'warning',
150
+ text: text.noticeIncomplete,
151
+ primaryLabel: text.reauthenticate,
152
+ developerDetail: state.message,
153
+ };
154
+ onPrimary = relogin;
155
+ }
156
+ if (primaryRoute?.availability === 'starting') {
157
+ podState = { ...podState, busy: true };
158
+ }
159
+ else if (primaryRoute?.availability === 'unavailable' && !notice) {
160
+ notice = { tone: 'warning', text: primaryRoute.unavailableReason ?? text.noticeUnreachable };
161
+ onPrimary = noop;
162
+ }
128
163
  }
129
- const routeList = state.status === 'connecting'
130
- ? [state.route]
131
- : routes.length > 0
132
- ? routes
133
- : [];
134
- const mappedState = presentationState(state, storageState);
135
- return surface(visibleRouteCopy.title, (_jsxs("div", { className: "flex w-full flex-col gap-4", children: [routeList.map((route) => {
136
- const retryRouteId = state.status === 'error'
137
- ? state.retryRouteId
138
- : state.status === 'expired'
139
- ? state.remembered?.routeId ?? (routes.length === 1 ? routes[0]?.id : undefined)
140
- : undefined;
141
- const canRetry = Boolean(onRetry && (retryRouteId === route.id
142
- || (storageRouteId === route.id
143
- && (storageState?.status === 'conflict' || storageState?.status === 'error'))));
144
- const canStart = state.status === 'anonymous';
145
- const canCancel = state.status === 'connecting';
146
- return (_jsx(WebIdLoginRouteView, { route: route, state: mappedState, copy: routeViewCopy, onStart: canStart ? onLogin : undefined, onRetry: canRetry ? onRetry : undefined, onCancel: canCancel ? onCancel : undefined, onSwitchAccount: onSwitchAccount, framed: false }, route.id));
147
- }), auxiliary ? _jsx("div", { children: auxiliary }) : null] })));
164
+ return frame(_jsxs(_Fragment, { children: [_jsx(PodSignIn, { app: app, state: podState, notice: notice, locale: locale, copy: { ...routeCopy, ...podSignInCopy }, developerMode: developerMode, primaryIcon: null, capabilities: { customService: false, register: false }, onPrimary: onPrimary, onUseAnother: onUseAnother }), extraRoutes.length > 0 ? (_jsx("div", { className: "mt-3 flex flex-col gap-2", children: extraRoutes.map((route) => (_jsx(Button, { type: "button", variant: "outline", className: "h-11 w-full rounded-lg text-sm font-medium", disabled: route.availability === 'unavailable', onClick: () => void onLogin(route.id), children: formatCopy(text.signInWith, { service: route.label }) }, route.id))) })) : null, state.status === 'connecting' && onCancel ? (_jsx(Button, { type: "button", variant: "ghost", className: "mt-2 h-9 w-full rounded-lg px-2 text-sm font-medium", onClick: () => void onCancel(), children: text.cancel })) : null] }));
148
165
  }
@@ -5,7 +5,7 @@
5
5
  * top of a native form focus border creates the double-frame effect that this
6
6
  * package intentionally avoids.
7
7
  */
8
- export declare const controlFocusClass = "focus:outline-none focus:ring-0 focus-visible:border-ring";
8
+ export declare const controlFocusClass = "focus:outline-none focus:ring-0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-ring";
9
9
  export declare const interactiveFocusClass = "focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring";
10
10
  /**
11
11
  * Buttons communicate keyboard focus through their existing surface instead
@@ -5,7 +5,7 @@
5
5
  * top of a native form focus border creates the double-frame effect that this
6
6
  * package intentionally avoids.
7
7
  */
8
- export const controlFocusClass = 'focus:outline-none focus:ring-0 focus-visible:border-ring';
8
+ export const controlFocusClass = 'focus:outline-none focus:ring-0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-ring';
9
9
  export const interactiveFocusClass = 'focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring';
10
10
  /**
11
11
  * Buttons communicate keyboard focus through their existing surface instead
@@ -29,3 +29,4 @@ export * from './utils';
29
29
  export * from './storage-bootstrap';
30
30
  export * from './webid-auth';
31
31
  export * from './workspace';
32
+ export * from './pod-sign-in/index';
@@ -28,3 +28,4 @@ export * from './utils.js';
28
28
  export * from './storage-bootstrap.js';
29
29
  export * from './webid-auth.js';
30
30
  export * from './workspace.js';
31
+ export * from './pod-sign-in/index.js';
@@ -2,5 +2,7 @@ import type { LoginModalProps } from './types';
2
2
  /**
3
3
  * Shared login modal. The host supplies the brand and, optionally, the product
4
4
  * name that user-facing messages refer to.
5
+ *
6
+ * @deprecated Use PodSignIn inside PodSignInFrame (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
5
7
  */
6
8
  export declare function LoginModal(props: LoginModalProps): import("react").JSX.Element | null;
@@ -12,6 +12,8 @@ import { LocalReachabilitySummary } from './LocalReachabilitySummary.js';
12
12
  /**
13
13
  * Shared login modal. The host supplies the brand and, optionally, the product
14
14
  * name that user-facing messages refer to.
15
+ *
16
+ * @deprecated Use PodSignIn inside PodSignInFrame (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
15
17
  */
16
18
  export function LoginModal(props) {
17
19
  const { state, storageConflict, view } = props;
@@ -30,4 +30,7 @@ export interface LoginViewProps {
30
30
  overlayClassName?: string;
31
31
  cardClassName?: string;
32
32
  }
33
+ /**
34
+ * @deprecated Use PodSignIn (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
35
+ */
33
36
  export declare function LoginView({ state, identity, error, restorable, providers, brand, host, ariaLabel, actions, authWindowStatus, connectingProvider, allowAdditionalProviders, overlayClassName, cardClassName, }: LoginViewProps): import("react").JSX.Element | null;
@@ -6,6 +6,9 @@ const CLOSED_AUTH_WINDOW = {
6
6
  reason: 'dismissed',
7
7
  ready: false,
8
8
  };
9
+ /**
10
+ * @deprecated Use PodSignIn (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
11
+ */
9
12
  export function LoginView({ state, identity, error = null, restorable = false, providers, brand, host = 'document', ariaLabel, actions, authWindowStatus = CLOSED_AUTH_WINDOW, connectingProvider = null, allowAdditionalProviders = false, overlayClassName, cardClassName, }) {
10
13
  if (state === 'authenticated')
11
14
  return null;
@@ -20,11 +20,17 @@ export declare function LoginAvatar({ name, avatarUrl, size, marker, }: {
20
20
  size?: 'md' | 'lg';
21
21
  marker?: ReactNode;
22
22
  }): import("react").JSX.Element;
23
+ /**
24
+ * @deprecated Use PodSignIn (state `restoring`) (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
25
+ */
23
26
  export declare function LoginRestoringView({ accountName, avatarUrl, label, }: {
24
27
  accountName?: string;
25
28
  avatarUrl?: string;
26
29
  label?: string;
27
30
  }): import("react").JSX.Element;
31
+ /**
32
+ * @deprecated Use PodSignIn (`busy` on the primary action) (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
33
+ */
28
34
  export declare function LoginConnectingView({ title, detail, providerLabel, providerHost, onCancel, cancelLabel, }: {
29
35
  title?: string;
30
36
  detail?: string;
@@ -33,6 +39,9 @@ export declare function LoginConnectingView({ title, detail, providerLabel, prov
33
39
  onCancel?: () => void;
34
40
  cancelLabel?: string;
35
41
  }): import("react").JSX.Element;
42
+ /**
43
+ * @deprecated Use PodSignIn (states `remembered` / `expired`) (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
44
+ */
36
45
  export declare function LoginAccountView({ name, avatarUrl, bindingLabel, expired, expiredTitle, expiredDescription, enterLabel, switchLabel, error, onDismissError, dismissErrorLabel, onEnter, onSwitchAccount, onReauthenticate, }: {
37
46
  name: string;
38
47
  avatarUrl?: string;
@@ -93,6 +102,9 @@ export interface RememberedLoginViewCopy {
93
102
  connectingDetail: string;
94
103
  cancelLabel: string;
95
104
  }
105
+ /**
106
+ * @deprecated Use PodSignIn (states `remembered` / `expired`) (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
107
+ */
96
108
  export declare function RememberedLoginView({ state, copy, onContinue, onReauthenticate, onSwitchAccount, onCancel, onDismissError, }: {
97
109
  state: SessionLoginPresentationState;
98
110
  copy: RememberedLoginViewCopy;
@@ -102,6 +114,9 @@ export declare function RememberedLoginView({ state, copy, onContinue, onReauthe
102
114
  onCancel?: () => void;
103
115
  onDismissError?: () => void;
104
116
  }): import("react").JSX.Element | null;
117
+ /**
118
+ * @deprecated Use PodSignIn with a `notice` (see `pod-sign-in/`). Kept for one more version; behavior is unchanged.
119
+ */
105
120
  export declare function LoginFailureView({ title, description, primaryLabel, onPrimary, secondaryLabel, onSecondary, }: {
106
121
  title?: string;
107
122
  description?: string | null;