Files
memind/mindspace-conversation-package-routes.mjs
T

145 lines
5.5 KiB
JavaScript

function defaultSendData(res, _req, data) {
return res.json({ data });
}
function defaultRouteError(res, _req, error) {
return res.status(500).json({ message: error?.message || 'MindSpace 服务异常' });
}
function resolveRegistry(input) {
return typeof input === 'function' ? input() : input;
}
function encodeDownloadFilename(filename) {
const safe = String(filename ?? '').trim() || 'mindspace-artifact';
return `attachment; filename="${encodeURIComponent(safe)}"; filename*=UTF-8''${encodeURIComponent(safe)}`;
}
export function createGetConversationPackageHandler({
registry,
getRegistry,
userAuth,
getUserAuth,
ensureMindSpaceEnabled = () => true,
sendData = defaultSendData,
mindSpaceError = defaultRouteError,
beforeReadManifest,
} = {}) {
return async function getConversationPackage(req, res) {
const activeRegistry = resolveRegistry(getRegistry ?? registry);
if (!activeRegistry || !ensureMindSpaceEnabled(res, req)) {
if (res.headersSent) return undefined;
return res.status(503).json({ message: 'MindSpace 对话包未启用' });
}
const sessionId = String(req.params?.sessionId ?? '').trim();
if (!sessionId) return res.status(400).json({ message: '缺少 sessionId' });
try {
const activeUserAuth = resolveRegistry(getUserAuth ?? userAuth);
if (!(await activeUserAuth.ownsSession(req.currentUser.id, sessionId))) {
return res.status(403).json({ message: '无权访问该会话' });
}
if (typeof beforeReadManifest === 'function') {
await beforeReadManifest({ req, userId: req.currentUser.id, sessionId });
}
const manifest = await activeRegistry.readManifestForSession({
userId: req.currentUser.id,
sessionId,
});
if (!manifest) return res.status(404).json({ message: '对话包不存在' });
return sendData(res, req, manifest);
} catch (error) {
return mindSpaceError(res, req, error);
}
};
}
export function createDownloadConversationPackageManifestHandler({
registry,
getRegistry,
userAuth,
getUserAuth,
ensureMindSpaceEnabled = () => true,
mindSpaceError = defaultRouteError,
beforeReadManifest,
} = {}) {
return async function downloadConversationPackageManifest(req, res) {
const activeRegistry = resolveRegistry(getRegistry ?? registry);
if (!activeRegistry || !ensureMindSpaceEnabled(res, req)) {
if (res.headersSent) return undefined;
return res.status(503).json({ message: 'MindSpace 对话包未启用' });
}
const sessionId = String(req.params?.sessionId ?? '').trim();
if (!sessionId) return res.status(400).json({ message: '缺少 sessionId' });
try {
const activeUserAuth = resolveRegistry(getUserAuth ?? userAuth);
if (!(await activeUserAuth.ownsSession(req.currentUser.id, sessionId))) {
return res.status(403).json({ message: '无权访问该会话' });
}
if (typeof beforeReadManifest === 'function') {
await beforeReadManifest({ req, userId: req.currentUser.id, sessionId });
}
const manifest = await activeRegistry.readManifestForSession({
userId: req.currentUser.id,
sessionId,
});
if (!manifest) return res.status(404).json({ message: '对话包不存在' });
const filename = `${manifest.packageId || sessionId}-manifest.json`;
res.set('Content-Type', 'application/json; charset=utf-8');
res.set('Content-Disposition', encodeDownloadFilename(filename));
res.set('Cache-Control', 'private, no-store');
if (req.requestId) res.setHeader('X-Request-Id', req.requestId);
return res.send(`${JSON.stringify(manifest, null, 2)}\n`);
} catch (error) {
return mindSpaceError(res, req, error);
}
};
}
export function createDownloadConversationPackageArtifactHandler({
registry,
getRegistry,
userAuth,
getUserAuth,
ensureMindSpaceEnabled = () => true,
mindSpaceError = defaultRouteError,
} = {}) {
return async function downloadConversationPackageArtifact(req, res) {
const activeRegistry = resolveRegistry(getRegistry ?? registry);
if (!activeRegistry || !ensureMindSpaceEnabled(res, req)) {
if (res.headersSent) return undefined;
return res.status(503).json({ message: 'MindSpace 对话包未启用' });
}
const sessionId = String(req.params?.sessionId ?? '').trim();
const artifactId = String(req.params?.artifactId ?? '').trim();
if (!sessionId) return res.status(400).json({ message: '缺少 sessionId' });
if (!artifactId) return res.status(400).json({ message: '缺少 artifactId' });
try {
const activeUserAuth = resolveRegistry(getUserAuth ?? userAuth);
if (!(await activeUserAuth.ownsSession(req.currentUser.id, sessionId))) {
return res.status(403).json({ message: '无权访问该会话' });
}
const result = await activeRegistry.readArtifactObject({
userId: req.currentUser.id,
sessionId,
artifactId,
});
if (!result) return res.status(404).json({ message: '文件不存在' });
const filename = result.artifact.displayName || result.artifact.id;
res.set('Content-Type', result.artifact.mimeType || 'application/octet-stream');
res.set('Content-Disposition', encodeDownloadFilename(filename));
res.set('Cache-Control', 'private, no-store');
if (req.requestId) res.setHeader('X-Request-Id', req.requestId);
return res.send(result.body);
} catch (error) {
return mindSpaceError(res, req, error);
}
};
}
export const conversationPackageRouteInternals = {
encodeDownloadFilename,
};