import { existsSync } from 'node:fs';
import { resolve } from 'node:path';
import { TeknavData } from '../teknav-data.js';
const today = new Date().toISOString().slice(0, 10);
function clean(value) {
return String(value ?? '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
}
function isPastOrTodayDate(date) {
const value = String(date ?? '').slice(0, 10);
return /^\d{4}-\d{2}-\d{2}$/.test(value) && value <= today;
}
function isPublishedArticle(article) {
if (article.status === 'منتشرشده') return true;
if (article.status === 'پیشنویس' || article.status === 'در انتظار بررسی') return false;
return !!article.dateEn;
}
function ogImageExists(article) {
const image = article.ogImage || `/images/og/${article.slug}.jpg`;
return existsSync(resolve(`public${image}`));
}
const problems = [];
const warnings = [];
const rows = TeknavData.articles
.filter((article) => isPublishedArticle(article) && isPastOrTodayDate(article.dateEn))
.map((article) => {
const h2 = (article.content?.match(/
= 120,
keywords: keywordCount >= 7,
headings: h2 >= 4,
body: words >= 600,
image: ogImageExists(article),
reviewed: !!article.factCheckedAt,
canonical: !!article.canonicalPath,
};
for (const [name, ok] of Object.entries({
meta: checks.meta,
headings: checks.headings,
image: checks.image,
reviewed: checks.reviewed,
canonical: checks.canonical,
})) {
if (!ok) problems.push(`${article.slug}: ${name}`);
}
if (!checks.keywords) warnings.push(`${article.slug}: broaden keywords/tags`);
if (!checks.body) warnings.push(`${article.slug}: consider expanding article body`);
return {
slug: article.slug,
words,
h2,
keywordCount,
metaLength: clean(article.metaDescription).length,
image: checks.image,
reviewed: checks.reviewed,
};
});
console.table(rows);
if (problems.length > 0) {
console.error(`[seo-quality] ${problems.length} issue(s):`);
for (const problem of problems) console.error(`- ${problem}`);
process.exit(1);
}
if (warnings.length > 0) {
console.warn(`[seo-quality] ${warnings.length} warning(s):`);
for (const warning of warnings) console.warn(`- ${warning}`);
}
console.log(`[seo-quality] passed ${rows.length} Persian indexable articles`);