Files
2026-07-27 15:34:35 +08:00

81 lines
2.4 KiB
JavaScript

import fs from 'node:fs';
const STUB_MARKERS = ['临时补出', '服务号兜底', '服务号自动补出简版页面'];
export function isStubPublicHtmlContent(content) {
const value = String(content ?? '');
return STUB_MARKERS.some((marker) => value.includes(marker));
}
export function artifactFileExists(artifact) {
if (typeof artifact?.exists === 'boolean') {
return artifact.exists;
}
const localPath = String(artifact?.localPath ?? '').trim();
if (!localPath) return false;
try {
return fs.existsSync(localPath) && fs.statSync(localPath).isFile();
} catch {
return false;
}
}
export function isStubPublicHtmlArtifact(artifact) {
if (typeof artifact?.isStub === 'boolean') {
return artifact.isStub;
}
const localPath = String(artifact?.localPath ?? '').trim();
if (!localPath) return false;
try {
return isStubPublicHtmlContent(fs.readFileSync(localPath, 'utf8'));
} catch {
return false;
}
}
/** Real HTML artifacts only — never fall back to stub placeholders. */
export function filterSendableHtmlArtifacts(artifacts = []) {
return artifacts.filter((artifact) => artifactFileExists(artifact) && !isStubPublicHtmlArtifact(artifact));
}
export function selectSendableHtmlArtifacts({ verifiedArtifacts = [], confirmedArtifacts = [] } = {}) {
const candidates = verifiedArtifacts.length > 0 ? verifiedArtifacts : confirmedArtifacts;
return filterSendableHtmlArtifacts(candidates);
}
export function verifyPageArtifactContent(artifact, { minBytes = 512 } = {}) {
if (!artifactFileExists(artifact)) {
return { ok: false, reason: 'missing_file' };
}
if (isStubPublicHtmlArtifact(artifact)) {
return { ok: false, reason: 'stub_placeholder' };
}
if (!String(artifact?.localPath ?? '').trim()) {
if (
Number(artifact?.sizeBytes ?? 0) <
minBytes
) {
return {
ok: false,
reason: 'too_small',
};
}
if (artifact?.isHtmlDocument !== true) {
return {
ok: false,
reason: 'not_html_document',
};
}
return { ok: true, reason: null };
}
const size = fs.statSync(artifact.localPath).size;
if (size < minBytes) {
return { ok: false, reason: 'too_small' };
}
const content = fs.readFileSync(artifact.localPath, 'utf8');
if (!/<(?:html|body|main|article)\b/i.test(content)) {
return { ok: false, reason: 'not_html_document' };
}
return { ok: true, reason: null };
}