import fs from 'node:fs'; import path from 'node:path'; import { PUBLISH_KEY_UUID, PUBLISH_ROOT_DIR } from './user-publish.mjs'; import { normalizeWorkspaceRelativePath } from './mindspace-pages.mjs'; const LOCAL_HOST_PATTERN = /^(localhost|127\.0\.0\.1|\[::1\]|192\.168\.|10\.|100\.)/i; export function resolvePublicRequestOrigin({ hostHeader = '', forwardedProto = '', protocol = 'http' } = {}) { const host = String(hostHeader ?? '').split(',')[0].trim(); if (!host) return ''; const fwdProto = String(forwardedProto ?? '').split(',')[0].trim(); const isLocalHost = LOCAL_HOST_PATTERN.test(host); const resolvedProtocol = isLocalHost ? fwdProto || protocol || 'http' : 'https'; return `${resolvedProtocol}://${host}`; } export function buildPublishedHtmlViewContext({ origin = '', requestPath = '', filePath = '', thumbnailPngPathForSvg = (value) => value, fileExists = fs.existsSync, } = {}) { const cleanPath = String(requestPath ?? '').split('?')[0].split('#')[0]; const servedName = path.basename(String(filePath ?? '')); const urlLast = decodeURIComponent(cleanPath.split('/').filter(Boolean).pop() ?? ''); const isImplicitIndex = urlLast.toLowerCase() !== servedName.toLowerCase(); const pageUrl = !origin ? '' : `${origin}${isImplicitIndex && !cleanPath.endsWith('/') ? `${cleanPath}/` : cleanPath}`; const pageDirUrl = !origin ? '' : isImplicitIndex ? `${origin}${cleanPath.endsWith('/') ? cleanPath : `${cleanPath}/`}` : `${origin}${cleanPath.slice(0, cleanPath.lastIndexOf('/') + 1)}`; let fallbackImageUrl = ''; const svgSibling = String(filePath ?? '').replace(/\.[^./]+$/, '.thumbnail.svg'); if (pageDirUrl && fileExists(svgSibling)) { const pngName = path.basename(thumbnailPngPathForSvg(svgSibling)); fallbackImageUrl = `${pageDirUrl}${pngName}`; } return { origin, cleanPath, pageUrl, pageDirUrl, fallbackImageUrl, }; } export function parseMindSpacePublishFilePath(absoluteFilePath, h5Root) { const resolved = path.resolve(String(absoluteFilePath ?? '')); const publishRoot = path.resolve(h5Root, PUBLISH_ROOT_DIR); if (resolved !== publishRoot && !resolved.startsWith(`${publishRoot}${path.sep}`)) { return null; } const rest = resolved.slice(publishRoot.length + 1).split(path.sep).filter(Boolean); if (rest.length < 2) return null; const ownerKey = String(rest[0] ?? '').trim().toLowerCase(); if (!PUBLISH_KEY_UUID.test(ownerKey)) return null; const relativePath = normalizeWorkspaceRelativePath(rest.slice(1).join('/')); if (!relativePath) return null; return { userId: ownerKey, relativePath }; } export function buildMindSpacePageDataPayload({ pageId, accessMode = null } = {}) { const id = String(pageId ?? '').trim(); if (!id) return null; const payload = { pageId: id }; const mode = String(accessMode ?? '').trim(); if (mode) payload.accessMode = mode; return payload; } export function injectMindSpacePageDataContext(html, context = {}) { const payload = buildMindSpacePageDataPayload(context); if (!payload) return String(html ?? ''); let nextHtml = String(html ?? ''); const serialized = JSON.stringify(payload).replace(/`, ``, ].join('\n'); if (/<\/head>/i.test(nextHtml)) { return nextHtml.replace(/<\/head>/i, `${injection}\n`); } if (/