Files
memind/scripts/backfill-mindspace-geo.mjs
T
john 357e26ab49
Memind CI / Test, build, and release guards (pull_request) Failing after 7m12s
Memind CI / Test, build, and release guards (push) Has been cancelled
feat(seo-geo): 落盘自动补齐与 143 全量回填支持
Finish/交付写盘前自动回填 mindspace-geo,扩展 storage publications 扫描与 geo meta 解析,并增加 143 生产回填脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 10:26:02 +08:00

118 lines
3.1 KiB
JavaScript

#!/usr/bin/env node
/**
* Batch backfill mindspace-geo / description / minimal cover for HTML pages.
*
* Usage:
* node scripts/backfill-mindspace-geo.mjs [--dry-run] [--no-fix-warnings]
* node scripts/backfill-mindspace-geo.mjs --scope all --user <uuid>
* node scripts/backfill-mindspace-geo.mjs --file public/hello-john.html
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { backfillMindspaceSeoGeoHtml } from '../mindspace-geo-backfill.mjs';
import { collectHtmlTargets } from '../mindspace-seo-audit.mjs';
const repoRoot = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
const DEFAULT_PUBLISH_ROOT = 'MindSpace';
function parseArgs(argv) {
let scope = 'all';
let root = path.join(repoRoot, DEFAULT_PUBLISH_ROOT);
let publicRoot = path.join(repoRoot, 'public');
let storageRoot = null;
let userId = null;
let file = null;
let dryRun = false;
let forceGeo = false;
let fixWarnings = true;
for (let i = 2; i < argv.length; i += 1) {
const arg = argv[i];
if (arg === '--dry-run') dryRun = true;
else if (arg === '--force-geo') forceGeo = true;
else if (arg === '--no-fix-warnings') fixWarnings = false;
else if (arg === '--scope' && argv[i + 1]) {
scope = argv[i + 1];
i += 1;
} else if (arg === '--root' && argv[i + 1]) {
root = path.resolve(argv[i + 1]);
i += 1;
} else if (arg === '--public-root' && argv[i + 1]) {
publicRoot = path.resolve(argv[i + 1]);
i += 1;
} else if (arg === '--storage-root' && argv[i + 1]) {
storageRoot = path.resolve(argv[i + 1]);
i += 1;
} else if (arg === '--user' && argv[i + 1]) {
userId = argv[i + 1];
i += 1;
} else if (arg === '--file' && argv[i + 1]) {
file = path.resolve(argv[i + 1]);
i += 1;
} else if (arg === '--help' || arg === '-h') {
console.log(`Usage: node scripts/backfill-mindspace-geo.mjs [--scope mindspace|platform|all] [--dry-run] [--force-geo] [--user <uuid>] [--file <html>]`);
process.exit(0);
}
}
return {
scope,
root,
publicRoot,
storageRoot,
userId,
file,
dryRun,
forceGeo,
fixWarnings,
};
}
const {
scope,
root,
publicRoot,
storageRoot,
userId,
file,
dryRun,
forceGeo,
fixWarnings,
} = parseArgs(process.argv);
const targets = collectHtmlTargets({
scope,
mindspaceRoot: root,
publicRoot,
storageRoot,
userId,
file,
});
let changed = 0;
let skipped = 0;
for (const htmlPath of targets) {
const before = fs.readFileSync(htmlPath, 'utf8');
const after = backfillMindspaceSeoGeoHtml(before, {
forceGeo,
fixWarnings,
htmlFilePath: htmlPath,
});
if (after === before) {
skipped += 1;
continue;
}
changed += 1;
if (dryRun) {
console.log(`[dry-run] would update ${htmlPath}`);
continue;
}
fs.writeFileSync(htmlPath, after, 'utf8');
console.log(`updated ${htmlPath}`);
}
console.log(
`${dryRun ? '[dry-run] ' : ''}done: ${changed} updated, ${skipped} unchanged, ${targets.length} scanned (scope=${scope})`,
);