fix(plaza): use hero-generated thumbnails and portal cover URLs
Plaza posts now resolve cover_url to /u/{slug}/pages/{urlSlug}.thumbnail.png
instead of MindSpace workspace paths that fail on plaza.tkmind.cn. Public-html
and chat quick-plaza flows regenerate workspace thumbnails with force:true
after hero images are on disk so feed cards embed the generated art.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -255,21 +255,43 @@ export async function quickPlazaFromChat({
|
|||||||
mindSpacePages,
|
mindSpacePages,
|
||||||
mindSpacePublications,
|
mindSpacePublications,
|
||||||
plazaPosts,
|
plazaPosts,
|
||||||
|
ensureWorkspaceHtmlThumbnail,
|
||||||
|
publishDir,
|
||||||
}) {
|
}) {
|
||||||
if (!mindSpacePages || !mindSpacePublications || !plazaPosts) {
|
if (!mindSpacePages || !mindSpacePublications || !plazaPosts) {
|
||||||
throw Object.assign(new Error('Plaza 或 MindSpace 未启用'), { code: 'plaza_unavailable' });
|
throw Object.assign(new Error('Plaza 或 MindSpace 未启用'), { code: 'plaza_unavailable' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { analysis } = bundle;
|
const { analysis, resolvedHtml } = bundle;
|
||||||
const page = await ensureChatPageForPlaza({
|
const page = await ensureChatPageForPlaza({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
bundle,
|
bundle,
|
||||||
mindSpacePages,
|
mindSpacePages,
|
||||||
|
ensureWorkspaceHtmlThumbnail,
|
||||||
publishDir,
|
publishDir,
|
||||||
body,
|
body,
|
||||||
skipThumbnail: true,
|
skipThumbnail: !ensureWorkspaceHtmlThumbnail || !publishDir,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
analysis.contentMode === 'static_html' &&
|
||||||
|
analysis.relativePath &&
|
||||||
|
resolvedHtml?.content &&
|
||||||
|
ensureWorkspaceHtmlThumbnail &&
|
||||||
|
publishDir
|
||||||
|
) {
|
||||||
|
await ensureWorkspaceHtmlThumbnail(
|
||||||
|
publishDir,
|
||||||
|
analysis.relativePath,
|
||||||
|
resolvedHtml.content,
|
||||||
|
{
|
||||||
|
title: page.title,
|
||||||
|
subtitle: page.summary,
|
||||||
|
force: true,
|
||||||
|
},
|
||||||
|
).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
if (analysis.contentMode === 'static_html' && analysis.relativePath) {
|
if (analysis.contentMode === 'static_html' && analysis.relativePath) {
|
||||||
await assertWorkspacePathNotAlreadyOnPlaza({
|
await assertWorkspacePathNotAlreadyOnPlaza({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@@ -372,6 +394,8 @@ export async function quickPlazaFromPublicHtml({
|
|||||||
mindSpacePublications,
|
mindSpacePublications,
|
||||||
plazaPosts,
|
plazaPosts,
|
||||||
readWorkspaceHtml,
|
readWorkspaceHtml,
|
||||||
|
ensureWorkspaceHtmlThumbnail,
|
||||||
|
publishDir,
|
||||||
}) {
|
}) {
|
||||||
if (!mindSpacePages || !mindSpacePublications || !plazaPosts) {
|
if (!mindSpacePages || !mindSpacePublications || !plazaPosts) {
|
||||||
throw Object.assign(new Error('Plaza 或 MindSpace 未启用'), { code: 'plaza_unavailable' });
|
throw Object.assign(new Error('Plaza 或 MindSpace 未启用'), { code: 'plaza_unavailable' });
|
||||||
@@ -396,11 +420,19 @@ export async function quickPlazaFromPublicHtml({
|
|||||||
relativePath: normalized,
|
relativePath: normalized,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const title = titleFromPublicHtml(content, normalized);
|
||||||
|
if (ensureWorkspaceHtmlThumbnail && publishDir) {
|
||||||
|
await ensureWorkspaceHtmlThumbnail(publishDir, normalized, content, {
|
||||||
|
title,
|
||||||
|
force: true,
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
const page = await ensureWorkspaceHtmlPageForPlaza({
|
const page = await ensureWorkspaceHtmlPageForPlaza({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
relativePath: normalized,
|
relativePath: normalized,
|
||||||
content,
|
content,
|
||||||
title: titleFromPublicHtml(content, normalized),
|
title,
|
||||||
mindSpacePages,
|
mindSpacePages,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+83
-13
@@ -43,23 +43,61 @@ export function defaultPlazaCoverUrl(publicUrl) {
|
|||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
const [pathname, suffix = ''] = value.split(/([?#].*)/, 2);
|
const [pathname, suffix = ''] = value.split(/([?#].*)/, 2);
|
||||||
if (!pathname) return '';
|
if (!pathname) return '';
|
||||||
const nextPath = pathname.endsWith('/') ? `${pathname}index.thumbnail.png` : `${pathname}.thumbnail.png`;
|
const normalizedPath = pathname.replace(/\.html$/i, '');
|
||||||
|
const nextPath = normalizedPath.endsWith('/')
|
||||||
|
? `${normalizedPath}index.thumbnail.png`
|
||||||
|
: `${normalizedPath}.thumbnail.png`;
|
||||||
return `${nextPath}${suffix}`;
|
return `${nextPath}${suffix}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizePlazaThumbnailUrl(url) {
|
||||||
|
const value = String(url ?? '').trim();
|
||||||
|
if (!value) return value;
|
||||||
|
return value.replace(/\.html\.thumbnail\.png(?=($|[?#]))/i, '.thumbnail.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMindSpacePlazaCoverUrl(url) {
|
||||||
|
const value = String(url ?? '').trim();
|
||||||
|
return /\/MindSpace\//i.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildPlazaPublicationCoverPath(ownerSlug, urlSlug) {
|
||||||
|
return `/u/${encodeURIComponent(ownerSlug)}/pages/${encodeURIComponent(urlSlug)}.thumbnail.png`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl,
|
||||||
|
publicUrl,
|
||||||
|
publicationUrlSlug = null,
|
||||||
|
userSlug = null,
|
||||||
|
} = {}) {
|
||||||
|
const fallback =
|
||||||
|
publicationUrlSlug && userSlug
|
||||||
|
? buildPlazaPublicationCoverPath(userSlug, publicationUrlSlug)
|
||||||
|
: '';
|
||||||
|
const explicit = String(inputCoverUrl ?? '').trim();
|
||||||
|
if (!explicit) {
|
||||||
|
return resolvePlazaCoverUrl(fallback, fallback.startsWith('/u/') ? '' : publicUrl);
|
||||||
|
}
|
||||||
|
if ((isMindSpacePlazaCoverUrl(explicit) || /\.html\.thumbnail\.png/i.test(explicit)) && fallback) {
|
||||||
|
return resolvePlazaCoverUrl(fallback, '');
|
||||||
|
}
|
||||||
|
return resolvePlazaCoverUrl(explicit, publicUrl);
|
||||||
|
}
|
||||||
|
|
||||||
export function resolvePlazaCoverUrl(inputCoverUrl, publicUrl) {
|
export function resolvePlazaCoverUrl(inputCoverUrl, publicUrl) {
|
||||||
const value = String(inputCoverUrl ?? '').trim();
|
const value = String(inputCoverUrl ?? '').trim();
|
||||||
if (!value) return defaultPlazaCoverUrl(publicUrl);
|
if (!value) return normalizePlazaThumbnailUrl(defaultPlazaCoverUrl(publicUrl));
|
||||||
if (/^https?:\/\//i.test(value)) return value;
|
if (/^https?:\/\//i.test(value)) return normalizePlazaThumbnailUrl(value);
|
||||||
const base = String(publicUrl ?? '').trim();
|
const base = String(publicUrl ?? '').trim();
|
||||||
if (base && /^https?:\/\//i.test(base)) {
|
if (base && /^https?:\/\//i.test(base)) {
|
||||||
try {
|
try {
|
||||||
return new URL(value, base).toString();
|
return normalizePlazaThumbnailUrl(new URL(value, base).toString());
|
||||||
} catch {
|
} catch {
|
||||||
return value;
|
return normalizePlazaThumbnailUrl(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return normalizePlazaThumbnailUrl(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatStats(row) {
|
function formatStats(row) {
|
||||||
@@ -91,11 +129,18 @@ function promoteFreshPosts(items, now = Date.now()) {
|
|||||||
|
|
||||||
function formatPostRow(row, { category, viewerReacted = null, publicationUrl = null } = {}) {
|
function formatPostRow(row, { category, viewerReacted = null, publicationUrl = null } = {}) {
|
||||||
const resolvedPublicationUrl = publicationUrl ?? row.public_url ?? null;
|
const resolvedPublicationUrl = publicationUrl ?? row.public_url ?? null;
|
||||||
|
const publicationUrlSlug =
|
||||||
|
row.publication_url_slug ?? row.url_slug ?? null;
|
||||||
return {
|
return {
|
||||||
id: row.id,
|
id: row.id,
|
||||||
title: row.title,
|
title: row.title,
|
||||||
summary: row.summary ?? '',
|
summary: row.summary ?? '',
|
||||||
cover_url: resolvePlazaCoverUrl(row.cover_url, resolvedPublicationUrl),
|
cover_url: resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: row.cover_url,
|
||||||
|
publicUrl: resolvedPublicationUrl,
|
||||||
|
publicationUrlSlug,
|
||||||
|
userSlug: row.user_slug,
|
||||||
|
}),
|
||||||
category: category ?? {
|
category: category ?? {
|
||||||
id: row.category_id,
|
id: row.category_id,
|
||||||
name: row.category_name ?? '',
|
name: row.category_name ?? '',
|
||||||
@@ -123,6 +168,8 @@ export const plazaInternals = {
|
|||||||
clampLimit,
|
clampLimit,
|
||||||
normalizeSort,
|
normalizeSort,
|
||||||
defaultPlazaCoverUrl,
|
defaultPlazaCoverUrl,
|
||||||
|
buildPlazaPublicationCoverPath,
|
||||||
|
resolvePlazaPublicationCoverUrl,
|
||||||
resolvePlazaCoverUrl,
|
resolvePlazaCoverUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -219,7 +266,7 @@ export function createPlazaPostService(
|
|||||||
|
|
||||||
const loadPublicationContext = async (userId, publicationId) => {
|
const loadPublicationContext = async (userId, publicationId) => {
|
||||||
const [rows] = await pool.query(
|
const [rows] = await pool.query(
|
||||||
`SELECT pr.id, pr.user_id, pr.status, pr.public_url,
|
`SELECT pr.id, pr.user_id, pr.status, pr.public_url, pr.url_slug,
|
||||||
p.title, p.summary, p.cover_image_asset_id
|
p.title, p.summary, p.cover_image_asset_id
|
||||||
FROM h5_publish_records pr
|
FROM h5_publish_records pr
|
||||||
JOIN h5_page_records p ON p.id = pr.page_id
|
JOIN h5_page_records p ON p.id = pr.page_id
|
||||||
@@ -327,7 +374,12 @@ export function createPlazaPostService(
|
|||||||
const categoryId = await resolveCategoryId(input?.category_id, input?.category_slug);
|
const categoryId = await resolveCategoryId(input?.category_id, input?.category_slug);
|
||||||
const userSnapshot = await loadUserSnapshot(userId);
|
const userSnapshot = await loadUserSnapshot(userId);
|
||||||
const tags = normalizeTags(input?.tags);
|
const tags = normalizeTags(input?.tags);
|
||||||
const coverUrl = resolvePlazaCoverUrl(input?.cover_url, publication.public_url);
|
const coverUrl = resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: input?.cover_url,
|
||||||
|
publicUrl: publication.public_url,
|
||||||
|
publicationUrlSlug: publication.url_slug,
|
||||||
|
userSlug: userSnapshot.user_slug,
|
||||||
|
});
|
||||||
const allowComment = input?.allow_comment == null ? true : Boolean(input.allow_comment);
|
const allowComment = input?.allow_comment == null ? true : Boolean(input.allow_comment);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const postId = idFactory();
|
const postId = idFactory();
|
||||||
@@ -391,7 +443,7 @@ export function createPlazaPostService(
|
|||||||
|
|
||||||
const updatePost = async (userId, postId, input) => {
|
const updatePost = async (userId, postId, input) => {
|
||||||
const [rows] = await pool.query(
|
const [rows] = await pool.query(
|
||||||
`SELECT pp.*, pr.public_url
|
`SELECT pp.*, pr.public_url, pr.url_slug AS publication_url_slug
|
||||||
FROM plaza_posts pp
|
FROM plaza_posts pp
|
||||||
JOIN h5_publish_records pr ON pr.id = pp.publication_id
|
JOIN h5_publish_records pr ON pr.id = pp.publication_id
|
||||||
WHERE pp.id = ? AND pp.user_id = ? LIMIT 1`,
|
WHERE pp.id = ? AND pp.user_id = ? LIMIT 1`,
|
||||||
@@ -413,7 +465,14 @@ export function createPlazaPostService(
|
|||||||
}
|
}
|
||||||
if (input?.cover_url != null) {
|
if (input?.cover_url != null) {
|
||||||
updates.push('cover_url = ?');
|
updates.push('cover_url = ?');
|
||||||
params.push(resolvePlazaCoverUrl(input.cover_url, post.public_url));
|
params.push(
|
||||||
|
resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: input.cover_url,
|
||||||
|
publicUrl: post.public_url,
|
||||||
|
publicationUrlSlug: post.publication_url_slug,
|
||||||
|
userSlug: post.user_slug,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (input?.allow_comment != null) {
|
if (input?.allow_comment != null) {
|
||||||
updates.push('allow_comment = ?');
|
updates.push('allow_comment = ?');
|
||||||
@@ -456,7 +515,8 @@ export function createPlazaPostService(
|
|||||||
const getPostById = async (postId, { viewerId = null, includeHidden = false } = {}) => {
|
const getPostById = async (postId, { viewerId = null, includeHidden = false } = {}) => {
|
||||||
const statusClause = includeHidden ? '' : `AND pp.status = 'published'`;
|
const statusClause = includeHidden ? '' : `AND pp.status = 'published'`;
|
||||||
const [rows] = await pool.query(
|
const [rows] = await pool.query(
|
||||||
`SELECT pp.*, c.name AS category_name, c.slug AS category_slug, c.icon AS category_icon, pr.public_url
|
`SELECT pp.*, c.name AS category_name, c.slug AS category_slug, c.icon AS category_icon,
|
||||||
|
pr.public_url, pr.url_slug AS publication_url_slug
|
||||||
FROM plaza_posts pp
|
FROM plaza_posts pp
|
||||||
JOIN plaza_categories c ON c.id = pp.category_id
|
JOIN plaza_categories c ON c.id = pp.category_id
|
||||||
JOIN h5_publish_records pr ON pr.id = pp.publication_id
|
JOIN h5_publish_records pr ON pr.id = pp.publication_id
|
||||||
@@ -499,6 +559,15 @@ export function createPlazaPostService(
|
|||||||
if (!cursor && normalizedSort !== 'recommend' && plazaRedis?.getFeedCache) {
|
if (!cursor && normalizedSort !== 'recommend' && plazaRedis?.getFeedCache) {
|
||||||
const cached = await plazaRedis.getFeedCache(normalizedSort, categorySlug, null);
|
const cached = await plazaRedis.getFeedCache(normalizedSort, categorySlug, null);
|
||||||
if (cached?.posts) {
|
if (cached?.posts) {
|
||||||
|
cached.posts = cached.posts.map((post) => ({
|
||||||
|
...post,
|
||||||
|
cover_url: resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: post.cover_url,
|
||||||
|
publicUrl: post.publication_url,
|
||||||
|
publicationUrlSlug: post.publication_url_slug,
|
||||||
|
userSlug: post.author?.slug ?? post.user_slug,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
if (viewerId && loadViewerReactions) {
|
if (viewerId && loadViewerReactions) {
|
||||||
const reactionMap = await loadViewerReactions(
|
const reactionMap = await loadViewerReactions(
|
||||||
viewerId,
|
viewerId,
|
||||||
@@ -546,7 +615,8 @@ export function createPlazaPostService(
|
|||||||
: 'pp.hot_score DESC, pp.id DESC';
|
: 'pp.hot_score DESC, pp.id DESC';
|
||||||
|
|
||||||
const [rows] = await pool.query(
|
const [rows] = await pool.query(
|
||||||
`SELECT pp.*, c.name AS category_name, c.slug AS category_slug, c.icon AS category_icon, pr.public_url
|
`SELECT pp.*, c.name AS category_name, c.slug AS category_slug, c.icon AS category_icon,
|
||||||
|
pr.public_url, pr.url_slug AS publication_url_slug
|
||||||
FROM plaza_posts pp
|
FROM plaza_posts pp
|
||||||
JOIN plaza_categories c ON c.id = pp.category_id
|
JOIN plaza_categories c ON c.id = pp.category_id
|
||||||
JOIN h5_publish_records pr ON pr.id = pp.publication_id
|
JOIN h5_publish_records pr ON pr.id = pp.publication_id
|
||||||
|
|||||||
@@ -53,6 +53,47 @@ test('resolvePlazaCoverUrl prefers explicit cover urls and falls back to publica
|
|||||||
plazaInternals.resolvePlazaCoverUrl('', '/u/john/pages/demo'),
|
plazaInternals.resolvePlazaCoverUrl('', '/u/john/pages/demo'),
|
||||||
'/u/john/pages/demo.thumbnail.png',
|
'/u/john/pages/demo.thumbnail.png',
|
||||||
);
|
);
|
||||||
|
assert.equal(
|
||||||
|
plazaInternals.defaultPlazaCoverUrl('/MindSpace/user/public/page.html'),
|
||||||
|
'/MindSpace/user/public/page.thumbnail.png',
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
plazaInternals.resolvePlazaCoverUrl(
|
||||||
|
'https://m.tkmind.cn/MindSpace/u/public/demo.html.thumbnail.png',
|
||||||
|
'/u/john/pages/demo',
|
||||||
|
),
|
||||||
|
'https://m.tkmind.cn/MindSpace/u/public/demo.thumbnail.png',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('resolvePlazaPublicationCoverUrl prefers portal publication thumbnail over MindSpace cover', () => {
|
||||||
|
assert.equal(
|
||||||
|
plazaInternals.resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: '',
|
||||||
|
publicUrl: 'https://m.tkmind.cn/MindSpace/wx_ul610et8/public/demo.html',
|
||||||
|
publicationUrlSlug: 'plaza-batch-001',
|
||||||
|
userSlug: 'wx_ul610et8',
|
||||||
|
}),
|
||||||
|
'/u/wx_ul610et8/pages/plaza-batch-001.thumbnail.png',
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
plazaInternals.resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: 'https://m.tkmind.cn/MindSpace/wx_ul610et8/public/demo.html.thumbnail.png',
|
||||||
|
publicUrl: 'https://m.tkmind.cn/MindSpace/wx_ul610et8/public/demo.html',
|
||||||
|
publicationUrlSlug: 'plaza-batch-001',
|
||||||
|
userSlug: 'wx_ul610et8',
|
||||||
|
}),
|
||||||
|
'/u/wx_ul610et8/pages/plaza-batch-001.thumbnail.png',
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
plazaInternals.resolvePlazaPublicationCoverUrl({
|
||||||
|
inputCoverUrl: 'https://cdn.example.com/cover.png',
|
||||||
|
publicUrl: '/u/john/pages/demo',
|
||||||
|
publicationUrlSlug: 'demo',
|
||||||
|
userSlug: 'john',
|
||||||
|
}),
|
||||||
|
'https://cdn.example.com/cover.png',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('mapPlazaError maps documented API codes', () => {
|
test('mapPlazaError maps documented API codes', () => {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import {
|
|||||||
quickPlazaFromChat,
|
quickPlazaFromChat,
|
||||||
quickPlazaFromPublicHtml,
|
quickPlazaFromPublicHtml,
|
||||||
} from '../mindspace-chat-plaza.mjs';
|
} from '../mindspace-chat-plaza.mjs';
|
||||||
|
import { resolveMindSpaceUserPublishDir } from '../mindspace-runtime-config.mjs';
|
||||||
|
import { ensureWorkspaceHtmlThumbnail } from '../mindspace-workspace-thumbnails.mjs';
|
||||||
|
|
||||||
function assertRouter(api) {
|
function assertRouter(api) {
|
||||||
if (
|
if (
|
||||||
@@ -41,6 +43,8 @@ export function attachPortalMindSpaceChatShareRoutes(
|
|||||||
getQuickPlazaFromPublicHtmlStatusFn =
|
getQuickPlazaFromPublicHtmlStatusFn =
|
||||||
getQuickPlazaFromPublicHtmlStatus,
|
getQuickPlazaFromPublicHtmlStatus,
|
||||||
quickPlazaFromPublicHtmlFn = quickPlazaFromPublicHtml,
|
quickPlazaFromPublicHtmlFn = quickPlazaFromPublicHtml,
|
||||||
|
ensureWorkspaceHtmlThumbnailFn = ensureWorkspaceHtmlThumbnail,
|
||||||
|
resolveMindSpaceUserPublishDirFn = resolveMindSpaceUserPublishDir,
|
||||||
now = Date.now,
|
now = Date.now,
|
||||||
logger = console,
|
logger = console,
|
||||||
} = {},
|
} = {},
|
||||||
@@ -114,6 +118,7 @@ export function attachPortalMindSpaceChatShareRoutes(
|
|||||||
h5Root,
|
h5Root,
|
||||||
req.body,
|
req.body,
|
||||||
);
|
);
|
||||||
|
const publishDir = resolveMindSpaceUserPublishDirFn(h5Root, req.currentUser);
|
||||||
const result = await quickPlazaFromChatFn({
|
const result = await quickPlazaFromChatFn({
|
||||||
user: req.currentUser,
|
user: req.currentUser,
|
||||||
bundle,
|
bundle,
|
||||||
@@ -121,6 +126,8 @@ export function attachPortalMindSpaceChatShareRoutes(
|
|||||||
mindSpacePages: pages,
|
mindSpacePages: pages,
|
||||||
mindSpacePublications: publications,
|
mindSpacePublications: publications,
|
||||||
plazaPosts,
|
plazaPosts,
|
||||||
|
ensureWorkspaceHtmlThumbnail: ensureWorkspaceHtmlThumbnailFn,
|
||||||
|
publishDir,
|
||||||
});
|
});
|
||||||
logger.info('[quick-plaza] ok', {
|
logger.info('[quick-plaza] ok', {
|
||||||
ms: now() - startedAt,
|
ms: now() - startedAt,
|
||||||
@@ -214,6 +221,7 @@ export function attachPortalMindSpaceChatShareRoutes(
|
|||||||
req.body?.relativePath ??
|
req.body?.relativePath ??
|
||||||
'',
|
'',
|
||||||
).trim();
|
).trim();
|
||||||
|
const publishDir = resolveMindSpaceUserPublishDirFn(h5Root, req.currentUser);
|
||||||
const result = await quickPlazaFromPublicHtmlFn({
|
const result = await quickPlazaFromPublicHtmlFn({
|
||||||
user: req.currentUser,
|
user: req.currentUser,
|
||||||
relativePath,
|
relativePath,
|
||||||
@@ -222,6 +230,8 @@ export function attachPortalMindSpaceChatShareRoutes(
|
|||||||
plazaPosts,
|
plazaPosts,
|
||||||
readWorkspaceHtml: (input) =>
|
readWorkspaceHtml: (input) =>
|
||||||
chatSave.readWorkspaceHtml(input),
|
chatSave.readWorkspaceHtml(input),
|
||||||
|
ensureWorkspaceHtmlThumbnail: ensureWorkspaceHtmlThumbnailFn,
|
||||||
|
publishDir,
|
||||||
});
|
});
|
||||||
const plazaUrl = resolvePlazaPostUrl(
|
const plazaUrl = resolvePlazaPostUrl(
|
||||||
result.post.id,
|
result.post.id,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import test from 'node:test';
|
import test from 'node:test';
|
||||||
import { attachPortalMindSpaceChatShareRoutes } from './portal-mindspace-chat-share-routes.mjs';
|
import { attachPortalMindSpaceChatShareRoutes } from './portal-mindspace-chat-share-routes.mjs';
|
||||||
|
import { resolveMindSpaceUserPublishDir } from '../mindspace-runtime-config.mjs';
|
||||||
|
import { ensureWorkspaceHtmlThumbnail } from '../mindspace-workspace-thumbnails.mjs';
|
||||||
|
|
||||||
function createRouterRecorder() {
|
function createRouterRecorder() {
|
||||||
const routes = new Map();
|
const routes = new Map();
|
||||||
@@ -194,6 +196,8 @@ test('quick Plaza from chat preserves dependencies, timing, result, and errors',
|
|||||||
mindSpacePages: dependencies.services.pages,
|
mindSpacePages: dependencies.services.pages,
|
||||||
mindSpacePublications: dependencies.services.publications,
|
mindSpacePublications: dependencies.services.publications,
|
||||||
plazaPosts: dependencies.services.plazaPosts,
|
plazaPosts: dependencies.services.plazaPosts,
|
||||||
|
ensureWorkspaceHtmlThumbnail,
|
||||||
|
publishDir: resolveMindSpaceUserPublishDir('/workspace', req.currentUser),
|
||||||
});
|
});
|
||||||
|
|
||||||
const failureApi = createRouterRecorder();
|
const failureApi = createRouterRecorder();
|
||||||
|
|||||||
Reference in New Issue
Block a user