Files
memind/wechat/verify/share-preview.mjs
john b5a88d9746 fix(brand): require TKMind platform marker on wechat page delivery
Backfill missing platform-brand footer at serve time and block service-
account links when the HTML file omits data-mindspace-page-tag.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 14:15:42 +08:00

71 lines
2.5 KiB
JavaScript

import fs from 'node:fs';
import { artifactFileExists } from './page-artifact.mjs';
import { hasPlatformBrandMarker } from '../../mindspace-page-tag.mjs';
export { hasPlatformBrandMarker };
const RASTER_IMAGE_PATTERN = /\.(png|jpe?g|webp|gif)(?:[?#]|$)/i;
export function hasMindspaceCoverMeta(html) {
return /<meta[^>]*name=["']mindspace-cover["']/i.test(String(html ?? ''));
}
export function hasShareDescription(html) {
const source = String(html ?? '');
return (
/<meta[^>]+property=["']og:description["']/i.test(source) ||
/<meta[^>]+name=["']description["']/i.test(source)
);
}
export function hasRasterShareImageHint(html) {
const source = String(html ?? '');
if (/<meta[^>]+property=["']og:image["'][^>]+content=["'][^"']+/i.test(source)) {
const match =
source.match(/<meta[^>]+property=["']og:image["'][^>]+content=["']([^"']+)["']/i) ??
source.match(/<meta[^>]+content=["']([^"']+)["'][^>]+property=["']og:image["']/i);
const url = match?.[1] ?? '';
if (url && !/\.svg(?:[?#]|$)/i.test(url)) return true;
}
const coverMatch = source.match(/<meta[^>]*name=["']mindspace-cover["'][^>]*content=(["'])([\s\S]*?)\1/i);
if (!coverMatch?.[2]) return false;
try {
const meta = JSON.parse(coverMatch[2].replaceAll('&quot;', '"'));
const cover = String(meta.cover ?? meta.image ?? '').trim();
if (!cover) return false;
if (/^https?:\/\//i.test(cover)) return RASTER_IMAGE_PATTERN.test(cover);
return RASTER_IMAGE_PATTERN.test(cover) || !/\.svg(?:[?#]|$)/i.test(cover);
} catch {
return false;
}
}
/**
* WeChat link cards need mindspace-cover (for thumbnail.png) + description.
* Visual pages should also reference a raster hero in cover/image when possible.
*/
export function verifySharePreviewMeta(html) {
if (!hasMindspaceCoverMeta(html)) {
return { ok: false, reason: 'missing_mindspace_cover' };
}
if (!hasShareDescription(html)) {
return { ok: false, reason: 'missing_description' };
}
if (!hasPlatformBrandMarker(html)) {
return { ok: false, reason: 'missing_platform_brand' };
}
return { ok: true, reason: null };
}
export function verifyArtifactSharePreview(artifact) {
if (!artifactFileExists(artifact)) {
return { ok: false, reason: 'missing_file' };
}
const content = fs.readFileSync(artifact.localPath, 'utf8');
return verifySharePreviewMeta(content);
}
export function filterSharePreviewReadyArtifacts(artifacts = []) {
return artifacts.filter((artifact) => verifyArtifactSharePreview(artifact).ok);
}