@undefineds.co/xpod 0.4.25 → 0.4.27
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/api/ApiServer.d.ts +1 -0
- package/dist/api/ApiServer.js +38 -0
- package/dist/api/ai-config/AiConfigStore.js +18 -6
- package/dist/api/ai-gateway/connect/index.d.ts +1 -0
- package/dist/api/ai-gateway/connect/index.js +39 -18
- package/dist/api/ai-gateway/models/ProviderModelsAdapter.js +5 -2
- package/dist/api/container/common.js +8 -2
- package/dist/api/container/index.js +2 -2
- package/dist/api/container/local.js +6 -3
- package/dist/api/handlers/AiGatewayHandler.d.ts +1 -0
- package/dist/api/handlers/AiGatewayHandler.js +53 -3
- package/dist/api/handlers/AiGatewayManagementHandler.js +9 -0
- package/dist/api/handlers/TaskHandler.js +15 -10
- package/dist/api/network/NetworkEnvironmentConfigurationStore.js +1 -1
- package/dist/api/runs/ManagedRunWorker.d.ts +0 -1
- package/dist/api/runs/ManagedRunWorker.js +2 -14
- package/dist/api/runs/PiAgentRuntimeDriver.d.ts +0 -8
- package/dist/api/runs/PiAgentRuntimeDriver.js +65 -21
- package/dist/api/runs/RunStateCenter.js +1 -0
- package/dist/api/runs/store.d.ts +1 -0
- package/dist/api/runs/store.js +13 -0
- package/dist/api/tasks/TaskMaterializer.js +13 -6
- package/dist/api/tasks/TaskResumeDiagnostics.d.ts +28 -0
- package/dist/api/tasks/TaskResumeDiagnostics.js +148 -0
- package/dist/api/tasks/TaskService.js +40 -23
- package/dist/storage/conditions/StorageETagHandler.d.ts +1 -1
- package/dist/storage/conditions/StorageETagHandler.js +13 -4
- package/dist/util/task-model-diagnostics.d.ts +67 -0
- package/dist/util/task-model-diagnostics.js +118 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.js +10 -10
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeyRow.d.ts +3 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeyRow.js +2 -2
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.js +77 -23
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.js +59 -59
- package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +2 -0
- package/node_modules/@undefineds.co/ai-connections/dist/collections.js +14 -6
- package/node_modules/@undefineds.co/ai-connections/dist/contract/ai-connections-client.d.ts +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/contract/ai-connections-client.js +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/gateway-model-roles.d.ts +11 -0
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/gateway-model-roles.js +11 -0
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/normalize.d.ts +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/normalize.js +12 -5
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/request.js +10 -2
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/types.d.ts +10 -0
- package/node_modules/@undefineds.co/ai-connections/package.json +1 -1
- package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +1 -0
- package/node_modules/@undefineds.co/extension-sdk/package.json +1 -1
- package/node_modules/@undefineds.co/pod-collections/dist/index.cjs +60 -13
- package/node_modules/@undefineds.co/pod-collections/dist/mapping.d.ts +16 -1
- package/node_modules/@undefineds.co/pod-collections/dist/mapping.js +51 -0
- package/node_modules/@undefineds.co/pod-collections/dist/mutations.js +14 -18
- package/node_modules/@undefineds.co/pod-collections/package.json +1 -1
- package/node_modules/@undefineds.co/shared-ui/dist/list.d.ts +8 -1
- package/node_modules/@undefineds.co/shared-ui/dist/list.js +4 -1
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpChrome.d.ts +1 -1
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpChrome.js +2 -2
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpViews.js +2 -2
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignInFrame.d.ts +3 -3
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignInFrame.js +5 -5
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/parts.d.ts +5 -5
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/parts.js +5 -5
- package/node_modules/@undefineds.co/shared-ui/dist/section-header.js +1 -1
- package/node_modules/@undefineds.co/shared-ui/dist/theme.css +5 -32
- package/node_modules/@undefineds.co/shared-ui/package.json +1 -1
- package/node_modules/@undefineds.co/solid-sdk/package.json +1 -1
- package/package.json +2 -2
- package/static/app/assets/main.css +1 -1
- package/static/app/assets/main.js +1 -1
- package/static/dashboard/assets/AccountAuthBoundary-Dv52SZc6.js +1 -0
- package/static/dashboard/assets/DesktopOidcCallback-DaT_Rumf.js +1 -0
- package/static/dashboard/assets/DevicePages-HjclpIVm.js +2 -0
- package/static/dashboard/assets/ModelsPage-Be2TPd-x.js +11 -0
- package/static/dashboard/assets/{PaneListHeader-Dn5O0mwy.js → PaneListHeader-DtvnRmFq.js} +1 -1
- package/static/dashboard/assets/{PodDeletionAuthorizationPanel-D3NOG6ZM.js → PodDeletionAuthorizationPanel-BJk_8rJq.js} +3 -3
- package/static/dashboard/assets/PodPage-C4gzEspV.js +1 -0
- package/static/dashboard/assets/{SystemSettingsPage-BNQP_Yuc.js → SystemSettingsPage-HaNrP1H1.js} +1 -1
- package/static/dashboard/assets/TasksPage-BdO5K2L7.js +1 -0
- package/static/dashboard/assets/{WebDesktopEntry-vnb4CZWp.js → WebDesktopEntry-Cj9_ZfJU.js} +1 -1
- package/static/dashboard/assets/XpodAiConnectionsPodStore-B7gmXBmC.js +3 -0
- package/static/dashboard/assets/XpodShellApp-D_KY4nCW.js +4 -0
- package/static/dashboard/assets/{account-session-DCUmCop1.js → account-session-DlcKNG7k.js} +1 -1
- package/static/dashboard/assets/{button-By5Bgvmb.js → button-wslF55uZ.js} +1 -1
- package/static/dashboard/assets/collection-runtime-uxxgEu13.js +1 -0
- package/static/dashboard/assets/{createLucideIcon-bunMzPms.js → createLucideIcon-BJQl82Qk.js} +1 -1
- package/static/dashboard/assets/dashboard-CbJ-JkrI.css +1 -0
- package/static/dashboard/assets/{dashboard-mlsg3yaw.js → dashboard-Or0gnkou.js} +2 -2
- package/static/dashboard/assets/index-BqFeOML9.js +1 -0
- package/static/dashboard/assets/{index-DvMG5pHk.js → index-DgKn1twH.js} +2 -2
- package/static/dashboard/assets/{label-Bj03L9xs.js → label-CS6Sx6Zb.js} +1 -1
- package/static/dashboard/assets/list-UyhlCFKk.js +1 -0
- package/static/dashboard/assets/{nav-item-style-BNqWQY6p.js → nav-item-style-CW1Nnorq.js} +1 -1
- package/static/dashboard/assets/{pod-collections-host-KnnGFZHL.js → pod-collections-host-DjK2xf-b.js} +6 -6
- package/static/dashboard/assets/{safe-continuation-D9AhcWiB.js → safe-continuation-ClWAhcma.js} +1 -1
- package/static/dashboard/assets/{section-header-CLCzbOp_.js → section-header-CEIEcco-.js} +1 -1
- package/static/dashboard/assets/{setting-row-DTCec8A2.js → setting-row-CaYv3dfF.js} +1 -1
- package/static/dashboard/assets/xpod-remembered-login-BUF9fin1.js +310 -0
- package/static/dashboard/dashboard.html +2 -2
- package/static/settings/assets/{AccountAuthBoundary-C0og_gIA.js → AccountAuthBoundary-Chqd38oU.js} +1 -1
- package/static/settings/assets/{DesktopOidcCallback-C5q4oFZ0.js → DesktopOidcCallback-VUrOSM_q.js} +1 -1
- package/static/settings/assets/DevicePages-C6qwvWwu.js +2 -0
- package/static/settings/assets/ModelsPage-Ry_dObRQ.js +11 -0
- package/static/settings/assets/{PaneListHeader-DqVlMe2D.js → PaneListHeader-B5RkRqr4.js} +1 -1
- package/static/settings/assets/{PodDeletionAuthorizationPanel-DgVvarVY.js → PodDeletionAuthorizationPanel-DPM-5Izt.js} +3 -3
- package/static/settings/assets/PodPage-CxND6wwc.js +1 -0
- package/static/settings/assets/{SystemSettingsPage-Crzm_DrI.js → SystemSettingsPage-C8EdMkW7.js} +1 -1
- package/static/settings/assets/TasksPage-DuqptEm8.js +1 -0
- package/static/settings/assets/{WebDesktopEntry-BGC5eRF2.js → WebDesktopEntry-BRcyktkv.js} +1 -1
- package/static/settings/assets/XpodAiConnectionsPodStore-CyA_BJVC.js +3 -0
- package/static/settings/assets/XpodShellApp-CsivHJl0.js +4 -0
- package/static/settings/assets/XpodThemeProvider-CbJ-JkrI.css +1 -0
- package/static/settings/assets/{XpodThemeProvider-CB6LepTA.js → XpodThemeProvider-DK3pIdRG.js} +2 -2
- package/static/settings/assets/{account-session-BcLjCj0x.js → account-session-DJOZ03xr.js} +1 -1
- package/static/settings/assets/auth-callback-GIBYEz_7.js +1 -0
- package/static/settings/assets/{button-BObT8pTE.js → button-D3yW-2o1.js} +1 -1
- package/static/settings/assets/collection-runtime-DfGo25mh.js +1 -0
- package/static/settings/assets/{createLucideIcon-BVsUxXpZ.js → createLucideIcon-CacwLsmB.js} +1 -1
- package/static/settings/assets/{index-ktjMkj7-.js → index-r5KRYsKC.js} +1 -1
- package/static/settings/assets/{label-BrqO8_m_.js → label-MJjUmvzG.js} +1 -1
- package/static/settings/assets/list-Ce-5k1MX.js +1 -0
- package/static/settings/assets/{nav-item-style-Di2CxkDU.js → nav-item-style-ZUbL8KOZ.js} +1 -1
- package/static/settings/assets/{pod-collections-host-KnnGFZHL.js → pod-collections-host-DjK2xf-b.js} +6 -6
- package/static/settings/assets/{safe-continuation-Dx6ceJpY.js → safe-continuation-vlBZFSlU.js} +1 -1
- package/static/settings/assets/{section-header-Dtl7yjVr.js → section-header-DGJdEvQw.js} +1 -1
- package/static/settings/assets/{setting-row-BL6Hhe8N.js → setting-row-C7tuFiho.js} +1 -1
- package/static/settings/assets/{settings-DaRBxoZk.js → settings-CyQPih1O.js} +1 -1
- package/static/settings/assets/xpod-remembered-login-D-TzzT5K.js +567 -0
- package/static/settings/auth-callback.html +3 -3
- package/static/settings/settings.html +3 -3
- package/static/dashboard/assets/AccountAuthBoundary-BvoDydRz.js +0 -1
- package/static/dashboard/assets/DesktopOidcCallback-BwIj874x.js +0 -1
- package/static/dashboard/assets/DevicePages-jOjMcvsr.js +0 -2
- package/static/dashboard/assets/ModelsPage-CMTdfqBR.js +0 -11
- package/static/dashboard/assets/PodPage-BueBdJ9_.js +0 -1
- package/static/dashboard/assets/TasksPage-CxtLJiSF.js +0 -1
- package/static/dashboard/assets/XpodAiConnectionsPodStore-wx3Ttupm.js +0 -18
- package/static/dashboard/assets/XpodShellApp-5FWY8-d5.js +0 -4
- package/static/dashboard/assets/collection-runtime-BnomuB0E.js +0 -1
- package/static/dashboard/assets/dashboard-C64R553B.css +0 -1
- package/static/dashboard/assets/xpod-remembered-login-Dr69A0Rv.js +0 -295
- package/static/settings/assets/DevicePages-fyHjjucT.js +0 -2
- package/static/settings/assets/ModelsPage-EyOByLyE.js +0 -11
- package/static/settings/assets/PodPage-DY4Oi9wg.js +0 -1
- package/static/settings/assets/TasksPage-CfXJbnlt.js +0 -1
- package/static/settings/assets/XpodAiConnectionsPodStore-CXcmgKmQ.js +0 -3
- package/static/settings/assets/XpodShellApp-D1PS3Iut.js +0 -4
- package/static/settings/assets/XpodThemeProvider-C64R553B.css +0 -1
- package/static/settings/assets/auth-callback-DSPQ28ar.js +0 -1
- package/static/settings/assets/collection-runtime-DzNbdZGe.js +0 -1
- package/static/settings/assets/index-browser-3WfrNbcG.js +0 -273
- package/static/settings/assets/xpod-remembered-login-Q66DH12t.js +0 -295
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PodCollectionError } from './types.js';
|
|
2
|
-
import { descriptorRowToColumnValues, fieldBindings, isUriArrayField, projectionFieldOrder, } from './mapping.js';
|
|
2
|
+
import { descriptorRowToColumnValues, fieldBindings, isUriArrayField, normalizeMutationRow, normalizeUriArray, projectionFieldOrder, } from './mapping.js';
|
|
3
3
|
import { documentOfIri, resourceIdForRow, subjectIriForRow } from './layout.js';
|
|
4
4
|
import { sessionFetchOf } from './read.js';
|
|
5
5
|
import { projectionCovers, projectionHash } from './diff.js';
|
|
@@ -109,13 +109,6 @@ export function reconcilePendingWrites(pending, next, hashOf, writeOnly = EMPTY_
|
|
|
109
109
|
}
|
|
110
110
|
/** 默认「没有只写字段」,与 `projectionCovers()` 的默认值同义。 */
|
|
111
111
|
const EMPTY_WRITE_ONLY = new Set();
|
|
112
|
-
function absoluteUri(value, base) {
|
|
113
|
-
if (typeof value !== 'string' || value.length === 0)
|
|
114
|
-
return undefined;
|
|
115
|
-
if (/^[a-z][a-z0-9+.-]*:/iu.test(value))
|
|
116
|
-
return value;
|
|
117
|
-
return new URL(value, base).toString();
|
|
118
|
-
}
|
|
119
112
|
/**
|
|
120
113
|
* `array: true` + `type: 'uri'` 字段的唯一写入口(§4.1):一次 SPARQL PATCH,
|
|
121
114
|
* 先删旧值再插新值。`array + uri` 之外字段不允许走这里。
|
|
@@ -126,12 +119,8 @@ export async function writeField(context, fieldName, options) {
|
|
|
126
119
|
throw new PodCollectionError('write_field_not_uri_array', `field ${fieldName} is not array+uri; it must go through the ORM`);
|
|
127
120
|
}
|
|
128
121
|
const documentUrl = documentOfIri(context.document);
|
|
129
|
-
const previous = (
|
|
130
|
-
|
|
131
|
-
.filter((value) => value !== undefined);
|
|
132
|
-
const next = (Array.isArray(options.next) ? options.next : [options.next])
|
|
133
|
-
.map((value) => absoluteUri(value, documentUrl))
|
|
134
|
-
.filter((value) => value !== undefined);
|
|
122
|
+
const previous = normalizeUriArray(options.previous, documentUrl);
|
|
123
|
+
const next = normalizeUriArray(options.next, documentUrl);
|
|
135
124
|
const triples = (iris) => iris
|
|
136
125
|
.map((iri) => `<${options.subjectIri}> <${field.predicate}> <${iri}> .`)
|
|
137
126
|
.join('\n');
|
|
@@ -183,10 +172,14 @@ export function createMutationHandlers(context) {
|
|
|
183
172
|
return {
|
|
184
173
|
onInsert: async ({ transaction }) => {
|
|
185
174
|
for (const mutation of transaction.mutations) {
|
|
186
|
-
const row = mutation.modified;
|
|
187
175
|
const key = String(mutation.key);
|
|
188
176
|
const resourceId = resourceIdForRow(descriptor, context.document, context.podUrl, key);
|
|
189
177
|
const subjectIri = subjectIriForRow(descriptor, context.document, key);
|
|
178
|
+
const row = normalizeMutationRow(descriptor, table, mutation.modified, {
|
|
179
|
+
database: context.database, podUrl: context.podUrl, document: context.document, resourceId,
|
|
180
|
+
});
|
|
181
|
+
// TanStack keeps modified as its optimistic/committed transaction row.
|
|
182
|
+
Object.assign(mutation.modified, row);
|
|
190
183
|
pending.register({
|
|
191
184
|
key,
|
|
192
185
|
intent: row,
|
|
@@ -207,10 +200,13 @@ export function createMutationHandlers(context) {
|
|
|
207
200
|
for (const mutation of transaction.mutations) {
|
|
208
201
|
const key = String(mutation.key);
|
|
209
202
|
const original = mutation.original;
|
|
210
|
-
const modified = mutation.modified;
|
|
211
203
|
const changes = mutation.changes;
|
|
212
204
|
const resourceId = resourceIdForRow(descriptor, context.document, context.podUrl, key);
|
|
213
205
|
const subjectIri = subjectIriForRow(descriptor, context.document, key);
|
|
206
|
+
const modified = normalizeMutationRow(descriptor, table, mutation.modified, {
|
|
207
|
+
database: context.database, podUrl: context.podUrl, document: context.document, resourceId,
|
|
208
|
+
});
|
|
209
|
+
Object.assign(mutation.modified, modified);
|
|
214
210
|
const beforeHash = original && Object.keys(original).length > 0 ? hashOf(original) : undefined;
|
|
215
211
|
pending.register({
|
|
216
212
|
key,
|
|
@@ -220,13 +216,13 @@ export function createMutationHandlers(context) {
|
|
|
220
216
|
});
|
|
221
217
|
await runWrite(key, async () => {
|
|
222
218
|
const columnChanges = {};
|
|
223
|
-
for (const
|
|
219
|
+
for (const field of Object.keys(changes)) {
|
|
224
220
|
if (uriArrayFieldNames.has(field))
|
|
225
221
|
continue;
|
|
226
222
|
const column = columnOf(field);
|
|
227
223
|
if (column === undefined)
|
|
228
224
|
continue;
|
|
229
|
-
columnChanges[column] =
|
|
225
|
+
columnChanges[column] = modified[field];
|
|
230
226
|
}
|
|
231
227
|
if (Object.keys(columnChanges).length > 0) {
|
|
232
228
|
const updated = await context.database.updateById(table, resourceId, columnChanges);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
export
|
|
2
|
+
export interface ListSurfaceProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/**
|
|
4
|
+
* Render the surface as the single child element (e.g. a real `ul` or an
|
|
5
|
+
* existing sortable container) so native semantics, ref and events stay on
|
|
6
|
+
* that element without adding a wrapper.
|
|
7
|
+
*/
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}
|
|
3
10
|
/**
|
|
4
11
|
* Bordered, divided container for a group of rows. Presentation only: it adds
|
|
5
12
|
* no list role, navigation or focus behaviour of its own.
|
|
@@ -6,7 +6,10 @@ import { cn } from './utils.js';
|
|
|
6
6
|
* Bordered, divided container for a group of rows. Presentation only: it adds
|
|
7
7
|
* no list role, navigation or focus behaviour of its own.
|
|
8
8
|
*/
|
|
9
|
-
export const ListSurface = React.forwardRef(({ className, ...props }, ref) =>
|
|
9
|
+
export const ListSurface = React.forwardRef(({ className, asChild = false, children, ...props }, ref) => {
|
|
10
|
+
const Component = asChild ? Slot : 'div';
|
|
11
|
+
return (_jsx(Component, { ref: ref, className: cn('divide-y rounded-xl border border-border bg-card', className), ...props, children: children }));
|
|
12
|
+
});
|
|
10
13
|
ListSurface.displayName = 'ListSurface';
|
|
11
14
|
/**
|
|
12
15
|
* Pure row composition. A non-interactive row is a semantic container; nested
|
|
@@ -11,5 +11,5 @@ export interface IdpChromeProps {
|
|
|
11
11
|
serviceLabel?: string;
|
|
12
12
|
locale?: PodSignInLocale;
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
14
|
+
/** 44px tinted bar at the top of every sign-in-service page (B group). */
|
|
15
15
|
export declare function IdpChrome({ serviceName, serviceHost, icon, serviceLabel, locale }: IdpChromeProps): import("react").JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { resolvePodSignInCopy } from './copy.js';
|
|
3
3
|
import { XpodMark } from './XpodMark.js';
|
|
4
|
-
/**
|
|
4
|
+
/** 44px tinted bar at the top of every sign-in-service page (B group). */
|
|
5
5
|
export function IdpChrome({ serviceName, serviceHost, icon, serviceLabel, locale }) {
|
|
6
6
|
const label = serviceLabel ?? resolvePodSignInCopy(locale).serviceLabel;
|
|
7
|
-
return (_jsxs("div", { "data-pod-sign-in": "idp-chrome", className: "flex
|
|
7
|
+
return (_jsxs("div", { "data-pod-sign-in": "idp-chrome", className: "flex h-11 shrink-0 items-center gap-2 border-b border-border bg-[hsl(var(--sunken))] px-4 text-[13px] text-foreground", children: [_jsx("span", { className: "flex shrink-0 items-center justify-center", children: icon ?? _jsx(XpodMark, { size: 24 }) }), _jsxs("span", { className: "min-w-0 truncate font-medium", children: [serviceName, " \u00B7 ", label] }), serviceHost ? _jsx("span", { className: "ml-auto truncate font-mono text-xs text-muted-foreground", children: serviceHost }) : null] }));
|
|
8
8
|
}
|
|
@@ -31,7 +31,7 @@ export function IdpSignInView(props) {
|
|
|
31
31
|
if (!pending)
|
|
32
32
|
onSubmit({ email: email.trim(), password });
|
|
33
33
|
};
|
|
34
|
-
return (_jsxs(ScreenLayout, { "data-pod-sign-in-state": "idp-sign-in", chrome: _jsx(IdpFrameHeader, { ...props }), onSubmit: submit, actions: (_jsxs(_Fragment, { children: [error ? _jsx("p", { role: "alert", className: "text-[13px] text-destructive", children: error }) : null, _jsx(ActionButton, { type: "submit", className: primaryButtonClass, busy: pending, children: copy.signIn }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [onRegister || registerHref ? (_jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-1 gap-y-0", children: [_jsx("span", { className: "whitespace-nowrap text-xs text-muted-foreground", children: copy.noAccount }), _jsx(TextAction, { href: registerHref, disabled: pending, onClick: onRegister, children: copy.registerLink })] })) : _jsx("span", {}), onUseOtherSolid ? (_jsx("button", { type: "button", className: cn(textButtonClass, 'text-primary hover:underline'), disabled: pending, onClick: onUseOtherSolid, children: copy.useOtherSolid })) : null] })] })), children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-[17px] font-semibold text-foreground", children: formatCopy(copy.signInTitle, { service: serviceName }) }), returnToAppName ? (_jsx("p", { className: "text-sm text-muted-foreground", children: formatCopy(copy.returnToApp, { app: returnToAppName }) })) : null] }), _jsxs("div", { "data-pod-sign-in": "fields", className: "flex flex-col gap-
|
|
34
|
+
return (_jsxs(ScreenLayout, { "data-pod-sign-in-state": "idp-sign-in", chrome: _jsx(IdpFrameHeader, { ...props }), onSubmit: submit, actions: (_jsxs(_Fragment, { children: [error ? _jsx("p", { role: "alert", className: "text-[13px] text-destructive", children: error }) : null, _jsx(ActionButton, { type: "submit", className: primaryButtonClass, busy: pending, children: copy.signIn }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [onRegister || registerHref ? (_jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-1 gap-y-0", children: [_jsx("span", { className: "whitespace-nowrap text-xs text-muted-foreground", children: copy.noAccount }), _jsx(TextAction, { href: registerHref, disabled: pending, onClick: onRegister, children: copy.registerLink })] })) : _jsx("span", {}), onUseOtherSolid ? (_jsx("button", { type: "button", className: cn(textButtonClass, 'text-primary hover:underline'), disabled: pending, onClick: onUseOtherSolid, children: copy.useOtherSolid })) : null] })] })), children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-[17px] font-semibold text-foreground", children: formatCopy(copy.signInTitle, { service: serviceName }) }), returnToAppName ? (_jsx("p", { className: "text-sm text-muted-foreground", children: formatCopy(copy.returnToApp, { app: returnToAppName }) })) : null] }), _jsxs("div", { "data-pod-sign-in": "fields", className: "flex flex-col gap-4", children: [_jsx(Field, { label: copy.email, error: fieldErrors?.email, children: (fieldProps) => (_jsx(EmailInput, { ...fieldProps, name: "email", autoComplete: "username", autoCapitalize: "none", spellCheck: false, className: inputClass, value: email, disabled: pending, onChange: (event) => {
|
|
35
35
|
setEmail(event.target.value);
|
|
36
36
|
onFieldChange?.('email', event.target.value);
|
|
37
37
|
} })) }), _jsx(Field, { label: copy.password, error: fieldErrors?.password, labelAside: onForgot || forgotHref ? (_jsx(TextAction, { className: "min-h-7 text-[13px]", href: forgotHref, onClick: onForgot, children: copy.forgotPassword })) : undefined, children: (fieldProps) => (_jsx(Input, { ...fieldProps, name: "password", type: "password", autoComplete: "current-password", className: inputClass, value: password, disabled: pending, onChange: (event) => {
|
|
@@ -56,7 +56,7 @@ export function IdpRegisterView(props) {
|
|
|
56
56
|
password,
|
|
57
57
|
});
|
|
58
58
|
};
|
|
59
|
-
return (_jsxs(ScreenLayout, { "data-pod-sign-in-state": "idp-register", chrome: _jsx(IdpFrameHeader, { ...props }), onSubmit: submit, actions: (_jsxs(_Fragment, { children: [error ? _jsx("p", { role: "alert", className: "text-[13px] text-destructive", children: error }) : null, _jsx(ActionButton, { type: "submit", className: primaryButtonClass, busy: pending, children: copy.registerSubmit }), onSignIn ? (_jsx("button", { type: "button", className: cn(textButtonClass, 'self-center text-primary hover:underline'), disabled: pending, onClick: onSignIn, children: copy.haveAccount })) : null] })), children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-[17px] font-semibold text-foreground", children: formatCopy(copy.registerTitle, { service: serviceName }) }), returnToAppName ? (_jsx("p", { className: "text-sm text-muted-foreground", children: formatCopy(copy.returnToApp, { app: returnToAppName }) })) : null] }), _jsxs("div", { className: "flex flex-col gap-
|
|
59
|
+
return (_jsxs(ScreenLayout, { "data-pod-sign-in-state": "idp-register", chrome: _jsx(IdpFrameHeader, { ...props }), onSubmit: submit, actions: (_jsxs(_Fragment, { children: [error ? _jsx("p", { role: "alert", className: "text-[13px] text-destructive", children: error }) : null, _jsx(ActionButton, { type: "submit", className: primaryButtonClass, busy: pending, children: copy.registerSubmit }), onSignIn ? (_jsx("button", { type: "button", className: cn(textButtonClass, 'self-center text-primary hover:underline'), disabled: pending, onClick: onSignIn, children: copy.haveAccount })) : null] })), children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-[17px] font-semibold text-foreground", children: formatCopy(copy.registerTitle, { service: serviceName }) }), returnToAppName ? (_jsx("p", { className: "text-sm text-muted-foreground", children: formatCopy(copy.returnToApp, { app: returnToAppName }) })) : null] }), _jsxs("div", { className: "flex flex-col gap-4", children: [requireUsername ? (_jsx(Field, { label: copy.username, error: fieldErrors?.username, hint: usernamePreview ? _jsx("span", { role: "status", className: "font-mono text-xs", children: usernamePreview }) : undefined, children: (fieldProps) => (_jsx(Input, { ...fieldProps, name: "username", type: "text", autoComplete: "username", autoCapitalize: "none", spellCheck: false, className: inputClass, value: username, disabled: pending, onChange: (event) => {
|
|
60
60
|
setUsername(event.target.value);
|
|
61
61
|
onFieldChange?.('username', event.target.value);
|
|
62
62
|
} })) })) : null, _jsx(Field, { label: copy.email, error: fieldErrors?.email, children: (fieldProps) => (_jsx(EmailInput, { ...fieldProps, name: "email", autoComplete: "email", autoCapitalize: "none", spellCheck: false, className: inputClass, value: email, disabled: pending, onChange: (event) => {
|
|
@@ -9,7 +9,7 @@ export interface PodSignInFrameProps {
|
|
|
9
9
|
* service name.
|
|
10
10
|
*/
|
|
11
11
|
appIntro?: ReactNode;
|
|
12
|
-
/**
|
|
12
|
+
/** The 360px wide body. */
|
|
13
13
|
children: ReactNode;
|
|
14
14
|
/**
|
|
15
15
|
* `dialog` only. `true` (default) draws a modal layer over the document;
|
|
@@ -25,7 +25,7 @@ export interface PodSignInFrameProps {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Outer frame of every sign-in surface. `window` fills the host window,
|
|
28
|
-
* `dialog` is a
|
|
29
|
-
*
|
|
28
|
+
* `dialog` is a 400px layer, `page` is two columns. All three share the same
|
|
29
|
+
* 360px body, so a state looks the same wherever the host places it.
|
|
30
30
|
*/
|
|
31
31
|
export declare function PodSignInFrame({ presentation, ariaLabel, appIntro, children, modal, onClose, closeLabel, dataAttributes, }: PodSignInFrameProps): import("react").JSX.Element;
|
|
@@ -90,11 +90,11 @@ function useModalFocus(active, onClose) {
|
|
|
90
90
|
}, [active]);
|
|
91
91
|
return ref;
|
|
92
92
|
}
|
|
93
|
-
const bodyClass = 'flex min-h-0 w-full max-w-[
|
|
93
|
+
const bodyClass = 'flex min-h-0 w-full max-w-[360px] flex-1 flex-col';
|
|
94
94
|
/**
|
|
95
95
|
* Outer frame of every sign-in surface. `window` fills the host window,
|
|
96
|
-
* `dialog` is a
|
|
97
|
-
*
|
|
96
|
+
* `dialog` is a 400px layer, `page` is two columns. All three share the same
|
|
97
|
+
* 360px body, so a state looks the same wherever the host places it.
|
|
98
98
|
*/
|
|
99
99
|
export function PodSignInFrame({ presentation, ariaLabel, appIntro, children, modal = true, onClose, closeLabel, dataAttributes, }) {
|
|
100
100
|
const isModal = presentation === 'dialog' && modal;
|
|
@@ -104,8 +104,8 @@ export function PodSignInFrame({ presentation, ariaLabel, appIntro, children, mo
|
|
|
104
104
|
return (_jsx("div", { role: "region", "aria-label": ariaLabel, "data-pod-sign-in-frame": "window", ...dataAttributes, className: "pod-sign-in flex h-full min-h-0 w-full min-w-0 justify-center overflow-hidden bg-background text-foreground", children: _jsx("div", { className: bodyClass, children: children }) }));
|
|
105
105
|
}
|
|
106
106
|
if (presentation === 'page') {
|
|
107
|
-
return (_jsxs("div", { role: "region", "aria-label": ariaLabel, "data-pod-sign-in-frame": "page", ...dataAttributes, className: "pod-sign-in grid min-h-[100dvh] w-full bg-background text-foreground md:grid-cols-2", children: [intro ? (_jsx("aside", { "data-pod-sign-in": "intro", className: "hidden flex-col justify-center gap-6 bg-[hsl(var(--sunken))] px-12 py-10 md:flex", children: intro })) : null, _jsx("div", { className: cn('flex min-w-0 items-center justify-center px-4 py-8', intro ? '' : 'md:col-span-2'), children: _jsx("div", { className:
|
|
107
|
+
return (_jsxs("div", { role: "region", "aria-label": ariaLabel, "data-pod-sign-in-frame": "page", ...dataAttributes, className: "pod-sign-in grid min-h-[100dvh] w-full bg-background text-foreground md:grid-cols-2", children: [intro ? (_jsx("aside", { "data-pod-sign-in": "intro", className: "hidden flex-col justify-center gap-6 bg-[hsl(var(--sunken))] px-12 py-10 md:flex", children: intro })) : null, _jsx("div", { className: cn('flex min-w-0 items-center justify-center px-4 py-8', intro ? '' : 'md:col-span-2'), children: _jsx("div", { className: bodyClass, children: children }) })] }));
|
|
108
108
|
}
|
|
109
|
-
const card = (_jsxs("div", { ref: dialogRef, role: isModal ? 'dialog' : 'region', "aria-modal": isModal ? true : undefined, "aria-label": ariaLabel, tabIndex: -1, "data-pod-sign-in-frame": "dialog", ...dataAttributes, className: cn('pod-sign-in relative flex
|
|
109
|
+
const card = (_jsxs("div", { ref: dialogRef, role: isModal ? 'dialog' : 'region', "aria-modal": isModal ? true : undefined, "aria-label": ariaLabel, tabIndex: -1, "data-pod-sign-in-frame": "dialog", ...dataAttributes, className: cn('pod-sign-in relative flex max-h-[90dvh] w-[min(400px,calc(100vw-2rem))] flex-col overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-lg focus:outline-none motion-safe:animate-in motion-safe:fade-in-0'), children: [isModal && onClose && closeLabel ? (_jsx("button", { type: "button", "aria-label": closeLabel, className: "absolute right-2 top-2 flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground hover:bg-accent", onClick: onClose, children: _jsx("span", { "aria-hidden": "true", children: "\u00D7" }) })) : null, _jsx("div", { className: cn(bodyClass, 'mx-auto'), children: children })] }));
|
|
110
110
|
return isModal ? (_jsx("div", { className: "fixed inset-0 z-[var(--layer-modal)] flex items-center justify-center bg-background/80 p-4", children: card })) : (_jsx("div", { className: "flex w-full items-center justify-center p-4", children: card }));
|
|
111
111
|
}
|
|
@@ -2,11 +2,11 @@ import { type ReactNode } from 'react';
|
|
|
2
2
|
import { type ButtonProps } from '../button.js';
|
|
3
3
|
import { type FormFieldProps } from '../form-field.js';
|
|
4
4
|
import type { StorageLocation } from './types.js';
|
|
5
|
-
/**
|
|
6
|
-
export declare const primaryButtonClass = "h-auto min-h-
|
|
7
|
-
export declare const outlineButtonClass = "h-auto min-h-
|
|
8
|
-
export declare const textButtonClass = "h-9 rounded-lg px-2 text-sm font-medium";
|
|
9
|
-
export declare const fieldClass = "h-
|
|
5
|
+
/** Minimum hit targets (spec §5); content may grow when text is enlarged or wraps. */
|
|
6
|
+
export declare const primaryButtonClass = "h-auto min-h-11 w-full whitespace-normal break-normal rounded-lg py-2 text-sm font-medium leading-snug";
|
|
7
|
+
export declare const outlineButtonClass = "h-auto min-h-11 w-full whitespace-normal break-normal rounded-lg py-2 text-sm font-medium leading-snug";
|
|
8
|
+
export declare const textButtonClass = "h-auto min-h-9 max-w-full whitespace-normal break-normal rounded-lg px-2 py-1 text-sm font-medium leading-snug";
|
|
9
|
+
export declare const fieldClass = "h-11 w-full rounded-lg border border-input bg-card px-3 text-sm text-foreground placeholder:text-muted-foreground disabled:opacity-60";
|
|
10
10
|
export declare function Spinner({ className }: {
|
|
11
11
|
className?: string;
|
|
12
12
|
}): import("react").JSX.Element;
|
|
@@ -7,11 +7,11 @@ import { cn } from '../utils.js';
|
|
|
7
7
|
import { FormField } from '../form-field.js';
|
|
8
8
|
import { Checkbox } from '../checkbox.js';
|
|
9
9
|
import { StorageBadge } from './StorageBadge.js';
|
|
10
|
-
/**
|
|
11
|
-
export const primaryButtonClass = 'h-auto min-h-
|
|
10
|
+
/** Minimum hit targets (spec §5); content may grow when text is enlarged or wraps. */
|
|
11
|
+
export const primaryButtonClass = 'h-auto min-h-11 w-full whitespace-normal break-normal rounded-lg py-2 text-sm font-medium leading-snug';
|
|
12
12
|
export const outlineButtonClass = primaryButtonClass;
|
|
13
|
-
export const textButtonClass = 'h-9 rounded-lg px-2 text-sm font-medium';
|
|
14
|
-
export const fieldClass = 'h-
|
|
13
|
+
export const textButtonClass = 'h-auto min-h-9 max-w-full whitespace-normal break-normal rounded-lg px-2 py-1 text-sm font-medium leading-snug';
|
|
14
|
+
export const fieldClass = 'h-11 w-full rounded-lg border border-input bg-card px-3 text-sm text-foreground placeholder:text-muted-foreground disabled:opacity-60';
|
|
15
15
|
export function Spinner({ className }) {
|
|
16
16
|
return _jsx(Loader2, { "aria-hidden": "true", className: cn('h-4 w-4 shrink-0 animate-spin motion-reduce:animate-none', className) });
|
|
17
17
|
}
|
|
@@ -55,7 +55,7 @@ export function usePastDelay(delayMs) {
|
|
|
55
55
|
* Pass `onSubmit` to make the whole screen one form (actions submit it).
|
|
56
56
|
*/
|
|
57
57
|
export function ScreenLayout({ chrome, children, actions, onSubmit, mainClassName, ...state }) {
|
|
58
|
-
const inner = (_jsxs(_Fragment, { children: [chrome, _jsx("div", { "data-pod-sign-in": "main", className: cn('flex min-h-0 flex-1 flex-col gap-
|
|
58
|
+
const inner = (_jsxs(_Fragment, { children: [chrome, _jsx("div", { "data-pod-sign-in": "main", className: cn('flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-6 pb-2 pt-5', mainClassName), children: children }), actions ? _jsx("div", { "data-pod-sign-in": "actions", className: "flex shrink-0 flex-col gap-3 px-6 pb-6 pt-3", children: actions }) : null] }));
|
|
59
59
|
const className = 'flex min-h-0 flex-1 flex-col';
|
|
60
60
|
return onSubmit
|
|
61
61
|
? _jsx("form", { ...state, onSubmit: onSubmit, className: className, noValidate: true, children: inner })
|
|
@@ -6,5 +6,5 @@ import { cn } from './utils.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export function SectionHeader({ title, description, actions, level = 2, titleClassName, className, ...props }) {
|
|
8
8
|
const headingClassName = cn('text-sm leading-normal text-foreground', titleClassName);
|
|
9
|
-
return (_jsxs("div", { ...props, className: cn('flex flex-wrap items-start justify-between gap-3', className), children: [_jsxs("div", { className: "min-w-0", children: [level === 3 ? (_jsx("h3", { className: headingClassName, children: title })) : level === 4 ? (_jsx("h4", { className: headingClassName, children: title })) : (_jsx("h2", { className: headingClassName, children: title })), description ? _jsx("p", { className: "mt-1 text-xs leading-normal text-muted-foreground", children: description }) : null] }), actions ? _jsx("div", { className: "flex
|
|
9
|
+
return (_jsxs("div", { ...props, className: cn('flex flex-wrap items-start justify-between gap-3', className), children: [_jsxs("div", { className: "min-w-0", children: [level === 3 ? (_jsx("h3", { className: headingClassName, children: title })) : level === 4 ? (_jsx("h4", { className: headingClassName, children: title })) : (_jsx("h2", { className: headingClassName, children: title })), description ? _jsx("p", { className: "mt-1 text-xs leading-normal text-muted-foreground", children: description }) : null] }), actions ? _jsx("div", { className: "flex min-w-0 max-w-full flex-wrap items-center gap-2", children: actions }) : null] }));
|
|
10
10
|
}
|
|
@@ -314,33 +314,6 @@
|
|
|
314
314
|
line-height: 22px;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
.pod-sign-in h1 {
|
|
318
|
-
font-size: 22px;
|
|
319
|
-
line-height: 1.4;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/* Keep the choices visible at the native window's minimum height. */
|
|
323
|
-
@media (max-height: 559px) {
|
|
324
|
-
.pod-sign-in[data-pod-sign-in-frame='window'] [data-pod-sign-in='main'] {
|
|
325
|
-
gap: 1rem;
|
|
326
|
-
padding-top: 1rem;
|
|
327
|
-
padding-bottom: 0.5rem;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
.pod-sign-in[data-pod-sign-in-frame='window'] [data-pod-sign-in='actions'] {
|
|
331
|
-
gap: 0.75rem;
|
|
332
|
-
padding-top: 0.75rem;
|
|
333
|
-
padding-bottom: 1rem;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/* Taller native windows keep the submit action close to the form. */
|
|
338
|
-
@media (min-width: 400px) and (min-height: 560px) {
|
|
339
|
-
.pod-sign-in[data-pod-sign-in-frame='window'] [data-pod-sign-in='actions'] {
|
|
340
|
-
padding-bottom: 5rem;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
317
|
/*
|
|
345
318
|
* Front-door focus for links, buttons and summary. Form controls are excluded:
|
|
346
319
|
* the shared control primitive owns their focus outline, so a control never
|
|
@@ -364,21 +337,21 @@
|
|
|
364
337
|
[data-pod-sign-in-frame="window"] [data-pod-sign-in-state="idp-sign-in"] [data-pod-sign-in="main"] {
|
|
365
338
|
flex: 1 0 auto;
|
|
366
339
|
overflow: visible;
|
|
367
|
-
gap:
|
|
368
|
-
padding:
|
|
340
|
+
gap: 6px;
|
|
341
|
+
padding: 4px 16px 2px;
|
|
369
342
|
}
|
|
370
343
|
|
|
371
344
|
[data-pod-sign-in-frame="window"] [data-pod-sign-in-state="idp-sign-in"] [data-pod-sign-in="fields"] {
|
|
372
|
-
gap:
|
|
345
|
+
gap: 6px;
|
|
373
346
|
}
|
|
374
347
|
|
|
375
348
|
[data-pod-sign-in-frame="window"] [data-pod-sign-in-state="idp-sign-in"] [data-pod-sign-in="field"] {
|
|
376
|
-
gap:
|
|
349
|
+
gap: 1px;
|
|
377
350
|
}
|
|
378
351
|
|
|
379
352
|
[data-pod-sign-in-frame="window"] [data-pod-sign-in-state="idp-sign-in"] [data-pod-sign-in="actions"] {
|
|
380
353
|
gap: 0;
|
|
381
|
-
padding:
|
|
354
|
+
padding: 4px 16px 6px;
|
|
382
355
|
}
|
|
383
356
|
|
|
384
357
|
@media (prefers-reduced-motion: reduce) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undefineds.co/xpod",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.27",
|
|
4
4
|
"description": "Xpod is an extended Community Solid Server, offering rich-feature, production-level Solid Pod and identity management.",
|
|
5
5
|
"repository": "https://github.com/undefinedsco/xpod",
|
|
6
6
|
"author": "developer@undefineds.co",
|
|
@@ -387,7 +387,7 @@
|
|
|
387
387
|
}
|
|
388
388
|
},
|
|
389
389
|
"optionalDependencies": {
|
|
390
|
-
"@undefineds.co/xpod-darwin-arm64": "0.4.
|
|
390
|
+
"@undefineds.co/xpod-darwin-arm64": "0.4.27"
|
|
391
391
|
},
|
|
392
392
|
"resolutions": {
|
|
393
393
|
"@inrupt/solid-client-authn-browser": "^3.1.1",
|