@undefineds.co/xpod 0.3.48 → 0.3.49
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/bin/xpod.js +0 -0
- package/dist/api/chatkit/pod-store.d.ts +16 -17
- package/dist/api/chatkit/pod-store.js +299 -231
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/schema.d.ts +1 -1
- package/dist/api/chatkit/service.js +13 -11
- package/dist/api/chatkit/service.js.map +1 -1
- package/dist/api/chatkit/store.d.ts +1 -0
- package/dist/api/chatkit/store.js +23 -11
- package/dist/api/chatkit/store.js.map +1 -1
- package/dist/api/chatkit/types.d.ts +17 -10
- package/dist/api/chatkit/types.js +97 -14
- package/dist/api/chatkit/types.js.map +1 -1
- package/dist/api/container/common.js +16 -2
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/routes.js +3 -0
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +3 -0
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/ChatKitV1Handler.js +1 -2
- package/dist/api/handlers/ChatKitV1Handler.js.map +1 -1
- package/dist/api/handlers/CoordinationHandler.d.ts +6 -0
- package/dist/api/handlers/CoordinationHandler.js +115 -0
- package/dist/api/handlers/CoordinationHandler.js.map +1 -0
- package/dist/api/handlers/MatrixHandler.d.ts +11 -0
- package/dist/api/handlers/MatrixHandler.js +120 -2
- package/dist/api/handlers/MatrixHandler.js.map +1 -1
- package/dist/api/handlers/RunHandler.js +33 -15
- package/dist/api/handlers/RunHandler.js.map +1 -1
- package/dist/api/handlers/index.d.ts +1 -0
- package/dist/api/handlers/index.js +1 -0
- package/dist/api/handlers/index.js.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/matrix/PodMatrixStore.d.ts +25 -1
- package/dist/api/matrix/PodMatrixStore.js +243 -38
- package/dist/api/matrix/PodMatrixStore.js.map +1 -1
- package/dist/api/matrix/index.d.ts +1 -1
- package/dist/api/matrix/index.js.map +1 -1
- package/dist/api/matrix/types.d.ts +23 -2
- package/dist/api/matrix/types.js.map +1 -1
- package/dist/api/protocol-metadata.d.ts +4 -0
- package/dist/api/protocol-metadata.js +54 -0
- package/dist/api/protocol-metadata.js.map +1 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.d.ts +42 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.js +250 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.js.map +1 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.jsonld +186 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.d.ts +39 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.js +91 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.js.map +1 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.jsonld +146 -0
- package/dist/api/reconciler/WakeAgentQueue.d.ts +23 -0
- package/dist/api/reconciler/WakeAgentQueue.js +123 -0
- package/dist/api/reconciler/WakeAgentQueue.js.map +1 -0
- package/dist/api/reconciler/WakeAgentQueue.jsonld +91 -0
- package/dist/api/reconciler/coordination.d.ts +61 -0
- package/dist/api/reconciler/coordination.js +109 -0
- package/dist/api/reconciler/coordination.js.map +1 -0
- package/dist/api/reconciler/coordination.jsonld +186 -0
- package/dist/api/reconciler/index.d.ts +4 -0
- package/dist/api/reconciler/index.js +21 -0
- package/dist/api/reconciler/index.js.map +1 -0
- package/dist/api/runs/ManagedRunWorker.js +0 -5
- package/dist/api/runs/ManagedRunWorker.js.map +1 -1
- package/dist/api/runs/RunStateCenter.d.ts +1 -1
- package/dist/api/runs/RunStateCenter.js +12 -28
- package/dist/api/runs/RunStateCenter.js.map +1 -1
- package/dist/api/runs/store.d.ts +12 -15
- package/dist/api/runs/store.js +24 -15
- package/dist/api/runs/store.js.map +1 -1
- package/dist/api/tasks/TaskMaterializer.d.ts +1 -0
- package/dist/api/tasks/TaskMaterializer.js +10 -13
- package/dist/api/tasks/TaskMaterializer.js.map +1 -1
- package/dist/api/tasks/TaskService.d.ts +0 -2
- package/dist/api/tasks/TaskService.js +6 -16
- package/dist/api/tasks/TaskService.js.map +1 -1
- package/dist/api/tasks/store.d.ts +0 -2
- package/dist/api/tasks/store.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +1 -1
- package/dist/cli/commands/auth.js +4 -5
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/backup.js +1 -1
- package/dist/cli/commands/backup.js.map +1 -1
- package/dist/cli/commands/login.js +1 -1
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/pod.js +1 -1
- package/dist/cli/commands/pod.js.map +1 -1
- package/dist/cli/lib/auth-helper.d.ts +5 -3
- package/dist/cli/lib/auth-helper.js +5 -3
- package/dist/cli/lib/auth-helper.js.map +1 -1
- package/dist/cli/lib/credentials-store.d.ts +22 -4
- package/dist/cli/lib/credentials-store.js +68 -51
- package/dist/cli/lib/credentials-store.js.map +1 -1
- package/dist/components/components.jsonld +5 -1
- package/dist/components/context.jsonld +103 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/provision/LocalPodProvisioningService.d.ts +1 -0
- package/dist/provision/LocalPodProvisioningService.js +9 -0
- package/dist/provision/LocalPodProvisioningService.js.map +1 -1
- package/dist/provision/LocalPodProvisioningService.jsonld +4 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatKitV1Handler.js","sourceRoot":"","sources":["../../../src/api/handlers/ChatKitV1Handler.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ChatKitV1Handler.js","sourceRoot":"","sources":["../../../src/api/handlers/ChatKitV1Handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ChatKit v1 (OpenAI-compatible) routes.\n *\n * This is a REST wrapper around our internal ChatKit store/service so that\n * clients expecting `/v1/chatkit/...` can work without speaking the single\n * `/v1/chatkit` protocol endpoint.\n *\n * Notes:\n * - We accept (but do not require) `OpenAI-Beta: chatkit_beta=v1`.\n * - Auth is handled by ApiServer middleware (same as other API routes).\n */\n\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport type { StoreContext, ChatKitStore } from '../chatkit/store';\nimport type { Page, ThreadItem, ThreadMetadata, ThreadRef } from '../chatkit/types';\nimport { toThreadRef } from '../chatkit/types';\nimport { getWebId, getAccountId } from '../auth/AuthContext';\n\nexport interface ChatKitV1HandlerOptions {\n store: ChatKitStore<StoreContext>;\n}\n\ntype ChatKitThreadObject = ThreadMetadata & { object: 'chatkit.thread' };\ntype ChatKitThreadItemObject = ThreadItem & { object: 'chatkit.thread_item' };\n\nexport function registerChatKitV1Routes(server: ApiServer, options: ChatKitV1HandlerOptions): void {\n const { store } = options;\n\n const buildContext = (request: AuthenticatedRequest): StoreContext => {\n const auth = request.auth;\n const userId = auth ? (getWebId(auth) ?? getAccountId(auth) ?? 'anonymous') : 'anonymous';\n return { userId, auth };\n };\n\n // GET /v1/chatkit/threads\n server.get('/v1/chatkit/threads', async (request, response) => {\n const url = new URL(request.url ?? '', `http://${request.headers.host}`);\n const limit = parseOptionalInt(url.searchParams.get('limit')) ?? 20;\n const after = url.searchParams.get('after') ?? undefined;\n const order = (url.searchParams.get('order') ?? 'desc') as 'asc' | 'desc';\n\n const page = await store.loadThreads(limit, after, order, buildContext(request));\n const data: ChatKitThreadObject[] = page.data.map((t) => ({ ...t, object: 'chatkit.thread' }));\n\n sendJson(response, 200, {\n object: 'list',\n data,\n has_more: page.has_more,\n after: page.after,\n });\n });\n\n // GET /v1/chatkit/threads/:thread_id\n server.get('/v1/chatkit/threads/:thread_id', async (request, response, params) => {\n const threadRef = getThreadRefFromRequest(request, response, params.thread_id);\n if (!threadRef) {\n return;\n }\n const ctx = buildContext(request);\n const thread = await store.loadThread(threadRef, ctx);\n const items = await store.loadThreadItems(threadRef, undefined, 50, 'asc', ctx);\n\n sendJson(response, 200, {\n ...thread,\n object: 'chatkit.thread',\n items: {\n ...items,\n object: 'list',\n data: items.data.map((it) => ({ ...it, object: 'chatkit.thread_item' })),\n },\n });\n });\n\n // DELETE /v1/chatkit/threads/:thread_id\n server.delete('/v1/chatkit/threads/:thread_id', async (request, response, params) => {\n const threadRef = getThreadRefFromRequest(request, response, params.thread_id);\n if (!threadRef) {\n return;\n }\n await store.deleteThread(threadRef, buildContext(request));\n // OpenAI style: return a success object (keep simple)\n sendJson(response, 200, { success: true });\n });\n\n // GET /v1/chatkit/threads/:thread_id/items\n server.get('/v1/chatkit/threads/:thread_id/items', async (request, response, params) => {\n const url = new URL(request.url ?? '', `http://${request.headers.host}`);\n const threadRef = getThreadRefFromRequest(request, response, params.thread_id);\n if (!threadRef) {\n return;\n }\n const limit = parseOptionalInt(url.searchParams.get('limit')) ?? 50;\n const after = url.searchParams.get('after') ?? undefined;\n const order = (url.searchParams.get('order') ?? 'asc') as 'asc' | 'desc';\n\n const page = await store.loadThreadItems(\n threadRef,\n after,\n limit,\n order,\n buildContext(request),\n );\n const data: ChatKitThreadItemObject[] = page.data.map((it) => ({ ...it, object: 'chatkit.thread_item' }));\n\n sendJson(response, 200, {\n object: 'list',\n data,\n has_more: page.has_more,\n after: page.after,\n });\n });\n}\n\nfunction parseOptionalInt(value: string | null): number | undefined {\n if (!value) {\n return undefined;\n }\n const n = Number.parseInt(value, 10);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction getThreadRefFromRequest(\n request: AuthenticatedRequest,\n response: any,\n rawThreadId: string,\n): ThreadRef | null {\n void request;\n try {\n return toThreadRef({\n thread_id: decodeURIComponent(rawThreadId),\n });\n } catch (error) {\n sendJson(response, 400, {\n error: error instanceof Error ? error.message : 'Invalid thread reference',\n });\n return null;\n }\n}\n\nfunction sendJson(response: any, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ApiServer } from '../ApiServer';
|
|
2
|
+
import type { ClientReconcilerCoordinator } from '../reconciler';
|
|
3
|
+
export interface CoordinationHandlerOptions {
|
|
4
|
+
clientReconcilerCoordinator: ClientReconcilerCoordinator;
|
|
5
|
+
}
|
|
6
|
+
export declare function registerCoordinationRoutes(server: ApiServer, options: CoordinationHandlerOptions): void;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCoordinationRoutes = registerCoordinationRoutes;
|
|
4
|
+
const AuthContext_1 = require("../auth/AuthContext");
|
|
5
|
+
function registerCoordinationRoutes(server, options) {
|
|
6
|
+
const { clientReconcilerCoordinator } = options;
|
|
7
|
+
server.post('/v1/clients/heartbeat', async (request, response) => {
|
|
8
|
+
try {
|
|
9
|
+
const user = authenticatedUser(request);
|
|
10
|
+
const body = await readJson(request) ?? {};
|
|
11
|
+
const client = await clientReconcilerCoordinator.upsertClientCapability({
|
|
12
|
+
clientId: requireString(body.clientId, 'clientId'),
|
|
13
|
+
kind: requireString(body.kind, 'kind'),
|
|
14
|
+
user,
|
|
15
|
+
canCoordinateClientOwnedThread: body.canCoordinateClientOwnedThread === true,
|
|
16
|
+
canRunAgent: body.canRunAgent === true,
|
|
17
|
+
workspaces: Array.isArray(body.workspaces) ? body.workspaces.filter((item) => typeof item === 'string') : [],
|
|
18
|
+
});
|
|
19
|
+
sendJson(response, 200, { client });
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
sendJson(response, statusForError(error), { error: formatError(error) });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
server.post('/v1/threads/coordination/lease', async (request, response) => {
|
|
26
|
+
try {
|
|
27
|
+
const ownerUser = authenticatedUser(request);
|
|
28
|
+
const body = await readJson(request) ?? {};
|
|
29
|
+
const thread = requireThread(body.thread);
|
|
30
|
+
const requesterClientId = typeof body.clientId === 'string' ? body.clientId : undefined;
|
|
31
|
+
const lease = await clientReconcilerCoordinator.activate({
|
|
32
|
+
thread,
|
|
33
|
+
ownerUser,
|
|
34
|
+
requesterClientId,
|
|
35
|
+
});
|
|
36
|
+
sendJson(response, 200, {
|
|
37
|
+
lease: lease ?? null,
|
|
38
|
+
isOwner: Boolean(lease && requesterClientId && lease.ownerClientId === requesterClientId),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
sendJson(response, statusForError(error), { error: formatError(error) });
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
server.post('/v1/threads/coordination/lease/release', async (request, response) => {
|
|
46
|
+
try {
|
|
47
|
+
const ownerUser = authenticatedUser(request);
|
|
48
|
+
const body = await readJson(request) ?? {};
|
|
49
|
+
const released = await clientReconcilerCoordinator.releaseLease({
|
|
50
|
+
thread: requireThread(body.thread),
|
|
51
|
+
ownerUser,
|
|
52
|
+
clientId: requireString(body.clientId, 'clientId'),
|
|
53
|
+
});
|
|
54
|
+
sendJson(response, 200, { released });
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
sendJson(response, statusForError(error), { error: formatError(error) });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function authenticatedUser(request) {
|
|
62
|
+
const auth = request.auth;
|
|
63
|
+
if (!auth) {
|
|
64
|
+
throw forbidden('Authenticated user is required');
|
|
65
|
+
}
|
|
66
|
+
const user = (0, AuthContext_1.getWebId)(auth) ?? (0, AuthContext_1.getAccountId)(auth);
|
|
67
|
+
if (!user) {
|
|
68
|
+
throw forbidden('Solid user authentication is required');
|
|
69
|
+
}
|
|
70
|
+
return user;
|
|
71
|
+
}
|
|
72
|
+
async function readJson(request) {
|
|
73
|
+
const chunks = [];
|
|
74
|
+
for await (const chunk of request) {
|
|
75
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
76
|
+
}
|
|
77
|
+
const raw = Buffer.concat(chunks).toString('utf8').trim();
|
|
78
|
+
if (!raw) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return JSON.parse(raw);
|
|
82
|
+
}
|
|
83
|
+
function requireString(value, field) {
|
|
84
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
85
|
+
throw new Error(`${field} is required`);
|
|
86
|
+
}
|
|
87
|
+
return value.trim();
|
|
88
|
+
}
|
|
89
|
+
function requireThread(value) {
|
|
90
|
+
const uri = requireString(value, 'thread');
|
|
91
|
+
if (!/^(https?:\/\/|urn:)/u.test(uri)) {
|
|
92
|
+
throw new Error('thread must be an absolute http(s) or urn URI');
|
|
93
|
+
}
|
|
94
|
+
return uri;
|
|
95
|
+
}
|
|
96
|
+
function forbidden(message) {
|
|
97
|
+
const error = new Error(message);
|
|
98
|
+
error.statusCode = 403;
|
|
99
|
+
return error;
|
|
100
|
+
}
|
|
101
|
+
function statusForError(error) {
|
|
102
|
+
if (error && typeof error === 'object' && 'statusCode' in error && typeof error.statusCode === 'number') {
|
|
103
|
+
return error.statusCode;
|
|
104
|
+
}
|
|
105
|
+
return 400;
|
|
106
|
+
}
|
|
107
|
+
function sendJson(response, status, data) {
|
|
108
|
+
response.statusCode = status;
|
|
109
|
+
response.setHeader('Content-Type', 'application/json');
|
|
110
|
+
response.end(JSON.stringify(data));
|
|
111
|
+
}
|
|
112
|
+
function formatError(error) {
|
|
113
|
+
return error instanceof Error ? error.message : String(error);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=CoordinationHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoordinationHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/CoordinationHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport type { ApiServer } from '../ApiServer';\nimport { getAccountId, getWebId } from '../auth/AuthContext';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport type { ClientReconcilerCoordinator } from '../reconciler';\n\nexport interface CoordinationHandlerOptions {\n clientReconcilerCoordinator: ClientReconcilerCoordinator;\n}\n\nexport function registerCoordinationRoutes(server: ApiServer, options: CoordinationHandlerOptions): void {\n const { clientReconcilerCoordinator } = options;\n\n server.post('/v1/clients/heartbeat', async (request, response) => {\n try {\n const user = authenticatedUser(request);\n const body = await readJson<Record<string, unknown>>(request) ?? {};\n const client = await clientReconcilerCoordinator.upsertClientCapability({\n clientId: requireString(body.clientId, 'clientId'),\n kind: requireString(body.kind, 'kind') as any,\n user,\n canCoordinateClientOwnedThread: body.canCoordinateClientOwnedThread === true,\n canRunAgent: body.canRunAgent === true,\n workspaces: Array.isArray(body.workspaces) ? body.workspaces.filter((item): item is string => typeof item === 'string') : [],\n });\n sendJson(response, 200, { client });\n } catch (error) {\n sendJson(response, statusForError(error), { error: formatError(error) });\n }\n });\n\n server.post('/v1/threads/coordination/lease', async (request, response) => {\n try {\n const ownerUser = authenticatedUser(request);\n const body = await readJson<Record<string, unknown>>(request) ?? {};\n const thread = requireThread(body.thread);\n const requesterClientId = typeof body.clientId === 'string' ? body.clientId : undefined;\n const lease = await clientReconcilerCoordinator.activate({\n thread,\n ownerUser,\n requesterClientId,\n });\n sendJson(response, 200, {\n lease: lease ?? null,\n isOwner: Boolean(lease && requesterClientId && lease.ownerClientId === requesterClientId),\n });\n } catch (error) {\n sendJson(response, statusForError(error), { error: formatError(error) });\n }\n });\n\n server.post('/v1/threads/coordination/lease/release', async (request, response) => {\n try {\n const ownerUser = authenticatedUser(request);\n const body = await readJson<Record<string, unknown>>(request) ?? {};\n const released = await clientReconcilerCoordinator.releaseLease({\n thread: requireThread(body.thread),\n ownerUser,\n clientId: requireString(body.clientId, 'clientId'),\n });\n sendJson(response, 200, { released });\n } catch (error) {\n sendJson(response, statusForError(error), { error: formatError(error) });\n }\n });\n}\n\nfunction authenticatedUser(request: AuthenticatedRequest): string {\n const auth = request.auth;\n if (!auth) {\n throw forbidden('Authenticated user is required');\n }\n const user = getWebId(auth) ?? getAccountId(auth);\n if (!user) {\n throw forbidden('Solid user authentication is required');\n }\n return user;\n}\n\nasync function readJson<T>(request: AuthenticatedRequest): Promise<T | undefined> {\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) {\n return undefined;\n }\n return JSON.parse(raw) as T;\n}\n\nfunction requireString(value: unknown, field: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(`${field} is required`);\n }\n return value.trim();\n}\n\nfunction requireThread(value: unknown): string {\n const uri = requireString(value, 'thread');\n if (!/^(https?:\\/\\/|urn:)/u.test(uri)) {\n throw new Error('thread must be an absolute http(s) or urn URI');\n }\n return uri;\n}\n\nfunction forbidden(message: string): Error {\n const error = new Error(message) as Error & { statusCode?: number };\n error.statusCode = 403;\n return error;\n}\n\nfunction statusForError(error: unknown): number {\n if (error && typeof error === 'object' && 'statusCode' in error && typeof (error as { statusCode?: unknown }).statusCode === 'number') {\n return (error as { statusCode: number }).statusCode;\n }\n return 400;\n}\n\nfunction sendJson(response: ServerResponse, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
@@ -3,4 +3,15 @@ import type { MatrixStore } from '../matrix/types';
|
|
|
3
3
|
export interface MatrixHandlerOptions {
|
|
4
4
|
store: MatrixStore;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Register the Matrix Client-Server compatibility adapter.
|
|
8
|
+
*
|
|
9
|
+
* Keep these externally visible routes Matrix-shaped:
|
|
10
|
+
* - `/.well-known/matrix/client` is public discovery.
|
|
11
|
+
* - `/_matrix/client/...` is Matrix's protocol namespace.
|
|
12
|
+
*
|
|
13
|
+
* Do not mount this adapter under `/api` or `/matrix`; first-party Xpod
|
|
14
|
+
* clients should use Xpod-owned chat/message APIs, while Matrix clients need
|
|
15
|
+
* the standard route shape to interoperate with existing SDKs.
|
|
16
|
+
*/
|
|
6
17
|
export declare function registerMatrixRoutes(server: ApiServer, options: MatrixHandlerOptions): void;
|
|
@@ -2,8 +2,26 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerMatrixRoutes = registerMatrixRoutes;
|
|
4
4
|
const AuthContext_1 = require("../auth/AuthContext");
|
|
5
|
+
/**
|
|
6
|
+
* Register the Matrix Client-Server compatibility adapter.
|
|
7
|
+
*
|
|
8
|
+
* Keep these externally visible routes Matrix-shaped:
|
|
9
|
+
* - `/.well-known/matrix/client` is public discovery.
|
|
10
|
+
* - `/_matrix/client/...` is Matrix's protocol namespace.
|
|
11
|
+
*
|
|
12
|
+
* Do not mount this adapter under `/api` or `/matrix`; first-party Xpod
|
|
13
|
+
* clients should use Xpod-owned chat/message APIs, while Matrix clients need
|
|
14
|
+
* the standard route shape to interoperate with existing SDKs.
|
|
15
|
+
*/
|
|
5
16
|
function registerMatrixRoutes(server, options) {
|
|
6
17
|
const { store } = options;
|
|
18
|
+
server.get('/.well-known/matrix/client', async (request, response) => {
|
|
19
|
+
sendJson(response, 200, {
|
|
20
|
+
'm.homeserver': {
|
|
21
|
+
base_url: requestBaseUrl(request),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}, { public: true });
|
|
7
25
|
server.get('/_matrix/client/versions', async (_request, response) => {
|
|
8
26
|
sendJson(response, 200, {
|
|
9
27
|
versions: [
|
|
@@ -35,6 +53,19 @@ function registerMatrixRoutes(server, options) {
|
|
|
35
53
|
server.post('/_matrix/client/v3/login', async (_request, response) => {
|
|
36
54
|
sendMatrixError(response, 501, 'M_UNRECOGNIZED', 'Matrix-native login is not implemented; use Solid/OIDC API authentication.');
|
|
37
55
|
}, { public: true });
|
|
56
|
+
server.get('/_matrix/client/v3/account/whoami', async (request, response) => {
|
|
57
|
+
try {
|
|
58
|
+
const account = await store.getAccount(buildContext(request));
|
|
59
|
+
sendJson(response, 200, {
|
|
60
|
+
user_id: account.userId,
|
|
61
|
+
...(account.deviceId ? { device_id: account.deviceId } : {}),
|
|
62
|
+
is_guest: false,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
sendMatrixError(response, 400, 'M_UNKNOWN', formatError(error));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
38
69
|
server.post('/_matrix/client/v3/createRoom', async (request, response) => {
|
|
39
70
|
try {
|
|
40
71
|
const body = await readJson(request);
|
|
@@ -55,6 +86,55 @@ function registerMatrixRoutes(server, options) {
|
|
|
55
86
|
sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));
|
|
56
87
|
}
|
|
57
88
|
});
|
|
89
|
+
server.get('/_matrix/client/v3/joined_rooms', async (request, response) => {
|
|
90
|
+
try {
|
|
91
|
+
const joinedRooms = await store.listJoinedRooms(buildContext(request));
|
|
92
|
+
sendJson(response, 200, { joined_rooms: joinedRooms });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
sendMatrixError(response, 400, 'M_UNKNOWN', formatError(error));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
server.post('/_matrix/client/v3/join/:roomIdOrAlias', async (request, response, params) => {
|
|
99
|
+
try {
|
|
100
|
+
const result = await store.joinRoom(decodeURIComponent(params.roomIdOrAlias), buildContext(request));
|
|
101
|
+
sendJson(response, 200, { room_id: result.roomId });
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
server.post('/_matrix/client/v3/rooms/:roomId/join', async (request, response, params) => {
|
|
108
|
+
try {
|
|
109
|
+
const result = await store.joinRoom(decodeURIComponent(params.roomId), buildContext(request));
|
|
110
|
+
sendJson(response, 200, { room_id: result.roomId });
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
server.post('/_matrix/client/v3/rooms/:roomId/invite', async (request, response, params) => {
|
|
117
|
+
try {
|
|
118
|
+
const body = await readJson(request);
|
|
119
|
+
if (!body || typeof body.user_id !== 'string' || body.user_id.length === 0) {
|
|
120
|
+
throw new Error('Invite requires user_id');
|
|
121
|
+
}
|
|
122
|
+
await store.inviteUser(decodeURIComponent(params.roomId), body.user_id, buildContext(request));
|
|
123
|
+
sendJson(response, 200, {});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
server.post('/_matrix/client/v3/rooms/:roomId/leave', async (request, response, params) => {
|
|
130
|
+
try {
|
|
131
|
+
await store.leaveRoom(decodeURIComponent(params.roomId), buildContext(request));
|
|
132
|
+
sendJson(response, 200, {});
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
58
138
|
server.get('/_matrix/client/v3/sync', async (request, response) => {
|
|
59
139
|
try {
|
|
60
140
|
const url = new URL(request.url ?? '', `http://${request.headers.host ?? 'localhost'}`);
|
|
@@ -82,6 +162,15 @@ function registerMatrixRoutes(server, options) {
|
|
|
82
162
|
sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));
|
|
83
163
|
}
|
|
84
164
|
});
|
|
165
|
+
server.get('/_matrix/client/v3/rooms/:roomId/members', async (request, response, params) => {
|
|
166
|
+
try {
|
|
167
|
+
const members = await store.getMembers(decodeURIComponent(params.roomId), buildContext(request));
|
|
168
|
+
sendJson(response, 200, { chunk: members });
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));
|
|
172
|
+
}
|
|
173
|
+
});
|
|
85
174
|
server.get('/_matrix/client/v3/rooms/:roomId/event/:eventId', async (request, response, params) => {
|
|
86
175
|
try {
|
|
87
176
|
const event = await store.getEvent(decodeURIComponent(params.roomId), decodeURIComponent(params.eventId), buildContext(request));
|
|
@@ -97,6 +186,12 @@ function registerMatrixRoutes(server, options) {
|
|
|
97
186
|
server.get('/_matrix/client/v3/rooms/:roomId/state/:eventType/:stateKey', async (request, response, params) => {
|
|
98
187
|
await sendState(request, response, params, decodeURIComponent(params.stateKey ?? ''));
|
|
99
188
|
});
|
|
189
|
+
server.put('/_matrix/client/v3/rooms/:roomId/state/:eventType', async (request, response, params) => {
|
|
190
|
+
await putState(request, response, params, '');
|
|
191
|
+
});
|
|
192
|
+
server.put('/_matrix/client/v3/rooms/:roomId/state/:eventType/:stateKey', async (request, response, params) => {
|
|
193
|
+
await putState(request, response, params, decodeURIComponent(params.stateKey ?? ''));
|
|
194
|
+
});
|
|
100
195
|
async function sendState(request, response, params, stateKey) {
|
|
101
196
|
try {
|
|
102
197
|
const state = await store.getState(decodeURIComponent(params.roomId), decodeURIComponent(params.eventType), stateKey, buildContext(request));
|
|
@@ -106,11 +201,24 @@ function registerMatrixRoutes(server, options) {
|
|
|
106
201
|
sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));
|
|
107
202
|
}
|
|
108
203
|
}
|
|
204
|
+
async function putState(request, response, params, stateKey) {
|
|
205
|
+
try {
|
|
206
|
+
const content = await readJson(request);
|
|
207
|
+
const event = await store.setState(decodeURIComponent(params.roomId), decodeURIComponent(params.eventType), stateKey, content ?? {}, buildContext(request));
|
|
208
|
+
sendJson(response, 200, { event_id: event.eventId });
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
109
214
|
}
|
|
110
215
|
function buildContext(request) {
|
|
111
216
|
const auth = request.auth;
|
|
112
|
-
const
|
|
113
|
-
|
|
217
|
+
const webId = auth ? (0, AuthContext_1.getWebId)(auth) : undefined;
|
|
218
|
+
if (!webId) {
|
|
219
|
+
throw new Error('Matrix API requires Solid WebID authentication');
|
|
220
|
+
}
|
|
221
|
+
return { webId, auth };
|
|
114
222
|
}
|
|
115
223
|
async function readJson(request) {
|
|
116
224
|
const chunks = [];
|
|
@@ -130,6 +238,16 @@ function parseOptionalNumber(value) {
|
|
|
130
238
|
const parsed = Number.parseInt(value, 10);
|
|
131
239
|
return Number.isFinite(parsed) ? parsed : undefined;
|
|
132
240
|
}
|
|
241
|
+
function requestBaseUrl(request) {
|
|
242
|
+
const forwardedProto = headerValue(request.headers['x-forwarded-proto']);
|
|
243
|
+
const forwardedHost = headerValue(request.headers['x-forwarded-host']);
|
|
244
|
+
const proto = forwardedProto?.split(',')[0]?.trim() || 'http';
|
|
245
|
+
const host = forwardedHost?.split(',')[0]?.trim() || request.headers.host || 'localhost';
|
|
246
|
+
return `${proto}://${host}`;
|
|
247
|
+
}
|
|
248
|
+
function headerValue(value) {
|
|
249
|
+
return Array.isArray(value) ? value[0] : value;
|
|
250
|
+
}
|
|
133
251
|
function sendJson(response, status, data) {
|
|
134
252
|
response.statusCode = status;
|
|
135
253
|
response.setHeader('Content-Type', 'application/json');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatrixHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/MatrixHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport type { ApiServer } from '../ApiServer';\nimport { getAccountId, getWebId } from '../auth/AuthContext';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport type { MatrixCreateRoomRequest, MatrixStore, MatrixStoreContext } from '../matrix/types';\n\nexport interface MatrixHandlerOptions {\n store: MatrixStore;\n}\n\nexport function registerMatrixRoutes(server: ApiServer, options: MatrixHandlerOptions): void {\n const { store } = options;\n\n server.get('/_matrix/client/versions', async (_request, response) => {\n sendJson(response, 200, {\n versions: [\n 'r0.6.1',\n 'v1.1',\n 'v1.2',\n 'v1.3',\n 'v1.4',\n 'v1.5',\n 'v1.6',\n 'v1.7',\n 'v1.8',\n 'v1.9',\n 'v1.10',\n 'v1.11',\n ],\n unstable_features: {\n 'co.undefineds.matrix.pod_storage': true,\n },\n });\n }, { public: true });\n\n server.get('/_matrix/client/v3/login', async (_request, response) => {\n sendJson(response, 200, {\n flows: [\n { type: 'm.login.token' },\n ],\n });\n }, { public: true });\n\n server.post('/_matrix/client/v3/login', async (_request, response) => {\n sendMatrixError(response, 501, 'M_UNRECOGNIZED', 'Matrix-native login is not implemented; use Solid/OIDC API authentication.');\n }, { public: true });\n\n server.post('/_matrix/client/v3/createRoom', async (request, response) => {\n try {\n const body = await readJson<MatrixCreateRoomRequest>(request);\n const room = await store.createRoom(body ?? {}, buildContext(request));\n sendJson(response, 200, { room_id: room.roomId });\n } catch (error) {\n sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));\n }\n });\n\n server.put('/_matrix/client/v3/rooms/:roomId/send/:eventType/:txnId', async (request, response, params) => {\n try {\n const content = await readJson<Record<string, unknown>>(request);\n const event = await store.sendEvent(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventType),\n decodeURIComponent(params.txnId),\n content ?? {},\n buildContext(request),\n );\n sendJson(response, 200, { event_id: event.eventId });\n } catch (error) {\n sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/sync', async (request, response) => {\n try {\n const url = new URL(request.url ?? '', `http://${request.headers.host ?? 'localhost'}`);\n const sync = await store.sync(buildContext(request), {\n since: url.searchParams.get('since') ?? undefined,\n limit: parseOptionalNumber(url.searchParams.get('limit')),\n });\n sendJson(response, 200, sync);\n } catch (error) {\n sendMatrixError(response, 400, 'M_UNKNOWN', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/messages', async (request, response, params) => {\n try {\n const url = new URL(request.url ?? '', `http://${request.headers.host ?? 'localhost'}`);\n const messages = await store.listMessages(decodeURIComponent(params.roomId), buildContext(request), {\n from: url.searchParams.get('from') ?? undefined,\n dir: url.searchParams.get('dir') === 'f' ? 'f' : 'b',\n limit: parseOptionalNumber(url.searchParams.get('limit')),\n });\n sendJson(response, 200, messages);\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/event/:eventId', async (request, response, params) => {\n try {\n const event = await store.getEvent(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventId),\n buildContext(request),\n );\n sendJson(response, 200, event);\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/state/:eventType', async (request, response, params) => {\n await sendState(request, response, params, '');\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/state/:eventType/:stateKey', async (request, response, params) => {\n await sendState(request, response, params, decodeURIComponent(params.stateKey ?? ''));\n });\n\n async function sendState(\n request: AuthenticatedRequest,\n response: ServerResponse,\n params: Record<string, string>,\n stateKey: string,\n ): Promise<void> {\n try {\n const state = await store.getState(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventType),\n stateKey,\n buildContext(request),\n );\n sendJson(response, 200, state);\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n }\n}\n\nfunction buildContext(request: AuthenticatedRequest): MatrixStoreContext {\n const auth = request.auth;\n const userId = auth ? getWebId(auth) ?? getAccountId(auth) ?? 'anonymous' : 'anonymous';\n return { userId, auth };\n}\n\nasync function readJson<T>(request: AuthenticatedRequest): Promise<T | undefined> {\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) {\n return undefined;\n }\n return JSON.parse(raw) as T;\n}\n\nfunction parseOptionalNumber(value: string | null): number | undefined {\n if (!value) {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nfunction sendJson(response: ServerResponse, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n\nfunction sendMatrixError(response: ServerResponse, status: number, errcode: string, error: string): void {\n sendJson(response, status, { errcode, error });\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MatrixHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/MatrixHandler.ts"],"names":[],"mappings":";;AAqBA,oDA6OC;AAhQD,qDAA+C;AAQ/C;;;;;;;;;;GAUG;AACH,SAAgB,oBAAoB,CAAC,MAAiB,EAAE,OAA6B;IACnF,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE1B,MAAM,CAAC,GAAG,CAAC,4BAA4B,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACnE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,cAAc,EAAE;gBACd,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC;aAClC;SACF,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAErB,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;QAClE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,QAAQ,EAAE;gBACR,QAAQ;gBACR,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,OAAO;gBACP,OAAO;aACR;YACD,iBAAiB,EAAE;gBACjB,kCAAkC,EAAE,IAAI;aACzC;SACF,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAErB,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;QAClE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,KAAK,EAAE;gBACL,EAAE,IAAI,EAAE,eAAe,EAAE;aAC1B;SACF,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAErB,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;QACnE,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,4EAA4E,CAAC,CAAC;IACjI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAErB,MAAM,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC1E,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9D,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACtB,OAAO,EAAE,OAAO,CAAC,MAAM;gBACvB,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAA0B,OAAO,CAAC,CAAC;YAC9D,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YACvE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,yDAAyD,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QACxG,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAA0B,OAAO,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,SAAS,CACjC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EACjC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,EACpC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,EAChC,OAAO,IAAI,EAAE,EACb,YAAY,CAAC,OAAO,CAAC,CACtB,CAAC;YACF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACxE,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YACvE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QACxF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YACrG,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QACvF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9F,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QACzF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAwB,OAAO,CAAC,CAAC;YAC5D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3E,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/F,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QACxF,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAChF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QAChE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,UAAU,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAC;YACxF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;gBACnD,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS;gBACjD,KAAK,EAAE,mBAAmB,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aAC1D,CAAC,CAAC;YACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,2CAA2C,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC1F,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,UAAU,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAC;YACxF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE;gBAClG,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS;gBAC/C,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBACpD,KAAK,EAAE,mBAAmB,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aAC1D,CAAC,CAAC;YACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,0CAA0C,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QACzF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YACjG,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,iDAAiD,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAChG,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAChC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EACjC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,EAClC,YAAY,CAAC,OAAO,CAAC,CACtB,CAAC;YACF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,mDAAmD,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAClG,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,6DAA6D,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC5G,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,mDAAmD,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAClG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,6DAA6D,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC5G,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,KAAK,UAAU,SAAS,CACtB,OAA6B,EAC7B,QAAwB,EACxB,MAA8B,EAC9B,QAAgB;QAEhB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAChC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EACjC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,EACpC,QAAQ,EACR,YAAY,CAAC,OAAO,CAAC,CACtB,CAAC;YACF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,KAAK,UAAU,QAAQ,CACrB,OAA6B,EAC7B,QAAwB,EACxB,MAA8B,EAC9B,QAAgB;QAEhB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAA0B,OAAO,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAChC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EACjC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,EACpC,QAAQ,EACR,OAAO,IAAI,EAAE,EACb,YAAY,CAAC,OAAO,CAAC,CACtB,CAAC;YACF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,OAA6B;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAA,sBAAQ,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,KAAK,UAAU,QAAQ,CAAI,OAA6B;IACtD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;AAC9B,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAoB;IAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACtD,CAAC;AAED,SAAS,cAAc,CAAC,OAA6B;IACnD,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACzE,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC;IAC9D,MAAM,IAAI,GAAG,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IACzF,OAAO,GAAG,KAAK,MAAM,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAoC;IACvD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACjD,CAAC;AAED,SAAS,QAAQ,CAAC,QAAwB,EAAE,MAAc,EAAE,IAAa;IACvE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IACvD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,eAAe,CAAC,QAAwB,EAAE,MAAc,EAAE,OAAe,EAAE,KAAa;IAC/F,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport type { ApiServer } from '../ApiServer';\nimport { getWebId } from '../auth/AuthContext';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport type { MatrixCreateRoomRequest, MatrixStore, MatrixStoreContext } from '../matrix/types';\n\nexport interface MatrixHandlerOptions {\n store: MatrixStore;\n}\n\n/**\n * Register the Matrix Client-Server compatibility adapter.\n *\n * Keep these externally visible routes Matrix-shaped:\n * - `/.well-known/matrix/client` is public discovery.\n * - `/_matrix/client/...` is Matrix's protocol namespace.\n *\n * Do not mount this adapter under `/api` or `/matrix`; first-party Xpod\n * clients should use Xpod-owned chat/message APIs, while Matrix clients need\n * the standard route shape to interoperate with existing SDKs.\n */\nexport function registerMatrixRoutes(server: ApiServer, options: MatrixHandlerOptions): void {\n const { store } = options;\n\n server.get('/.well-known/matrix/client', async (request, response) => {\n sendJson(response, 200, {\n 'm.homeserver': {\n base_url: requestBaseUrl(request),\n },\n });\n }, { public: true });\n\n server.get('/_matrix/client/versions', async (_request, response) => {\n sendJson(response, 200, {\n versions: [\n 'r0.6.1',\n 'v1.1',\n 'v1.2',\n 'v1.3',\n 'v1.4',\n 'v1.5',\n 'v1.6',\n 'v1.7',\n 'v1.8',\n 'v1.9',\n 'v1.10',\n 'v1.11',\n ],\n unstable_features: {\n 'co.undefineds.matrix.pod_storage': true,\n },\n });\n }, { public: true });\n\n server.get('/_matrix/client/v3/login', async (_request, response) => {\n sendJson(response, 200, {\n flows: [\n { type: 'm.login.token' },\n ],\n });\n }, { public: true });\n\n server.post('/_matrix/client/v3/login', async (_request, response) => {\n sendMatrixError(response, 501, 'M_UNRECOGNIZED', 'Matrix-native login is not implemented; use Solid/OIDC API authentication.');\n }, { public: true });\n\n server.get('/_matrix/client/v3/account/whoami', async (request, response) => {\n try {\n const account = await store.getAccount(buildContext(request));\n sendJson(response, 200, {\n user_id: account.userId,\n ...(account.deviceId ? { device_id: account.deviceId } : {}),\n is_guest: false,\n });\n } catch (error) {\n sendMatrixError(response, 400, 'M_UNKNOWN', formatError(error));\n }\n });\n\n server.post('/_matrix/client/v3/createRoom', async (request, response) => {\n try {\n const body = await readJson<MatrixCreateRoomRequest>(request);\n const room = await store.createRoom(body ?? {}, buildContext(request));\n sendJson(response, 200, { room_id: room.roomId });\n } catch (error) {\n sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));\n }\n });\n\n server.put('/_matrix/client/v3/rooms/:roomId/send/:eventType/:txnId', async (request, response, params) => {\n try {\n const content = await readJson<Record<string, unknown>>(request);\n const event = await store.sendEvent(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventType),\n decodeURIComponent(params.txnId),\n content ?? {},\n buildContext(request),\n );\n sendJson(response, 200, { event_id: event.eventId });\n } catch (error) {\n sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/joined_rooms', async (request, response) => {\n try {\n const joinedRooms = await store.listJoinedRooms(buildContext(request));\n sendJson(response, 200, { joined_rooms: joinedRooms });\n } catch (error) {\n sendMatrixError(response, 400, 'M_UNKNOWN', formatError(error));\n }\n });\n\n server.post('/_matrix/client/v3/join/:roomIdOrAlias', async (request, response, params) => {\n try {\n const result = await store.joinRoom(decodeURIComponent(params.roomIdOrAlias), buildContext(request));\n sendJson(response, 200, { room_id: result.roomId });\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.post('/_matrix/client/v3/rooms/:roomId/join', async (request, response, params) => {\n try {\n const result = await store.joinRoom(decodeURIComponent(params.roomId), buildContext(request));\n sendJson(response, 200, { room_id: result.roomId });\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.post('/_matrix/client/v3/rooms/:roomId/invite', async (request, response, params) => {\n try {\n const body = await readJson<{ user_id?: unknown }>(request);\n if (!body || typeof body.user_id !== 'string' || body.user_id.length === 0) {\n throw new Error('Invite requires user_id');\n }\n await store.inviteUser(decodeURIComponent(params.roomId), body.user_id, buildContext(request));\n sendJson(response, 200, {});\n } catch (error) {\n sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));\n }\n });\n\n server.post('/_matrix/client/v3/rooms/:roomId/leave', async (request, response, params) => {\n try {\n await store.leaveRoom(decodeURIComponent(params.roomId), buildContext(request));\n sendJson(response, 200, {});\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/sync', async (request, response) => {\n try {\n const url = new URL(request.url ?? '', `http://${request.headers.host ?? 'localhost'}`);\n const sync = await store.sync(buildContext(request), {\n since: url.searchParams.get('since') ?? undefined,\n limit: parseOptionalNumber(url.searchParams.get('limit')),\n });\n sendJson(response, 200, sync);\n } catch (error) {\n sendMatrixError(response, 400, 'M_UNKNOWN', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/messages', async (request, response, params) => {\n try {\n const url = new URL(request.url ?? '', `http://${request.headers.host ?? 'localhost'}`);\n const messages = await store.listMessages(decodeURIComponent(params.roomId), buildContext(request), {\n from: url.searchParams.get('from') ?? undefined,\n dir: url.searchParams.get('dir') === 'f' ? 'f' : 'b',\n limit: parseOptionalNumber(url.searchParams.get('limit')),\n });\n sendJson(response, 200, messages);\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/members', async (request, response, params) => {\n try {\n const members = await store.getMembers(decodeURIComponent(params.roomId), buildContext(request));\n sendJson(response, 200, { chunk: members });\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/event/:eventId', async (request, response, params) => {\n try {\n const event = await store.getEvent(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventId),\n buildContext(request),\n );\n sendJson(response, 200, event);\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/state/:eventType', async (request, response, params) => {\n await sendState(request, response, params, '');\n });\n\n server.get('/_matrix/client/v3/rooms/:roomId/state/:eventType/:stateKey', async (request, response, params) => {\n await sendState(request, response, params, decodeURIComponent(params.stateKey ?? ''));\n });\n\n server.put('/_matrix/client/v3/rooms/:roomId/state/:eventType', async (request, response, params) => {\n await putState(request, response, params, '');\n });\n\n server.put('/_matrix/client/v3/rooms/:roomId/state/:eventType/:stateKey', async (request, response, params) => {\n await putState(request, response, params, decodeURIComponent(params.stateKey ?? ''));\n });\n\n async function sendState(\n request: AuthenticatedRequest,\n response: ServerResponse,\n params: Record<string, string>,\n stateKey: string,\n ): Promise<void> {\n try {\n const state = await store.getState(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventType),\n stateKey,\n buildContext(request),\n );\n sendJson(response, 200, state);\n } catch (error) {\n sendMatrixError(response, 404, 'M_NOT_FOUND', formatError(error));\n }\n }\n\n async function putState(\n request: AuthenticatedRequest,\n response: ServerResponse,\n params: Record<string, string>,\n stateKey: string,\n ): Promise<void> {\n try {\n const content = await readJson<Record<string, unknown>>(request);\n const event = await store.setState(\n decodeURIComponent(params.roomId),\n decodeURIComponent(params.eventType),\n stateKey,\n content ?? {},\n buildContext(request),\n );\n sendJson(response, 200, { event_id: event.eventId });\n } catch (error) {\n sendMatrixError(response, 400, 'M_BAD_JSON', formatError(error));\n }\n }\n}\n\nfunction buildContext(request: AuthenticatedRequest): MatrixStoreContext {\n const auth = request.auth;\n const webId = auth ? getWebId(auth) : undefined;\n if (!webId) {\n throw new Error('Matrix API requires Solid WebID authentication');\n }\n return { webId, auth };\n}\n\nasync function readJson<T>(request: AuthenticatedRequest): Promise<T | undefined> {\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) {\n return undefined;\n }\n return JSON.parse(raw) as T;\n}\n\nfunction parseOptionalNumber(value: string | null): number | undefined {\n if (!value) {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nfunction requestBaseUrl(request: AuthenticatedRequest): string {\n const forwardedProto = headerValue(request.headers['x-forwarded-proto']);\n const forwardedHost = headerValue(request.headers['x-forwarded-host']);\n const proto = forwardedProto?.split(',')[0]?.trim() || 'http';\n const host = forwardedHost?.split(',')[0]?.trim() || request.headers.host || 'localhost';\n return `${proto}://${host}`;\n}\n\nfunction headerValue(value: string | string[] | undefined): string | undefined {\n return Array.isArray(value) ? value[0] : value;\n}\n\nfunction sendJson(response: ServerResponse, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n\nfunction sendMatrixError(response: ServerResponse, status: number, errcode: string, error: string): void {\n sendJson(response, status, { errcode, error });\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
@@ -13,8 +13,16 @@ function registerRunRoutes(server, options) {
|
|
|
13
13
|
server.get('/v1/runs', async (request, response) => {
|
|
14
14
|
try {
|
|
15
15
|
const url = new URL(request.url ?? '', `http://${request.headers.host ?? 'localhost'}`);
|
|
16
|
-
const
|
|
17
|
-
|
|
16
|
+
const { storeOptions, commandKind } = parseRunListRequest(url);
|
|
17
|
+
const requestedLimit = storeOptions.limit;
|
|
18
|
+
let runs = await runStore.listRuns(commandKind ? { ...storeOptions, limit: undefined } : storeOptions, buildStoreContext(request));
|
|
19
|
+
if (commandKind) {
|
|
20
|
+
runs = runs.filter((run) => (0, store_1.deriveRunCommandProjection)(run.id)?.commandKind === commandKind);
|
|
21
|
+
}
|
|
22
|
+
if (requestedLimit) {
|
|
23
|
+
runs = runs.slice(0, requestedLimit);
|
|
24
|
+
}
|
|
25
|
+
sendJson(response, 200, { runs: runs.map(projectRunForApi) });
|
|
18
26
|
}
|
|
19
27
|
catch (error) {
|
|
20
28
|
logger.error(`Failed to list runs: ${error}`);
|
|
@@ -24,7 +32,7 @@ function registerRunRoutes(server, options) {
|
|
|
24
32
|
server.get('/v1/runs/:runId', async (request, response, params) => {
|
|
25
33
|
try {
|
|
26
34
|
const run = await runStore.loadRun(decodeURIComponent(params.runId), buildStoreContext(request));
|
|
27
|
-
sendJson(response, 200, { run });
|
|
35
|
+
sendJson(response, 200, { run: projectRunForApi(run) });
|
|
28
36
|
}
|
|
29
37
|
catch (error) {
|
|
30
38
|
logger.error(`Failed to load run: ${error}`);
|
|
@@ -34,7 +42,7 @@ function registerRunRoutes(server, options) {
|
|
|
34
42
|
server.get('/v1/runs/:runId/steps', async (request, response, params) => {
|
|
35
43
|
try {
|
|
36
44
|
const steps = await runStore.loadRunSteps(decodeURIComponent(params.runId), buildStoreContext(request));
|
|
37
|
-
sendJson(response, 200, { steps });
|
|
45
|
+
sendJson(response, 200, { steps: steps.map(projectRunStepForApi) });
|
|
38
46
|
}
|
|
39
47
|
catch (error) {
|
|
40
48
|
logger.error(`Failed to load run steps: ${error}`);
|
|
@@ -59,12 +67,8 @@ function registerRunRoutes(server, options) {
|
|
|
59
67
|
id: (0, store_1.generateRunStepResourceId)({
|
|
60
68
|
key: (0, types_1.generateId)('run-step'),
|
|
61
69
|
runId: run.id,
|
|
62
|
-
commandKind: run.commandKind,
|
|
63
|
-
surfaceId: run.surfaceId,
|
|
64
70
|
createdAt: now,
|
|
65
71
|
}),
|
|
66
|
-
commandKind: run.commandKind,
|
|
67
|
-
surfaceId: run.surfaceId,
|
|
68
72
|
runId: run.id,
|
|
69
73
|
run: resolveRunResource(run, context),
|
|
70
74
|
type: schema_1.RunStepType.CANCEL_REQUESTED,
|
|
@@ -72,7 +76,7 @@ function registerRunRoutes(server, options) {
|
|
|
72
76
|
data: { status: run.status },
|
|
73
77
|
createdAt: now,
|
|
74
78
|
}, context);
|
|
75
|
-
sendJson(response, 200, { run });
|
|
79
|
+
sendJson(response, 200, { run: projectRunForApi(run) });
|
|
76
80
|
}
|
|
77
81
|
catch (error) {
|
|
78
82
|
logger.error(`Failed to cancel run: ${error}`);
|
|
@@ -80,18 +84,32 @@ function registerRunRoutes(server, options) {
|
|
|
80
84
|
}
|
|
81
85
|
});
|
|
82
86
|
}
|
|
83
|
-
function
|
|
87
|
+
function projectRunForApi(run) {
|
|
88
|
+
return {
|
|
89
|
+
...run,
|
|
90
|
+
...(0, store_1.deriveRunCommandProjection)(run.id),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function projectRunStepForApi(step) {
|
|
94
|
+
return {
|
|
95
|
+
...step,
|
|
96
|
+
...(0, store_1.deriveRunCommandProjection)(step.runId || step.id),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function parseRunListRequest(url) {
|
|
84
100
|
const workspace = url.searchParams.get('workspace') ?? undefined;
|
|
85
101
|
if (workspace && !(0, types_2.isWorkspaceRef)(workspace)) {
|
|
86
102
|
throw new Error('workspace must be an http(s):// or file:// workspace reference');
|
|
87
103
|
}
|
|
88
104
|
return {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
105
|
+
storeOptions: {
|
|
106
|
+
task: url.searchParams.get('task') ?? undefined,
|
|
107
|
+
thread: url.searchParams.get('thread') ?? undefined,
|
|
108
|
+
workspace,
|
|
109
|
+
status: parseRunStatus(url.searchParams.get('status')),
|
|
110
|
+
limit: parseOptionalNumber(url.searchParams.get('limit')),
|
|
111
|
+
},
|
|
92
112
|
commandKind: parseCommandKind(url.searchParams.get('commandKind')),
|
|
93
|
-
status: parseRunStatus(url.searchParams.get('status')),
|
|
94
|
-
limit: parseOptionalNumber(url.searchParams.get('limit')),
|
|
95
113
|
};
|
|
96
114
|
}
|
|
97
115
|
function parseCommandKind(value) {
|